From: ATH-MaaS <huggingface.co/ATH-MaaS>Newsgroups: alt.freeweights.textSubject:

OvisOCR2

Date: 2026-11-15Commit: cbdede8Signed: 2DC28CC7B26A283B ✓

Image text to text model with 853M parameters. Safetensors weights, 1.73 GB in all. Published by ATH-MaaS under Apache-2.0.

853M params1.73GBOvisOCR2safetensorspermissive
FactsParams853MSize1.73 GBFormatssafetensorsTaskimage text to textLicenseApache-2.0From sourcepermissive
$ fw get ATH-MaaS/OvisOCR2
# manifest sha256 4aa4d72e4a2f… · 1.73 GB · 16 files
$ fw verify ./OvisOCR2 ATH-MaaS/OvisOCR2
From sourceHosted (signed)ATH-MaaS/OvisOCR2Last check: 2026-11-15 02:36 UTC

Get help: custom fine-tune or private deploy. We review your setup before we quote.

Fine-tune of Qwen3.5-0.8B.

Works with

Overview

Size
1.73 GB
Weights
1.71 GB (safetensors)
Parameters
853M
Formats
safetensors
Task
image text to text
License
Apache-2.0 (permissive)
Files
16, each with a sha256
Publisher
ATH-MaaS
Added
2026-11-15
Section
alt.freeweights.text
Lineage

Original release from the publisher.

Base model: Qwen/Qwen3.5-0.8B

Where these bytes come from
Publisher at the pinned commit→You

Sources are tried in order. A file counts only when its size and sha256 match the manifest. Sources are checked when you ask for them, not on a timer.

Sources
BadgeHostLast checkResult
From sourcehuggingface.co2026-11-15 02:36 UTCpassed

Model card

From the publisher at commit cbdede8. Shown as plain text with links; images open at the publisher.

OvisOCR2#

Image: Ovis

Technical Report &nbsp;|&nbsp; Online Demo

Introduction#

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.

Image: Performance of OvisOCR2 on OmniDocBench v1.6

Performance#

Image: OmniDocBench v1.6 comparison

Image: PureDocBench comparison

Inference#

pip install "vllm==0.22.1" pillow
from PIL import Image
from vllm import LLM, SamplingParams


class OvisOCR2Parser:
    def __init__(self, model_name_or_path: str):
        self.model = LLM(
            model=model_name_or_path,
            tensor_parallel_size=1,
            gpu_memory_utilization=0.8,
            gdn_prefill_backend="triton"
        )

        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.'
        self.prompt = self.model.get_tokenizer().apply_chat_template(
            [{"role": "user", "content": [{"type": "image"}, {"type": "text", "text": prompt}]}],
            tokenize=False,
            add_generation_prompt=True,
            enable_thinking=False
        )

        self.sampling_params = SamplingParams(
            max_tokens=16384,
            temperature=0.0
        )

    def _clean_truncated_repeats(
        self,
        text: str,
        min_text_len: int = 8000,
        max_period: int = 200,
        min_period: int = 1,
        min_repeat_chars: int = 100,
        min_repeat_times: int = 5
    ) -> str:
        n = len(text)
        if n < min_text_len:
            return text

        max_period = min(max_period, n - 1)
        for unit_len in range(min_period, max_period + 1):
            if text[n - 1] != text[n - 1 - unit_len]:
                continue

            match_len = 1
            idx = n - 2
            while idx >= unit_len and text[idx] == text[idx - unit_len]:
                match_len += 1
                idx -= 1

            total_len = match_len + unit_len
            repeat_times = total_len // unit_len
            tail_len = total_len % unit_len

            if repeat_times >= min_repeat_times and total_len >= min_repeat_chars:
                return text[: n - total_len + unit_len] + text[n - tail_len:]

        return text

    def parse(self, images: list[Image.Image], filter_imgtags: bool = True) -> list[str]:
        vllm_inputs = [
            {
                "prompt": self.prompt,
                "multi_modal_data": {"image": image},
                "mm_processor_kwargs": {
                    "images_kwargs": {
                        "min_pixels": 448 * 448,
                        "max_pixels": 2880 * 2880
                    }
                }
            }
            for image in images
        ]

        outputs = self.model.generate(vllm_inputs, self.sampling_params)

        markdowns = []
        for output in outputs:
            text = output.outputs[0].text.strip()
            if filter_imgtags:
                text = "\n\n".join(
                    block
                    for block in text.split("\n\n")
                    if not block.strip().startswith('<img src="images/bbox_')
                )
            markdowns.append(self._clean_truncated_repeats(text))

        return markdowns


