Skip to content

[Model] Support Unlimited OCR - #46564

Merged
ywang96 merged 24 commits into
vllm-project:mainfrom
gty111:unlimited_ocr
Jun 28, 2026
Merged

[Model] Support Unlimited OCR#46564
ywang96 merged 24 commits into
vllm-project:mainfrom
gty111:unlimited_ocr

Conversation

@gty111

@gty111 gty111 commented Jun 24, 2026

Copy link
Copy Markdown
Collaborator

Purpose

Support https://huggingface.co/baidu/Unlimited-OCR

Test

OmniDocBench

Metric FA4 FlexAttention Paper v1.6
Overall ↑ 92.12 92.38 93.92
Text Edit ↓ 0.089 0.087 0.042
Formula CDM ↑ 95.34 95.53 95.79
Formula Edit ↓ 0.108 0.105
Table TEDS ↑ 89.90 90.33 90.16
Table TEDS-S ↑ 93.27 93.60 93.32
Read-order Edit ↓ 0.143 0.143 0.129

Essential Elements of an Effective PR Description Checklist
  • The purpose of the PR, such as "Fix some issue (link existing issues this PR will resolve)".
  • The test plan, such as providing test command.
  • The test results, such as pasting the results comparison before and after, or e2e results
  • (Optional) The necessary documentation update, such as updating supported_models.md and examples for a new model.

Signed-off-by: Tianyu Guo <guoty9@mail2.sysu.edu.cn>
Comment thread vllm/model_executor/models/unlimited_ocr.py Outdated
Comment thread vllm/model_executor/models/unlimited_ocr.py Outdated
Comment thread vllm/v1/worker/gpu_model_runner.py Outdated
Comment thread vllm/model_executor/models/registry.py
Signed-off-by: Isotr0py <mozf@mail2.sysu.edu.cn>
@Isotr0py
Isotr0py requested a review from DarkLight1337 as a code owner June 24, 2026 03:54
Signed-off-by: Tianyu Guo <guoty9@mail2.sysu.edu.cn>
@mergify

mergify Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Documentation preview: https://vllm--46564.org.readthedocs.build/en/46564/

@mergify mergify Bot added the documentation Improvements or additions to documentation label Jun 24, 2026
@MurphyYin

Copy link
Copy Markdown

Hi, I’m from the Unlimited-OCR team. Could you clarify whether, in the OmniDocBench v1.5 evaluation, the coordinate information between <|det|> and <|\det|> was kept and the full output was used directly for evaluation?

@gty111

gty111 commented Jun 24, 2026

Copy link
Copy Markdown
Collaborator Author

Hi, I’m from the Unlimited-OCR team. Could you clarify whether, in the OmniDocBench v1.5 evaluation, the coordinate information between <|det|> and <|\det|> was kept and the full output was used directly for evaluation?

Hi, thanks for reaching out!

Short answer: No, the coordinates were not kept. We don't feed the raw output into the evaluator. Each prediction first goes through a to_markdown step (same as the official Unlimited-OCR / DeepSeek-OCR post-processing) that strips all <|ref|> / <|det|>…<|/det|> markers and their coordinates, keeping only the recognized text. The cleaned markdown is what OmniDocBench v1.5 scores.

Example — raw output:

<|det|>title [120, 45, 480, 78]<|/det|>Annual Financial Report 2025
<|ref|>image<|/ref|><|det|>[100, 150, 400, 350]<|/det|>
<|det|>text [88, 370, 510, 405]<|/det|>Revenue grew by 12% year over year.

After to_markdown (this is what gets evaluated):

Annual Financial Report 2025
![](images/0.jpg)
Revenue grew by 12% year over year.

Notes:

  • Bboxes are only used for marker removal, never scored.
  • Image regions → ![](images/N.jpg); reading order is taken as emitted, not re-sorted by coordinates.

If your v1.5 protocol expects coordinates to be retained or a different post-process, please share it and we'll re-run to match.

Signed-off-by: Tianyu Guo <guoty9@mail2.sysu.edu.cn>
@gty111
gty111 requested a review from heheda12345 as a code owner June 24, 2026 06:31
@gty111

gty111 commented Jun 26, 2026

Copy link
Copy Markdown
Collaborator Author

Thanks for the PR! I made a quick pass and I have one quick question on the KV cache management part: The current implementation reuses FullAttentionSpec and its manager, while I feel RSWA looks more similar to SlidingWindowSpec. So I was wondering if we should make it a subclass of SlidingWindowSpec/Manager instead. Would like to understand the high-level idea better.

@ivanium
We chose FullAttentionSpec as the base because R-SWA is full attention over the prefix plus a sliding window over the generated tokens — the prefix (image + prompt) stays globally visible to every decode token, and only the decode region is windowed. FullAttentionManager's defaults already match this (prefix is never evicted, pool sizing uses the full-attention worst-case bound), so RSWAManager just adds remove_gap_blocks to keep the runtime held set bounded at prefix + window.

