长文档 OCR 的难点与无限解析思路

作者:梅琳marlin2026.11.04 01:21浏览量:0

简介:长文档 OCR 常面临页数增加带来的显存压力与跨页内容断裂问题。本文从稀疏参考滑动窗口注意力机制、分块解码与 KV Cache 复用等角度,梳理长文档 OCR 的优化思路,帮助读者理解如何以更稳定的计算成本持续解析多页 PDF 与扫描文档。

一、为什么长文档 OCR 不是简单堆积页数

在 OCR 场景中,单页识别通常已经比较成熟。真正困难的是把几十页、几百页甚至上千页的扫描 PDF 稳定转成可编辑文本与结构。问题的本质不是“单页识别不准”,而是系统能否在长序列中持续保持高质量输出。

当文档页数增加,常见挑战包括:

  • 显存占用持续上升:模型需要维护的视觉特征、文本状态、注意力缓存都会增长。
  • 跨页内容容易断裂:表格可能跨页,段落可能跨页,页眉页脚可能干扰正文顺序。
  • 整本解析时误差会累积:前一页的理解偏差可能影响后一页的上下文。
  • 拆页处理又会带来拼接问题:如果简单按页独立识别,跨页段落和表格容易被硬生生切断。

因此,长文档 OCR 的核心不是“识别更多页”,而是如何在有限计算资源下,让模型具备持续向下解析的能力。


二、从“人如何抄书”理解长文档处理

一个很直观的类比是:人在抄写一本几百页的书时,并不会每写一个字都回头重新浏览前几百页。通常的做法是:

  • 当前页是主要关注对象;
  • 只有遇到跨页内容时,才回看前文;
  • 对前文只关注少量相关位置,而不是整本重读。

这对应到模型设计上,就是一个关键判断:多页文档内部,页内信息联系通常非常紧密,而跨页依赖是稀疏的、局部的。既然跨页依赖并不密集,就没有必要让每一页的每个视觉 Token 都参与后续所有页的计算。

基于这个观察,可以设计一套机制,把长文档建模成“局部密集、远程稀疏”的注意力结构。


二、稀疏参考滑动窗口注意力:Page Gate 与 Token Sieve

为了解决长文档 OCR 中视觉 Token 规模膨胀的问题,可以采用稀疏参考滑动窗口注意力机制。其核心不是无限扩大窗口,而是对“参考哪些页面”和“参考页面中的哪些 Token”做两层筛选。

Page Gate:先选页面

Page Gate 的作用是缩小视觉参考范围。模型在解析当前页时,并不需要把所有历史页面的视觉 Token 全部加载进来,而是先判断哪些页面与当前页可能存在跨页关系。

经过 Page Gate 后:

  • 当前页保持完整计算;
  • 相关历史页被保留;
  • 无关页面的视觉 Token 不再参与当前注意力计算;
  • 跨页位置关系仍然可以被表达。

这样,视觉参考范围从“全部页面”缩小为“少量相关页面”,计算量显著下降。

Token Sieve:再挑重点

即使只保留若干个相关页面,每个页面仍然包含大量视觉信息块。Token Sieve 进一步对这些视觉 Token 进行打分,只选择少量最相关的远程 Token 参与计算。

可以把它理解为:

  1. 全部页面
  2. │
  3. ▼
  4. Page Gate:筛选候选页面
  5. │
  6. ▼
  7. 候选页面的视觉 Token
  8. │
  9. ▼
  10. Token Sieve:筛选高相关 Token
  11. │
  12. ▼
  13. 参与跨页注意力计算

这种两层筛选机制,使得模型在解析长文档时,不需要持续维护全部视觉 Token,从而降低单步计算负担。


三、为什么上一代方法还不够

早期的一些长文档处理方法,已经尝试控制文本侧缓存增长。例如通过滑动窗口或缓存复用方式,让文本侧的 KV Cache 不会随页数线性膨胀。

但问题在于,即使文本侧缓存被控制住,视觉侧仍然是瓶颈。因为在某些方案中,模型仍然需要关注全部参考视觉 Token。对于几十页的论文,这种开销尚可接受;但对于数百页年报或上千页档案,视觉 Token 总量可能非常庞大。

