9.7 KiB
// File: specs/100-Infrastructures/134-ai-model-change/spec.md // Change Log: // - 2026-06-03: Initial specification for Thai-Optimized AI Model Stack (ADR-034)
Feature Specification: Thai-Optimized AI Model Stack
Feature Branch: 134-ai-model-change
Created: 2026-06-03
Status: Draft
Category: 100-Infrastructures
ADR Reference: ADR-034 (Supersedes ADR-023A Section 2.1)
Input: User description: "Implement ADR-034 — Switch AI model stack from gemma4:e2b to Thai-optimized Typhoon series: typhoon2.5-np-dms:latest (main AI) + typhoon-np-dms-ocr:latest (Thai OCR). Requires model switching logic in BullMQ processor, new unload/load methods in OllamaService, updated default model config. VRAM budget: RTX 2060 Super 8GB."
User Scenarios & Testing (mandatory)
User Story 1 — Thai OCR Extraction With New OCR Model (Priority: P1)
ในฐานะ DevOps Engineer ฉันต้องการให้งาน OCR ภาษาไทยใช้ Typhoon OCR-3B ที่ถูก fine-tune มาสำหรับภาษาไทย เพื่อให้ข้อความที่สกัดจาก PDF ภาษาไทยมีความแม่นยำสูงกว่า gemma4:e2b
Why this priority: งาน OCR ภาษาไทยคือจุดอ่อนหลักของระบบปัจจุบัน การเปลี่ยนเป็น Typhoon OCR model จะส่งผลโดยตรงต่อคุณภาพการ extract metadata และ text จากเอกสาร
Independent Test: ส่ง OCR job (jobType: 'ocr-extract') เข้า BullMQ ด้วย PDF ภาษาไทย และตรวจสอบว่า (1) job สำเร็จโดยไม่มี VRAM OOM error (2) ข้อความ OCR อ่านออกได้ (3) หลัง OCR เสร็จ main model ยังพร้อมใช้งาน
Acceptance Scenarios:
- Given
typhoon-np-dms-ocr:latestถูก create บน Desk-5439, When BullMQ ได้รับ jobocr-extractหรือsandbox-ocr-only, Then processor unload main model → load OCR model (keep_alive:0) → ประมวลผล → OCR model unload อัตโนมัติ - Given OCR job เสร็จแล้ว, When main model job เข้ามาต่อ, Then processor reload main model และประมวลผลสำเร็จภายใน 60 วินาที
- Given VRAM ถูกใช้งานสูงขณะมี OCR job, When job เข้าคิว, Then BullMQ concurrency=1 ป้องกัน VRAM overflow — ไม่เกิด OOM error
User Story 2 — General AI Tasks Use Thai-Optimized Main Model (Priority: P2)
ในฐานะ DevOps Engineer ฉันต้องการให้ระบบ AI ใช้ typhoon2.5-np-dms:latest เป็น main model สำหรับงาน extraction, RAG Q&A, และ AI suggestion แทน gemma4:e2b เพื่อประสิทธิภาพภาษาไทยที่ดีขึ้น
Why this priority: เมื่อ OCR ทำงานได้แล้ว ต้องมั่นใจว่า AI extraction/RAG ที่ใช้ main model ทำงานได้กับโมเดลใหม่
Independent Test: ส่ง ai-extract job เข้า BullMQ → ตรวจสอบว่า backend เรียก typhoon2.5-np-dms:latest (ไม่ใช่ gemma4:e2b) และได้ผลลัพธ์ที่ถูกต้อง
Acceptance Scenarios:
- Given
typhoon2.5-np-dms:latestถูก create บน Desk-5439, When backend start up, ThenAiSettingsService.DEFAULT_MODEL = 'typhoon2.5-np-dms:latest' - Given main model พร้อม, When ส่ง extraction/RAG/suggestion job, Then ผลลัพธ์ return โดยไม่มี "model not found" error
- Given การ reload main model หลัง OCR job, When warm reload, Then ใช้เวลา ≤ 60 วินาที (cold start acceptable)
User Story 3 — System Health Reflects New Model Stack (Priority: P3)
ในฐานะ AI Admin ฉันต้องการเห็นสถานะของ model stack ใหม่ใน AI Admin Console เพื่อยืนยันว่าระบบทำงานถูกต้องหลัง deploy
Why this priority: Operations team ต้องการ observability เพื่อตรวจสอบหลัง deployment
Independent Test: เปิด AI Admin Console → System Health → เห็นชื่อ typhoon2.5-np-dms และ typhoon-np-dms-ocr แทน gemma4
Acceptance Scenarios:
- Given backend รันกับ model stack ใหม่, When GET
/api/ai/health, Then response แสดง main model =typhoon2.5-np-dms:latestและ ocr model =typhoon-np-dms-ocr:latest - Given มี model switching เกิดขึ้น, When ดู BullMQ job logs, Then เห็น log บันทึก unload/load พร้อม model name และ timestamp
Edge Cases
- VRAM เต็ม (>8GB) ขณะ load OCR model → BullMQ retry; ไม่ crash; error log ชัดเจน
- Ollama API timeout ขณะ
unloadModel/loadModel→ throw descriptive error; ไม่ swallow silently - โมเดล
typhoon2.5-np-dmsไม่ถูก create บน Desk-5439 → backend start ได้; job fail พร้อม clear "model not found" error - OCR job และ main job เข้าคิวพร้อมกัน → BullMQ concurrency=1 handle อยู่แล้ว; ไม่ต้องแก้
- Cold start OCR (30–60s) ขณะ user รอ → ยอมรับได้; job polling แสดงสถานะ
Requirements (mandatory)
Functional Requirements
- FR-001: ระบบ MUST ใช้
typhoon2.5-np-dms:latestเป็น default main model สำหรับทุก AI job ที่ไม่ใช่ OCR - FR-002: ระบบ MUST ใช้
typhoon-np-dms-ocr:latestเฉพาะ job typeocr-extractและsandbox-ocr-only - FR-003: BullMQ processor MUST unload main model ก่อน load OCR model ทุกครั้งที่มี OCR job
- FR-004: OCR model MUST unload อัตโนมัติหลัง job เสร็จ (keep_alive: 0)
- FR-005: หลัง OCR job เสร็จ processor MUST reload main model (keep_alive: -1 หรือ indefinite)
- FR-006: OllamaService MUST expose
unloadModel(modelName)และloadModel(modelName, keepAlive?)methods - FR-007:
AiSettingsService.DEFAULT_MODELMUST hardcoded เป็น'typhoon2.5-np-dms:latest'(ตาม ADR-034) - FR-008: Embedding model
nomic-embed-textMUST ไม่เปลี่ยนแปลง (นอก scope) - FR-009: n8n MUST ไม่เรียก Ollama โดยตรง — ยังคง pattern
POST /api/ai/jobs→ BullMQ (ADR-023A) - FR-010: BullMQ concurrency MUST = 1 เพื่อป้องกัน VRAM overflow
Key Entities
- Custom Ollama Model
typhoon2.5-np-dms: Configuration ของ main AI model — base: typhoon2.5-qwen3-4b, keep_alive: indefinite, size ~2.5GB - Custom Ollama Model
typhoon-np-dms-ocr: Configuration ของ OCR model — base: typhoon-ocr1.5-3b, keep_alive: 0, size ~3.2GB - OllamaService.unloadModel / loadModel: Methods สำหรับ explicit model management ผ่าน Ollama API
- AiSettingsService.DEFAULT_MODEL: Hardcoded constant ชี้ไปยัง main model ใหม่
Success Criteria (mandatory)
Measurable Outcomes
- SC-001: OCR job ประมวลผล PDF ภาษาไทยได้ข้อความที่อ่านออกได้ (ไม่มี garbled Thai characters) > 90% ของ pages
- SC-002: ไม่มี VRAM OOM error ตลอดการ process OCR + main jobs ต่อเนื่อง 10 jobs
- SC-003: OCR cold start ≤ 60 วินาที; main model warm response ≤ 5 วินาที
- SC-004: Deploy custom models บน Desk-5439 (
ollama create) ใช้เวลา ≤ 15 นาทีต่อ model (download ขึ้นกับ network) - SC-005: ไม่มี regression ใน AI extraction/RAG functionality ที่เดิมทำงานได้
Assumptions
- A1: Desk-5439 มี internet access สำหรับ pull base models (
scb10x/typhoon*) จาก Ollama registry - A2: ADR-033 VRAM monitoring mechanism ใช้งานได้กับ Typhoon models
- A3: Custom Modelfiles ถูก define ใน
specs/04-Infrastructure-OPS/04-00-docker-compose/Desk-5439/แล้ว - A4: Embedding model
nomic-embed-textไม่เปลี่ยนแปลง - A5:
ai_available_modelstable (ADR-027) จำเป็นต้อง update seed เพื่อแสดง model ใหม่ใน admin console
Clarifications
Session 2026-06-03
- Q: nomic-embed-text embedding model เปลี่ยนหรือไม่? → A: ไม่เปลี่ยน — ADR-034 supersedes LLM stack เท่านั้น
- Q: Keep-alive value สำหรับ main model หลัง reload คือเท่าไร? → A: -1 (indefinite) ตาม ADR-034 "Stand by ตลอด (ไม่ใช่ 0)"
- Q:
sandbox-ocr-onlyต้องใช้ OCR model switching ด้วยหรือไม่? → A: ใช่ — เป็น OCR job type เหมือนocr-extract