Inheriting from SlidingWindowSpec wouldn't actually reuse anything, because the pattern is the opposite: it windows the whole sequence and evicts the head, whereas R-SWA must keep the head and only window the decode region. We'd end up overriding all of its core (max_memory_usage_bytes, remove_skipped_blocks, find_longest_cache_hit), so there's nothing left to gain.

Signed-off-by: Tianyu Guo <guoty9@mail2.sysu.edu.cn>
@ivanium

ivanium commented Jun 27, 2026

Copy link
Copy Markdown
Collaborator

Thanks for the PR! I made a quick pass and I have one quick question on the KV cache management part: The current implementation reuses FullAttentionSpec and its manager, while I feel RSWA looks more similar to SlidingWindowSpec. So I was wondering if we should make it a subclass of SlidingWindowSpec/Manager instead. Would like to understand the high-level idea better.

@ivanium We chose FullAttentionSpec as the base because R-SWA is full attention over the prefix plus a sliding window over the generated tokens — the prefix (image + prompt) stays globally visible to every decode token, and only the decode region is windowed. FullAttentionManager's defaults already match this (prefix is never evicted, pool sizing uses the full-attention worst-case bound), so RSWAManager just adds remove_gap_blocks to keep the runtime held set bounded at prefix + window.

Inheriting from SlidingWindowSpec wouldn't actually reuse anything, because the pattern is the opposite: it windows the whole sequence and evicts the head, whereas R-SWA must keep the head and only window the decode region. We'd end up overriding all of its core (max_memory_usage_bytes, remove_skipped_blocks, find_longest_cache_hit), so there's nothing left to gain.

Thanks for the detailed reply! I will make a pass now.

@Isotr0py
Isotr0py enabled auto-merge (squash) June 27, 2026 06:40

@ivanium ivanium left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the reply and updates! I made another pass with a few questions on the kv cache manager part

Comment thread vllm/v1/core/single_type_kv_cache_manager.py Outdated
Comment thread vllm/v1/core/kv_cache_manager.py Outdated
Comment thread vllm/v1/worker/gpu_model_runner.py Outdated
Comment thread vllm/v1/kv_cache_interface.py Outdated
Comment thread vllm/v1/worker/gpu_model_runner.py Outdated
Signed-off-by: Tianyu Guo <guoty9@mail2.sysu.edu.cn>
auto-merge was automatically disabled June 27, 2026 10:20

Head branch was pushed to by a user without write access

@mergify

mergify Bot commented Jun 27, 2026

Copy link
Copy Markdown
Contributor

Hi @gty111, the pre-commit checks have failed. Please run:

uv pip install pre-commit>=4.5.1
pre-commit install
pre-commit run --all-files

Then, commit the changes and push to your branch.

For future commits, pre-commit will run automatically on changed files before each commit.

gty111 and others added 2 commits June 27, 2026 18:26
Signed-off-by: Tianyu Guo <guoty9@mail2.sysu.edu.cn>
@njhill

njhill commented Jun 27, 2026

Copy link
Copy Markdown
Member

Thanks @gty111. Model runner changes look fine to me but could we ensure that it also works with Model Runner V2? We're hoping to deprecate Model Runner V1 soon.

Signed-off-by: Tianyu Guo <guoty9@mail2.sysu.edu.cn>
@gty111

gty111 commented Jun 28, 2026

Copy link
Copy Markdown
Collaborator Author

Thanks @gty111. Model runner changes look fine to me but could we ensure that it also works with Model Runner V2? We're hoping to deprecate Model Runner V1 soon.

Thanks for the review. R-SWA is now wired through Model Runner V2 as well: V2 passes per-request prompt_len as rswa_prefix_lens into the shared FlashAttention metadata builders (same as V1’s num_prompt_tokens path).

One caveat: Unlimited-OCR still needs NGramPerReqLogitsProcessor for good long-document OCR, and V2 does not support custom logits processors yet — production is recommended to use V1 until that lands. We’ve smoke-tested V2 on the 14-page PDF merge without the ngram processor; R-SWA itself works on V2.

@ywang96 ywang96 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gty111 Thanks for the great work and the collaboration with Baidu team @MurphyYin 🤝

@ywang96
ywang96 merged commit c6741b2 into vllm-project:main Jun 28, 2026
136 of 141 checks passed
@AndreasKaratzas

Copy link
Copy Markdown
Member

I think that this PR broke:

Will be pushing a fix soon.

PS
Test group name is weird cause it belongs in a custom branch, but I expect the failure to appear in our nightly as well.

wincent8 pushed a commit to wincent8/vllm that referenced this pull request Jun 29, 2026
Signed-off-by: Tianyu Guo <guoty9@mail2.sysu.edu.cn>
Signed-off-by: Isotr0py <mozf@mail2.sysu.edu.cn>
Co-authored-by: Isotr0py <mozf@mail2.sysu.edu.cn>
Co-authored-by: Roger Wang <hey@rogerw.io>
davanstrien added a commit to davanstrien/uv-scripts-for-ai that referenced this pull request Jun 30, 2026
…ngle-image batch OCR) (#63)

* ocr: add unlimited-ocr-vllm.py recipe (Baidu Unlimited-OCR, 3.3B — single-image batch OCR)

Offline-vLLM batch recipe for baidu/Unlimited-OCR (3.3B, MIT, a DeepSeek-OCR
descendant; vLLM support landed upstream 2026-06-28), mirroring deepseek-ocr-vllm.py.
One image per row -> layout-grounded markdown; --strip-grounding for clean text,
--grounding-column to keep both clean text and the raw <|det|> bboxes. Runs on
Baidu's dedicated vllm/vllm-openai:unlimited-ocr image (arch not in a stable wheel;
vLLM/torch come from the image via PYTHONPATH).

