All work
01 / 06
Case study
Jawi OCR
Fine-tuning Qwen2.5-VL-3B to extract Jawi script and transliterate it to Rumi, with the two stages evaluated separately.
- Role
- Researcher and ML engineer (solo)
- Year
- 2026
- Stack
- Qwen2.5-VL-3B · QLoRA · Unsloth · PyTorch · Hugging Face · Gradio
- Reading time
- 6 min
- Team
- Undergraduate thesis, UIN Ar-Raniry

Result
fewer character errors
CER Jawi: 82.51% → 17.35% on 790 held-out images



What I took from it
- 01
The combined scenario won: fonts alone did not cover real documents, and documents alone did not cover enough variation.
- 02
Score each stage separately; a decent Rumi score can hide a bad extraction underneath it.
- 03
Choose the checkpoint that generalises, not the one with the lowest training loss.
- 04
Ship the demo next to the metric; the side-by-side comparison is what made the improvement legible.
Where it still fails
- 39.36% word error rate on transliteration means a human still reviews the output.
- The model card warns that blur, cropping and heavy background noise push CER up.
- Cursive, heavily aged handwriting is harder than printed typesetting; the thesis scope is printed Jawi.
- PEJYD has exceptions for Arabic loanwords that the model can still get wrong.
- 790 test images is small by OCR standards; read the numbers as an estimate.
Sources
- CV - Zidan Mubarak (Google Docs export, updated 29 Oct 2026)Open (opens in a new tab)
- Hugging Face model card - zidanmubarak/jawi-qwen25-vl-qloraOpen (opens in a new tab)
- Hugging Face model files - adapter and showcase chartOpen (opens in a new tab)
- Hugging Face Space - jawi-transliterasi-demo (Gradio)Open (opens in a new tab)