feat(ai): ADR-032 Typhoon OCR integration - models, processors, cache, VRAM monitor, sandbox UI
CI / CD Pipeline / build (push) Successful in 4m51s
CI / CD Pipeline / deploy (push) Successful in 12m7s

This commit is contained in:
2026-05-30 22:18:51 +07:00
parent f86fcc05f5
commit ae1b1f35e1
56 changed files with 4057 additions and 153 deletions
@@ -164,7 +164,10 @@ graph TB
* **Orchestrator:** ใช้ **n8n** เป็นตัวควบคุม Flow การนำเข้าและเตรียมข้อมูล
* **LLM Engine (General Inference):** ใช้ **Ollama** บน Desk-5439 รันโมเดล `gemma4:9b` สำหรับงานทำความเข้าใจเอกสารและ RAG Q&A
* **LLM Engine (OCR Post-processing & Extraction):** ใช้ **Typhoon Local Model** (Typhoon 2 series) รันผ่าน Ollama บน Desk-5439 สำหรับทำความสะอาดข้อความ (OCR Post-processing) และสกัด Metadata (Classification/Extraction) จากข้อความที่ PaddleOCR สกัดมาแล้ว
* **LLM Engine & OCR (Thai Specialized Models - T040, US2, US3):** รองรับการสลับและเปิดใช้งานโมเดลเฉพาะทางภาษาไทย On-premises แบบ dynamic ได้แก่:
* **`scb10x/typhoon-ocr-3b`** (~3.5GB VRAM) สำหรับ OCR ภาษาไทยคุณภาพสูงผ่าน OCR Sandbox Selector (มี fallback ไปยัง Tesseract อัตโนมัติใน 5 วินาที)
* **`scb10x/typhoon2.1-gemma3-4b`** (~4.5GB VRAM) สำหรับงานสกัด Metadata และวิเคราะห์ข้อความภาษาไทยผ่าน AI Model Management
* ทั้งหมดนี้ควบคุมด้วยนโยบาย **`keep_alive = 0`** ( unload ทันทีหลัง inference) และ **`VramMonitorService`** ใน backend เพื่อหลีกเลี่ยง GPU VRAM OOM
* **Embedding Model:** ใช้ `nomic-embed-text` รันผ่าน Ollama บน Desk-5439 สำหรับแปลงเวกเตอร์ 768-มิติ
* **OCR & NLP:** ใช้ **PaddleOCR** สกัดข้อความจาก Scanned PDF และใช้ **PyThaiNLP** ตัดคำ/เตรียมข้อความภาษาไทย — ทั้งคู่รันบน Desk-5439
***Typhoon Cloud API:** ไม่ใช้ — `rag/typhoon.service.ts` ต้องถูก Remove ออกจาก Codebase (Dead Code + Security Risk)
@@ -238,6 +241,7 @@ graph TB
|---------|------|---------|--------|
| 1.0 | 2026-05-14 | ยุบรวมและแทนที่ ADR-017, 017B, 018, 020, 022 เป็นฉบับเดียว | ✅ Active |
| 1.1 | 2026-05-14 | Grilling Session: (1) ล็อค Local-only AI บน Desk-5439 ทั้งหมด (2) แยก Typhoon Local vs Cloud (3) ลบ Typhoon Cloud API ออก (4) กำหนด `ai_audit_logs` เป็น Development Feedback Log ไม่ใช่ Compliance (5) เพิ่ม Admin Hard Delete Policy | ✅ Active |
| 1.2 | 2026-05-30 | บันทึกการรองรับ Typhoon OCR-3B และ typhoon2.1-gemma3-4b แบบ Dynamic พร้อมระบบ VRAM capacity check และ Tesseract fallback | ✅ Active |
---
@@ -179,7 +179,11 @@ graph TB
> **นโยบาย:** เอกสารทั้งหมดใน LCBP3 จัดชั้นเป็น **INTERNAL** — AI Inference ทั้งหมดต้องรันภายใน Physical Isolation Boundary บน Desk-5439 เท่านั้น ห้ามใช้ Cloud AI Provider โดยเด็ดขาด
#### 2.1 Model Stack (2 โมเดลเท่านั้น)
#### 2.1 Model Stack & Dynamic Thai-Specialized Models (T041, US2, US3)
ระบบประมวลผลพื้นฐานจะรันด้วยชุด 2-Model Stack ที่ประหยัด VRAM เป็นหลัก และเปิดให้โหลดสลับไปประมวลผลด้วยโมเดลภาษาไทยเฉพาะทางประสิทธิภาพสูง (High-Performance Thai Specialized Models) ได้แบบ Dynamic ภายใต้การควบคุมของ VRAM Monitor เพื่อไม่ให้เกิด VRAM OOM:
##### ชุดประมวลผลหลัก (Baseline 2-Model Stack):
| โมเดล | Role | VRAM (โดยประมาณ) | หมายเหตุ |
|-------|------|-----------------|---------|
@@ -187,6 +191,13 @@ graph TB
| `nomic-embed-text` | Embedding 768-dim → Qdrant | ~0.3GB | สร้าง Semantic Vector สำหรับ Hybrid Search |
| **รวม (peak)** | | **~2.5GB** | **เผื่อ headroom ~5.5GB — มั่นใจสูง เพราะ context window ขนาดใหญ่ (8K tokens)** |
##### โมเดลภาษาไทยเฉพาะทางที่เป็นทางเลือก (Dynamic Thai Specialized Models):
| โมเดลทางเลือก | Role | VRAM (โดยประมาณ) | การจำกัดความเสี่ยง VRAM OOM |
|-------|------|-----------------|---------|
| **`scb10x/typhoon-ocr-3b`** | OCR ภาษาไทยใน OCR Sandbox | ~3.5GB | ตั้งค่า `"keep_alive": 0` (unload ทันทีหลังเสร็จสิ้น) + เช็ค VRAM ว่างต้อง ≥ 4000MB (มิฉะนั้นห้ามรันและ Fallback ไป Tesseract อัตโนมัติใน 5 วินาที) |
| **`scb10x/typhoon2.1-gemma3-4b`** | LLM สำหรับสกัดข้อมูลและจัดหมวดหมู่เอกสาร | ~4.5GB | ตั้งค่า `"keep_alive": 0` + ตรวจสอบ capacity โดย `VramMonitorService` ก่อนอนุญาตให้เปลี่ยนโมเดลหลัก |
* **Orchestrator:** ใช้ **n8n** เป็นตัวควบคุม Flow **Migration Phase เท่านั้น** (trigger batch, monitor progress, handle retry ระดับ batch) — ห้าม n8n เรียก Ollama หรือ PaddleOCR โดยตรง
* **Job Executor:** ทุก AI Inference (OCR, Extraction, Embedding, RAG) ต้องผ่าน **BullMQ บน NestJS เท่านั้น** — n8n call `POST /api/ai/jobs` เพื่อ queue job แล้ว poll ผลผ่าน `GET /api/ai/jobs/:jobId`
@@ -481,6 +492,7 @@ export class QdrantService {
| 1.0 | 2026-05-14 | ยุบรวมและแทนที่ ADR-017, 017B, 018, 020, 022 เป็นฉบับเดียว | ✅ Superseded |
| 1.1 | 2026-05-14 | Grilling Session: (1) ล็อค Local-only AI บน Desk-5439 ทั้งหมด (2) แยก Typhoon Local vs Cloud (3) ลบ Typhoon Cloud API ออก (4) กำหนด `ai_audit_logs` เป็น Development Feedback Log ไม่ใช่ Compliance (5) เพิ่ม Admin Hard Delete Policy | ✅ Superseded by 023A |
| 1.2 | 2026-05-15 | ADR-023A: เปลี่ยน Model Stack 3→2 (ลบ Typhoon Local, เปลี่ยน gemma4:9b → gemma4:e4b Q8_0), เพิ่ม BullMQ Queue Policy Table, เพิ่ม VRAM Budget breakdown | ✅ Active |
| 1.3 | 2026-05-30 | บันทึกการรองรับ Typhoon OCR-3B และ typhoon2.1-gemma3-4b แบบ Dynamic พร้อมระบบ VRAM capacity check และ Tesseract fallback | ✅ Active |
---
@@ -0,0 +1,108 @@
<!-- File: specs/06-Decision-Records/ADR-032-typhoon-ocr-integration.md -->
<!-- Change Log
- 2026-05-30: Created initial ADR-032 documenting the integration of Typhoon OCR-3B and typhoon2.1-gemma3-4b with sequential loading (keep_alive = 0) and Tesseract fallback.
- 2026-05-30: Status changed to Active — VramMonitorService, OcrCacheService, TyphoonOcrProcessor, TyphoonLlmProcessor implemented (T004-T009d, T021).
-->
# ADR-032: Typhoon OCR & LLM Integration Architecture
**Status:** Active
**Date:** 2026-05-30
**Decision Makers:** Development Team, System Architect, AI Integration Lead
**Related Documents:**
- [ADR-023: Unified AI Architecture (Base)](./ADR-023-unified-ai-architecture.md)
- [ADR-023A: Unified AI Architecture — Model Revision (gemma4:e2b, 2-Model Stack)](./ADR-023A-unified-ai-architecture.md)
- [ADR-016: Security & Authentication](./ADR-016-security-authentication.md)
- [Feature Specification (spec.md)](../200-fullstacks/232-typhoon-ocr-integration/spec.md)
---
## 🎯 Context and Problem Statement
โครงการ LCBP3-DMS มีความต้องการยกระดับความแม่นยำในการทำ OCR เอกสารภาษาไทยในระบบ **OCR Sandbox Runner** ให้สูงขึ้น (เป้าหมาย 95%+) โดยใช้โมเดลภาษาไทยเฉพาะทาง และเพิ่มโมเดลภาษาไทยระดับผู้เชี่ยวชาญใน **AI Model Management**
อย่างไรก็ดี การเพิ่มโมเดลสกัดข้อความที่เป็นวิสัยทัศน์คอมพิวเตอร์ (Vision-Language Model) และโมเดลภาษาขนาดใหญ่ (Large Language Model) เช่น `scb10x/typhoon-ocr-3b` (~3.5GB VRAM) และ `typhoon2.1-gemma3-4b` (~4.5GB VRAM) อาจส่งผลให้เกิดปัญหา **GPU VRAM Overflow** (เกินขีดจำกัด 8GB ของ RTX 2060 Super บน Admin Desktop Desk-5439) หากมีการโหลดเข้าสู่หน่วยความจำพร้อมกับโมเดลพื้นฐานอย่าง `gemma4` และ `nomic-embed-text`.
---
## ⚙️ Decision Drivers
- **Accuracy Focus:** ยกระดับความถูกต้องในการแปลผลภาษาไทยผ่าน `Typhoon OCR-3B` เป็นเอนจินทางเลือกใน OCR Sandbox.
- **GPU VRAM Budget ≤ 8GB:** ต้องควบคุมไม่ให้การโหลดโมเดลรันพร้อมกันจน VRAM ล้นและระบบแครช (Out-of-Memory).
- **Graceful Degradation:** หากบริการ AI ติดขัดหรือประมวลผลล้มเหลว ระบบ DMS หลักและฟังก์ชัน OCR สำรองต้องยังคงทำงานได้ปกติ.
- **Physical Isolation (Zero Trust):** รันโมเดลทั้งหมดภายในเครือข่าย On-premises บน Admin Desktop เท่านั้น ห้ามผ่าน Cloud.
---
## 🏛️ Proposed Decisions & Architecture
### 1. การเลือกเอนจินและรุ่นโมเดล (Engine & Model Selection)
* **AI Model Option:** เพิ่ม `typhoon2.1-gemma3-4b` เข้าไปในระบบ **AI Model Management** สำหรับงานวิเคราะห์ความหมายขั้นสูงในบริบทไทย.
* **OCR Sandbox Option:** วางแผนเพิ่ม `Typhoon OCR-3B` (รันบน Ollama ที่เครื่อง Admin Desktop) เป็นตัวเลือกคู่ขนานกับ Tesseract OCR.
### 2. นโยบายการจัดการ VRAM ด้วย Ollama Model Swapping (VRAM Swapping Policy)
เพื่อหลีกเลี่ยงข้อจำกัด 8GB VRAM ของ GPU โดยยังคงใช้โมเดลขนาดใหญ่ได้ ระบบจะเปลี่ยนจากการโหลดโมเดลค้างไว้พร้อมกัน (Simultaneous) เป็น **"การทำงานแบบสลับลำดับและจำกัดการจองหน่วยความจำ (Sequential with Ollama keep_alive)"**:
* **`keep_alive = 0`:** ในคำสั่งเรียกประมวลผล (Inference) ทุกชนิดไปยังโมเดล Typhoon จะต้องบังคับพารามิเตอร์ `"keep_alive": 0` เพื่อให้ Ollama ทำการคลายโมเดลออกจากหน่วยความจำ GPU ทันทีหลังตอบกลับสำเร็จ คืนพื้นที่ VRAM ให้โมเดลถัดไปทำงานได้ทันที.
* **Stateless Sidecar:** ตัว Python OCR Sidecar Container จะรับตัวแปรสภาพแวดล้อม `OLLAMA_API_URL` ใน `docker-compose.yml` (ชี้ไปที่ `http://192.168.10.100:11434`) เพื่อประมวลผล PDF-to-Image และส่งภาพสกัดต่อไปยัง Ollama.
### 3. Hyperparameters และ System Prompt สำหรับ Typhoon OCR
เพื่อให้ได้ผลลัพธ์การสกัดอักษรภาษาไทยที่ถูกต้องและลดสัญญาณรบกวน (Noise):
* **System Prompt:**
```text
"สกัดข้อความภาษาไทยและอังกฤษทั้งหมดจากภาพนี้อย่างถูกต้อง รักษาโครงสร้างบรรทัดและการเว้นวรรคให้ใกล้เคียงต้นฉบับมากที่สุด ห้ามเพิ่มคำอธิบายใดๆ"
```
* **LLM Hyperparameters:**
- `temperature = 0.0` (เพิ่มความเป็นระเบียบและให้ผลลัพธ์คงเดิม)
- `top_p = 0.9`
- `repeat_penalty = 1.0` (หรือ `repetition_penalty`)
- `keep_alive = 0`
### 4. ระบบการเก็บแคชชิ่ง (24-Hour Redis Caching)
ระบบจะทำการแคชผลลัพธ์ของการทำ OCR ด้วยโมเดลและไฟล์เดิมไว้เป็นเวลา **24 ชั่วโมง** ผ่าน Redis เพื่อลดต้นทุนเวลาประมวลผล (SLA < 60 วินาที/หน้า)
* **Cache Key:** `ocr:cache:{documentPublicId}:{engine}:{hash}`
* **TTL:** 86,400 วินาที (24 ชั่วโมง)
* **การเคลียร์แคช:** ทำโดยอัตโนมัติเมื่อเอกสารอัปเดต หรือแอดมินสั่งล้างผ่านระบบหลังบ้าน.
### 5. ระบบสลับเอนจินสำรองอัตโนมัติ (Graceful Fallback)
* หาก Ollama หรือโมเดล Typhoon ไม่สามารถเข้าถึงได้ หรือใช้เวลาทำ OCR **นานเกิน 60 วินาที** ระบบ NestJS backend (`OcrService`) จะทำการสลับเอนจินสำรองไปยัง **Tesseract OCR (tha+eng)** อัตโนมัติในเวลาไม่เกิน 5 วินาที พร้อมแจ้งเตือนผู้ใช้บนหน้าเว็บอินเตอร์เฟส.
---
## 📋 Implementation Status
| Component | Status | File |
|---|---|---|
| SQL delta: ai_audit_logs fields | ✅ Complete | `specs/03-Data-and-Storage/deltas/2026-05-30-extend-ai-audit-logs.sql` |
| SQL delta: typhoon_ocr_system prompt | ✅ Complete | `specs/03-Data-and-Storage/deltas/2026-05-30-add-typhoon-ocr-prompt.sql` |
| VRAMMonitorService | ✅ Complete | `backend/src/modules/ai/services/vram-monitor.service.ts` |
| OcrCacheService (24h Redis) | ✅ Complete | `backend/src/modules/ai/services/ocr-cache.service.ts` |
| AiAuditLog entity extension | ✅ Complete | `backend/src/modules/ai/entities/ai-audit-log.entity.ts` |
| OCR Sidecar: Typhoon OCR function | ✅ Complete | `specs/04-Infrastructure-OPS/.../ocr-sidecar/app.py` |
| OCR Sidecar: Dockerfile update | ✅ Complete | `specs/04-Infrastructure-OPS/.../ocr-sidecar/Dockerfile` |
| OCR Sidecar: docker-compose.yml | ✅ Complete | `specs/04-Infrastructure-OPS/.../ocr-sidecar/docker-compose.yml` |
| TyphoonOcrProcessor (BullMQ) | ✅ Complete | `backend/src/modules/ai/processors/typhoon-ocr.processor.ts` |
| TyphoonLlmProcessor (BullMQ) | ✅ Complete | `backend/src/modules/ai/processors/typhoon-llm.processor.ts` |
| ai.module.ts registration | ✅ Complete | `backend/src/modules/ai/ai.module.ts` |
| i18n keys (Thai) | ✅ Complete | `frontend/public/locales/th/ai.json` |
| OCR Engine Selector (Frontend) | 🔄 Pending | `frontend/src/features/ocr-sandbox/` |
| Fallback + Audit integration | 🔄 Pending | `backend/src/modules/ai/services/ocr.service.ts` |
| Model seeding (Admin Desktop) | 🔄 Manual | Ollama pull on Admin Desktop |
| Unit tests | 🔄 Pending | — |
## 📋 Consequences
### Positive
- ✅ **ความแม่นยำภาษาไทยสูง:** ได้ความถูกต้อง 95%+ บนข้อความภาษาไทย in Sandbox Runner.
- ✅ **แก้ปัญหา VRAM 8GB อย่างยั่งยืน:** การใช้ `keep_alive = 0` และ sequential queue ช่วยให้โมเดลรันแบบหมุนเวียนได้โดยไม่เกิด OOM บน RTX 2060 Super.
- ✅ **การเชื่อมต่ออิสระ (Stateless Sidecar):** ออกแบบสถาปัตยกรรม Sidecar ให้ Stateless และตั้งค่าผ่านตัวแปรสภาพแวดล้อมได้ยืดหยุ่น.
- ✅ **มีระบบสำรอง (High Uptime):** ผู้ใช้งานสามารถประมวลผลต่อได้ผ่าน Tesseract เสมอแม้โมเดล AI ขัดข้อง.
### Negative
- ❌ **Overhead ในการโหลดโมเดล (Latency):** การตั้งค่า `keep_alive = 0` ทำให้การรันงานข้ามคิวอาจเกิดดีเลย์เล็กน้อย (3-5 วินาที) ในการดึงโมเดลเข้า VRAM ใหม่ แต่นับเป็น Trade-off ที่ยอมรับได้เมื่อเทียบกับระบบแครช.
---
## 🔄 Review & Maintenance
* **Review Cycle:** ทุก 6 เดือน หรือเมื่อมีการอัปเกรดเครื่องประมวลผล (Admin Desktop GPU)
* **ผู้รับผิดชอบ:** AI Integration Lead ร่วมกับ System Architect Team
+1
View File
@@ -64,6 +64,7 @@ Architecture Decision Records (ADRs) เป็นเอกสารที่บ
| [ADR-007](./ADR-007-error-handling-strategy.md) | Error Handling & Recovery | ✅ Accepted | 2026-04-04 | Layered Error Classification พร้อม User-friendly Messages และ Recovery Actions |
| [ADR-008](./ADR-008-email-notification-strategy.md) | Email & Notification Strategy | ✅ Accepted (Pending Review) | 2026-02-24 | BullMQ + Redis Queue สำหรับ Multi-channel Notifications (Email, LINE, In-app) |
| [ADR-031](./ADR-031-hermes-agent-telegram-devops-bridge.md) | Hermes Agent & Telegram DevOps Bridge | 📝 Draft | 2026-05-28 | Hermes เป็น optional Developer Operations Agent พร้อม Telegram DevOps commands, read-only diagnostics, และ staged rollout |
| [ADR-032](./ADR-032-typhoon-ocr-integration.md) | Typhoon OCR Integration | 📝 Draft | 2026-05-30 | Typhoon OCR-3B และ typhoon2.1-gemma3-4b เป็นทางเลือก OCR/LLM บน Admin Desktop พร้อม VRAM monitoring และ Redis caching |
### Observability