116 lines
5.0 KiB
Markdown
116 lines
5.0 KiB
Markdown
# OCR Sidecar — Desk-5439
|
|
|
|
HTTP API server สำหรับสกัดข้อความจาก PDF ผ่าน np-dms-ocr (Ollama) — รันบน Desk-5439 ตาม ADR-023A/ADR-040.
|
|
|
|
## สถาปัตยกรรม
|
|
|
|
```
|
|
Backend (QNAP) → POST /ocr-upload → OCR Sidecar (Desk-5439:8765)
|
|
↓
|
|
PyMuPDF (fast-path: chars > 100)
|
|
↓ (ถ้า chars ≤ 100)
|
|
prepare_ocr_messages (typhoon_ocr)
|
|
+ poppler/pdftoppm (PDF → image)
|
|
↓
|
|
np-dms-ocr via Ollama /v1/chat/completions
|
|
↓
|
|
JSON → natural_text (Markdown)
|
|
```
|
|
|
|
## Endpoints
|
|
|
|
| Endpoint | Method | Auth | หน้าที่ |
|
|
|----------|--------|------|---------|
|
|
| `/health` | GET | — | ตรวจสอบสถานะ sidecar |
|
|
| `/ocr` | POST | X-API-Key | OCR จาก path (ใช้เมื่อ shared volume mount) |
|
|
| `/ocr-upload` | POST | X-API-Key | OCR จาก multipart file upload |
|
|
| `/embed` | POST | X-API-Key | BGE-M3 embedding (Dense + Sparse) พร้อม CPU fallback |
|
|
| `/rerank` | POST | X-API-Key | BGE-Reranker-Large chunk re-ranker พร้อม CPU fallback |
|
|
|
|
**Removed endpoints:**
|
|
- `POST /normalize` — ลบออกแล้วตาม ADR-040 Phase 8 (ไม่มี consumers)
|
|
|
|
## Environment Variables
|
|
|
|
| Variable | Default | หน้าที่ |
|
|
|----------|---------|---------|
|
|
| `OCR_SIDECAR_API_KEY` | (required) | API key สำหรับ authentication (Phase 1) |
|
|
| `OCR_SIDECAR_UPLOAD_BASE` | `/mnt/uploads` | Base path whitelist สำหรับ path traversal protection |
|
|
| `OLLAMA_API_URL` | `http://host.docker.internal:11434` | Ollama API URL |
|
|
| `OCR_MODEL` | `np-dms-ocr:latest` | ชื่อ OCR model ใน Ollama |
|
|
| `OCR_TIMEOUT` | `360` | Timeout วินาทีต่อ request |
|
|
| `OCR_CHAR_THRESHOLD` | `100` | Fast-path threshold (chars > 100 = ใช้ text layer โดยตรง) |
|
|
| `OCR_MAX_PAGES` | `0` | จำนวนหน้าสูงสุด (0 = ทุกหน้า) |
|
|
| `OCR_ACTIVE_PROFILE` | (optional) | ชื่อ profile ใน `ai_execution_profiles` |
|
|
| `VRAM_HEADROOM_THRESHOLD_MB` | `3000.0` | Threshold สำหรับ CPU fallback |
|
|
| `RETRIEVAL_TIMEOUT_SECONDS` | `30.0` | Timeout สำหรับ /embed และ /rerank |
|
|
| `MAX_SYSTEM_PROMPT_LENGTH` | `10000` | ความยาวสูงสุดของ systemPrompt |
|
|
|
|
## การ Deploy
|
|
|
|
```bash
|
|
# 1. คัดลอก .env.example เป็น .env และกรอกค่า
|
|
cp .env.example .env
|
|
# แก้ OCR_SIDECAR_API_KEY เป็นค่าจริง
|
|
|
|
# 2. Build และรัน
|
|
docker compose up -d --build
|
|
|
|
# 3. ตรวจสอบ
|
|
curl http://192.168.10.100:8765/health
|
|
```
|
|
|
|
## การทดสอบ
|
|
|
|
```bash
|
|
# รันทุก test (จาก project root)
|
|
python -m pytest tests/ -v
|
|
|
|
# รันเฉพาะ unit tests
|
|
python -m pytest tests/unit/ocr-sidecar/ -v
|
|
|
|
# รันเฉพาะ integration tests
|
|
python -m pytest tests/integration/ocr-sidecar/ -v
|
|
```
|
|
|
|
### Test Coverage
|
|
|
|
| Test File | หน้าที่ |
|
|
|-----------|---------|
|
|
| `test_path_traversal.py` | Path traversal protection (US1) |
|
|
| `test_api_key_validation.py` | API key validation (US1) |
|
|
| `test_residency_wiring.py` | Adaptive OCR residency wiring (US2) |
|
|
| `test_cpu_fallback.py` | CPU fallback for /embed and /rerank (US2) |
|
|
| `test_parameter_governance.py` | Runtime parameter governance (US3) |
|
|
| `test_active_prompt.py` | System prompt + DMS tags injection (US3) |
|
|
| `test_async_performance.py` | Async I/O + lifespan + concurrent requests (US4) |
|
|
|
|
## ADR-040 Phases
|
|
|
|
| Phase | Status | หน้าที่ |
|
|
|-------|--------|---------|
|
|
| Phase 1-2 | ✅ Complete | Setup + Foundational |
|
|
| Phase 3 | ✅ Complete | US1: Security Hardening |
|
|
| Phase 4 | ✅ Complete | US2: GPU Resource Management |
|
|
| Phase 5 | ✅ Complete | US3: Parameter Governance |
|
|
| Phase 6 | ✅ Complete | US4: Async I/O Performance |
|
|
| Phase 7 | ⏳ Blocked | US5: Network Isolation Auth (รอ ADR-041) |
|
|
| Phase 8 | ✅ Complete | Remove /normalize endpoint |
|
|
| Phase 9 | ✅ Complete | Polish & documentation |
|
|
|
|
## ไฟล์ในโปรเจกต์
|
|
|
|
```
|
|
ocr-sidecar/
|
|
├── app.py — FastAPI server (async I/O, lifespan)
|
|
├── Dockerfile — Docker image (python:3.10-slim + poppler + curl)
|
|
├── docker-compose.yml — Compose config (ocr-sidecar + ollama-metrics)
|
|
├── requirements.txt — Python dependencies
|
|
├── .env.example — Environment template
|
|
├── services/
|
|
│ ├── vram_monitor.py — VRAM headroom monitoring
|
|
│ └── residency_policy.py — Adaptive OCR residency calculation
|
|
└── tests/
|
|
└── test_retrieval_fallback.py — Retrieval fallback tests
|
|
```
|