Files
lcbp3/specs/200-fullstacks/233-ai-model-ocr-runner-management/plan.md
T
admin bc754e66fd
CI / CD Pipeline / build (push) Successful in 4m52s
CI / CD Pipeline / deploy (push) Successful in 17m39s
690602:0957 ADR-033-233 #01
2026-06-02 09:57:48 +07:00

14 KiB

Implementation Plan - Refactor and Fix AI Model & OCR Sandbox Management (ADR-033)

แผนงานนี้จัดทำขึ้นเพื่อแก้ไขปัญหาและปรับปรุงระบบการทำงานของ AI Admin Console และ OCR Sandbox Runner ตามการแจ้งปัญหาของระบบและข้อเสนอแนะของผู้ใช้งาน โดยยึดหลักการประมวลผลภายในขอบเขตความจุหน่วยความจำ VRAM (ADR-032) และการควบคุมผ่าน DMS API อย่างปลอดภัย


User Review Required

Important

การแก้ไขและเพิ่มระบบการยืนยันโมเดล (Ollama Model verification & load check)

  • การโหลดโมเดลหลักใน backend (Synchronous Pre-loading): เพื่อแก้ปัญหา "โหลดสำเร็จเร็วเกินไปแต่จริง ๆ โหลดไม่ผ่าน/ยังโหลดไม่เสร็จ" ระบบใน backend (AiService.activateAiModel) จะทำการตรวจสอบผ่าน Ollama /api/tags ว่าโมเดลมีอยู่จริงในเครื่อง Desk-5439 และจะสั่งโหลดโมเดลเข้า memory ทันทีผ่าน /api/generate ด้วย keep_alive: -1 (พร้อม timeout 30s) ก่อนที่จะเปลี่ยนการตั้งค่า Active ในฐานข้อมูล หากโหลดไม่สำเร็จจะปฏิเสธการสลับโมเดลพร้อมแจ้งข้อความ Error ที่ชัดเจนให้แอดมินทราบทันที
  • การปล่อยหน่วยความจำ GPU ของโมเดลเดิมออกทันที (Dynamic GPU Memory Release): หลังจากโหลดและเปลี่ยน Active Model ตัวใหม่สำเร็จ ระบบจะสั่ง Unload โมเดลตัวเดิมออกจาก GPU ทันทีโดยส่ง keep_alive: 0 เพื่อป้องกันทรัพยากร VRAM ทับถมค้างอยู่บนเครื่อง Desk-5439 จนเกิดภาวะ VRAM OOM
  • การเพิ่มเอนจิน Typhoon OCR-3B ตัวใหม่: ใน OCR Sandbox Runner จะรองรับและแมปตัวเลือกเอนจินทั้ง typhoon-ocr1.5-3b 3.2GB (v1.5) และ typhoon-ocr-3b 7.5GB (v1.0) ไปยังตัวเรียกโมเดลจริงของ Ollama (scb10x/typhoon-ocr1.5-3b และ scb10x/typhoon-ocr-3b ตามลำดับ) เพื่อให้ตรงกับขนาดและเวอร์ชันโมเดลจริง ป้องกันความสับสนของแอดมินในการตรวจสอบความจุ VRAM และทดสอบการทำงาน

Warning

การเปลี่ยนพฤติกรรม Fallback ของ VRAM Monitor (OOM Guard)

  • เมื่อระบบไม่สามารถเชื่อมต่อกับ Ollama /api/ps ได้ (เช่น เกิด Network Timeout หรือ Ollama ยังเป็นเวอร์ชันเก่าที่ไม่รองรับ /api/ps) ระบบจะเปลี่ยนจากการสมมติว่า VRAM เต็ม (hasCapacity = false) เป็น "การคืนค่าพร้อมใช้งานจำลอง (hasCapacity = true พร้อมคืน Free VRAM 6GB)" เพื่อป้องกันปัญหา OOM Guard บล็อกฟังก์ชัน RAG และ OCR Sandbox ทั้งระบบโดยไม่ได้ตั้งใจ