if __name__ == "__main__":
    parser = OvisOCR2Parser("ATH-MaaS/OvisOCR2")
    images = [Image.open("test1.jpg"), Image.open("test2.jpg")]
    markdowns = parser.parse(images)
    print(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:

import re
from pathlib import Path

from PIL import Image


BBOX_IMAGE_PATTERN = re.compile(
    r'<img src=' + r'"images/bbox_(\d+)_(\d+)_(\d+)_(\d+)\.jpg" />'
)


def save_renderable_markdown_with_visual_regions(
    markdown: str,
    page_image: Image.Image,
    output_dir: str,
) -> None:
    output_dir = Path(output_dir)
    images_dir = output_dir / "images"
    images_dir.mkdir(parents=True, exist_ok=True)

    width, height = page_image.size
    for left, top, right, bottom in BBOX_IMAGE_PATTERN.findall(markdown):
        x1 = max(0, min(width, round(int(left) * width / 1000)))
        y1 = max(0, min(height, round(int(top) * height / 1000)))
        x2 = max(0, min(width, round(int(right) * width / 1000)))
        y2 = max(0, min(height, round(int(bottom) * height / 1000)))
        if x2 <= x1 or y2 <= y1:
            continue

        crop_path = images_dir / f"bbox_{left}_{top}_{right}_{bottom}.jpg"
        page_image.crop((x1, y1, x2, y2)).convert("RGB").save(crop_path)

    (output_dir / "output.md").write_text(markdown, encoding="utf-8")


parser = OvisOCR2Parser("ATH-MaaS/OvisOCR2")
page_image = Image.open("test1.jpg")
markdown = parser.parse([page_image], filter_imgtags=False)[0]
save_renderable_markdown_with_visual_regions(markdown, page_image, "output")

Citation#

If you find OvisOCR2 useful, please consider citing our technical report:

@article{lu2026ovisocr2,
  title={OvisOCR2 Technical Report},
  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},
  journal={arXiv preprint arXiv:2607.13639},
  year={2026}
}

License#

This project is licensed under the Apache License, Version 2.0 (SPDX-License-Identifier: Apache-2.0).

Disclaimer#

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.

Files

16 files · 1.73 GBWeights 1.71 GB (safetensors). Sizes and sha256 from the signed manifest.
Hide all 16 files with their sha256
FileSizesha256
.eval_results/real5_omnidocbench.yaml1.42 KBb802fd0aa61881dc8fb20fc2819e910c43333c94f72bfa2d64a1a0a42cd9c87a
.gitattributes1.76 KB0897bcd3fd8c9279317953bafb23fc1abdc51ff5877c7a5c00983d74a9704a49
LICENSE11.5 KBbbedc3fda3305820b977265f01b8619d87570a6739de3a5582c3464840f1e57a
README.md7.95 KBf2510d6d02471c01a2808102da79cb47106963f18486f2ac05dd5c0b53fc1c7a
chat_template.jinja7.75 KB273d8e0e683b885071fb17e08d71e5f2a5ddfb5309756181681de4f5a1822d80
config.json2.91 KBb90b86f35c8e6925ef74ee04d0e758f0a845c83a42089ad82bbaa948de9b4204
merges.txt3.35 MBa9d356d7bdf1ef4949e3e748e95b8e10ad9d4e2e838eddc38a0a7b6b94d1db8d
model.safetensors1.71 GB9270560288656ece5cb3a6989001afcf5af8d223bceed4a423c33a008861d009
performance.png878 KB771a452b0072234bd09984f9702f751ddfbf3a58e5aca6286ce493d1d1d0dfdc
performance_omnidocbench_v16.png606 KBf67200bf177cc8fc14774f1895386aab06ca544bf0a672d0789778a5fb15f087
performance_puredocbench.png575 KB65c8a4ce9391f29ab35d2c4e379d0aeac38a315409c0ff4dd210f3627a3cc1a7
preprocessor_config.json390 B27225450ac9c6529872ee1924fcb0962ff5634834f817040f444118116f4e516
tokenizer.json12.8 MB5f9e4d4901a92b997e463c1f46055088b6cca5ca61a6522d1b9f64c4bb81cb42
tokenizer_config.json16.7 KB49e2b6e395f959f077f1e992b338919c0d4a9732fc6e613995e06557f843500c
video_preprocessor_config.json385 B7768af27c1fafa9cc9011c1dc20067e03f8915e03b63504550e11d5066986d13
vocab.json6.72 MBce99b4cb2983d118806ce0a8b777a35b093e2000a503ebde25853284c9dfa003
VersionsEach time the pinned upstream commit or file list changed in this repo. Newest first.
Upstream commitDateContents
cbdede82e0 pinned now2026-11-15 02:36 UTC16 files · 1.73 GB

Use it