因此,长文档 OCR 的优化需要同时覆盖两个维度:

  • 文本侧:控制历史文本状态的大小;
  • 视觉侧:控制历史视觉 Token 的参与量。

仅解决其中一面,长文档解析仍会遇到明显瓶颈。


四、无限跨度解码:用分块与缓存复用延续解析

除了注意力机制优化,另一个关键点是解码过程如何“接得上”。

长文档可以采用按页面分块处理的方式。不是一次性把所有页面塞进模型,而是把文档切分为若干块,顺序处理。在块与块之间,通过复用边界页的 KV Cache,让模型“记住”已经解析过的上下文。

这样做有几个好处:

  • 每一步解码的计算成本保持相对稳定;
  • 显存不会随全书页数持续飙升;
  • 解析结果能够跨块延续,减少硬拼接错误。

用伪代码可以粗略表示这一过程:

  1. cache = 初始化空缓存
  2. for block in document_blocks:
  3. # 读取当前块页面
  4. visual_tokens = extract_visual_tokens(block)
  5. # 复用上一块末端的缓存
  6. outputs, cache = model.decode(
  7. visual_tokens,
  8. past_kv=cache
  9. )
  10. # 写入当前块解析结果
  11. write_results(outputs)
  12. # 只保留边界页缓存,供下一块使用
  13. cache = keep_boundary_cache(cache)

在实际工程中,这种分块与缓存复用方式可以有效降低峰值显存。例如在某些长序列推理条件下,KV Cache 峰值显存可以从数十 GB 级别下降到个位数 GB 级别。

需要注意的是,“无限解析”并不意味着总耗时不变。它指的是解析跨度可以持续延伸,而不是整本书的耗时与页数无关。整本书的处理时间仍会随页数增加,但每一步的计算与显存成本可以保持相对平稳。


五、长文档解析中的工程问题

除了模型结构,长文档 OCR 还涉及不少工程细节。

页面顺序与扫描质量

对于扫描 PDF,页面方向、倾斜、噪声、印章遮挡都会影响结果。在进入长文档解析前,通常需要有前置处理:

  • 方向校正;
  • 去噪与二值化;
  • 版面区域检测;
  • 页眉页脚识别与过滤。

这些步骤不直接属于模型推理,但会显著影响后续跨页信息筛选的稳定性。

表格跨页识别

表格是最容易在分页处断裂的结构。长文档解析需要具备跨页表格的续接能力。理想情况下,模型在识别到页面末尾的表格线时,应能在下一页继续识别表头或表体。

这类能力依赖跨页参考机制。Page Gate 和 Token Sieve 如果能保留上一页的表格结构信息,那么下一页的表格识别会更容易避免断裂。

段落连续性

段落跨页时,如果简单对每一页独立输出,可能出现:

  • 句子被截断;
  • 页尾行和页首行被错误合并;
  • 列表编号混乱。

持续解析的意义正在于此:将上一页末尾的语义状态带入下一页开头,使跨页段落保持连贯。


六、如何评估长文档 OCR 效果

长文档 OCR 的评估不能只看单页准确率。更值得关注的指标包括:

  • 整本解析一致性:全书标题、章节、段落是否稳定输出;
  • 跨页表格完整率:表格是否在分页处保持结构;
  • 缓存占用曲线:显存是否随页数保持平稳;
  • 误差传播程度:早期页面的识别错误是否被后续页面放大;
  • 断点续接能力:从任意页重新开始解析时,结果是否一致。

对于实际业务来说,一个核心诉求是减少拆页、拼接和人工修复工作。只要模型能够稳定地连续解析,工程链路就会明显简化。


七、小结

长文档 OCR 的难点不只是识别精度,而是如何让模型在持续解析时保持稳定、连续与可控的计算成本。稀疏参考滑动窗口注意力机制通过页面筛选与 Token 筛选,降低视觉侧计算压力;分块解码与 KV Cache 复用则让解析过程可以持续向下延续。

这类思路对扫描书籍、财务报告、档案资料、合同合集等场景都有实际价值。随着长文档 OCR 能力不断成熟,应用侧可以更少地关注拆页与拼接,而更多地把精力放在解析结果的后处理与业务集成上。