百度Unlimited OCR 2技术拆解:KV缓存降96%的长文档推理革命

作者:KAKAKA2026.11.03 23:55浏览量:0

简介:百度开源的Unlimited OCR 2通过稀疏参考滑动窗口注意力与持续解码机制,将百页文档推理的峰值KV缓存从47GB压至1.77GB,降幅约96%,实现数千页连续识别。本文从显存瓶颈出发,拆解SR-SWA的按需选取逻辑与分块解码的常数级开销设计,并给出长文档OCR工程的落地建议。

百度Unlimited OCR 2技术拆解:KV缓存降96%的长文档推理革命

一、问题起点:长文档OCR的真正瓶颈不是精度,而是显存

OCR技术发展至今,单页识别精度已经进入相当成熟的阶段。真正制约工程落地的,是”连续处理”这件事——当用户需要把整本书、整套卷宗、整批档案一次性转写时,模型必须在单个序列里维持跨越数千页的上下文状态。

这里的关键开销是KV缓存。自回归解码过程中,模型需要为每个已处理的token保留键值对,供后续注意力计算复用。可以把它理解为模型”边读边记”的草稿纸:文档越长,草稿纸越厚。传统全注意力解码在百页级文档上,峰值KV缓存可达数十GB量级,远超常见推理卡的可用显存,更不用说模型权重、激活值等其他开销还要另算。

百度此次开源的Unlimited OCR 2,正是围绕这个瓶颈做文章。它给出的对比数据是:在百页级单序列测试中,峰值KV缓存占用从标准解码的47GB降至1.77GB,降幅约96%。47GB这个数字已经超过不少笔记本电脑的整机内存容量——换言之,上一代方案在这类场景下基本无法在单卡上完成推理。

更值得关注的是它的定位延续性。上一代Unlimited OCR凭借多页文档连续解析能力,在开源社区积累了可观的采用度,累计下载量超过千万、代码仓库收获约2.86万Star,围绕在线演示、推理框架适配的生态也在持续推进。第二代的升级重点很明确:在保持连续处理能力的前提下,把计算与缓存负担压下来。

二、核心思路:从”摊开所有页面”到”按需回看”

理解SR-SWA(稀疏参考滑动窗口注意力,Sparse Reference Sliding Window Attention)最直观的类比,是人类抄书的工作方式。

人手抄书时,眼睛主要盯住正在抄写的那一页,逐段推进;只有当上下文需要前后对照——比如核对一个人名、追溯一个指代、确认章节衔接——才会回头翻一翻相关页面。没有人会一边抄写,一边在脑中同时摊开整本书的所有页面参与”注意力计算”。

上一代方案的问题恰恰在此:虽然已经通过滑动窗口类机制大幅压缩了推理阶段的KV缓存,但在”回看”环节,所有输入页面的视觉信息仍然要参与注意力计算。文档越长,参与计算的信息越多,而其中相当一部分与当前正在识别的几行文字毫无关系——典型的”陪跑”计算。

SR-SWA的设计逻辑就是把这种”陪跑”剔除:

  • 局部聚焦:以滑动窗口覆盖当前识别位置附近的视觉与文本上下文,保证逐行转写的连续性;
  • 稀疏参考:当需要跨页对照时,按需选取相关页面的视觉信息参与注意力,而非全量回看;
  • 重复计算削减:被选中的参考页面信息在后续步骤中可复用,避免同一页视觉特征被反复编码。

这一机制带来的直接收益是注意力计算量随文档增长呈次线性甚至近常数增长,而不是线性膨胀。

三、持续解码:让单步开销不随文档变长而上涨

仅有稀疏注意力还不够。如果解码阶段的缓存管理仍是”每步追加、全量保留”,那么无论注意力多稀疏,显存占用依然会随页数线性攀升。

Unlimited OCR 2配合的持续解码机制,核心目标是让单步解码开销与文档长度解耦。其工程含义可以概括为三点:

  1. 分块处理:将超长文档按块组织,块内维持完整上下文,块间通过稀疏参考建立关联,而非把所有块的中间状态同时驻留显存;
  2. 缓存淘汰与保留策略:滑动窗口外的历史信息不再无条件保留,仅保留被判定为”后续可能被参考”的部分;
  3. 状态复用:已完成的页面解析结果以紧凑形式传递,避免视觉特征在显存中长期堆积。

两者结合的效果,就是官方给出的那条曲线:文档从几十页扩展到数千页,峰值缓存不再线性上涨,而是被压在一个接近常数的区间内。这也解释了”页数没上限”这一表述的技术底色——不是真的无限,而是瓶颈从显存容量转移到了工程上更可控的维度。

用伪代码示意其调度逻辑,大致如下:

  1. # 概念示意,非实际接口
  2. for chunk in split_document(pages, chunk_size=N):
  3. window = sliding_window(chunk, size=W)
  4. for page in chunk:
  5. # 局部窗口内全注意力
  6. local_ctx = window.context(page)
  7. # 稀疏选取相关参考页,而非全量历史
  8. refs = sparse_select(history_index, query=page, top_k=K)
  9. state = decode(page, local_ctx, refs)
  10. # 仅保留可复用状态,其余释放
  11. history_index.update(compact(state))

四、性能与代价的平衡:96%的缓存削减意味着什么

把47GB压到1.77GB,不只是”省显存”这么简单,它改变了部署形态:

  • 单卡可承载更长文档:原本需要多卡切分或分批处理的百页级任务,现在单卡即可完成连续推理;
  • 批处理吞吐提升:显存余量可用于并发多个请求,提高单位时间的页面处理量;
  • 长尾文档成本下降:对于数百页的合同、卷宗、技术手册,不再需要按页切割后逐段拼接,减少了跨段上下文丢失导致的识别不一致。

需要客观说明的是,稀疏化并非没有代价。参考页选取策略若判断失误,可能影响跨页指代、表格跨页衔接等场景的准确性;这类问题需要通过参考选取的召回率与窗口大小的调优来平衡。工程实践中,建议针对文档类型(连续正文、多栏排版、表格密集)分别设定窗口与参考参数,而非一套配置通吃。

五、工程落地建议

对于准备将长文档OCR能力接入自有系统的团队,以下几点值得注意:

第一,按文档长度分层设计推理路径。 短文档(数页以内)走常规全注意力路径即可,稀疏机制带来的收益有限却增加了调度复杂度;长文档才启用持续解码与稀疏参考。

第二,把KV缓存预算作为容量规划的一等指标。 在压测阶段就应记录峰值缓存、平均缓存与文档页数的关系曲线,据此推算单实例可承载的最大页数与并发数,而不是等上线后被动扩容。

第三,关注跨页一致性而非单页精度。 长文档OCR的验收标准应包含跨页实体一致性、页码与章节结构还原、表格跨页合并等指标,这些恰恰是稀疏参考策略最敏感的地方。

第四,做好结果落地的后处理链路。 识别输出建议以结构化形式(页级文本块+版面坐标)保存,便于后续做段落合并、目录重建与全文检索索引,而不是直接落成一份纯文本。

六、结语

Unlimited OCR 2的技术价值,不在于又一个OCR模型的出现,而在于它把长文档连续处理从”显存不允许”推进到了”工程可调度”。SR-SWA用稀疏参考替代全量回看,持续解码用分块与状态复用替代线性堆积,两者共同把KV缓存这个长文档推理的硬约束压成了近似常数。对于档案数字化、法律卷宗处理、技术文档转写等场景,这条路径提供的不仅是性能数字,更是一种可复用的长序列推理工程范式——先想清楚哪些信息真的需要被”记住”,剩下的,让它随窗口滑走。