-
With a parameter size of 0.9B, PaddleOCR-VL-1.5 achieves 94.5% accuracy on OmniDocBench v1.5, surpassing the previous SOTA model PaddleOCR-VL. Significant improvements are observed in table, formula, and text recognition.
-
It introduces an innovative approach to document parsing by supporting irregular-shaped localization, enabling accurate polygonal detection under skewed and warped document conditions. Evaluations across five real-world scenarios—scanning, skew, warping, screen-photography, and illumination—demonstrate superior performance over mainstream open-source and proprietary models.
-
The model introduces text spotting (text-line localization and recognition), along with seal recognition, with all corresponding metrics setting new SOTA results in their respective tasks.
-
PaddleOCR-VL-1.5 further strengthens its capability in specialized scenarios and multilingual recognition. Recognition performance is improved for rare characters, ancient texts, multilingual tables, underlines, and checkboxes, and language coverage is extended to include China's Tibetan script and Bengali.
-
The model supports automatic cross-page table merging and cross-page paragraph heading recognition, effectively mitigating content fragmentation issues in long-document parsing.
Make sure to have transformers above v5.
You can load the model as follows. Since you need to have the detected regions, please refer to notebook for complete inference.
1import torch
2from transformers import AutoProcessor, AutoModelForImageTextToText
3model_id = "PaddlePaddle/PaddleOCR-VL-1.5-hf"
4
5processor = AutoProcessor.from_pretrained(ocr_model_id)
6model = AutoModelForImageTextToText.from_pretrained(
7 model_id, torch_dtype=torch.bfloat16
8).to(device)
9
10def ocr_region(crop, prompt):
11 """Run PaddleOCR-VL 1.5 on a single cropped region."""
12 messages = [
13 {
14 "role": "user",
15 "content": [
16 {"type": "image", "image": crop},
17 {"type": "text", "text": prompt},
18 ],
19 }
20 ]
21 inputs = processor.apply_chat_template(
22 messages,
23 add_generation_prompt=True,
24 tokenize=True,
25 return_dict=True,
26 return_tensors="pt",
27 ).to(ocr_model.device)
28
29 generated_ids = model.generate(**inputs, max_new_tokens=1024)
30 trimmed = generated_ids[0][inputs["input_ids"].shape[-1] :]
31 return processor.decode(trimmed, skip_special_tokens=True)
32
33parsed_regions = []
34
35# assuming you have detected regions from PPDocLayoutv3 in detections
36
37for det in detections:
38 label = det["label"]
39 prompt = LABEL_TO_PROMPT.get(label)
40
41 x1, y1, x2, y2 = det["box"]
42 crop = image.crop((x1, y1, x2, y2))
43 text = recognise_region(crop, prompt)
44
45 parsed_regions.append({**det, "prompt": prompt, "text": text})
46 print(f"[{det['order']}] {label} prompt={prompt}")
47 print(text)
We would like to thank
PaddleFormers,
Keye,
MinerU,
OmniDocBench for providing valuable code, model weights and benchmarks. We also appreciate everyone's contribution to this open-source project!
If you find PaddleOCR-VL-1.5 helpful, feel free to give us a star and citation.
1@misc{cui2026paddleocrvl15multitask09bvlm,
2 title={PaddleOCR-VL-1.5: Towards a Multi-Task 0.9B VLM for Robust In-the-Wild Document Parsing},
3 author={Cheng Cui and Ting Sun and Suyin Liang and Tingquan Gao and Zelun Zhang and Jiaxuan Liu and Xueqing Wang and Changda Zhou and Hongen Liu and Manhui Lin and Yue Zhang and Yubo Zhang and Yi Liu and Dianhai Yu and Yanjun Ma},
4 year={2026},
5 eprint={2601.21957},
6 archivePrefix={arXiv},
7 primaryClass={cs.CV},
8 url={https://arxiv.org/abs/2601.21957},
9}