百度开源OCR新模型:千页长文档一口气读到底

作者:KAKAKA2026.11.04 01:09浏览量:0

简介:超长文档OCR难在哪?本文以百度开源的文心Unlimited OCR 2为线索,拆解其两大核心设计:借鉴“人类抄书”直觉的稀疏参考滑动窗口注意力SR-SWA,与基于重叠分块、缓存复用与及时释放的无限解码机制;结合47GB降至1.77GB的KV Cache峰值显存压缩、360提升至1315 TPS的并发吞吐等官方数据,并沉淀长文档解析系统的通用工程实践。

一、为什么“页数”会成为OCR的极限

在传统OCR的认知里,“一页一识别”是默认工作模式:页面切好、逐张推理、结果拼接。但真实业务中的文档往往不是这个形态——标书、卷宗、财报、技术手册、论文合集,动辄数百页起步,数千页也不罕见。

一旦要求模型把整份文档当作一个连续整体来理解,问题立刻升级:

  • 跨页关联是刚需:跨页表格、连续图表、脚注与正文的前后引用,都要求解码时能“回看”前文信息;
  • 视觉Token序列爆炸:端到端多模态模型(视觉编码器+解码器)处理文档时,每页经视觉编码通常会展开成数百个视觉Token,数千页叠加,Token序列很容易达到数十万量级;
  • 注意力成本失控:解码器每生成一步,都要对已有Token做注意力计算,序列越长,单步代价越高;
  • KV Cache是真正的天花板:每个Token的键值缓存都要常驻显存。页数越多、缓存越大,千页级别很快把GPU显存吃穿。

百度这次开源的文心Unlimited OCR 2给出的答卷是:3600多页的长篇小说合集,单序列推理一口气读到底;1200多页的科幻三部曲理解起来同样不费力;并在多页文档基准评测中取得了SOTA表现。

二、设计直觉:像人一样“抄书”

这套方案的技术灵感来自一件特别朴素的事:抄书。

想象人类抄一本厚书时的行为——目光始终停留在当前页;遇到跨页关联,偶尔翻回去参考一下;绝不会每抄一句话,都把前面所有页面重新读一遍。

把这个直觉抽象成注意力设计,就是三条原则:

  1. 当前页是主舞台:绝大多数注意力应落在滑动窗口内的近期内容上;
  2. 历史页是参考资料:按需、稀疏地回看,而非全量重读;
  3. 回看是有成本的:参考范围必须被主动收窄。

团队提出的SR-SWA(稀疏参考滑动窗口注意力机制),正是这个直觉的“两级漏斗”实现:

  • 页面门控(Page Gating)——粗筛:以页为粒度判断“哪些历史页可能与当前解码位置相关”,先把候选参考范围从“全部历史页”收窄到一个小集合;
  • Token筛选器(Token Filter)——细筛:在候选页面内部,进一步挑出与当前解码最相关的视觉Token块,其余Token不参与注意力计算。

粗到细的好处是双重的:页粒度的门控计算开销极小,却能把候选空间压缩一个数量级;Token级筛选则保证真正参与注意力的,是“值得看”的视觉信息。两者叠加的结果是:无论文档是100页还是3000页,单步解码的注意力计算成本都能保持近似恒定——这正是“抄书直觉”的数学化表达。

三、无限解码:显存里的“滚动工作区”

解决了“算多少”,还要解决“存多少”。即便每步只关注少数Token,如果所有页面的视觉缓存一直堆积在GPU里,几千页下来照样吃不消。于是又有了第二件武器:无限解码机制。

它的核心思路可以概括为“分块+重叠+复用+释放”:

  1. 分块:把整份文档拆成一块块相互有重叠的页面组;
  2. 顺序处理:按顺序逐块解码,而非全局并行;
  3. 边界复用:相邻分块共享的边界页面,其视觉KV Cache直接复用——既避免重复编码,也保证跨块语义的连续性;
  4. 及时释放:已被处理完、不会再被后续解码引用的视觉KV Cache,立即释放。

用一段示意伪代码来描述这个滚动窗口的逻辑(仅示意思想,非真实接口):

  1. # 无限解码的滚动窗口处理(伪代码)
  2. groups = split_with_overlap(pages, chunk_size=K, overlap=O)
  3. cache = {} # 视觉KV Cache工作区
  4. for gi, group in enumerate(groups):
  5. for page in group:
  6. if page.id not in cache: # 边界页命中缓存, 直接复用
  7. cache[page.id] = encode(page)
  8. refs = page_gating(cache) # 1. 页面门控: 粗筛候选页
  9. tokens = token_filter(refs) # 2. Token筛选: 细选相关块
  10. step_decode(tokens) # 3. 稀疏注意力解码
  11. keep = boundary_pages(groups[gi+1]) # 下一分块的边界页集合
  12. for pid in list(cache): # 4. 释放陈旧缓存
  13. if pid not in keep:
  14. del cache[pid]

