Multi-page OCR models tend to fall apart on long PDFs. The context fills up, tables start repeating themselves, and the model invents a page that doesn't exist. Baidu's Unlimited-OCR-2 is a 3B, MIT-licensed model built for that failure. According to Baidu, page 500 costs about the same per decoding step as page 1.

I haven't run it. This post covers what the model card, the paper and the benchmark card actually say, how to run Unlimited-OCR-2 locally with Transformers or SGLang, and which of Baidu's numbers I'd want to see someone else reproduce.

What changed from Unlimited-OCR 1 to Unlimited-OCR-2

The first Unlimited-OCR came out in June 2026 and was pitched as pushing DeepSeek-OCR "one step further." It parsed multi-page documents in a single context, but the paper notes it had a 40-page input limit. That's why it doesn't appear on Baidu's new hundred-page benchmark at all.

Version 2 landed on GitHub on 2026-10-27, and the paper went up on arXiv two days later. The headline change is Sparse Reference Sliding Window Attention (SR-SWA). Every decoder attention layer now looks at a fixed-size set of "working references", 512 tokens in the card's example, instead of attending to all remote visual tokens. The paper puts it as "a document parsing model that looks only at what it transcribes."

The second change is less flashy and probably more useful, a scheme Baidu calls the Unlimited-Horizon Decoding Paradigm. The document gets split into overlapping page chunks, and each chunk reuses the KV cache of the boundary page it shares with the previous chunk. KV caches outside the active chunk are released. Baidu's numbers on MarathonDocBench, from Table 4 of the paper:

Standard decoding Chunked + KV reuse
Peak KV cache (B=1) 47.00 GB 1.77 GB
End-to-end throughput (B=16) 360 TPS 1,315 TPS

On per-step speed, the paper claims 7.0× over full attention and 5.6× over R-SWA (the v1 mechanism) at hundred-page scale. Those figures compare attention variants against each other. They say nothing about whole OCR pipelines, so don't read them as "your PDFs finish 7× faster."

How to run Unlimited-OCR-2 locally with Transformers

The card says it was tested on Python 3.10 with an NVIDIA A800-80GB. There's no minimum VRAM listed anywhere, in the card or the repo. The weights are BF16 safetensors, so a 3B model is small on disk, but whatever fits on your 24 GB card is something you'll have to find out yourself. Pinned versions, straight from the card:

pip install torch==2.13.0 torchvision pillow transformers==4.52.1 huggingface-hub==0.36.0 \ tokenizers==0.21.4 addict==2.4.0 einops==0.8.2 easydict==1.13 
import torch from transformers import AutoModel, AutoTokenizer model_name = "baidu/Unlimited-OCR-2" tokenizer = AutoTokenizer.from_pretrained(model_name, trust_remote_code=True) model = AutoModel.from_pretrained(model_name, trust_remote_code=True, use_safetensors=True, torch_dtype=torch.bfloat16).eval().cuda() 

trust_remote_code=True runs Python from the Hub repo. Read it and pin a revision before this goes anywhere near production data.

There are two entry points, and they behave differently. infer_multi takes the whole document in one request, so the model gets cross-page context:

pages = [f"your_doc/page_{i}.jpg" for i in range(1, 8)] text, num_tokens = model.infer_multi(tokenizer, image_files=pages, output_path="output/multi", save_results=True) 

The prompt is built for you as "<PAGE><image>" * num_pages + "Multi page parsing.". Each page is encoded as a single global view ("base mode"), and you get one <PAGE> marker per input page, in order.

infer handles one page, using dynamic tiling ("gundam mode"):

text = model.infer(tokenizer, image_file="your_doc/page_1.jpg", output_path="output/single", save_results=True) 

Running infer in a loop gives you higher-resolution tiles per page, but tables that continue across pages get no help. infer_multi gets the cross-page context, but in the Transformers path each page is a lower-resolution base-mode view. The SGLang client lets you request gundam tiles on multi-page requests with crop_mode, so that's the route if you want both. For a dense 8-point financial filing, I'd test both on ten pages before committing to either.

Serving it with Baidu's SGLang fork

For serving, the card recommends a customized SGLang wheel, sglang-0.5.20.dev13+g75b9b06b02, which lives in the wheel/ directory of the GitHub repo. So you're running a fork, and upstream SGLang upgrades won't automatically help you.