Note

การควบคุมความปลอดภัยของฮาร์ดแวร์ประมวลผล (API Key Guarding)

  • ระบบประมวลผล OCR ที่อยู่นอกเครือข่ายความปลอดภัย (FastAPI Sidecar บน Desk-5439) ได้ถูกติดตั้งระบบกรองความปลอดภัยผ่าน API Key Header (X-API-Key) ป้องกันความพยายามแอบใช้กำลังประมวลผลโดยตรงจากภายนอก ขณะที่ตัวเครื่อง DMS Backend NestJS จะส่ง Header นี้แนบไปกับทุกคำขอโดยอัตโนมัติ

Open Questions

ไม่มีประเด็นที่ค้างคา โดยเราได้จัดตั้งสถาปัตยกรรม ADR-033 เพื่อจัดเก็บแนวทางการออกแบบและตัดสินใจในการจัดการโมเดลอย่างถาวรเรียบร้อยแล้ว


Proposed Changes

[Backend Components]

เราจะเริ่มจากการเพิ่มเอนจิน OCR ในชนิดข้อมูลและปรับปรุง logic การตรวจสอบ VRAM, การเรียกใช้งาน Ollama และการเพิ่ม endpoint ที่ยังตกหล่นใน Controller พร้อมทั้งอัปเกรด API Key Header Guard และ VRAM Unloader

[MODIFY] sandbox-ocr-engine.service.ts

  • ปรับปรุงชนิดข้อมูล SandboxOcrEngineType ให้ตรงตามตัวเลือกใน UI
  • ดึงค่า API Key จาก Config และส่ง Axios Request ไปยัง sidecar /ocr-upload ด้วย header X-API-Key

[MODIFY] ocr.service.ts

  • ดึงค่า API Key จาก Config และแนบ header X-API-Key ไปกับทุกคำขอประมวลผล OCR และตรวจเช็คสุขภาพที่ส่งไปยัง sidecar

[MODIFY] vram-monitor.service.ts

  • ปรับปรุงฟังก์ชัน fetchAndCacheVramStatus ในส่วน catch block ให้ส่งกลับค่า fallback ที่ยืดหยุ่น (hasCapacity = true) เพื่อไม่ให้ OOM Guard ทำงานค้างตลอดเวลาเมื่อ API ขัดข้อง

[MODIFY] ollama.service.ts

  • ปรับปรุงฟังก์ชัน checkHealth() ให้ดึงข้อมูลโมเดลจาก /api/ps เพื่อแสดงรายชื่อโมเดลที่โหลดอยู่บนหน่วยความจำ GPU จริง ๆ
  • เพิ่มฟังก์ชัน loadModel(modelName: string): Promise<boolean> เพื่อทำการตรวจสอบรายชื่อโมเดลใน Ollama (/api/tags) และสั่งโหลดโมเดลหลักขึ้น GPU memory ทันที
  • เพิ่มฟังก์ชัน unloadModel(modelName: string): Promise<boolean> สั่งบอกให้ Ollama ทำการสลัดล้างโมเดลนั้นออกจากหน่วยความจำ GPU ในทันทีโดยใช้ keep_alive: 0

[MODIFY] ai.service.ts

  • ปรับปรุงฟังก์ชัน activateAiModel() ให้เรียกใช้งาน ollamaService.loadModel(modelName) เพื่อยืนยันว่าโหลดโมเดลสำเร็จก่อนเขียนทับสถานะใน DB
  • หลังสลับและโหลดโมเดลตัวใหม่สำเร็จ จะสั่งเรียกใช้ unloadModel(previousModel) เพื่อสลัดโมเดลตัวเก่าออกและล้าง VRAM ทันที