核心效果在于:显存中始终只需要维护一个有限的缓存工作区,其大小取决于分块策略,而与文档总页数解耦。这就是”Unlimited”的工程含义——不是真的没有上限,而是把上限从“显存容量”变成了“你愿意读多久”。

四、官方数据:省了多少,快了多少

按照官方技术报告给出的测试数据:

指标 数值
单序列推理KV Cache峰值显存 47 GB → 1.77 GB(约26倍压缩)
16并发端到端吞吐 360 TPS → 1315 TPS(约3.7倍)
百页级文档单步解码速度 较全注意力方案提速约7倍
长度稳定性 最长300页评测范围内,解析精度保持稳定

这些数字应该怎么读?有三点值得展开:

  1. 显存压缩是并发提升的前提。单实例峰值从47GB降到1.77GB,意味着同样的GPU预算可以承载多得多的并发流——吞吐的跃升,很大程度上是“省出来的”;
  2. 提速来自两处叠加:注意力稀疏化降低了每一步的计算量,缓存瘦身则降低了显存调度与读写压力,二者共同作用才有数倍级的端到端收益;
  3. 精度稳定性才是真正的门槛。长文档方案最常见的坑是“页数一长、精度衰减”。在300页的评测范围内精度保持稳定,说明稀疏化并没有以牺牲跨页关联能力为代价。

当然,官方数据基于其设定的测试条件;实际收益会随文档类型、扫描质量、硬件配置与部署参数浮动,落地之前,建议用自有语料做一轮基准回归。

五、演进脉络:从文本缓存优化到视觉超长输入管理

这一模型并非凭空出现。上一代模型开源后,已在国际主流开源模型社区累计超过1000万次下载,长文档解析能力经过了大规模的真实检验。

这一代的推进方向很明确:上一代重点解决的是长文本生成时的缓存优化,这一代把战场推进到了超长视觉输入的计算与显存管理。两者的问题结构相似——序列长、缓存大——但视觉输入更棘手:视觉Token密度更高,页面之间存在大量结构化关联(跨页表格、连续图表、脚注引用),不能简单当作均匀的文本流来处理。这也解释了为什么“页面门控”要以页为粒度设计:页是视觉文档的天然结构单元。

六、一个彩蛋:像素为身,Token为血

在这次公开的技术报告里,还藏着一个小彩蛋:

像素为身,Token为血。已阅尽千页,不为KV Cache所限,亦不为上下文长度所缚。

熟悉经典动漫中那段广为流传的咏唱桥段的读者,应该能一眼认出这段文字的句式出处。这个创意最早来自上一代模型开源后的社区互动:有开发者把那段经典咏唱改编成了以模型为主题的版本,开发团队看到后非常喜欢,最终将其正式收录进了2.0的技术报告。一段社区创作走进官方技术文档,也算开源社区与研发团队之间一次小小的双向奔赴。

七、给工程团队的通用启示

剥开具体实现细节,这次开源所验证的经验,对任何长文档解析系统都有参考价值:

  1. 显存预算要与文档长度解耦。“分块+重叠+滚动释放”是把“无限”变成“有限工作区”的通用范式,适用于一切流式长输入场景;
  2. 注意力稀疏化遵循“粗筛—细筛”漏斗。先用低成本的粗粒度门控(页/段落/块)定位候选区域,再做Token级精选,避免在巨大候选集上做昂贵的精细计算;
  3. 缓存要有生命周期管理。明确“哪些缓存将来还会被引用”才能安全释放;边界缓存复用则是保证语义连续性的关键,重叠窗口不能省;
  4. 并发扩展先降单实例峰值。吞吐想线性扩展,前提是单流的显存足迹足够小,先做减法再做乘法;
  5. 长度稳定性测试不可省略。只测单页准确率会严重高估长文档表现,应设计“精度—页数”曲线来度量衰减,把跨页关联任务(表格续接、图表理解、脚注回指)纳入评测集。

结语

超长文档解析的瓶颈,从来不是“能不能识别一页”,而是“能不能把几千页当作一个连续整体来理解,并且读得起”。文心Unlimited OCR 2用SR-SWA回答了前半个问题,用无限解码机制回答了后半个问题。关于这套方案的更多技术细节,百度将在11月12日举行的百度世界2026大会上进一步分享,对长文档多模态解析感兴趣的工程师值得关注。