ThaOCR rec β€” Khmer + English text-line recogniser (CRNN-CTC, ONNX)

Stage 3 of 5 of the ThaOCR pipeline. Reads one text-line crop at a time. CRNN-CTC, arch "M": conv channels 48-96-192-256, projection 320, BiLSTM 2 layers x 256, 4.76 M parameters. Input is a grey line crop of height 48 and dynamic width, [N,1,48,W], float32 in 0..1. The output has one step per time column over 195 symbols (Khmer letters, vowels, signs, digits, Latin letters, punctuation; blank id 0), decoded with greedy CTC. Text is normalised with normalize_khmer (canonical ordering of Khmer clusters, visually identical spellings merged).

Every version has an fp32 ONNX, an int8 ONNX (dynamic quantisation of the same checkpoint, 4.8 MB) and its own .vocab.json. Use the vocab with the same name as the model: the int8 file shares the vocab of its fp32 sibling.

Models

id version file size description
crnn_m_v1 v1 rec/crnn_m_v1.onnx 19.1 MB CRNN-CTC m v1 (fp32)
crnn_m_v1_int8 v1 rec/crnn_m_v1_int8.onnx 4.8 MB CRNN-CTC m v1 (int8)
crnn_m_v2 v2 rec/crnn_m_v2.onnx 19.1 MB CRNN-CTC M v2 (print + handwriting, fp32)
crnn_m_v2_int8 v2 rec/crnn_m_v2_int8.onnx 4.8 MB CRNN-CTC M v2 (print + handwriting, int8 4.8 MB)
crnn_m_v2_hw v2.1 rec/crnn_m_v2_hw.onnx 19.1 MB CRNN-CTC M v2.1 (print + REAL handwriting, fp32)
crnn_m_v2_hw_int8 v2.1 rec/crnn_m_v2_hw_int8.onnx 4.8 MB CRNN-CTC M v2.1 (print + REAL handwriting, int8 4.8 MB)
crnn_m_v2_stamp v2.2 rec/crnn_m_v2_stamp.onnx 19.1 MB CRNN-CTC M v2.2 (print + handwriting + text under stamps)
crnn_m_v2_stamp_int8 v2.2 rec/crnn_m_v2_stamp_int8.onnx 4.8 MB CRNN-CTC M v2.2 int8 (phone size)
crnn_m_v2_stamp2 (default) v2.3 rec/crnn_m_v2_stamp2.onnx 19.1 MB CRNN-CTC M v2.3 (print + handwriting + text under stamps, gentle)
crnn_m_v2_stamp2_int8 v2.3 rec/crnn_m_v2_stamp2_int8.onnx 4.8 MB CRNN-CTC M v2.3 int8 (phone size)
crnn_m_v2_stamp3 v2.4 rec/crnn_m_v2_stamp3.onnx 19.1 MB CRNN-CTC M v2.4 (v2.3 + 4 epochs)
crnn_m_v2_stamp3_int8 v2.4 rec/crnn_m_v2_stamp3_int8.onnx 4.8 MB CRNN-CTC M v2.4 int8 (phone size)

The default is crnn_m_v2_stamp2 (v2.3); use its _int8 file on phones. crnn_m_v2_stamp3 (v2.4) is slightly better on every val set but has not been made the default yet.

Use

import onnxruntime as ort, json
sess = ort.InferenceSession("rec/crnn_m_v2_stamp2_int8.onnx")
vocab = json.load(open("rec/crnn_m_v2_stamp2.vocab.json"))["itos"]
# grey line crop, height 48, shape [1,1,48,W] float32 in 0..1 -> greedy CTC over the output, blank id 0

Lineage (each version starts from the previous best checkpoint)

version model id epochs / lr what was added val CER print / real_dev
v1 crnn_m_v1 6 / 1.5e-3 mix_print_scene: sections S01–S08 + synthetic scene sets 0.29 % / –
expA (internal) 2 + rec_doclaynet real English lines 0.29 % / 14.8 %
v2 crnn_m_v2 6 / 1e-3 + docgen print + synthetic handwriting (exam sheets, forms) 0.22 % / 13.6 %
v2.1 crnn_m_v2_hw 3 / 5e-4 + real Khmer handwriting (Thareah, SoyVitou) 0.23 % / 13.1 %
v2.2 crnn_m_v2_stamp 2 / 1.2e-4 + stamp augmentation (STAMP_AUG=0.12) 0.22 % / 12.9 %
v2.3 crnn_m_v2_stamp2 4 / 1.2e-4 same data, longer, from v2.1 0.216 % / 12.7 %
v2.4 crnn_m_v2_stamp3 4 / 1e-4 v2.3 + 4 epochs 0.213 % / 12.6 %