uv venv --python 3.10 source .venv/bin/activate uv pip install wheel/sglang-0.5.20.dev13+g75b9b06b02-py3-none-any.whl uv pip install pymupdf==1.27.2.2 uv pip install fastokens==0.3.2 

These are the environment variables that matter, copied exactly (the card sets a few more for shared memory and the VLM cache). Yes, EANABLE is misspelled in the card. Copy it as-is, or check the code before you "fix" it.

export SGLANG_UOCR_EANABLE_DOC_LIMIT=1 # 1 = enable, 0 = whole document in one window export SGLANG_UOCR_DOC_GUNDAM_PAGE_WINDOW=10 # pages per window (gundam mode) export SGLANG_UOCR_DOC_BASE_PAGE_WINDOW=10 # pages per window (base mode) export SGLANG_UOCR_MAX_PAGE_TOKENS=20000 # per-page output cap; must be > 0 export SGLANG_OPT_UOCR_SAM_REL_POS_BIAS_MB=64 export PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True 

The full launch command has around 20 flags (CUDA graph buckets, --disable-radix-cache, --enable-custom-logit-processor) and serves on port 10000. Copy it from the card rather than from me. Then read the card's memory notes, which are the most honest part of the release:

  • --mem-fraction-static 0.7 is stable. At 0.75, "leaves too little headroom at 32+ concurrent requests."
  • --max-prefill-tokens drives a temporary tensor of roughly [tokens, context/32], so going from 4096 to 2048 halves that peak.
  • The default SAM attention-bias chunk (512) can make a single ~462 MiB allocation and OOM, which is why the card sets it to 64.
  • A smaller page window lowers peak memory but hurts cross-page merging.

That last note is the knob for consumer GPUs. If you're short on VRAM, try PAGE_WINDOW below 10 first, and accept that tables split across window boundaries will suffer.

The client is plain OpenAI-compatible /v1/chat/completions with base64 page images, PDF pages rendered at 300 DPI via PyMuPDF, and a no-repeat n-gram logit processor (ngram_size: 35, window 1024 for multi-page). Keep that processor on. It's there because OCR models loop.

MarathonDocBench: the benchmark Baidu wrote for itself

MarathonDocBench is 100 documents of 100 to 300 pages each, around 18k page images, in mixed Chinese and English. Baidu built and scored it, and Baidu wins by a mile:

Model Overall
Unlimited OCR Works 2 77.06
Kimi-K3 33.7
Gemini-3.8-Flash 28.6
Gemini-3.1-Pro Preview 27.0
DeepSeek-4.1-Flash 12.34

A lead of 43 points should make you suspicious, and the benchmark card explains part of it. The competitor baselines "send all pages in one request, progressively downscale images on oversize/timeout and retry, skip docs over the image cap, and leave failures as empty predictions so the denominator stays 100."

So a general VLM that hits its provider's per-request image cap, or still fails after the downscale-and-retry loop, gets a zero for that document. That's a fair test of "can you parse 300 pages in one shot," which is Baidu's whole pitch. It isn't a test of whether Gemini is worse at reading a page than a 3B model, and nobody gave the competitors a chunked pipeline. On the model card itself, the leaderboard is just a PNG. The text table only appears on the dataset card and in the paper.

Some numbers in the paper are less flattering and worth more:

  • On OmniDocBench (single page), v2 scores 94.02, against 93.92 for v1. The 1.2B TeleOCR scores 96.91. If your documents are short, this model isn't the obvious pick.
  • MPDocBench (dozens of pages) jumps from 61.89 to 84.59 versus v1, and that's where v2 actually got better.
  • HeadingTEDS on MarathonDocBench is 48.2, its weakest metric. The paper's limitations section admits the sparse attention "does not preserve global document information," including heading hierarchies. If you need a correct table of contents from a 300-page manual, plan to fix headings yourself.

Should you use it?

If you regularly parse 100+ page PDFs into Markdown and currently stitch per-page OCR output together with regex and prayer, yes, spend an afternoon on it. MIT license, 3B parameters, and a chunked decoding scheme with published memory numbers is a better offer than most of what's out there. Run it on your own ugliest document, not on MarathonDocBench.

If you're on a 12 GB card, wait for someone to post real VRAM figures. Baidu tested on an 80 GB A800 and didn't publish a floor.

What's the longest PDF you've thrown at an OCR model before it fell over, and what are you running for that today? I'd especially like to hear from anyone who has put this up against Docling, Marker or a plain per-page loop on a real 300-page scan.

Sources