Chakkhu (ចក្ខុ, "eye") reads Khmer and English text lines from pictures: documents, old printed and typewritten pages, scans, phone photos of paper, screenshots, chat pictures and signs. It is small (18.6M parameters), runs on a CPU, and tells you how sure it is about every line.
Demo + free API: muyleanging/Chakkhu-OCR-Demo · ONNX (no PyTorch, int8, 39 MB): muyleanging/Chakkhu-OCR-Khmer-ONNX · Made by Ing Muyleang.
| Model | Character errors (CER) ↓ | Lines fully right ↑ |
|---|---|---|
| Tesseract 5 (khm+eng, best) | 20.55% | 16.5% |
| Netra-OCR | 5.87% | 56.9% |
| Chakkhu | 4.50% | 58.8% |
By picture kind (CER %):
| KHOB task | Tesseract 5 | Netra-OCR | Chakkhu |
|---|---|---|---|
| clean document | 12.8 | 5.02 | 2.26 |
| sent through Messenger | 14.0 | 6.16 | 2.85 |
| scanned | 13.8 | 4.55 | 2.43 |
| phone-scanned | 19.1 | 4.13 | 3.27 |
| street, day | 31.8 | 5.78 | 6.41 |
| street, night | 35.3 | 10.64 | 11.17 |
| short lines (≤ 10 chars) | 51.8 | 22.41 | 8.73 |
| English / numbers only | 40.8 | 21.95 | 24.58 |
All models were scored by us with the same script, the same line crops and the same Khmer text normalization
(chakkhu/khnormal.py: one fixed order inside every cluster, split vowels joined, invisible characters removed —
NFC alone does not do this for Khmer). KHOB level-1 tasks 2–4 use the task-1 boxes aligned to each picture; two
pages that show a different letter were left out. The reader's CTC weight (0.5) was set before scoring; 0.3 and
0.7 give 4.62% and 4.59%.
Old government documents (12 held-out pages of 1993–2003 royal decrees, laws and sub-decrees, never trained on; labels: Gemini's reading, kept where it agreed with Chakkhu): previous version 3.62% → 2.09% CER, 51.7% → 66.8% lines fully right.
Weaker on: street signs (decorative fonts, night photos), English-only lines. Handwriting: some (2,311 real lines in training), not measured yet.
line picture (grey, 64 px high)
→ CNN ResNet blocks: 64 × W → 2 rows × W/8 columns
→ Transformer 6 layers, d 320, sees the whole line
├→ CTC head per column: a cluster or <blank> (fast draft, letter count)
└→ decoder 3 layers, writes one Khmer cluster per step; first trained as a language model on Khmer text
Reading with both heads: the decoder writes its 4 best guesses (beam search), the CTC draft is added, and
each guess is scored by both heads (0.5 · CTC + 0.5 · decoder). A guess that repeats or skips words gets a bad
CTC score; a guess with a missing vowel gets a bad decoder score.
Confidence: agreement of the two heads × how sure the CTC columns are. Use it to decide which lines a person
(or a bigger model) should check.
Vocabulary: 3,402 tokens (Khmer clusters + Latin, digits, punctuation; rare clusters fall back to single characters, so any text can be written).
pip install torch pillow safetensors huggingface_hub rapidfuzz
from huggingface_hub import snapshot_download
import sys
folder = snapshot_download("muyleanging/Chakkhu-OCR-Khmer")
sys.path.insert(0, folder)
from chakkhu import load, read
model, tok = load(folder) # CPU; load(folder, device="cuda") for a GPU
print(read(model, tok, ["line.png"])) # one picture = one text line
print(read(model, tok, ["line.png"], confidence=True)) # [("…", 0.98)]
# read(..., beam=0) → faster, CTC head only
Whole pages: the demo has a line finder, and a free API:
from gradio_client import Client, handle_file
c = Client("muyleanging/Chakkhu-OCR-Demo")
c.predict(handle_file("page.jpg"), "page", api_name="/read")
# → {"text": …, "lines": [{"text", "confidence", "box": [x, y, w, h]}], "ms": …}
About 5 hours on one GPU in total (two runs: from scratch, then a 1-hour continuation with old-document data).
| Hardware | one 24 GB GPU (rented cloud machine); data preparation, checking and scoring on an Apple M-series laptop |
| Run 1 (from scratch) | about 4 hours |
| Run 2 (continuation, + old-document lines) | 1 hour · learning rate 2e-4, warm-up 500 steps |
| Total | about 5 GPU-hours |
| Precision · batch | bf16 · 96 lines |
| Speed | about 226 training lines per second; reading ~20 ms per line on a GPU, ~140 ms on a laptop CPU |
| Parameters | 18.6M (weights 74 MB) |
Thanks to the authors of these open datasets and fonts, Wikipedia contributors, Open Development Cambodia, and the KHOB benchmark authors.
If you use Chakkhu, please cite it:
@misc{ing2026chakkhu,
author = {Ing, Muyleang},
title = {Chakkhu: A Small Khmer and English Text-Line OCR Model with Line Confidence},
year = {2026},
publisher = {Hugging Face},
howpublished = {\url{https://huggingface.co/muyleanging/Chakkhu-OCR-Khmer}},
note = {Model and demo; CER 4.50\% on the KHOB benchmark}
}
Benchmark and baselines used in the results:
Model weights and code: Apache-2.0. Made by Ing Muyleang. Please credit "Chakkhu by Ing Muyleang" and cite it (above) when you use it.