real_dev is the owner's real Khmer document dev set (character error rate).

How v2.3 (default) was trained

Trainer training/rec/train.py (the Khm-Dataset-Creation CRNN trainer + packed line sets). --aug strong = GPU-side warp, slant, low resolution, polarity inversion. STAMP_AUG=0.12 = training/rec/stamp_aug.py overlays grey ring arcs and short stamp strokes on 12 % of crops, so text under Cambodian official red stamps is still read.

STAMP_AUG=0.12 python -m training.rec.train --mix training/rec/configs/final_v2_hand_real.json \
    --out work/runs/rec_v2_M_stamp2 --arch M --aug strong --init work/runs/rec_v2_M_ft/best.pt \
    --epochs 4 --lr 1.2e-4

Dataset mix final_v2_hand_real (1,041,136 lines per epoch):

  • synthetic print sections S01–S08 (200,000 lines sampled): Khmer news corpus rendered with 21 open-licence Khmer fonts + Khmer OS fonts, with print/scan effects
  • synthetic scene/signboard sets: dataset_v2 (scene, heavy, medium, + 25,000 clean), dataset_nf_mix, dataset_hard, dataset_nf_hard, dataset_long (10,000)
  • rec_doclaynet: 90,860 real English lines cut from DocLayNet pages (text-layer transcriptions)
  • rec_docgen: 99,869 printed lines from docgen v2 pages (Khmer + English, many fonts)
  • rec_exam_hand: 69,081 synthetic Khmer handwriting lines from docgen exam answer sheets (handwriting fonts, phone-photo degradation)
  • rec_docgen_hand: 11,905 synthetic handwritten form values (names, numbers, dates)
  • rec_hand_real_thareah: 2,311 real Khmer handwriting lines (Thareah/khmer-handwriting, 147 scanned pages), oversampled x8
  • rec_hand_real_soyvitou: 3,549 real Khmer handwritten words/short lines (SoyVitou/khmer-handwritten-dataset-4.2k), oversampled x4

Validation character error rate (best epoch): synthetic print V01 0.216 %, synthetic scene 2.73 %, real English 0.29 %, docgen print 7.5 %, synthetic exam handwriting 4.5 %, synthetic form handwriting 3.6 %, real handwriting Thareah 21.3 %, SoyVitou 9.8 %, owner's real Khmer document dev set 12.7 %.

Training data and licences

data type licence
Khmer news corpus (5,601 articles, 257,501 train lines, scraped by the owner for research; source URLs not recorded) rendered with Khmer fonts synthetic lines text: research use; fonts OFL 1.1 / LGPL 2.1 (Khmer OS)
Synthetic scene sets dataset_v2, nf_mix, hard, nf_hard, long synthetic lines generated
docgen v2 / exam pages (English from 19 Project Gutenberg books, Faker identities; no real people) synthetic lines generated
DocLayNet v2 (English lines) real lines CDLA-Permissive 1.0
Thareah/khmer-handwriting (2,891 lines) real lines MIT
SoyVitou/khmer-handwritten-dataset-4.2k (4,202 snippets) real lines MIT

Part of the training text is research-use only, so the licence field is other: check that your use fits those terms. The owner's private exam photos were never used for training.

Part of ThaOCR

ThaOCR is a five-stage Khmer + English document OCR pipeline (layout, text-line detection, line recognition, font classification, page structure). Every model is plain ONNX (opset 17) and runs with onnxruntime on CPU. There is one repo per stage:

The index repo Thareah/ThaOCR-models holds the full models.json manifest for all five stages. models.rec.json in this repo lists only this stage. The file and vocab paths in both are relative to a folder into which all stage repos are downloaded together, for example hf download Thareah/ThaOCR-rec --local-dir ThaOCR. The pre/post-processing (letterbox + NMS, DB unclip, width bucketing + CTC, ...) is small numpy/OpenCV code in the ThaOCR backend (backend/app/services/stages/).

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support