We are pleased to announce the release of OvisOCR2, a compact 0.8B end-to-end model for page-level document parsing. Given a document page image, OvisOCR2 generates a Markdown representation in natural reading order, covering text, formulas, tables, and visual regions.
OvisOCR2 is developed by post-training Qwen3.5-0.8B using a carefully designed data engine that combines real-world and synthetic data, together with a multi-stage training recipe integrating SFT, RL, and OPD. The model delivers strong document parsing performance while maintaining a small deployment footprint.
OvisOCR2 achieves an overall score of 96.58 on OmniDocBench v1.6, establishing a new state of the art and becoming the first end-to-end model to top this leaderboard previously dominated by pipeline methods. On PureDocBench, OvisOCR2 also achieves the highest Avg3 score of 75.06.
Performance of OvisOCR2 on OmniDocBench v1.6
Performance
OmniDocBench v1.6 comparison
PureDocBench comparison
Inference
pip install "vllm==0.22.1" pillow
python
1from PIL import Image
2from vllm import LLM, SamplingParams
345classOvisOCR2Parser:6def__init__(self, model_name_or_path:str):7 self.model = LLM(8 model=model_name_or_path,9 tensor_parallel_size=1,10 gpu_memory_utilization=0.8,11 gdn_prefill_backend="triton"12)1314 prompt ='\nExtract all readable content from the image in natural human reading order and output the result as a single Markdown document. For charts or images, represent them using an HTML image tag: <'+'img src="images/bbox_{left}_{top}_{right}_{bottom}.jpg" />, where left, top, right, bottom are bounding box coordinates scaled to [0, 1000). Format formulas as LaTeX. Format tables as HTML: <table>...</table>. Transcribe all other text as standard Markdown. Preserve the original text without translation or paraphrasing.'15 self.prompt = self.model.get_tokenizer().apply_chat_template(16[{"role":"user","content":[{"type":"image"},{"type":"text","text": prompt}]}],17 tokenize=False,18 add_generation_prompt=True,19 enable_thinking=False20)2122 self.sampling_params = SamplingParams(23 max_tokens=16384,24 temperature=0.025)2627def_clean_truncated_repeats(28 self,29 text:str,30 min_text_len:int=8000,31 max_period:int=200,32 min_period:int=1,33 min_repeat_chars:int=100,34 min_repeat_times:int=535)->str:36 n =len(text)37if n < min_text_len:38return text
3940 max_period =min(max_period, n -1)41for unit_len inrange(min_period, max_period +1):42if text[n -1]!= text[n -1- unit_len]:43continue4445 match_len =146 idx = n -247while idx >= unit_len and text[idx]== text[idx - unit_len]:48 match_len +=149 idx -=15051 total_len = match_len + unit_len
52 repeat_times = total_len // unit_len
53 tail_len = total_len % unit_len
5455if repeat_times >= min_repeat_times and total_len >= min_repeat_chars:56return text[: n - total_len + unit_len]+ text[n - tail_len:]5758return text
5960defparse(self, images:list[Image.Image], filter_imgtags:bool=True)->list[str]:61 vllm_inputs =[62{63"prompt": self.prompt,64"multi_modal_data":{"image": image},65"mm_processor_kwargs":{66"images_kwargs":{67"min_pixels":448*448,68"max_pixels":2880*288069}70}71}72for image in images
73]7475 outputs = self.model.generate(vllm_inputs, self.sampling_params)7677 markdowns =[]78for output in outputs:79 text = output.outputs[0].text.strip()80if filter_imgtags:81 text ="\n\n".join(82 block
83for block in text.split("\n\n")84ifnot block.strip().startswith('<img src="images/bbox_')85)86 markdowns.append(self._clean_truncated_repeats(text))8788return markdowns
899091if __name__ =="__main__":92 parser = OvisOCR2Parser("ATH-MaaS/OvisOCR2")93 images =[Image.open("test1.jpg"), Image.open("test2.jpg")]94 markdowns = parser.parse(images)95print(markdowns[0])
By default, parse removes HTML image tags for visual regions. To render Markdown with visual regions, set filter_imgtags=False and save the Markdown file together with the referenced image crops as follows:
If you find OvisOCR2 useful, please consider citing our technical report:
bibtex
1@article{lu2026ovisocr2,
2 title={OvisOCR2 Technical Report},
3 author={Shiyin Lu and Yinglun Li and Yu Xia and Yuhui Chen and An-Yang Ji and Jun-Peng Jiang and Qing-Guo Chen and Jianshan Zhao and En Lin and Haijun Li and Cheng Qin and Zhao Xu and Weihua Luo},
4 journal={arXiv preprint arXiv:2607.13639},
5 year={2026}
6}
We used filtering and quality-assurance procedures during data construction to reduce parsing errors such as repeated outputs, incomplete content, invalid table/formula structures, and reading-order inconsistencies. Due to the diversity and complexity of real-world documents, OvisOCR2 may still produce incorrect or incomplete outputs. Please manually verify results in critical applications.