[MODIFY] ai.controller.ts

  • ฉีด OcrService เข้ามา in constructor
  • ลงทะเบียนและเปิดใช้งาน REST API endpoints:
    • GET /ai/ocr-engines (ดึงรายชื่อ OCR engines ทั้งหมดและสถานะ Active)
    • POST /ai/ocr-engines/:engineId/select (แอดมินสลับ OCR engine หลักของระบบ)
  • ตรวจสอบและ normalize engineType ใน submitSandboxOcr ให้ครอบคลุมทุกโมเดล

[MODIFY] app.py

  • ปรับปรุง _process_pdf_doc และ process_with_typhoon_ocr ให้แยกความแตกต่างของ typhoon-ocr-3b (v1.0) และ typhoon-ocr1.5-3b (v1.5) เพื่อส่ง model name ไปเรียกใน Ollama ได้ตรงตัวจริง
  • ติดตั้ง APIKeyHeader validation เพื่อปกป้อง endpoint /ocr, /ocr-upload และ /normalize

[Frontend Components]

การปรับปรุง UI ของ AI Admin Console ให้ยืดหยุ่น เรียงลำดับเมนูและแสดงสถานะได้ตอบโจทย์การทำงานจริงของแอดมิน

[MODIFY] page.tsx

  • เพิ่มแถบแสดงชื่อโมเดลที่ Active และสถานะการโหลดขึ้นหน่วยความจำ GPU ปัจจุบัน (ดึงข้อมูลจาก health?.ollama?.models) วางคู่กับสวิตช์ System Toggle (AI feature enabled)
  • ปรับปรุงให้ dropdown โมเดลแสดงโมเดลตัวเลือก Typhoon อื่น ๆ ที่แอดมินเพิ่มเข้ามาได้สมบูรณ์

[MODIFY] OcrSandboxPromptManager.tsx

  • สลับลำดับ sub-tabs ในหน้า OCR Sandbox ให้ตัวทดสอบสกัดข้อความ (OCR Sandbox Runner) แสดงเป็นตัวแรก และอยู่ก่อน Prompt Template Editor เพื่อเรียงลำดับตามขั้นตอนประมวลผลจริง
  • เปลี่ยนค่า activeTab เริ่มต้นเป็น 'sandbox'
  • ปรับปรุงข้อความและตัวเลือกเอนจินประมวลผลใน Dropdown:
    • Auto (Current Baseline)
    • Tesseract OCR
    • typhoon-ocr1.5-3b 3.2GB
    • typhoon-ocr-3b 7.5GB

[Documentation]

[NEW] ADR-033-active-model-and-ocr-management.md

  • บันทึกสถาปัตยกรรมและกฎการตรวจสอบโมเดลล่วงหน้า (Pre-loading validation) และโครงสร้างการสลับ OCR Sandbox Runner ที่ได้รับการตัดสินใจในครั้งนี้

Verification Plan

Automated Tests

  • รันการตรวจสอบ Typescript ของทั้ง frontend และ backend เพื่อยืนยันว่าคอมไพล์ผ่าน 100%:
    pnpm --filter backend build
    
  • รัน Unit Tests เพื่อทดสอบความถูกต้องของ Logic ทั้งหมดใน module ai:
    pnpm --filter backend test
    

Manual Verification

  • แอดมินตรวจสอบหน้า Overview & Health ในเบราว์เซอร์ ยืนยันว่าส่วน "ระบบจัดการ OCR Engine" โหลดข้อมูลได้สมบูรณ์ ไม่แครช
  • ตรวจสอบส่วน VRAM GPU Monitor ว่า OOM Guard มีสถานะความจุพร้อมโหลดโมเดลหลักได้ตามปกติ
  • ทดสอบเลือกเปลี่ยนโมเดลหลักใน dropdown และตรวจสอบว่า backend ตรวจความพร้อมกับ Ollama จริง
  • ตรวจสอบว่าหน้า OCR Sandbox Runner มีปุ่มแท็บ "OCR Sandbox" ปรากฏก่อน "Prompt Editor" และทำงานได้ถูกต้อง