Validated on HF Jobs: ufo-ColPali (5/5) and encyclopaedia-britannica-1771 (6/6
content pages ~= ground-truth ocr_text length).

Multi-page is single-image-only via vLLM (the integration garbles multi-image, and
is unproven upstream — PR vllm-project/vllm#46564 benchmarks single-page only).
Multi-page lives in the model's SGLang build: serving-unlimited-ocr.md now carries a
validated working SGLang command (pinned lmsysorg/sglang:v0.5.10.post1 + a100-large +
--attention-backend flashinfer; HF h200 nodes currently fail GPU init with CUDA
error 802) alongside the vLLM single-image serving option.

Also updates ocr/README.md (table row, serve line, modes table, dedicated-image
note) and ocr/CLAUDE.md (dev notes + full investigation). Additive only; superset
gate (tools/verify-superset.sh ocr uv-scripts/ocr) passes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* ocr: correct unlimited-ocr multi-page framing (vLLM works on clean docs)

Control test (same clean synthetic 2-page doc, vLLM server) returned both pages
<PAGE>-separated with real text — so the earlier "vLLM multi-page garbles/broken"
was an input-difficulty artifact (the hard Britannica/ufo scans), not an engine
failure. Corrected across the recipe docstring, serving-unlimited-ocr.md, README,
and CLAUDE.md: both engines read clean multi-page docs; SGLang is the *more robust*
path (held up on hard/degraded scans where vLLM hallucinated). Batch recipe stays
single-image; multi-page is a serving concern.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* ocr: address review on unlimited-ocr-vllm.py (column guard, upload retry, --model)

- guard add_column against an existing output/grounding column (fixes the
  in-place multi-model append crash; parity with deepseek-ocr2-vllm.py)
- push_to_hub: 3-attempt retry + HF_HUB_DISABLE_XET fallback + max_shard_size="500MB"
- add --model flag (default baidu/Unlimited-OCR)
- CLAUDE.md: move the (Production Ready) entry to "Other OCR Scripts";
  note the deferred SGLang multi-page-batch follow-up

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@njhill njhill mentioned this pull request Jun 30, 2026
22 tasks
rjrock pushed a commit to rjrock/vllm that referenced this pull request Jul 1, 2026
Signed-off-by: Tianyu Guo <guoty9@mail2.sysu.edu.cn>
Signed-off-by: Isotr0py <mozf@mail2.sysu.edu.cn>
Co-authored-by: Isotr0py <mozf@mail2.sysu.edu.cn>
Co-authored-by: Roger Wang <hey@rogerw.io>
noooop pushed a commit to noooop/vllm that referenced this pull request Jul 9, 2026
Signed-off-by: Tianyu Guo <guoty9@mail2.sysu.edu.cn>
Signed-off-by: Isotr0py <mozf@mail2.sysu.edu.cn>
Co-authored-by: Isotr0py <mozf@mail2.sysu.edu.cn>
Co-authored-by: Roger Wang <hey@rogerw.io>
Signed-off-by: wang.yuqi <yuqi.wang@daocloud.io>
Dao007forever pushed a commit to Dao007forever/vllm that referenced this pull request Jul 18, 2026
Signed-off-by: Tianyu Guo <guoty9@mail2.sysu.edu.cn>
Signed-off-by: Isotr0py <mozf@mail2.sysu.edu.cn>
Co-authored-by: Isotr0py <mozf@mail2.sysu.edu.cn>
Co-authored-by: Roger Wang <hey@rogerw.io>
philippesic pushed a commit to philippesic/vllm-semantic-cache that referenced this pull request Jul 19, 2026
Signed-off-by: Tianyu Guo <guoty9@mail2.sysu.edu.cn>
Signed-off-by: Isotr0py <mozf@mail2.sysu.edu.cn>
Co-authored-by: Isotr0py <mozf@mail2.sysu.edu.cn>
Co-authored-by: Roger Wang <hey@rogerw.io>
plasticchris pushed a commit to plasticchris/vllm that referenced this pull request Jul 20, 2026
Signed-off-by: Tianyu Guo <guoty9@mail2.sysu.edu.cn>
Signed-off-by: Isotr0py <mozf@mail2.sysu.edu.cn>
Co-authored-by: Isotr0py <mozf@mail2.sysu.edu.cn>
Co-authored-by: Roger Wang <hey@rogerw.io>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

deepseek Related to DeepSeek models documentation Improvements or additions to documentation new-model Requests to new models ready ONLY add when PR is ready to merge/full CI is needed v1

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants