Run Baidu's state-of-the-art long-horizon OCR on AMD GPUs — backed by real evaluation data, precision aligned.
OmniDocBench v1.6 Overall 92.431 (PyTorch fast path) · gate PASS · 1.88× lossless speedup · 16 GB VRAM · R-SWA constant memory
14-page academic paper → 41KB structured Markdown on AMD Radeon PRO W7900 48GB VRAM.
Zero format loss.
| OmniDocBench v1.6 | Gate | Speed | Min VRAM |
|---|---|---|---|
| 92.431 Overall ✓ (PyTorch fast path) | PASS | 1.88× lossless · ~0.21 pp/s (4-GPU) | 16 GB |
中文文档 (Chinese README) | Full parity report | Benchmarks | Architecture | Tuning guide
Baidu's Unlimited-OCR is the new state-of-the-art for long-horizon document parsing — entire books, multi-page contracts, dense tables in a single forward pass. We've ported it to AMD ROCm and run the full OmniDocBench v1.6 standard evaluation (1,651 pages) to establish precision alignment.
| Model | Overall ↑ | TextEdit ↓ | FormulaCDM ↑ | TableTEDS ↑ | TableTEDS_s ↑ | Read-orderEdit ↓ |
|---|---|---|---|---|---|---|
| PyTorch fast path (this project, AMD ROCm gfx1100) | 92.431 | 0.087 | 95.831 | 90.162 | 93.30 | 0.1442 |
| prior baseline (PyTorch, torch 2.5.1+rocm6.2) | 91.97 | 0.0939 | 95.72 | 89.58 | 92.83 | 0.1449 |
| Baidu paper* | 93.92 | 0.042 | 95.79 | 90.16 | 93.32 | 0.129 |
Scored and computed per the official OmniDocBench leaderboard methodology — see
generate_result_tables.ipynb(cell 2: the three columns — Text EditDist, Formula CDM×100, Table TEDS×100 — are rounded to 3 decimals beforeOverall = ((1−Text)×100 + CDM + TEDS)/3; CDM/TEDS are read fromdisplay_formula.page.CDM.ALL/table.page.TEDS.ALL× 100, not the sample-level.all.*.all. The scorer's rawoverall_notebookis 92.436.)
*Baidu self-report from arxiv:2606.23050 — not on the OmniDocBench leaderboard and not independently reproduced by anyone. Our 92.431 (PyTorch fast path, pinned weights 84757cb0, torch 2.10+rocm7.0) is a controlled, reproducible measurement (committed manifest, gate PASS), up +0.465 vs the prior 91.97 baseline with all modules ≥ baseline. The gain is env+weights + the decode_bpe postprocess fix, not batching luck — the Task-8 identity gate confirmed fast ≈ direct (Δ=0.0 exact post-fix) on the same env.
Honest parity framing. The ~1.49pt gap to Baidu's 93.92 is ~entirely Text EditDist, and a lossless per-page decomposition (docs/parity/moderate-tail-attribution-2026-07-11.md) shows the realistic lossless ceiling is ~92.5–93.0 — our 92.431 is within ~0.07–0.57 of it (essentially at ceiling). The gap decomposes ~35% inline-math LaTeX style (the model emits semantically-correct \(...\), \sin where GT uses $...$, \operatorname{s i n}; CDM 0.958 confirms the math is right — char-level EditDist penalizes delimiter/spacing) + ~25% genuine recognition limits + ~25% dense-layout divergence (book indexes/newspapers) + ~15% format/spacing. Only ~+0.5 pts is closable losslessly. 37% of pages hold 93.2% of the EditDist mass; 62.8% of pages are "good" (EditDist <0.05). Full diagnosis: docs/PARITY.md.
Speed. The fast path (bucketed batching) is 1.88× lossless vs the direct per-page path on a controlled 30-page gate (same env, same scorer, Overall Δ=0.0 exact post-fix), and the full 1,651-page run does ~0.21 pages/s aggregate on 4× gfx1100 (wall ~7,840 s). Benchmarks →*
→ Full parity report with per-module breakdown · Reproduction recipe →
This project runs Unlimited-OCR via two backends on AMD ROCm gfx1100:
| Backend | Status | OmniDocBench |
|---|---|---|
PyTorch fast path (bucketed batching, model.infer) |
✅ Verified aligned reference (the 92.431 above) + 1.88× lossless speedup | Overall 92.431, gate PASS — 1,651 pages, committed manifest |
| vLLM / ROCm serving | ⏳ Numerics-blocked preview | Catastrophic on ~10% of pages (first-token EOS) |
The PyTorch fast path (bucketed batching) is the verified aligned reference: the Task-8 identity gate confirmed it matches the direct per-page path exactly (post-decode_bpe-fix Δ=0.0; the earlier apparent 4/30-page single-accented-char divergence was the decode_bpe postprocess bug, now fixed — the only residual byte-differences are trailing newlines with zero EditDist impact), so it is both accurate (92.431) and 1.88× faster. The vLLM/ROCm serving backend regresses to first-token EOS on ~10% of pages (on a 150-page representative sample, same scorer: vLLM Overall 22.3 vs the PyTorch backend 66.4). The cause is forward-pass numerics — bf16 + optimized MoE/attention kernels (TRITON/ROCM_ATTN) vs PyTorch eager — on borderline pages. It is not R-SWA (ruled out by a direct ablation: forcing full causal attention in PyTorch does not reproduce the EOS), and not any config / decoding-contract / processor bug (all ruled out). The 92.431 figure advertised in this README is the PyTorch fast path; the vLLM/ROCm serving path has no passing score yet.
⏳ vLLM + ROCm backend → waiting for the official vLLM v0.25.0+ release. Definitive re-verification (serving unlimited-ocr on a real vLLM/ROCm build and re-scoring) is deferred until vLLM publishes an official v0.25.0+ ROCm wheel (the first stable release with core-side R-SWA + the Triton backend). The serving scripts are staged and ready for that day: scripts/rswa_spike/. Full investigation + the re-verification trigger: docs/parity/rswa-spike-verdict-2026-07-11.md.
- Evaluation you can trust — Standard OmniDocBench v1.6 benchmark, committed manifests for every run, strict regression gate prevents silent quality drops. The original Baidu repository has none of this.
- AMD native — One command to launch on any ROCm 6.0+ GPU. 16 GB consumer Radeon handles an entire book. No NVIDIA GPU, no CUDA, no compromises.
- Structured output — Markdown with tables, formulas, and bounding boxes preserved — same inference API as the original.
git clone https://github.com/AIwork4me/Unlimited-OCR-ROCm.git && cd Unlimited-OCR-ROCm
./scripts/setup_rocm.sh && source .venv/bin/activate
unlimited-ocr --pdf ./my_document.pdf --output-dir ./outputsdocker compose up -d
unlimited-ocr --pdf ./my_document.pdf --output-dir ./outputs| HuggingFace | ModelScope | AMD Radeon Cloud | |
|---|---|---|---|
| Cost | Free | Free | Free trial |
| GPU | Shared | Shared | Dedicated AMD GPU |
| Setup | 0 (in-browser) | 0 (in-browser) | ~60 s |
| Best for | Quick look | Quick look | Real workloads |
Recommended: try the HuggingFace or ModelScope demo to see the output quality, then register at AMD Radeon Cloud for dedicated hardware — the same GPU we benchmark on.
# Max speed
unlimited-ocr --pdf doc.pdf --image-mode gundam --pdf-dpi 150 --concurrency 8
# Max quality
unlimited-ocr --pdf doc.pdf --image-mode base --pdf-dpi 300 --max-length 32768
# Low VRAM (16 GB GPU)
unlimited-ocr --pdf doc.pdf --image-mode gundam --pdf-dpi 100 --mem-fraction 0.6Full guide: docs/TUNING.md
Traditional attention: KV cache grows with every token → O(n²) memory.
R-SWA (Reference Sliding Window Attention): The model only keeps visual tokens (~256) + last 128 output tokens in cache:
Traditional: KV[t1, t2, ..., t1000] ← 1000× growth → OOM
R-SWA: KV[visual~256] + KV[last_128] ← CONSTANT
Verified by OCRing the same academic paper at increasing page counts:
| Pages | VRAM |
|---|---|
| 1 | 7.3 GB |
| 5 | 7.4 GB |
| 10 | 7.4 GB |
| 25 | 7.5 GB |
| 50 | 7.5 GB |
VRAM grows only +0.2 GB from 1 to 50 pages. A 16 GB consumer Radeon handles an entire book. How it works →
Unlimited-OCR-ROCm is the only Unlimited-OCR distribution with a complete, automated evaluation pipeline. The original Baidu repository has none of this.
eval/ → omnidocbench predictions → gate gatekeeper → manifest.yaml → release
↓ BLOCK on regression
- Manifest — Every evaluation result produces a traceable YAML snapshot: git commit, model revision, environment, per-module metrics. Stored under
eval/results/with JSON Schema validation enforced in CI. - Gate — Strict regression gatekeeper. Overall score drop >0.3 or any module drop >0.005 → BLOCK. No blind merges ever.
- Release — Full automated pipeline: eval → manifest → gate → PR → merge → git tag → PyPI publish. Every release has a committed eval manifest.
See the release runbook for the full workflow.
unlimited-ocr --image-dir ./images | --pdf ./doc.pdf \
[--output-dir ./out] [--image-mode gundam|base] \
[--gpu 0] [--concurrency 8] [--pdf-dpi 200] \
[--page-size 16] [--torch-compile] \
[--async] [--quiet] [--version] [--config .unlimited-ocr.yaml]
For high-concurrency batch workloads, --async uses aiohttp + asyncio for lower overhead:
unlimited-ocr --pdf ./large_doc.pdf --async --concurrency 16The sync engine (default) uses requests + ThreadPoolExecutor. Choose sync for simplicity, async for scale.
# .unlimited-ocr.yaml
output_dir: ./outputs
image_mode: base
pdf_dpi: 150
concurrency: 8
quiet: falsePlace it in your project root or any parent directory — auto-discovered. Or --config ./my-config.yaml.
Unlimited-OCR-ROCm/
├── src/rocm_ocr/ # Python package (CLI, inference, evaluation pipeline, GPU tools)
├── docs/ # Architecture, benchmarks, parity, tuning, release runbook
├── eval/ # Evaluation manifests + JSON Schema (CI-enforced)
├── scripts/ # Setup, multi-GPU eval runners, benchmarks
├── tests/ # Unit tests (conftest fixtures)
├── examples/ # transformers_infer.py, SGLang server/client
├── Makefile # make install, make test, make benchmark, make eval-release
├── Dockerfile # ROCm 6.0+ Docker image
├── docker-compose.yml # Docker Compose orchestration
└── pyproject.toml # PEP 621 package metadata
SGLang: "No HIP GPUs available"
rocm-smi --showproductname
export HIP_VISIBLE_DEVICES=0OOM (out of memory)
Reduce --mem-fraction or --pdf-dpi. See docs/TUNING.md Scenario 3.
torch.cuda.is_available() → False
pip uninstall torch torchvision torchaudio -y
pip install --index-url https://download.pytorch.org/whl/rocm6.2 torch torchvision torchaudioPhase 1 — Evidence Engine: OmniDocBench parity + credibility-first docs ✅
Phase 2 — Upstream Integration: SGLang/vLLM on ROCm, consumer Radeon first-class in AMD docs ⏳
Phase 3 — Thin Integrations: OpenAI-compatible endpoint, one-click hosted demo, RAG framework example ⏳
Built on Baidu Unlimited-OCR, DeepSeek-OCR, SGLang, and AMD ROCm.
Special thanks to AMD for compute support. Try it on AMD Radeon Cloud.
MIT License. LICENSE · Contributing
