---
name: ocr-selector
description: >
  Select the most appropriate OCR / document parsing tool for any task.
  Trigger on: OCR, scan tài liệu, trích xuất văn bản, PDF extraction, image to text,
  handwriting recognition, chữ viết tay, nhận dạng chữ viết, "tool nào để OCR",
  "which OCR should I use", "how to extract text from PDF", "scan sách",
  "nhận dạng tiếng Việt", "nhận dạng tiếng Trung", "extract table from PDF",
  "công thức toán LaTeX", "handwritten document", "viết tay tiếng Việt",
  "multi-language OCR", "document intelligence", "RAG pipeline OCR",
  "MCP document server", "parse PDF", "convert PDF to markdown", "book translator OCR".
  Also trigger when user uploads/mentions a document file and wants to read or process it.
  ALWAYS recommend the right tool before writing code.
risk: low
origin: first-party
---

# OCR Selector

Chọn đúng công cụ OCR/document parsing. **Sai tool = kết quả rỗng hoặc kém.**

---

## Bước 1 — Phân loại nhanh

```
Loại input?
├── PDF có text layer (digital PDF)   → markitdown hoặc kreuzberg
├── PDF scan / ảnh chụp tài liệu      → MinerU hoặc PaddleOCR
├── Chữ viết tay tiếng Việt           → Vintern-3-5
├── Chữ viết tay ngôn ngữ khác        → olmOCR hoặc PaddleOCR
├── Ảnh chụp (không phải PDF)         → PaddleOCR hoặc LightOnOCR-2
├── Office files (Word/Excel/PPT)     → markitdown hoặc kreuzberg
└── Cần fine-tune model riêng         → Viet-Handwriting-OCR-v2 dataset
```

---

## Bước 2 — Decision Matrix

| Usecase | Tool | GPU? | Chi tiết |
|---------|------|------|---------|
| **Tiếng Việt viết tay** | Vintern-3-5 | Có | [→](references/vintern.md) |
| **Tiếng Trung/Nhật/Hàn** | PaddleOCR | Không | [→](references/paddleocr.md) |
| **100+ ngôn ngữ, production** | PaddleOCR | Không | [→](references/paddleocr.md) |
| **PDF scan → RAG/LLM** | MinerU | Tuỳ | [→](references/mineru.md) |
| **Layout phức tạp, bảng, công thức** | MinerU vlm-engine | Có | [→](references/mineru.md) |
| **Academic papers / LaTeX** | olmOCR | Có | [→](references/olmocr.md) |
| **Tiếng Pháp / Châu Âu** | LightOnOCR-2 | Có | [→](references/lightonocr.md) |
| **PDF digital → Markdown nhanh** | markitdown | Không | [→](references/markitdown.md) |
| **90+ formats, Node.js/Rust** | kreuzberg | Không | [→](references/kreuzberg.md) |
| **GUI desktop, offline, privacy** | pdfmd | Không | [→](references/pdfmd.md) |
| **MCP Server cho IDE/Agent** | MinerU-Ecosystem | Tuỳ | [→](references/mineru.md) |
| **Debug cấu trúc PDF** | firecrawl/pdf-inspector | Không | [→](references/firecrawl.md) |
| **Fine-tune handwriting VN** | Viet-Handwriting dataset | — | [→](references/datasets.md) |

---

## Bước 3 — Detect nhanh trong code

```python
import fitz  # pip install pymupdf

def detect_input_type(path: str) -> str:
    if not path.endswith('.pdf'):
        return "image"  # → PaddleOCR hoặc LightOnOCR-2

    doc = fitz.open(path)
    chars = sum(len(p.get_text().strip()) for p in doc)

    if chars > 200:
        return "pdf_digital"   # → markitdown hoặc kreuzberg (nhanh)
    else:
        return "pdf_scan"      # → MinerU hoặc PaddleOCR (cần OCR)
```

---

## Bước 4 — Code mẫu theo tool

### MinerU (khuyến nghị mặc định)
```bash
pip install mineru
mineru -p document.pdf -o ./output                       # CPU mode
mineru -p document.pdf -o ./output --backend vlm-engine  # GPU, SOTA
```

### PaddleOCR (đa ngôn ngữ, CJK)
```bash
pip install paddlepaddle paddleocr
python -c "from paddleocr import PaddleOCR; ocr=PaddleOCR(lang='vi'); print(ocr.ocr('img.jpg'))"
```

### markitdown (PDF digital, không cần GPU)
```bash
pip install markitdown
markitdown document.pdf > output.md
```

### kreuzberg (Node.js / đa ngôn ngữ lập trình)
```bash
npm install kreuzberg
```
```typescript
import { extract } from 'kreuzberg'
const result = await extract('document.pdf')
```

### olmOCR (academic papers)
```bash
pip install olmocr
python -m olmocr.pipeline ./pdfs/ --workspace ./output
```

### LightOnOCR-2 (European languages)
```python
from transformers import AutoProcessor, AutoModelForImageTextToText
from PIL import Image
model = AutoModelForImageTextToText.from_pretrained("lightonai/LightOnOCR-2-1B")
processor = AutoProcessor.from_pretrained("lightonai/LightOnOCR-2-1B")
image = Image.open("document.png")
output = model.generate(**processor(images=image, return_tensors="pt"))
print(processor.decode(output[0], skip_special_tokens=True))
```

### Vintern-3-5 (tiếng Việt chuyên biệt)
```python
# Xem: https://github.com/5CD-AI/Vintern-3-5
from transformers import AutoModel, AutoTokenizer
model = AutoModel.from_pretrained("5CD-AI/Vintern-3-5", trust_remote_code=True)
```

### MCP Server cho Claude Code / Cursor
```bash
claude mcp add mineru uvx mcp-mineru        # MinerU MCP
claude mcp add kreuzberg uvx kreuzberg-mcp  # kreuzberg MCP (no GPU)
```

---

## Anti-patterns

```
❌ markitdown với PDF scan        → output rỗng (không có OCR engine)
❌ olmOCR không có GPU            → rất chậm, thực tế không dùng được
❌ LightOnOCR-2 cho tiếng Việt viết tay → kết quả kém
❌ Vintern-3-5 cho tài liệu tiếng Đức   → dùng LightOnOCR-2
❌ PaddleOCR cho academic LaTeX papers  → dùng olmOCR
❌ MinerU vlm-engine trên CPU    → cực chậm, dùng pipeline mode
```

---

## Output format khi tư vấn

```
Tool được chọn: [Tên]
Lý do: [1 câu]
Cài đặt: [pip/npm command]
Code mẫu: [≤10 dòng chạy được ngay]
Lưu ý: [GPU/ngôn ngữ/điều kiện đặc biệt]
```

---

## Tham khảo chi tiết

| File | Nội dung |
|------|---------|
| `references/mineru.md` | MinerU — backends, config, MCP, benchmarks |
| `references/paddleocr.md` | PaddleOCR — ngôn ngữ, scene OCR, CJK |
| `references/olmocr.md` | olmOCR — academic, LaTeX, cost |
| `references/lightonocr.md` | LightOnOCR-2 — European langs, model variants |
| `references/vintern.md` | Vintern-3-5 — Vietnamese, fine-tuning |
| `references/markitdown.md` | markitdown — formats, LLM integration |
| `references/kreuzberg.md` | kreuzberg — bindings, plugin API |
| `references/pdfmd.md` | pdfmd — GUI, CLI, privacy |
| `references/firecrawl.md` | firecrawl/pdf-inspector — debug |
| `references/datasets.md` | Viet-Handwriting-OCR-v2 dataset |
