Variants
Usage
Recommended prompt for plain transcription (Thai):
อ่านข้อความทั้งหมดในภาพนี้แบบครบถ้วนและตรงตามต้นฉบับ รวมถึงตัวเลข ตาราง หัวข้อ และเนื้อหาทุกส่วน ห้ามสรุป ห้ามข้ามส่วนใด ห้ามเพิ่มคำอธิบาย
vllm serve PorsukR/P110-ThaiOCR-4B-FP8 --max-model-len 32768
from openai import OpenAIimport base64 client = OpenAI(base_url="http://localhost:8000/v1", api_key="none")img = base64.b64encode(open("page.png", "rb").read()).decode()resp = client.chat.completions.create( model="PorsukR/P110-ThaiOCR-4B-FP8", messages=[{"role": "user", "content": [ {"type": "image_url", "image_url": {"url": f"data:image/png;base64,{img}"}}, {"type": "text", "text": "อ่านข้อความทั้งหมดในภาพนี้แบบครบถ้วนและตรงตามต้นฉบับ รวมถึงตัวเลข ตาราง หัวข้อ และเนื้อหาทุกส่วน ห้ามสรุป ห้ามข้ามส่วนใด ห้ามเพิ่มคำอธิบาย"}, ]}], temperature=0, max_tokens=4096, # stops a rare runaway repeat; raise it for very dense pages extra_body={"chat_template_kwargs": {"enable_thinking": False}},)print(resp.choices[0].message.content)
Tested with vLLM 0.29.0 and transformers 5.17.0.
Evaluation
All models were run on the same hardware with the same scoring code (October 2026). Qwen3.5-4B is the base model
P110 was fine-tuned from. Models with two runs are averaged. Bold marks the best score in each row.
Prompts: on ThaiOCRBench every model gets the benchmark's own prompt for each task. For CER, the text crops (ocr_th,
iapp, openthaigpt) use the plain OCR prompt from the Usage section, and the PDF pages use a page-to-JSON prompt (text blocks, headings,
tables) that falls back to the plain OCR prompt if the JSON is invalid. Typhoon OCR 7B is trained for its own fixed
prompt, so its CER rows use its official prompt and sampling settings instead.
ThaiOCRBench (13 tasks, higher is better)
ThaiOCRBench, all 2,808 items. P110 is a general document model: it transcribes text and answers questions about documents (classification,
key-information mapping, charts, infographics).
Charts: see the main repo.
Typhoon OCR 7B with its own official prompt scores 0.476 on the 5 transcription tasks (it is not built for
the other 8).
Character error rate (CER %, lower is better)
Typhoon OCR 7B is better on handwriting and on the openthaigpt crops. Qwen3.5-4B (base) often reads the text
but adds explanations or summaries despite the plain-OCR prompt; those extra characters count as errors, so several of
its crop scores reach the 100% cap.
How CER is measured
CER is the character edit distance (Levenshtein) between the model output and the reference text, divided by the
length of the reference, averaged over items. Each item is capped at 100%, so one runaway output cannot dominate the
average. Before comparing, both texts go through the same normalization for every model: Unicode NFC, a detached sara
am (ํ + า) joined into ำ, curly quotes made straight, markdown table rules and |*# markup removed, dotted or
underlined fill-in lines (……, ___) removed, and all whitespace removed (Thai does not separate words with spaces, and
models differ in how they space and break lines).
The held-out splits of mekpro/ocr_th and iapp/thai_handwriting_dataset are 10% of each subset, chosen with a fixed
seed (42) before training and never trained on. The training data was also checked for overlap with ThaiOCRBench.
The three PDF sets are in-house pages of Thai government documents with verified reference text.
Quantized variants
Table with columns: Variant, Format, For, CER % handwriting / printed| Variant | Format | For | CER % handwriting / printed |
|---|
| BF16 | safetensors | vLLM, transformers | 35.52 / 1.98 |
| FP8 | compressed-tensors FP8 dynamic | vLLM, Ada / Hopper and newer | 35.58 / 2.13 |
| W4A16 | compressed-tensors INT4 (GPTQ) | vLLM, Ampere and newer | 36.30 / 2.38 |
| NVFP4 | compressed-tensors NVFP4 (MLP) + FP8 (attention) | vLLM, Blackwell |
The full held-out sets from the CER table (iapp handwriting, 1,355 items; ocr_th printed text, 400 items), run on each released file, lower is better. The BF16 row is the released merged weights; the CER table above comes from the evaluation run before merging, so its numbers differ slightly. GGUF files were run in llama.cpp with --image-min-tokens 64.
Training data (summary)
Synthetic Thai documents rendered from many layouts and fonts (forms, memos, tables, receipts); realistic
handwritten documents composed from real handwriting segmented into individual characters; pages from publicly
available Thai documents with verified text; public Thai OCR datasets (mekpro/ocr_th, iapp/thai_handwriting_dataset,
training splits only); and question–answer pairs whose answers are taken directly from the verified text. No
benchmark test data was used for training.
Limitations
- Handwriting is the weakest area (see the table above).
- Upside-down or heavily rotated pages are not detected; rotate pages upright first.
- Very long or dense pages can occasionally loop; set a
max_tokens limit.
- Rare stray non-Thai glyphs inside Thai words can appear.
License and attribution
Developed by Porsuk Rungarunsrisuk. Released under Apache-2.0 (see LICENSE and NOTICE). Built on Qwen3.5-4B by the Qwen team
(Alibaba Cloud); this project is not affiliated with or endorsed by the Qwen team.
Citation
@misc{rungarunsrisuk2026p110thaiocr, title = {P110-ThaiOCR-4B: a 4B vision-language model for Thai document OCR}, author = {Rungarunsrisuk, Porsuk}, year = {2026}, url = {https://huggingface.co/PorsukR/P110-ThaiOCR-4B}}