$ fw get ATH-MaaS/OvisOCR2
# manifest sha256 4aa4d72e4a2f… · 1.73 GB · 16 files
$ fw verify ./OvisOCR2 ATH-MaaS/OvisOCR2
fw.pyChecks the signature and every sha256, tries each source in order, resumes.
$ python3 fw.py get https://freeweights.allternit.com/manifests/ATH-MaaS/OvisOCR2.json --dir ./OvisOCR2 $ python3 fw.py verify ./OvisOCR2 ./ATH-MaaS__OvisOCR2.json
hfThe Hugging Face CLI with one setting. Same repo id.
$ HF_ENDPOINT=https://freeweights.allternit.com hf download ATH-MaaS/OvisOCR2 --revision cbdede82e048659b83310476ff807da825f8fe78 --local-dir ./OvisOCR2
transformersLoad the weights in Python.
import os os.environ["HF_ENDPOINT"] = "https://freeweights.allternit.com" from transformers import AutoModelForImageTextToText, AutoProcessor processor = AutoProcessor.from_pretrained("ATH-MaaS/OvisOCR2", revision="cbdede82e048659b83310476ff807da825f8fe78") model = AutoModelForImageTextToText.from_pretrained("ATH-MaaS/OvisOCR2", revision="cbdede82e048659b83310476ff807da825f8fe78", device_map="auto")
vLLMServe an OpenAI-compatible API.
$ HF_ENDPOINT=https://freeweights.allternit.com vllm serve ATH-MaaS/OvisOCR2 --revision cbdede82e048659b83310476ff807da825f8fe78

License

Name
Apache License 2.0
Id
Apache-2.0
Class
Permissive
Redistribution
yes
Listing
Hosted (signed)
Decided
License as declared by the publisher. No person read it. 2026-11-15
Text in
LICENSE
Text sha256
bbedc3fda3305820b977265f01b8619d87570a6739de3a5582c3464840f1e57a
Terms gate
No extra terms beyond the license.

Read the license text

Licenses are checked against the license table. A custom license passes only after a person reads it.

Provenance

From: ATH-MaaS <huggingface.co/ATH-MaaS>Newsgroups: alt.freeweights.textSubject: OvisOCR2Date: 2026-11-15Commit: cbdede8Signed: 2DC28CC7B26A283B ✓
Upstream
ATH-MaaS/OvisOCR2
Pinned commit
cbdede82e048659b83310476ff807da825f8fe78
Manifest
OvisOCR2.json · .minisig
Manifest sha256
4aa4d72e4a2f3fb1567b83268f08d6cd360046e38edd7af760d46ff04f8fcc3b
Signature
minisign, Ed25519, key 2DC28CC7B26A283B
Created
2026-11-15 02:36 UTC
Generator
freeweights-manifest/0.1.0
Takedowns
None.

How to verify

$ curl -O https://freeweights.allternit.com/manifests/ATH-MaaS/OvisOCR2.json $ curl -O https://freeweights.allternit.com/manifests/ATH-MaaS/OvisOCR2.json.minisig $ minisign -Vm OvisOCR2.json -P RWQ7KGqyx4zCLXtUFOqvfv8L3g+8fpKJ1FsuxPyOYMF+4KufbUxKq1Oq $ shasum -a 256 <file> # compare with the Files tab

A manifest whose signature fails must be rejected. A file whose size or sha256 does not match must be discarded. Verify a download

Model tree

Parent

Qwen/Qwen3.5-0.8B · this model is a finetune of it

1 model in the catalog name this one as their parent.

Quantizations
1
Quantizations 1
Get it
Download
$ HF_ENDPOINT=https://freeweights.allternit.com hf download ATH-MaaS/OvisOCR2
Open in Freeweights Studio

Pull, verify and run it in the Allternit app on Desktop, web or phone.

Signed manifest
minisign, key 2DC28CC7B26A283B. OvisOCR2.json. Provenance. Takedown history: none.

Variants

1 quantized or adapter build of OvisOCR2. Each has its own license check and page.

From: laion <huggingface.co/laion>Subject: a2-rl-e2egit_large-50-32B
From: laion <huggingface.co/laion>Subject: a3-rl-DCAgent_exp_rpt_e2egit-large-15-8B
From: laion <huggingface.co/laion>Subject: a3-rl-DCAgent_exp_rpt_e2egit-v2-10-8B
From: laion <huggingface.co/laion>Subject: a3-rl-DCAgent_exp_rpt_pymethods2test-large-80-8B
From: laion <huggingface.co/laion>Subject: a3-rl-DCAgent_exp_rpt_unitsyn-python-large-10-8B
From: laion <huggingface.co/laion>Subject: a3-rl-DCAgent_mix_h2_language_proportional-65-8B