batisee / README.md
hero775's picture
honesty: v2 손글씨 인식 νšŒκ·€ λͺ…μ‹œ(v1 μš°μ„Έ), 정확도=ν•©μ„± in-domain λ²”μœ„, 손글씨 ꡐ정 μž¬ν•™μŠ΅ 진행쀑
fc15529 verified
|
Raw
History Blame Contribute Delete
12.8 kB
---
language:
- ko
- en
- zh
license: mit
tags:
- gguf
- ocr
- document-understanding
- korean
- multimodal
- vision
- deepseek-ocr
- batiai
- quantized
base_model: baidu/Unlimited-OCR
pipeline_tag: image-text-to-text
library_name: llama.cpp
---
# batisee β€” On-device Korean Document OCR by BatiAI
<p align="center">
<a href="https://flow.bati.ai"><img src="https://img.shields.io/badge/BatiFlow-on--device%20AI-blue?style=for-the-badge&logo=apple"></a>
<a href="#how-to-run-llamacpp"><img src="https://img.shields.io/badge/run-llama.cpp%20mtmd-orange?style=for-the-badge"></a>
<img src="https://img.shields.io/badge/Ollama-coming%20soon-lightgrey?style=for-the-badge">
</p>
> ℹ️ **Ollama**: `batisee` uses the brand-new **DeepSeek-OCR (`deepseek2ocr`)** architecture, which the bundled Ollama engine does not load yet. Run it today with **llama.cpp** (below); Ollama support will follow once the engine merges this architecture.
> **batisee** is BatiAI's on-device document-OCR model β€” part of the BatiAI perception family
> (**batisay** = speech-to-text, **batispeak** = diarization, **batisee** = document/OCR).
>
> Built on [`baidu/Unlimited-OCR`](https://huggingface.co/baidu/Unlimited-OCR) (DeepSeek-OCR architecture, MIT),
> **converted to GGUF directly from the original weights by BatiAI** (not a re-host of community quants),
> BatiAI-signed, and **verified for Korean** so you can run it on a Mac with confidence.
**batisee** λŠ” BatiAI 인지(perception) μ œν’ˆκ΅°μ˜ λ¬Έμ„œ OCR λͺ¨λΈμž…λ‹ˆλ‹€ (**batisay**=μŒμ„±μΈμ‹, **batispeak**=ν™”μžλΆ„λ¦¬, **batisee**=λ¬Έμ„œ/OCR).
[`baidu/Unlimited-OCR`](https://huggingface.co/baidu/Unlimited-OCR)(DeepSeek-OCR μ•„ν‚€ν…μ²˜, MIT)λ₯Ό 베이슀둜, **원본 κ°€μ€‘μΉ˜μ—μ„œ BatiAIκ°€ 직접 GGUF λ³€ν™˜**(타사 μ–‘μžν™”λ¬Ό 재배포 μ•„λ‹˜)ν•˜κ³ , BatiAI μ„œλͺ… + **ν•œκ΅­μ–΄ 검증**을 거쳐 Macμ—μ„œ λ°”λ‘œ 쓰도둝 νŒ¨ν‚€μ§•ν–ˆμŠ΅λ‹ˆλ‹€.
## Why batisee?
- **On-device** β€” runs locally on a Mac (no cloud, no upload). Q4_K_M is **1.9 GB**.
- **Korean-verified** β€” measured on rendered Korean documents (see results below): clean text **CER 0%**, hard document (small font + table + blur) **100% key-content recall** with table structure preserved.
- **Document-native** β€” outputs layout boxes (`<|det|>`) and converts tables to HTML `<table>`.
- **Our own conversion** β€” GGUF built directly from `baidu/Unlimited-OCR` original safetensors, BatiAI-signed (`general.author = BatiAI`).
- **MIT** β€” fully commercial-friendly.
## πŸ†• batisee **v2** (recommended for printed / dense documents) β€” fixes dense-document looping
> **Which to use:** **v2** for printed / dense / structured documents (receipts, multi-column, forms β€” fixes v1's looping).
> **v1** (repo root) for **free handwriting** β€” v2 currently regresses there (see point 3 below). A corrected handwriting fine-tune is in progress.
**v2** is a **BatiAI fine-tune** of batisee (LoRA on the text decoder), trained on rendered Korean
documents **+ real AI-Hub Korean handwriting**. It targets a failure mode we found while stress-testing v1:
on **dense receipts and multi-column pages**, the v1 Q4 GGUF can fall into a degenerate repeat loop
(tens of thousands of `<|det|>image` tokens) that a stronger repeat-penalty alone does **not** fix.
v2 cures this.
**What improved β€” measured on the shipped GGUFs:**
1. **Dense-document robustness (Q4 GGUF β€” the headline).** Held-out dense Korean receipts + multi-column
pages, **same recipe for both** (`--repeat-penalty 1.1 --repeat-last-n 512`):
| metric | v1 Q4 | v2 Q4 |
|---|---|---|
| parse CER | **17–27** (degenerate) | **0.20** |
| degenerate loops | **4 / 24** | **0 / 24** |
| worst output length | **50,872 chars** | 134 chars |
On the same receipt, v1 emits a 50 k-character `<|det|>image` loop; v2 returns a clean ~130-char parse.
2. **Parse quality** (transformers, apples-to-apples, both `repeat_penalty 1.05`): overall parse
**CER 0.349 β†’ 0.245** (~30 % relative), **every category down** β€” receipt 0.148β†’0.065,
multi-column 0.637β†’0.242, form 0.231β†’0.136, invoice 0.310β†’0.242, official 0.065β†’0.018, report 0.047β†’0.030.
3. **⚠️ Handwriting β€” loop-safe, but a recognition regression vs v1 (be aware).** v2 no longer *loops* on
handwriting (0 degenerate / 80 pages), **but it recognizes real Korean handwriting *worse* than v1.**
On held-out real AI-Hub handwriting, order-agnostic word recall is **β‰ˆ 7 % for v2 vs β‰ˆ 30 % for v1** β€” the
fine-tune over-anchored on printed-document patterns and tends to hallucinate document vocabulary on
free handwriting. **For handwriting, prefer v1 (repo root).** A corrected handwriting fine-tune is in progress.
**v2 files** β€” in the `v2/` folder; the v1 files stay at the repo root, unchanged:
| File | Size | Use |
|---|---:|---|
| `v2/batisee-text-Q4_K_M.gguf` | 1.9 GB | **recommended** |
| `v2/batisee-text-Q8_0.gguf` | 3.0 GB | highest quality |
| `v2/mmproj-batisee-BF16.gguf` | 826 MB | vision encoder (identical to v1 β€” text-only fine-tune) |
**⭐ v2 recipe β€” the penalty must be stronger than v1's:**
```bash
hf download batiai/batisee --include "v2/*" --local-dir ./batisee
llama-mtmd-cli -m ./batisee/v2/batisee-text-Q4_K_M.gguf --mmproj ./batisee/v2/mmproj-batisee-BF16.gguf \
--image your-document.png -p "document parsing." \
--jinja --temp 0 --repeat-penalty 1.1 --repeat-last-n 512 -ngl 99
```
llama.cpp's repeat-penalty uses a **sliding window** (default last-64 tokens), which is weaker than the
whole-sequence penalty in transformers; on dense pages v1's `1.05` is not enough. **`1.1` + `--repeat-last-n 512`**
removes the loops without hurting tables or legitimate repeated cells (validated: 0 loops on 80 handwriting +
36 dense synthetic pages; tables/receipts unaffected). Use this recipe for v2.
**Honest limitations (read before you rely on it):**
- **Accuracy gains are measured on rendered/synthetic Korean documents** (same generator family used for
fine-tuning β€” in-domain). Real-world generalization beyond that is **not** proven by these numbers.
- **Free handwriting is a regression vs v1** (word-recall β‰ˆ 7 % vs β‰ˆ 30 %) β€” see point 3 above. Use v1 for handwriting.
- Real-world **camera photos and heavy skew remain the frontier** (shared with v1; quantified separately).
- Tables are scored by **structure (TEDS)**, not CER β€” cell text can still slip on hard scans.
- **There is no separate "field-extraction" mode.** An `"extract fields."` prompt returns the same full-page
parse as `"document parsing."`, *not* structured JSON β€” parse the full-page output yourself for key/values.
**v2** λŠ” batisee 의 **BatiAI νŒŒμΈνŠœλ‹**(ν…μŠ€νŠΈ 디코더 LoRA)μž…λ‹ˆλ‹€. λ Œλ” ν•œκ΅­μ–΄ λ¬Έμ„œ **+ μ‹€μ œ AI-Hub ν•œκ΅­μ–΄ 손글씨**둜 ν•™μŠ΅ν–ˆκ³ ,
v1 의 약점(λ°€μ§‘ μ˜μˆ˜μ¦Β·λ‹€λ‹¨ νŽ˜μ΄μ§€μ—μ„œ Q4 GGUF κ°€ `<|det|>image` 수만 토큰 반볡 루프에 λΉ μ§€λŠ” ν˜„μƒ β€” κ°•ν•œ penalty λ‘œλ„ μ•ˆ 고쳐짐)을
**νŒŒμΈνŠœλ‹μœΌλ‘œ ν•΄κ²°**ν–ˆμŠ΅λ‹ˆλ‹€. λ°€μ§‘ λ¬Έμ„œ CER 17–27(퇴화)β†’**0.20**, 루프 4/24β†’**0/24**, 파슀 CER 0.349β†’0.245(μ•½ 30%↓, μ „ μΉ΄ν…Œκ³ λ¦¬ κ°œμ„ ),
**λ°˜λ“œμ‹œ v2 λ ˆμ‹œν”Ό(`--repeat-penalty 1.1 --repeat-last-n 512`)** μ‚¬μš©. ⚠️ **μ†κΈ€μ”¨λŠ” v1보닀 퇴행**(λ£¨ν”„λŠ” 0/80μ΄λ‚˜ μ‹€μ œ 인식은 v2 단어 recall β‰ˆ7% < v1 β‰ˆ30% β€” νŒŒμΈνŠœλ‹μ΄ μΈμ‡„λ¬Έμ„œμ— 과적합) β†’ **μ†κΈ€μ”¨λŠ” v1(루트) ꢌμž₯**, ꡐ정 μž¬ν•™μŠ΅ μ§„ν–‰ 쀑. 정확도 μˆ˜μΉ˜λŠ” **ν•©μ„± in-domain κΈ°μ€€**(μ‹€ μΌλ°˜ν™” 미증λͺ…). ν‘œλŠ” ꡬ쑰(TEDS) κΈ°μ€€, **별도 ν•„λ“œμΆ”μΆœ(JSON) κΈ°λŠ₯ μ—†μŒ**(`extract fields.` = `document parsing.` κ³Ό 동일 좜λ ₯).
## ⭐ Korean OCR results / ν•œκ΅­μ–΄ OCR 검증
Rendered Korean documents (ground-truth known) β†’ OCR β†’ compared. Method & images: [`ocr-poc/gate-results`](https://github.com/batiai/batiai-models/tree/main/ocr-poc/gate-results).
| Test / ν…ŒμŠ€νŠΈ | Difficulty / λ‚œμ΄λ„ | Hangul kept / ν•œκΈ€λ³΄μ‘΄ | Key recall / 핡심recall | Table / ν‘œ | CER |
|---|---|---|---|---|---|
| Gate 1 (clean) | clean text | **100%** | β€” | β€” | **0.0%** |
| Gate 2 (hard) | small font + table + blur | **100%** | **100%** | βœ… `<table>` | β€” |
Both **Q8_0** and **Q4_K_M** pass with no degradation and no decoding loops.
Q8/Q4 λͺ¨λ‘ ν’ˆμ§ˆ μ €ν•˜Β·λ””μ½”λ”© 루프 없이 톡과.
## Available files
| File | Size | Use |
|------|-----:|-----|
| `batisee-text-Q8_0.gguf` | 3.0 GB | highest quality / μ΅œκ³ ν’ˆμ§ˆ |
| `batisee-text-Q4_K_M.gguf` | 1.9 GB | **16 GB Mac sweet spot (recommended)** |
| `mmproj-batisee-BF16.gguf` | 826 MB | vision encoder (required) / λΉ„μ „ 인코더(ν•„μˆ˜) |
## How to run (llama.cpp)
> ⚠️ This is a **multimodal** model β€” you always need **both** the text GGUF **and** `mmproj-batisee-BF16.gguf`.
>
> 🍎 **On a Mac**: `brew install llama.cpp` (version **β‰₯ 9430**) provides `llama-mtmd-cli` and loads `batisee` directly β€” **verified on M4 Max, no source build needed**.
```bash
hf download batiai/batisee --include "batisee-text-Q4_K_M.gguf" --include "mmproj-batisee-BF16.gguf" --local-dir ./batisee
llama-mtmd-cli \
-m ./batisee/batisee-text-Q4_K_M.gguf \
--mmproj ./batisee/mmproj-batisee-BF16.gguf \
--image your-document.png \
-p "document parsing." \
--jinja --temp 0 --repeat-penalty 1.05 -ngl 99
```
### ⭐ Recipe matters (learned the hard way)
| Flag | Why |
|------|-----|
| `-p "document parsing."` | The prompt **must** be this. `"Free OCR."` triggers a buggy reasoning mode that emits meta-commentary instead of the text. |
| `--jinja` | Without it the chat-template step crashes. |
| `--temp 0 --repeat-penalty 1.05` | Without the penalty the decoder can fall into an infinite repeat loop. |
## Model details
- **Base**: [`baidu/Unlimited-OCR`](https://huggingface.co/baidu/Unlimited-OCR) β€” **DeepSeek-OCR architecture**
- Text: DeepSeek-3B-MoE (12 layers, 64 routed experts top-6, standard MHA, 32K context) β†’ `deepseek2ocr`
- Vision: DeepEncoder (CLIP-L-14 + SAM-ViT-B, 1024px) + linear projector
- **Conversion**: built directly from original safetensors with `llama.cpp` (DeepSeek-OCR support). Image normalization `mean = std = [0.5, 0.5, 0.5]`.
- **License**: MIT (inherited)
## BatiAI signing
All GGUFs carry:
- `general.author = BatiAI`
- `general.url = https://flow.bati.ai`
## Attribution & License
This model is a GGUF distribution of `baidu/Unlimited-OCR` (**MIT**), which is built on the DeepSeek-OCR architecture. Original authors' work and license are retained; BatiAI's contribution is the from-original GGUF conversion, signing, Korean verification, and on-device packaging.
λ³Έ λͺ¨λΈμ€ `baidu/Unlimited-OCR`(MIT)의 GGUF λ°°ν¬λ³Έμž…λ‹ˆλ‹€. μ›μ €μž‘μž μž‘μ—…Β·λΌμ΄μ„ μŠ€λ₯Ό μœ μ§€ν•˜λ©°, BatiAI κΈ°μ—¬λŠ” μ›λ³Έμ—μ„œμ˜ 직접 GGUF λ³€ν™˜Β·μ„œλͺ…Β·ν•œκ΅­μ–΄ κ²€μ¦Β·μ˜¨λ””λ°”μ΄μŠ€ νŒ¨ν‚€μ§•μž…λ‹ˆλ‹€.
## Roadmap
- βœ… **v2 shipped** β€” fixes dense-document looping, ~30 % parse-CER reduction on printed docs. See the v2 section above.
- πŸ”§ **In progress β€” handwriting fine-tune (corrected):** v2 regressed free-handwriting recognition vs v1 (over-anchored on printed docs). Re-doing it with spatial-order labels + anti-forgetting recipe + a word-recall no-regression gate vs v1.
- Next: **real-world camera photos / heavy skew / low-quality scans** β€” still the frontier; v2's measured gains are on rendered/synthetic docs.
- Ollama support once the `deepseek2ocr` engine merges.
- βœ… **v2 μΆœμ‹œ** β€” λ°€μ§‘λ¬Έμ„œ 루프 ν•΄κ²° + μΈμ‡„λ¬Έμ„œ 파슀 CER μ•½ 30%↓. πŸ”§ **μ†κΈ€μ”¨λŠ” ꡐ정 μž¬ν•™μŠ΅ μ§„ν–‰ 쀑**(v2κ°€ v1 λŒ€λΉ„ 손글씨 퇴행 β†’ 곡간정렬 라벨+anti-forgetting+λ¬΄νšŒκ·€ 게이트). μ‹€ 카메라/μ™œκ³‘μ€ λ‹€μŒ ν”„λ‘ ν‹°μ–΄.
## About BatiFlow
[BatiFlow](https://flow.bati.ai) β€” free, unlimited, on-device AI for Mac.
<!-- BENCH-START -->
### On-device benchmark β€” MacBook Pro M4 Max (Q4_K_M)
Measured with `brew` `llama-mtmd-cli` 9430, on the same 4 stress documents as the desktop GPU.
| Metric | Value |
|--------|-------|
| Engine | Homebrew `llama.cpp` (`llama-mtmd-cli`) **9430** β€” loads `deepseek2ocr` fine, **no source build needed** |
| Page latency (full pipeline) | **~3.0 s/page** cold, ~3 s warm (β‰ˆ desktop GPU's 2.56 s/page) |
| Memory (max RSS) | **2.94 GB** (peak 2.97 GB) |
| Quality | digital docs/tables near-perfect (numbers 100%, occasional single KR-glyph slip); heavy degradation / skew = known limits β†’ v2 roadmap |
> `tokens/sec` and standalone mmproj-encode time are **not emitted by the 9430 Homebrew bottle** (its perf block is suppressed); available via a source build if needed. Page latency + RSS are the user-facing numbers and confirm M4 Max β‰ˆ desktop-GPU class.
<!-- BENCH-END -->