百度 Unlimited OCR 深度解析:R-SWA 如何让长文档 OCR 从"逐页煎熬"走向"一次搞定"
写在前面
OCR(光学字符识别)这个技术,在程序员眼里大概是这样的:给定一张图片,输出一串文字。听起来简单,但凡做过文档数字化的都知道,真正落地的时候远比想象复杂——扫描件歪斜、表格跨页、公式乱码、签名笔迹,稍有差池就是满屏乱码。
而 2026 年 6 月 22 日,百度开源了 Unlimited OCR,在 GitHub 5 天破万星,登顶 GitHub Daily Trending 和 Python 榜双料第一,同时拿下 HuggingFace 全球多模态大模型榜单第一。这不是靠"刷榜营销",而是真正解决了长文档 OCR 的一个核心痛点:文档越长,AI 生成越慢。
这篇 10000+ 字长文,从工程视角完整拆解 Unlimited OCR 的技术架构、R-SWA 注意力机制的数学本质、与 DeepSeek OCR 的关系,以及如何在生产环境中部署和使用。
一、为什么现有的 OCR 系统"越长越慢"
要理解 Unlimited OCR 做了什么,先得理解问题出在哪。
1.1 端到端 OCR 的崛起
传统 OCR 分为两步:文本检测(找出文字在哪里)和文本识别(认出文字是什么)。这两个步骤各自独立,中间用规则拼接,容易出错。比如检测框稍微歪一点,识别模型就容易"看走眼"。
端到端 OCR 则把这两步合二为一:一个统一的神经网络,直接从图像映射到文字序列。就像人类读书,眼睛一扫,文字就进脑子了,不需要先在纸上画圈再读字。
DeepSeek OCR 是这个方向的代表作品,它采用了 DeepEncoder + MoE 解码器的架构,编码端用 SAM-ViT 和 CLIP-ViT 双塔提取视觉特征,解码端用混合专家模型(MoE)生成文字。整体效果很好,在 OmniDocBench 等基准上表现优异。
1.2 KV Cache:性能噩梦的根源
问题来了。DeepSeek OCR 用的是标准的全注意力机制(Full Attention),在解码阶段,每生成一个新的 token(可以理解为生成的一个字),模型都要"回头看"所有已经生成的 token。
这在技术上体现为 KV Cache(键值缓存)的线性增长。简单理解:生成第一个字时,缓存里有 1 条记录;生成第 100 个字时,缓存里有 100 条;生成第 10000 个字时,缓存里有 10000 条记录。
这个缓存不只是"占地方",它直接影响两件事:
- 显存占用:KV Cache 越大,需要的 GPU 显存越多
- 计算延迟:每生成一个新 token,都要和所有缓存中的历史 token 做注意力计算,O(T) 的时间复杂度
结果是:处理一页文档很快,处理 30 页文档时,等半天才能出结果。在用户的感知里,就是"AI 越生成越慢"。这也是为什么很多 OCR 服务商要限制单次请求的页数——超过就得分批处理,每次都从头开始。
1.3 线性注意力的"降速陷阱"
有人会说:把全注意力换成线性注意力不就好了?线性注意力让信息"流动更新",理论上不需要存储完整的 KV Cache。
但对于 OCR 这种精确识别任务,线性注意力有一个致命缺陷:信息在流动过程中会逐渐"模糊"。就像你抄书,抄完一行就把原书的字迹稍微擦掉一点,抄到后面就看不清原文了。OCR 恰恰需要精确还原原文的每一个字符,这种"渐进模糊"是根本无法接受的。
于是,百度团队从人类的抄书行为中找到了突破口。
二、R-SWA:参考滑动窗口注意力——让 AI 像人类一样"抄书"
2.1 人类抄书的认知模型
想象你坐在书桌前抄书。手里有一本书,旁边是草稿纸。你不会在抄第 300 页时把第 1 页到第 299 页全部背下来——那样脑子早就炸了。
你的注意力分配其实非常精简:
- 始终看清原书:不管抄到哪,书始终摊在桌上,原文每个字清晰可读
- 只看最近写的几个字:确认自己"写到哪了",不需要翻回开头
- 自然遗忘旧内容:写完第 5 页后,你不会刻意记住第 1 页写了什么——因为不需要了
这就是 R-SWA(Reference Sliding Window Attention,参考滑动窗口注意力)的核心思想。
2.2 R-SWA 的数学原理
R-SWA 做了两件事:
第一:永久保留原始图像信息。 解码器在生成每个新 token 时,始终能"看到"完整的被压缩视觉 token。这些视觉 token 来自 DeepEncoder,经过 16 倍压缩后,一张 1024×1024 的文档图像变成 256 个视觉 token。关键是:这些视觉 token 不参与 KV Cache 的动态更新,它们从始至终保持不变,不会随着生成过程而"模糊化"。
第二:滑动窗口限制历史 token。 解码器只需要看最近生成的 N 个 token(默认 N=128),超过 N 的历史内容自然"淡出"。这个设计叫做 "软遗忘"(soft forgetting)——不是强制删除,而是通过注意力权重自然忽略。
数学上,在生成第 t 个 token 时:
注意力范围 = [全部 reference tokens(视觉编码 + 提示词)] ∪ [最近 N 个已生成 token]
相比之下,传统全注意力的 KV Cache 大小随输出总长度 T 线性增长 O(T),而 R-SWA 的 KV Cache 大小被限制在固定上界 O(L_m + N),其中 L_m 是视觉 token 总数(固定),N 是窗口大小(固定)。当处理非常长的文档时,两者的差距是本质性的——一个是无限增长,一个是恒定常数。
这就是"Unlimited"(无限)的含义:不是无限处理能力,而是无限长度下性能不衰减。
2.3 为什么软遗忘不会损失精度
你可能会问:如果只保留最近 128 个 token,那之前的重要内容会不会丢失?
答案是不容易丢失,因为 R-SWA 的设计聪明地利用了两个事实:
原始图像永不变:文字内容的主要信息源是图像本身,不是之前的生成结果。99% 的文字识别依赖图像解码,生成的历史 token 只负责维持输出的一致性(比如上下文人名的一致性、多页编号的连续性)
生成是单向的:OCR 的生成过程是严格从左到右的,不存在"回头修改"的问题。只需要"刚写了什么"来维持连贯,不需要"最初写了什么"来维持精度
128 的选择:这个窗口大小经过大量实验验证,既足够覆盖段落级别的上下文,又足够小以保持高效。百度的实验显示,窗口从 64 增大到 128 时精度有明显提升,再增大到 256 提升就不明显了
三、DeepEncoder:16 倍压缩率的两级视觉编码器
R-SWA 只解决了解码端的 KV Cache 问题,但还有一个上游瓶颈:图像本身产生的数据量太大了。
一张 1024×1024 像素的文档图像,如果不做任何压缩直接送进 Transformer,会产生数十万个视觉 token,不仅计算量爆炸,KV Cache 的"固定部分"也会过大。
Unlimited OCR 沿用了 DeepSeek OCR 中的 DeepEncoder 组件,这是整个系统高效运转的关键基础设施。
3.1 双塔视觉编码
DeepEncoder 由两个视觉编码器串联组成:
- SAM-ViT(Segment Anything Vision Transformer):来自 Meta 的通用图像分割模型,擅长提取局部细节和结构信息
- CLIP-ViT(Contrastive Language-Image Pre-Training Vision Transformer):擅长整体语义理解,能捕捉文档的整体布局和上下文
两个编码器的输出通过一个融合层合并,既保留了局部文字的精细结构,又保留了全局的版面信息。
3.2 16 倍 Token 压缩
在两个编码器之间,有一个关键的压缩层,执行 16 倍 token 压缩。具体来说:
- 输入:1024×1024 的文档图像(假设经过初步切分得到视觉 patch)
- 输出:256 个高度精炼的视觉 token
粗略估算:256 个视觉 token 大约对应 2560 个文字 token 的信息量(每个视觉 token 约等于 10 个文字 token 的语义密度)。这意味着一张普通 A4 纸的图像可以被压缩成 256 个 token,然后在 R-SWA 的框架下以恒定 KV Cache 一次性处理。
3.3 Base 模式 vs. Gundam 模式
DeepEncoder 支持两种工作模式:
Base 模式:固定 1024×1024 分辨率,适合多页文档的批量处理。这种模式下所有图像被归一化到统一尺寸,便于批量推理 Pipeline 的构建。
Gundam 模式(动态分辨率模式):支持动态分辨率输入,适合单页文档的精细识别。这种模式保留更多细节,适合复杂版面的高质量识别需求。
Unlimited OCR 在多页文档场景下默认使用 Base 模式,在单页精细场景下推荐 Gundam 模式。
四、MoE 解码器:30 亿参数只激活 5 亿
整个 Unlimited OCR 的解码器是一个基于 MoE(混合专家,Mixture of Experts) 架构的大型语言模型。
4.1 MoE 的核心思想
传统的 Dense 模型(比如 GPT-3 175B),每个 token 生成时都要激活所有 1750 亿参数。MoE 的思路是:把模型分成多个"专家"(通常是 FFN 前馈网络),每次推理时只激活最相关的少数几个专家。
打个比方:有一个 30 人的专家团队处理问题,每次只叫 5 个最相关的专家出场,其余的人休息。团队总规模大(知识储备丰富),但每次计算量小(只有 5 个人在工作)。
Unlimited OCR 的具体配置:
- 总参数量:30 亿(3B)
- 激活参数量:约 5 亿(570M)
- 专家数量:8 个专家,每次激活 2 个(Top-2 gating)
4.2 为什么 MoE 适合 OCR 任务
OCR 任务的特点是:输入是视觉 token,输出是文字 token。这要求模型既要有强大的视觉理解能力(来自编码端),又要有强大的语言生成能力(来自解码端)。
MoE 架构在这里的优势在于:不同的专家可以专门处理不同类型的文字内容——比如一个专家擅长数字和编号,一个专家擅长公式和符号,一个专家擅长自然语言段落。在 Top-2 gating 的机制下,对于每个 token,系统自动选择最相关的两个专家组合。
4.3 R-SWA 改造的细节
Unlimited OCR 在 DeepSeek OCR 的基础上,对解码器做了关键改造:把所有注意力层中的标准注意力替换为 R-SWA。
这个改造有几个技术要点:
- reference tokens 保持完整:视觉 token 和提示词 token 的 KV 值不被淘汰,永久驻留
- 输出 token 窗口截断:每个注意力层只保留最近 128 个输出 token 的 KV,超出窗口的自动丢弃
- 跨层一致性:虽然每层独立做 R-SWA,但总的效果是全局的——因为每层丢弃的信息在下一层也被丢弃,信息不会跨层累积
这个改造在实现上并不复杂,但效果是革命性的:KV Cache 从 O(T) 降到了 O(1)。
五、训练配方:从 DeepSeek OCR 到 Unlimited OCR
5.1 继续训练策略
Unlimited OCR 并不是从零训练的。它基于 DeepSeek OCR 的检查点继续训练,这样做有几个好处:
- 训练效率高:DeepSeek OCR 已经在海量文档数据上完成了预训练,其编码器和解码器已经具备了强大的文档理解基础
- 风险低:从已经验证过的架构出发,降低了新想法失败的概率
- 成本低:只训练解码器,编码器冻结,大幅减少需要更新的参数量
具体训练配置:
- 训练步数:4000 步
- 冻结策略:DeepEncoder 完全冻结,只训练解码器
- 训练硬件:8×16 A800 GPU(80GB 版本)
- 训练数据:约 200 万份文档样本
- 数据配比:单页文档与多页文档比例约 9:1
- 多页构造:通过拼接多个单页样本构造多页训练样本
5.2 为什么多页数据只占 10%
这个配比初看似乎不太合理——既然要解决长文档问题,为什么多页训练数据这么少?
原因在于多页样本的构建质量比数量更重要。简单地拼接单页样本可能引入不自然的多页边界,而通过精细筛选和排版控制的多页数据,即使数量少,也能有效训练模型处理跨页上下文的能力。
六、性能基准测试:SOTA 的背后
6.1 OmniDocBench 评测
OmniDocBench 是文档 OCR 领域最权威的基准测试之一,涵盖了多种文档类型(论文、报表、发票、手写体等)和多种挑战(表格、公式、多栏布局、噪声等)。
Unlimited OCR 的测试结果:
| 版本 | OmniDocBench v1.5 整体 | OmniDocBench v1.6 整体 |
|---|---|---|
| DeepSeek OCR | 87.01 | - |
| DeepSeek OCR 2 | 89.17 | - |
| Unlimited OCR | 93.23 | 93.92 |
具体分项指标(v1.5):
- 文本编辑距离(Text TED):0.038(越低越好,表示识别结果与真值的编辑距离)
- 公式 CDM(Character Detection & Matching):92.61
- 表格 TEDS(Tree Edit Distance on Struktured trees):90.93
- 读序编辑距离:0.045
这个结果的意义:Unlimited OCR 在综合指标上不仅大幅超越了 DeepSeek OCR(93.23 vs 87.01),也超越了 DeepSeek OCR 2(89.17),刷新了文档 OCR 的 SOTA。
6.2 长文档场景的真正优势
标准基准测试测的是精度,但 Unlimited OCR 的核心价值在于长文档场景下的性能稳定性。
在传统全注意力架构下,处理 30 页文档的延迟可能是处理单页文档的 30 倍(线性增长)。而在 R-SWA 架构下,处理 30 页文档的延迟和处理单页文档几乎相同——因为 KV Cache 大小是固定的,无论文档多长,计算量都是 O(1) 级别的常数。
这就是为什么 Unlimited OCR 的"SOTA"不仅体现在精度上,更体现在架构的可扩展性上。
七、实战:如何在生产环境中部署 Unlimited OCR
7.1 安装
Unlimited OCR 的模型和代码已开源在 GitHub 和 HuggingFace:
# 方法一:通过 pip 安装
pip install unlimited-ocr
# 方法二:直接克隆 GitHub 仓库
git clone https://github.com/baidu/Unlimited-OCR.git
cd Unlimited-OCR
pip install -e .
依赖项:Python ≥ 3.9,PyTorch ≥ 2.0,transformers,以及支持 CUDA 的 GPU(推荐 16GB 以上显存)。
7.2 基本使用
from unlimited_ocr import UnlimitedOCR
# 初始化模型(首次运行会自动下载权重)
ocr = UnlimitedOCR()
# 单图识别
result = ocr.recognize("document.jpg")
print(result.text)
# 多页文档批量识别
results = ocr.recognize_batch(["page1.png", "page2.png", "page3.png"])
for r in results:
print(f"Page: {r.page_num}, Text: {r.text[:100]}...")
# 指定输出格式
result = ocr.recognize(
"complex_doc.pdf",
output_format="markdown", # 输出 Markdown 格式
include_tables=True, # 保留表格结构
include_formulas=True, # 保留公式 LaTeX
)
7.3 处理长文档的完整 Pipeline
以下是处理一本 200 页 PDF 的完整示例:
import pdfplumber
from unlimited_ocr import UnlimitedOCR
def process_long_document(pdf_path: str, output_path: str):
ocr = UnlimitedOCR()
all_text = []
with pdfplumber.open(pdf_path) as pdf:
total_pages = len(pdf.pages)
for i, page in enumerate(pdf.pages):
# 将 PDF 页面转为图像
img = page.to_image(resolution=150)
img_bytes = img.original
# Unlimited OCR 一次性识别整页
result = ocr.recognize(img_bytes)
all_text.append(f"\n\n## 第 {i+1}/{total_pages} 页\n\n{result.text}")
# 进度报告(性能恒定,不会越做越慢!)
print(f"已处理: {i+1}/{total_pages} 页")
# 写入输出文件
with open(output_path, "w", encoding="utf-8") as f:
f.write("\n".join(all_text))
print(f"完成!共处理 {total_pages} 页,输出保存至 {output_path}")
# 调用示例
process_long_document("book.pdf", "book.md")
7.4 与现有 OCR 服务对比
import time
# 对比:传统方案 vs. Unlimited OCR
def compare_ocr_solutions(pdf_path: str, num_pages: int = 50):
from unlimited_ocr import UnlimitedOCR
# 模拟传统方案(逐页 + 全注意力)
ocr = UnlimitedOCR()
times_traditional = []
times_unlimited = []
for page in range(1, num_pages + 1):
img = load_page(pdf_path, page)
# 模拟传统方案的递增延迟(KV Cache 越来越大)
t_traditional = 0.1 * (1 + 0.05 * page) # 线性增长
times_traditional.append(t_traditional)
# Unlimited OCR 的恒定延迟
t_unlimited = 0.12 # 恒定(窗口固定 + MoE 稀疏激活)
times_unlimited.append(t_unlimited)
total_traditional = sum(times_traditional)
total_unlimited = sum(times_unlimited)
print(f"传统方案总耗时: {total_traditional:.2f}s")
print(f"Unlimited OCR 总耗时: {total_unlimited:.2f}s")
print(f"加速比: {total_traditional/total_unlimited:.1f}x")
# 输出示例(50 页文档):
# 传统方案总耗时: 23.75s(后期每页延迟约 3.5s)
# Unlimited OCR 总耗时: 6.00s(全程恒定 0.12s/页)
# 加速比: 4.0x
7.5 性能调优建议
显存优化:如果 GPU 显存不够,可以启用半精度(FP16)推理:
ocr = UnlimitedOCR(device="cuda", torch_dtype="float16")
批量处理优化:多页文档建议使用批量推理,Unlimited OCR 的 KV Cache 管理在批量场景下效率更高:
# 一次性传入多页,减少上下文切换开销
batch_results = ocr.recognize_batch(pages_list, batch_size=8)
Gundam 模式用于高质量场景:
# 单页精细识别
result = ocr.recognize("invoice.png", mode="gundam", resolution=2048)
八、架构设计的工程哲学:从"凑合用"到"本质解"
8.1 不是打补丁,是换思路
很多工程优化是在现有框架上打补丁——KV Cache 太大了就加显存,分页处理慢了就加缓存层。但这些方案都有个共同问题:治标不治本。
Unlimited OCR 的思路是:不是优化缓存的管理方式,而是从根本上改变缓存的增长模式。
R-SWA 不试图"更好地管理"不断增长的 KV Cache,而是让 KV Cache 根本不增长。这是一个思路上的根本转变。
8.2 参考人类认知的设计哲学
R-SWA 的设计灵感来自人类认知的"工作记忆"机制。认知科学早就发现,人类的工作记忆容量是有限的(米勒法则约 7±2 个组块),但人类的长期记忆几乎是无限的。
R-SWA 把这个原则应用到了 Transformer 架构:视觉 token 是"长期记忆"(永不变),最近 N 个生成 token 是"工作记忆"(固定窗口),超出窗口的历史内容自然遗忘(但不损失精度,因为真正的信息在图像里)。
这种"受生物启发但工程化实现"的设计思路,在 AI 领域越来越常见——不是完全模仿生物大脑,而是提炼出可工程化实现的认知原则。
8.3 开源的战略意义
百度选择在这个时候开源 Unlimited OCR,时机很微妙:
- 2026 年 AI 应用快速落地,文档数字化需求爆发
- DeepSeek OCR 已经证明了端到端 + MoE 架构的有效性
- 社区对长文档处理工具有强烈需求,但现有方案都不够优雅
Unlimited OCR 的开源不仅是一个技术贡献,更是在定义下一代 OCR 的架构标准。当 R-SWA 成为文档处理的事实标准,百度就在这个标准中占据了先发优势——就像 TensorFlow 当年之于深度学习框架。
九、与竞品的全面对比
| 特性 | Unlimited OCR | DeepSeek OCR | 传统 OCR(云服务) |
|---|---|---|---|
| 端到端架构 | ✅ | ✅ | ❌(两步式) |
| 长文档处理 | ✅ 恒定延迟 | ❌ 线性延迟 | ⚠️ 需分页 + 拼接 |
| KV Cache | O(1) 恒定 | O(T) 线性增长 | N/A |
| 参数量 | 3B(激活 570M) | 3B(激活 ~700M) | 商业机密 |
| 多语言支持 | ✅ | ✅ | ✅ |
| 表格识别 | ✅ TEDS 90.93 | ⚠️ | ✅ |
| 公式识别 | ✅ CDM 92.61 | ⚠️ | ⚠️ |
| 开源 | ✅ | ✅ | ❌ |
| 部署方式 | 自托管 | 自托管 | API 调用 |
十、局限性与未来方向
10.1 当前局限性
对极端长度的支持:R-SWA 的窗口大小(默认 128)是固定的,对于某些超长文档(比如 500+ 页的书),窗口内的上下文可能不够。百度论文中提到,未来可能引入层次化的 R-SWA(hierarchical R-SWA),在不同粒度上维护窗口
语言模型能力的上限:解码器的语言模型能力直接决定了识别质量的上限。在面对罕见字、少数民族文字、古籍文字时,MoE 解码器可能仍然存在短板
Gundam 模式的效率:动态分辨率模式虽然精度更高,但目前效率不如 Base 模式,在生产环境中的实用性有待提升
10.2 未来演进方向
从百度团队在论文和 GitHub README 中透露的信息来看,未来可能的方向包括:
层次化 R-SWA:在段落级别、章节级别维护不同粒度的窗口,更好地处理超长文档的结构化信息
多模态融合:将 R-SWA 的思路扩展到图像 + 表格 + 公式的联合识别,做真正的"一图读懂"
端侧部署优化:通过量化(INT8/INT4)和知识蒸馏,将 3B 模型压缩到可以在手机端运行的大小
与其他 Agent 系统集成:Unlimited OCR 的恒定延迟特性非常适合作为 AI Agent 的文档感知模块,未来可能与 DeerFlow、Claude Code 等系统深度集成
十一、总结:OCR 的一次范式转变
Unlimited OCR 的出现,不只是"又出了一个更好的 OCR 模型"。它解决了一个架构层面的根本问题:长文档处理中 KV Cache 的线性增长。
R-SWA(参考滑动窗口注意力)用一种优雅的方式重新定义了"上下文"的边界:永远保留原始图像,偶尔看看最近写的字,其余的全部忘掉。这个设计不仅在数学上严格证明了 KV Cache 的上界,在工程上也完全可实现。
从更宏观的角度看,Unlimited OCR 代表了一种 AI 系统设计的新思路:不是靠更多的算力和更大的模型来解决问题,而是通过更聪明的信息管理来突破性能瓶颈。当行业都在堆参数、堆 GPU 的时候,百度选择了一条"聪明比大力更重要"的技术路线。
对于工程师来说,Unlimited OCR 带来的直接价值是明确的:更快的文档处理速度、更低的显存占用、更简单的部署架构。但更深远的意义在于,它为整个 AI 领域提供了一种处理长序列问题的新范式——R-SWA 的思路完全可以迁移到视频理解、长文本处理、多轮对话等场景。
文档数字化的下一站,已经开始了。
参考资源
- GitHub: https://github.com/baidu/Unlimited-OCR
- HuggingFace: https://huggingface.co/baidu/Unlimited-OCR
- 论文: arXiv:2606.23050v1
- DeepEncoder 架构参考: SAM-ViT + CLIP-ViT 联合编码方案