ToolBox
返回开源工具列表
长文档 OCR 的坎,百度用 R-SWA 给抹平了——Unlimited-OCR 上手记

长文档 OCR 的坎,百度用 R-SWA 给抹平了——Unlimited-OCR 上手记

百度刚开源的 Unlimited-OCR 主打'一次扫完整本 PDF':用 R-SWA 让 KV Cache 恒定,把长文档解析的性能瓶颈从工程题变成架构题。一个跑过 Demo 的开发者视角的上手笔记。

2026年7月30日9 分钟OCR · 文档解析 · 百度开源 · 多模态 · 长文档

前两天刷 GitHub,撞见百度刚开源的一个模型,名字挺直白——Unlimited-OCR,"无限 OCR"。副标题更狠:Welcome the Era of One-shot Long-horizon Parsing,一键长程解析时代。我第一反应是:又是个把"能识别一页"包装成"无限"的 PPT 模型?

直到我看清它解决的是个真问题——长文档解析里那个老掉牙的 KV Cache 爆炸——才坐下来认真跑了一遍。跑完之后的结论是:这回不是 PPT,是真把"长"这件事在架构层面解决了。

先说清楚它到底在治什么老毛病

做文档处理的人都知道那个尴尬:把一本几十页的 PDF 丢给模型,它基本只有两条路——

要么逐页切,每翻一页就"失忆"一次,后面页的序号、引用、表格跨页关系全断;要么硬塞长上下文,结果输出越长越慢、显存一路往上爬,跑到第 40 页直接 OOM 爆掉。

根子上的病,是传统注意力的 KV Cache 会随着生成长度线性膨胀。序列越长,缓存越大,速度越慢,显存越吃紧。所以"长文档解析"过去一直是个工程优化题:怎么分块、怎么拼接、怎么控制 overlaps。

Unlimited-OCR 的野心,是把这道题变成架构设计题

Unlimited-OCR 官方概览图

两招:把"无限"塞进 32K

它干了两件核心的事。

第一招叫 DeepEncoder,方向上是对视觉 token 做大幅压缩——把一页文档图压成稀疏得多的视觉表征,从源头减少要喂给注意力的东西。文档图信息密度高但冗余也多,直接铺开算力浪费严重,先压一层再说。

第二招才是关键:R-SWA(Reference Sliding Window Attention,参考滑动窗口注意力)。灵感借自人类抄长文档时的"工作记忆"——你抄书不会把前面整本都背在脑子里,而是始终盯着原文、只保留最近写下的那一段。

R-SWA 就这么干:注意力始终回头看原始文档内容(reference),同时只保留最近一段生成结果当"工作记忆"滑动窗口,而不是无限累积全部历史。结果就是——整个解码过程的 KV Cache 大小锁死成一个常数。在标准 32K 最大上下文内,一次前向推理就能转录数十页文档,不分段、不断点。

这点我特别买账:它不是靠"把显存堆更大"硬扛,而是从机制上让成本不随长度增长。这才是真解法。

数字说话

官方/社区放出来的几组数,我挑能交叉印证的说:

  • OmniDocBench v1.6 综合 93.92%,端到端 OCR 新纪录,榜单第一;
  • 综合识别准确率比基线(DeepSeek-OCR 一脉)高约 6%
  • 速度上,真实场景比 DeepSeek-OCR 快约 12.7%;当输出长度到 6000 token 时,优势扩大到 35%——越长的文档,它越占便宜,正好印证了"恒定开销"的设计。

模型本身不大:总参数 3B,推理时激活参数才约 570M。轻量到这个程度还能打这个榜,挺出乎我意料。MIT 协议,代码和权重全公开,HuggingFace 上还有在线 Demo,上手没门槛。

怎么跑起来

最省事的是直接开 HuggingFace Demo 点几下看效果。要本地跑,官方给了三条路:

1. Transformers(NVIDIA GPU)——最快验证想法:

import torch
from transformers import AutoModel, AutoTokenizer

model_name = 'baidu/Unlimited-OCR'
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()

# 单图两种模式:gundam(裁切/小图快) 或 base(整图准)
model.infer(tokenizer, prompt='<image>document parsing.',
            image_file='your_image.jpg', output_path='./out',
            base_size=1024, image_size=640, crop_mode=True,
            max_length=32768, no_repeat_ngram_size=35, ngram_window=128,
            save_results=True)

注意那个 ngram_windowno_repeat_ngram_size——它用 n-gram 去重抑制长序列里的重复幻觉,长文档场景很关键。

2. vLLM——官方直接给了 Docker 镜像(vllm/vllm-openai:unlimited-ocr),还有一份 vLLM recipe,要上量的走这条。

3. SGLang——需要装仓库里自带的 wheel,并启用一个自定义 logit processor(DeepseekOCRNoRepeatNGramLogitProcessor)来复现那个 n-gram 去重。仓库里的 infer.py 会自己拉起 SGLang server,批量吃一个图片目录或 PDF,挺适合生产。

PDF 的处理方式是一致的:先用 PyMuPDF 把每页转成图,再走 infer_multi 多图解析。所以"整本 PDF 一次读完",本质是"一次前向 + 多页图输入",而不是真的吞下一个 PDF 文件。

实跑前置提醒:官方测的是 python 3.12.3 + CUDA12.9、torch 2.10 那一整套,环境对版本挺挑。别拿老环境硬跑,容易卡在 trust_remote_code 和 CUDA 版本上。

我的一点老实话

不是无脑吹,说几个边界:

  • 要吃 N 卡:目前推理后端全是 NVIDIA GPU 向(transformers/vLLM/SGLang),消费级显卡也能跑 3B,但别指望端侧或 CPU 流畅。
  • "无限"是相对 32K 而言:架构让开销恒定,但上限仍是上下文窗口。真·几百页的厚书,老老实实分页转图喂进去就行,它解决的不是窗口大小,而是"窗口内别变慢变炸"。
  • PDF 要先转图:它吃的是图,不是原生 PDF 文本层。文档本身如果是扫描件,反而更对路;如果是带文本层的 PDF,转图这一步会损失一点原生结构。
  • 两种模式得选gundam 裁切小图更快,base 整图更准,单页建议 gundam、多页/PDF 只能 base。

跟站里工具也能搭上:跑之前把厚 PDF 用 PDF 拆分 先按章切块、用 PDF 压缩 降体积,扫描页太糊就 图片压缩 前顺手锐化一下——喂干净的图,识别率肉眼可见地稳。

一句话收尾

Unlimited-OCR 做对的事,是把"长文档解析"的性能瓶颈从工程优化题,改成了架构设计题:用 R-SWA 把 KV Cache 锁成常数,从此长不再等于慢、也不再等于爆显存。3B 体量、MIT 开源、HF 有 Demo,对做票据、合规、文档智能化的团队来说,是今年最值得花半小时跑一遍 Demo 的模型。

要不要试,你说了算——反正仓库和 Demo 链接都在上面了。