CoolFace
Modelpublic

shantipriya/hunyuan-ocr-odia

sourceHugging Faceapache-2.0updated 7mo agoView on Hugging Face
0likes
Model Card

HunyuanOCR Fine-tuned for Odia OCR

Fine-tuned tencent/HunyuanOCR on the OdiaGenAIOCR/odia-ocr-merged dataset using LoRA (r=64, alpha=128).

GitHub: shantipriyap/hunyuan_odia_ocr


Evaluation Results

CheckpointStepsCER↓WER↓Notes
Baseline (zero-shot)00.91110.9467HunyuanOCR, no fine-tuning
v5 (r=32)10000.75770.846Best word-level CER so far
v7 (r=32)32000.79090.941r=32 capacity ceiling
v8 baseline01.11881.4385Before v8 training
v8 ckpt-3250 (latest)3250in training—Loss ~0.93 best; 67% done
Note on evaluation: Training uses word-level crops (OdiaGenAIOCR/odia-ocr-merged). The Iftesha/odia-ocr-benchmark dataset contains paragraph-level images — a different domain where this model scores CER ~0.99 (expected, not trained on paragraphs).

Inference Samples (checkpoint-4000, step 80% of training)

Evaluated on 60 word-crop samples from OdiaGenAIOCR/odia-ocr-merged test split. Avg CER: 1.16 | Best CER: 0.64 (60 samples, ckpt-4000).

Note: Training is 80% complete (4000/5000 steps). Mode collapse persists — model outputs a small set of common Odia words. Expected to improve in final steps.

🟡 Best Available (CER 0.64–0.70)

ImageGround TruthPredictionCER
<img src="https://huggingface.co/shantipriya/hunyuan-ocr-odia/resolve/main/samples5/word_01.jpg" width="220"/>ବାକିମାନଙ୍କୁବାଲିକା0.64
<img src="https://huggingface.co/shantipriya/hunyuan-ocr-odia/resolve/main/samples5/word_02.jpg" width="220"/>ନିର୍ଦ୍ଧାରଣବିଶ୍ଵାସ0.70

🟠 Partial (CER 1.0)

ImageGround TruthPredictionCER
<img src="https://huggingface.co/shantipriya/hunyuan-ocr-odia/resolve/main/samples5/word_03.jpg" width="220"/>ଲବଙ୍ଗକୁମୁଖ୍ୟସ୍ଥ1.00
<img src="https://huggingface.co/shantipriya/hunyuan-ocr-odia/resolve/main/samples5/word_04.jpg" width="220"/>ଗ୍ରାଫ୍ବିଶ୍ୱର1.00

🔴 Poor (CER > 3.0)

ImageGround TruthPredictionCER
<img src="https://huggingface.co/shantipriya/hunyuan-ocr-odia/resolve/main/samples5/word_05.jpg" width="220"/>୫୦ବିଶ୍ୱର3.00
<img src="https://huggingface.co/shantipriya/hunyuan-ocr-odia/resolve/main/samples5/word_06.jpg" width="220"/>୫୨ବିଶ୍ୱାସ3.50

Training Loss Curve (v8, r=64)

StepLoss
102.3695
500~1.18
9101.0948
1500~1.11
21000.9964 ← first sub-1.0
25800.9339 ← best so far
27501.0291
3000~0.979
3250~0.979 (67% done, in training)

Training Configuration

ParameterValue
Base modeltencent/HunyuanOCR
LoRA rank64
LoRA alpha128
Learning rate2e-4
Warmup steps100
Max steps5000
Batch size1 (grad_accum=4)
Max seq len2048

Quick Start

python
import torch
from PIL import Image
from transformers import HunYuanVLForConditionalGeneration, AutoProcessor
from peft import PeftModel

BASE  = "tencent/HunyuanOCR"
CKPT  = "shantipriya/hunyuan-ocr-odia"

base  = HunYuanVLForConditionalGeneration.from_pretrained(
    BASE, torch_dtype=torch.bfloat16,
    attn_implementation="eager", device_map="auto")
model = PeftModel.from_pretrained(base, CKPT)
model.eval()
proc  = AutoProcessor.from_pretrained(BASE, use_fast=False)

img   = Image.open("odia_image.jpg").convert("RGB")
msgs  = [
    {"role": "system", "content": ""},        # required
    {"role": "user", "content": [
        {"type": "image", "image": img},
        {"type": "text",  "text": "Extract all Odia text from this image. Return only the Odia text."},
    ]},
]
text   = proc.apply_chat_template(msgs, tokenize=False, add_generation_prompt=True)
inputs = proc(text=[text], images=[img], return_tensors="pt").to("cuda")
with torch.no_grad():
    gen = model.generate(**inputs, max_new_tokens=256, do_sample=False)
result = proc.batch_decode(
    [gen[0][inputs["input_ids"].shape[1]:]], skip_special_tokens=True
)[0].strip()
print(result)
Note: The empty system message is required — omitting it causes a position_ids dimension error.

License

Apache 2.0