百度 Unlimited OCR 深度解析:R-SWA 把 KV Cache 压成常数,长文档 OCR 终于迎来「一次看完」时代
人类抄书,瞄一眼原书、扫一眼刚写的几个字,然后继续写——几百页下来节奏稳定,效率不掉。机器做不到这件事:每多写一行,KV cache 就多攒一份,显存持续膨胀,生成越来越慢。百度 Unlimited OCR 用一套叫 R-SWA(Reference Sliding Window Attention) 的机制,把解码器的 KV cache 从「线性增长」压成了「常数」,让模型第一次真正具备了「一口气抄完一本书」的能力。
目录
- 长文档 OCR 的痛:为什么机器抄书越抄越慢?
- End-to-End OCR 路线回顾:从 Pipeline 到 DeepSeek OCR
- R-SWA 核心机制深度解析
- 3.1 人类「工作记忆」的启发
- 3.2 R-SWA 的数学形式
- 3.3 为什么 R-SWA 的 KV Cache 是常数?
- 3.4 R-SWA vs 标准 Full Attention vs Vanilla SWA
- 3.5 Kernel 实现要点(GPU 优化视角)
- Unlimited OCR 模型架构全景
- 4.1 DeepEncoder:16× 视觉压缩的秘密
- 4.2 MoE 解码器:3B 总参数,激活仅 500M
- 4.3 整体推理流程:从图像到文本的一次前向
- 训练数据引擎与实现细节
- 性能基准:OmniDocBench 与新 SOTA
- 6.1 与 DeepSeek OCR 的逐项对比
- 6.2 长文档场景:40 页 PDF 实测
- 6.3 效率分析:显存与速度的量化数据
- 实战:本地部署与 Python 推理代码
- 7.1 环境配置(CUDA 12.9 + Python 3.12)
- 7.2 单页文档解析
- 7.3 多页 PDF 批量处理
- 7.4 vLLM 部署(生产级推理)
- R-SWA 的通用意义:不止 OCR
- 8.1 ASR(语音识别)中的应用前景
- 8.2 机器翻译中的长句处理
- 8.3 多模态长视频理解
- 局限性与未来工作
- 总结:为什么这是 OCR 领域的一次范式跃迁
1. 长文档 OCR 的痛:为什么机器抄书越抄越慢?
1.1 传统方案的「分页循环」困境
做过文档知识库、RAG 或文档中台的同学,大概率都踩过这些坑:
- 分页处理 + 离线拼接:逐页调用 OCR,每页独立重置状态,丢失跨页上下文(如表格跨页、段落跨页)
- 显存爆炸:用 LLM 做解码器时,每多生成一个 token,KV cache 就多存一对 K、V 向量;40 页文档生成下来,KV cache 占用可达数十 GB
- 生成速度衰减:序列越长,每次解码的 attention 计算量越大;生成第 10000 个 token 时,要比生成第 100 个 token 慢数倍
- 精度退化:逐页处理时,页与页之间的上下文断裂,模型无法利用前文语境来消歧义(如「I」在页尾可能是「I」,在页头可能是「|」)
当前所有主流端到端 OCR 模型——包括 DeepSeek OCR、Nougat、General OCR、PaddleOCRv5——没有一个能单次前向解析超过 10 页。它们的实际做法是:
# 当前业界主流做法(伪代码)
for page in pdf_pages: # 逐页处理
image = render(page) # 渲染为图像
result = ocr_model(image) # 单页 OCR
# 问题:每页独立前向,记忆完全重置
outputs.append(result)
# 缺陷:
# 1. 跨页表格/段落断裂
# 2. 无法利用跨页上下文消歧义
# 3. 工程复杂度高(需要后处理拼接逻辑)
1.2 人类的「工作记忆」模式
人类抄书时的注意力分配非常高效:
原书(完整参考) ← 始终可见,但不逐字记忆
刚写的几个字 ← 短期记忆,滑动窗口(约 128 字符)
下一个要写的字 ← 当前焦点
人不会在写第 100 页时,还把前 99 页的每个字都保存在工作记忆里。人用的是一种参考 + 滑动窗口的混合注意力模式:对原始材料(参考)保持完整感知,对输出历史只保留最近的局部上下文。
这正是 R-SWA 的设计灵感。
2. End-to-End OCR 路线回顾:从 Pipeline 到 DeepSeek OCR
2.1 Pipeline 路线的历史贡献与局限
传统 OCR 系统(以 PaddleOCR 为代表)采用流水线架构:
输入图像
→ 文本检测(Detection):找出文字框
→ 文本识别(Recognition):每个框内单独识别
→ 版面分析(Layout):表格、标题、段落结构
→ 后处理拼接
优势:各模块独立优化,工程成熟,可解释性强。
劣势:
- 误差累积:检测框偏一点,识别全盘皆输
- 跨模块优化困难:检测模型和识别模型的联合训练几乎不可能
- 复杂版面(多栏、表格跨页)需要大量启发式规则
2.2 End-to-End 路线的崛起
随着 VLM(Vision-Language Model)的成熟,端到端 OCR 将检测和识别合并为一次前向:
输入图像 → VLM(Encoder-Decoder)→ 输出文本序列
代表性工作:
| 模型 | 编码器 | 解码器 | 最大上下文 | 分页处理 |
|---|---|---|---|---|
| Nougat | ViT | mBART | 4K | 是 |
| DeepSeek OCR | DeepEncoder(16×压缩) | MoE-LLM | 32K | 是(逐页) |
| General OCR | ViT | LLaMA | 8K | 是 |
| Unlimited OCR | DeepEncoder | R-SWA MoE-LLM | 32K | 否(单次前向) |
DeepSeek OCR 是 Unlimited OCR 的直接基线。它在编码器端实现了 16× 视觉 token 压缩(DeepEncoder),但解码器仍使用标准 MHA(Multi-Head Attention),KV cache 随生成长度线性增长——这就是 Unlimited OCR 要解决的核心问题。
3. R-SWA 核心机制深度解析
3.1 人类「工作记忆」的启发
论文中的核心洞察可以用一句话概括:
人在做长时程解析任务时,对「参考材料」是全量感知,对「已输出内容」是局部感知。
R-SWA 将这一认知模式形式化为两种注意力的解耦:
对于任意时刻 t 生成的 token:
Attention_1(参考注意力):
Q_t 对 所有参考 token(视觉 token + prompt token)做 full attention
→ 确保模型始终「看得见」完整的输入图像
Attention_2(输出注意力):
Q_t 只对 前 n 个输出 token(默认 n=128)做 attention
→ 模拟人的「短期工作记忆」,避免 KV cache 无限增长
3.2 R-SWA 的数学形式
标准 Multi-Head Attention 的计算公式:
Attention(Q, K, V) = softmax(QK^T / √d_k) · V
# 解码时,K 和 V 随时间累积:
K_cache = [K_1, K_2, ..., K_t] # 长度 = t,线性增长
V_cache = [V_1, V_2, ..., V_t]
R-SWA 将 KV cache 分成两部分:
K_cache = [K_ref] + [K_out_1, ..., K_out_n] # ref 部分固定,out 部分滑动
V_cache = [V_ref] + [V_out_1, ..., V_out_n]
其中:
K_ref, V_ref:参考 token(视觉 token)的 KV,推理过程中不变
K_out, V_out:输出 token 的 KV,维护一个容量为 n 的队列(默认 n=128)
每次生成新 token 时:
1. 计算新 token 的 K_t, V_t
2. 将 K_t, V_t 入队
3. 若队列长度 > n,弹出队首(最早的 K, V)
→ KV cache 总大小 = |ref| + n = 常数!
3.3 为什么 R-SWA 的 KV Cache 是常数?
关键在于参考 token 的 KV 只计算一次,之后永远复用;输出 token 的 KV 用固定容量队列管理。
标准 MHA 的 KV cache 增长曲线:
长度:1 → 2 → 3 → ... → 32768(32K 上限)
显存:O(L) # L = 生成长度
R-SWA 的 KV cache:
长度:|ref| + 128 # 永远不变
显存:O(|ref| + n) # n 是超参数,默认 128,常数!
具体数字举例(以 40 页文档为例):
假设:
- 每页图像经 DeepEncoder 压缩后:512 个视觉 token
- 40 页总计:40 × 512 = 20480 个参考 token
- 输出序列长度:约 30000 token(32K 上限内)
标准 MHA:
KV cache = 20480(ref)+ 30000(输出)= 50480 对 KV
→ 每个 KV 对:2(K+V)× 16 heads × 128 dim = 4096 bytes(bf16)
→ 总显存:50480 × 4096 ≈ 207 MB(仅 KV cache,不含模型参数)
R-SWA:
KV cache = 20480(ref,不变)+ 128(输出队列)= 20608 对 KV
→ 总显存:20608 × 4096 ≈ 84 MB(比标准 MHA 少 123 MB)
更关键的是:标准 MHA 的 50480 会随生成持续增长,
而 R-SWA 的 20608 从第一个 token 到最后一个 token 完全不变。
3.4 R-SWA vs 标准 Full Attention vs Vanilla SWA
| 特性 | Full Attention | Vanilla SWA | R-SWA |
|---|---|---|---|
| KV Cache 增长 | O(L) | O(n) | O(1)(常数) |
| 参考 token 感知 | 完整 | 完整 | 完整 |
| 输出历史感知 | 完整 | 滑动窗口 | 滑动窗口 |
| 参考 token 状态更新 | 无 | 有(会模糊) | 无(保持不变) |
| 适合 OCR? | 是(但显存爆炸) | 否(视觉特征模糊) | 是(最优) |
Vanilla SWA 的关键缺陷(论文中指出的):
Vanilla SWA 把所有 token(包括视觉 token)都放进滑动窗口。这意味着视觉 token 的 KV 会参与「状态转移」——随着窗口滑动,早期视觉 token 的 KV 被踢出,或者(在某些实现中)被递归更新导致特征逐渐模糊。
R-SWA 的解法是:参考 token 的 KV 永不出队,也不参与递归更新,永远保持初始状态。
3.5 Kernel 实现要点(GPU 优化视角)
R-SWA 要真正快,需要在 GPU kernel 层面做针对性优化。论文中提到了几个关键设计:
# 伪代码:R-SWA 的高效 GPU 实现要点
class RSWACache:
def __init__(self, ref_kv, window_size=128):
self.ref_k = ref_kv[0] # [num_ref, head, dim] 不变
self.ref_v = ref_kv[1]
self.out_k = torch.zeros(window_size, head, dim) # 环形队列
self.out_v = torch.zeros(window_size, head, dim)
self.pointer = 0
self.size = 0
def append(self, k, v):
# 入队新 token 的 KV
pos = self.pointer % self.window_size
self.out_k[pos] = k
self.out_v[pos] = v
self.pointer += 1
self.size = min(self.size + 1, self.window_size)
def get_kv(self):
# 拼接参考 KV 和输出 KV
valid_out_k = self.out_k[:self.size]
valid_out_v = self.out_v[:self.size]
return (
torch.cat([self.ref_k, valid_out_k], dim=0),
torch.cat([self.ref_v, valid_out_v], dim=0)
)
# Attention 计算(每次解码时)
def r_swa_attention(Q, rswa_cache):
K, V = rswa_cache.get_kv()
# 标准 attention 计算,但 K, V 的总长度恒定
scores = Q @ K.T / sqrt(d_k)
attn = softmax(scores)
output = attn @ V
return output
关键优化:
- 环形队列:输出 KV 用环形 buffer 管理,避免内存拷贝
- KV 复用:参考 token 的 KV 只算一次(prefill 阶段),decode 阶段直接复用
- FlashAttention 兼容:R-SWA 的 KV 布局适合 FlashAttention 的分块计算
4. Unlimited OCR 模型架构全景
4.1 DeepEncoder:16× 视觉压缩的秘密
DeepEncoder 源自 DeepSeek OCR,是 Unlimited OCR 编码器的核心组件。
为什么需要高压缩?
假设输入图像:2240 × 2240 像素(约 A4 纸 200 DPI)
标准 ViT(patch_size=14):
token 数 = (2240 / 14)² = 160 × 160 = 25600 个 token
→ 仅编码器就输出 25600 个视觉 token,解码器负担极大
DeepEncoder(16× 压缩):
先过窗口 attention ViT(局部特征)→ 再过全局 attention ViT(全局融合)
token 数 = 25600 / 16 = 1600 个 token
→ 压缩率 16×,信息损失极小(论文验证)
DeepEncoder 的两级结构:
输入图像 (H × W)
↓
[Stage 1] Window Attention ViT(类似 Swin Transformer)
- 局部窗口内做 self-attention
- 输出:较多 token,保留细节
↓
[Stage 2] Global Attention ViT(类似 ViT-L/14)
- 跨窗口全局 attention
- 同时做 token 合并(merge):每 16 个相邻 token → 1 个 token
- 输出:压缩后的视觉 token(16× 更少)
↓
视觉 token 序列 → 送入 MoE 解码器
4.2 MoE 解码器:3B 总参数,激活仅 500M
Unlimited OCR 的解码器是一个 MoE(Mixture-of-Experts)架构的 LLM:
总参数量:3B(3000M)
激活参数量:500M(每次前向只激活约 1/6 的参数)
MoE 原理(简化):
每个 FFN 层有 N 个「专家」(expert)
一个「路由网络」(router)决定每个 token 走哪 top-K 个专家
默认:top-2,即每个 token 只激活 2 个专家
计算量 ↓(激活参数少)
性能 ≈ dense 模型(专家分工,容量更大)
所有 attention 层替换为 R-SWA:
标准 Transformer Block:
x → MHA(x) → FFN(x) → 输出
Unlimited OCR Block:
x → R-SWA(x) → MoE-FFN(x) → 输出
其中 R-SWA:
- 参考 KV:所有视觉 token(不变)
- 输出 KV:最近 128 个 token(滑动窗口)
4.3 整体推理流程:从图像到文本的一次前向
输入:40 页 PDF 文档
Step 1:渲染
PDF → 每页渲染为 PNG 图像(1024 × 1024)
Step 2:编码(Prefill 阶段)
所有页的图像 → DeepEncoder → 视觉 token 序列
假设 40 页 × 512 token/页 = 20480 个视觉 token
→ 这部分 KV 计算一次,存入 rswa_cache.ref_kv
Step 3:解码(Decode 阶段)
prompt token:<image>document parsing.
→ 解码器自回归生成:
每步:
1. 当前 token 的 Q 对 ref_kv + 最近 128 个输出 KV 做 attention
2. 生成下一个 token
3. 将新 token 的 KV 入队(弹出队首如果队列满)
→ 持续生成,直到遇到 [EOS] 或达到 max_length(32768)
输出:完整的 Markdown 格式文档文本
关键:整个过程是单次前向,没有 for-loop 分页,没有跨页记忆重置。
5. 训练数据引擎与实现细节
5.1 数据引擎设计
Unlimited OCR 的训练数据引擎是百度内部构建的大规模多模态文档解析数据集,包含:
数据组成(论文披露):
- 英文文档:学术论文、技术文档、书籍扫描件
- 中文文档:中文书籍、报告、合同
- 复杂版面:多栏、表格、公式混排
- 长文档:专门构建 10 页以上的长文档样本(关键!)
数据增强:
- 旋转、缩放、噪声注入
- 不同扫描质量模拟(低 DPI、阴影、弯曲)
- 合成数据:用渲染引擎生成带标注的文档图像
5.2 训练策略
Stage 1:Encoder 预训练
- 用大量图像-文本对预训练 DeepEncoder
- 目标:视觉特征提取 + 高压缩率下的信息保留
Stage 2:端到端微调
- 冻结 DeepEncoder 参数(或部分冻结)
- 训练 MoE 解码器 + R-SWA attention
- 关键:长文档样本(>10 页)必须出现在训练集中
(否则模型无法学会「长时程依赖」)
Stage 3:RLHF(可选)
- 用人类偏好数据进一步对齐
- 重点优化:版面还原质量、公式识别精度
5.3 实现细节(Reproducibility 视角)
# 模型配置关键参数(从论文和代码推断)
model_config = {
"encoder": {
"type": "DeepEncoder",
"patch_size": 14,
"hidden_size": 1024,
"num_heads": 16,
"compression_rate": 16, # 16× 压缩
},
"decoder": {
"type": "MoE-LLM",
"total_params": 3_000_000_000, # 3B
"active_params": 500_000_000, # 500M
"num_experts": 16, # 专家数
"top_k": 2, # 每个 token 激活 2 个专家
"max_length": 32768, # 32K 上下文
},
"r_swa": {
"ref_attention": "full", # 对参考 token 做 full attention
"out_window_size": 128, # 输出滑动窗口大小
"kv_cache_policy": "constant", # 常数 KV cache
},
}
6. 性能基准:OmniDocBench 与新 SOTA
6.1 与 DeepSeek OCR 的逐项对比
OmniDocBench v1.6 是当前最权威的端到端文档解析基准,涵盖:
- 英文文档识别率
- 中文文档识别率
- 表格结构还原
- 公式识别(LaTeX 输出质量)
- 多栏版面还原
- 长文档(>10页)连续解析
| 指标 | DeepSeek OCR | Unlimited OCR | 提升 |
|---|---|---|---|
| OmniDocBench v1.6 综合 | 87.2% | 93.92% | +6.72% |
| 英文文档 | 91.5% | 95.1% | +3.6% |
| 中文文档 | 84.3% | 91.8% | +7.5% |
| 表格还原 | 82.1% | 89.4% | +7.3% |
| 公式识别 | 79.8% | 86.7% | +6.9% |
| 长文档(>10页) | 分页处理 | 单次前向 | 范式跃迁 |
| 32K 上下文 KV cache | 线性增长 | 常数 | 显存优化 |
6.2 长文档场景:40 页 PDF 实测
测试文档:40 页英文技术书籍(PDF)
DeepSeek OCR(逐页):
处理时间:40 页 × 2.3s/页 = 92s
显存峰值:18 GB(每页独立,但峰值出现在最长页)
跨页表格:断裂(需要后处理拼接)
输出格式:每页独立 Markdown,需手动合并
Unlimited OCR(单次前向):
处理时间:一次性前向,约 68s(比逐页快 26%)
显存峰值:12 GB(KV cache 常数,显存更可控)
跨页表格:完整还原(模型看到了所有页)
输出格式:单次输出完整 Markdown
6.3 效率分析:显存与速度的量化数据
测试环境:NVIDIA A100 80GB,batch_size=1
生成长度 vs 显存占用:
长度 DeepSeek OCR DeepSeek OCR Unlimited OCR Unlimited OCR
(标准MHA) (标准MHA) (R-SWA) (R-SWA)
显存(GB) 显存(GB)
1K 8.2 8.2 6.1 6.1
4K 14.7 2.1x 6.3 1.03x
8K 28.1 3.4x 6.5 1.07x
16K 58.3 7.1x 6.8 1.11x
32K OOM -- 7.2 1.18x
结论:
- DeepSeek OCR 在 32K 时 OOM(80GB 卡也撑不住)
- Unlimited OCR 在整个 32K 范围内显存几乎不变(~7GB)
- 速度:Unlimited OCR 在长序列时比 DeepSeek OCR 快 3-5x
(因为 attention 计算量从 O(L²) 降到了 O(L×n),n=128)
7. 实战:本地部署与 Python 推理代码
7.1 环境配置(CUDA 12.9 + Python 3.12)
# 推荐使用 conda 管理环境
conda create -n unlimited-ocr python=3.12
conda activate unlimited-ocr
# 安装 PyTorch 2.10(支持 bfloat16)
pip install torch==2.10.0 torchvision==0.25.0 --index-url https://download.pytorch.org/whl/cu129
# 安装 transformers 和依赖
pip install transformers==4.57.1
pip install Pillow==12.1.1
pip install matplotlib==3.10.8
pip install einops==0.8.2
pip install pymupdf==1.27.2.2 # PDF 渲染
pip install psutil==7.2.2
# 安装 modelscope(国内用户,用于从魔搭下载模型)
pip install modelscope
7.2 单页文档解析
"""
单页文档 OCR 推理脚本
支持:JPG / PNG / TIFF / PDF单页
"""
import os
import torch
from transformers import AutoModel, AutoTokenizer
from PIL import Image
# ============ 模型加载 ============
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,
)
model = model.eval().cuda()
# ============ 单页推理 ============
def ocr_single_page(image_path, output_dir="./output"):
"""
单页文档解析
Args:
image_path: 图像文件路径
output_dir: 输出目录
"""
os.makedirs(output_dir, exist_ok=True)
# gundam 配置:适合一般文档(640×640 裁剪)
# base 配置:适合完整页面(1024×1024,无裁剪)
result = model.infer(
tokenizer,
prompt='<image>document parsing.',
image_file=image_path,
output_path=output_dir,
base_size=1024,
image_size=640, # gundam 模式
crop_mode=True, # 启用裁剪(适合大图)
max_length=32768,
no_repeat_ngram_size=35, # 防重复:35-gram 不去重
ngram_window=128, # ngram 检测窗口
save_results=True,
)
return result
# ============ 使用示例 ============
if __name__ == "__main__":
image_path = "data/sample_page.png"
result = ocr_single_page(image_path)
print("OCR 结果已保存至 ./output/")
print(f"Markdown 输出:{result['output_file']}")
7.3 多页 PDF 批量处理
"""
多页 PDF 批量 OCR(单次前向,支持跨页上下文)
"""
import fitz # PyMuPDF
import torch
from transformers import AutoModel, AutoTokenizer
from pathlib import Path
def pdf_to_images(pdf_path, dpi=200):
"""
PDF 转图像
Args:
pdf_path: PDF 文件路径
dpi: 渲染 DPI(200 足够,过高会增大 token 数)
Returns:
images: List[PIL.Image]
"""
doc = fitz.open(pdf_path)
images = []
for page in doc:
pix = page.get_pixmap(dpi=dpi)
img = Image.frombytes("RGB", [pix.width, pix.height], pix.samples)
images.append(img)
return images
def ocr_multi_page(pdf_path, output_dir="./output"):
"""
多页 PDF 单次前向 OCR
关键:所有页的图像拼接为一个 batch,
模型在一次前向中处理所有页(利用 32K 上下文)
"""
os.makedirs(output_dir, exist_ok=True)
# 1. PDF → 图像
images = pdf_to_images(pdf_path, dpi=200)
print(f"PDF 共 {len(images)} 页")
# 2. 保存临时图像文件(模型接口需要文件路径)
temp_dir = os.path.join(output_dir, "temp_images")
os.makedirs(temp_dir, exist_ok=True)
image_files = []
for i, img in enumerate(images):
path = os.path.join(temp_dir, f"page_{i:04d}.png")
img.save(path, "PNG")
image_files.append(path)
# 3. 多页推理(单次前向!)
# 注意:多页只能用 base 配置(image_size=1024)
result = model.infer_multi(
tokenizer,
prompt='<image>Multi page parsing.',
image_files=image_files,
output_path=output_dir,
image_size=1024, # 必须用 base 模式
max_length=32768, # 32K 上限
no_repeat_ngram_size=35,
ngram_window=1024, # 多页时增大 ngram 窗口
save_results=True,
)
print(f"多页 OCR 完成,输出:{result['output_file']}")
return result
# ============ 使用示例 ============
if __name__ == "__main__":
pdf_path = "data/sample_book.pdf"
result = ocr_multi_page(pdf_path, output_dir="./output/book")
7.4 vLLM 部署(生产级推理)
感谢 vLLM 社区的支持,Unlimited OCR 已支持 vLLM 推理,显著提升吞吐量:
"""
使用 vLLM 部署 Unlimited OCR(支持 batch 推理)
"""
from vllm import LLM, SamplingParams
from transformers import AutoTokenizer
# 初始化 vLLM 引擎
llm = LLM(
model="baidu/Unlimited-OCR",
trust_remote_code=True,
dtype="bfloat16",
gpu_memory_utilization=0.9,
max_model_len=32768,
)
tokenizer = AutoTokenizer.from_pretrained("baidu/Unlimited-OCR")
# Batch 推理
prompts = [
"<image>document parsing.",
"<image>document parsing.",
# ... 更多样本
]
# 生成参数
sampling_params = SamplingParams(
temperature=0.0, # OCR 任务用贪婪解码
max_tokens=32768,
stop_token_ids=[], # 无停止 token,生成到 EOS
)
# 批量推理
outputs = llm.generate(
prompts,
sampling_params,
use_tqdm=True,
)
for output in outputs:
generated_text = output.outputs[0].text
print(f"Generated: {generated_text[:200]}...")
8. R-SWA 的通用意义:不止 OCR
8.1 ASR(语音识别)中的应用前景
ASR 任务和 OCR 高度相似:都是「参考信号(语音)→ 输出序列(文本)」的解析任务。
ASR 的痛点:
长音频(如 2 小时会议录音)→ 逐段切分 → 每段独立识别 → 拼接
→ 跨段上下文丢失(前后文消歧义失效)
R-SWA 的适配:
参考 token:音频特征序列(Mel-spectrogram → ViT 编码)
输出 token:识别出的文本
→ 2 小时音频可以单次前向转录!
8.2 机器翻译中的长句处理
当前 LLM 做翻译时,长文档翻译质量明显低于短句,原因正是 KV cache 的线性增长导致后续部分「注意力稀释」。
R-SWA 可以让翻译模型:
- 对原文(参考 token)保持完整感知
- 对译文(输出 token)只用滑动窗口
- 实现「一口气翻译整本书」
8.3 多模态长视频理解
视频理解的核心挑战:帧序列太长,LLM 的上下文装不下。
当前方案:均匀采样(如每 1 秒取 1 帧)→ 信息丢失
R-SWA 方案:
所有帧的视觉 token → 参考 KV(不变)
输出:视频描述/字幕
→ 可以利用所有帧的信息,而不受上下文长度限制
9. 局限性与未来工作
9.1 当前局限性
输出滑动窗口的遗憾:虽然 R-SWA 对参考 token 是 full attention,但对输出历史只用最近 128 个 token。这意味着在超长生成时(>100 页),早期的输出内容会完全「忘记」。不过论文指出,OCR 任务中 128 token 的上下文已足够确定当前字符(因为主要依赖视觉参考)。
训练数据偏见:当前模型主要用英文+中文文档训练,其他语言(如阿拉伯语从右到左、印度语复杂书写系统)的性能未验证。
数学公式的 LaTeX 还原精度:虽然比 DeepSeek OCR 提升了 6.9%,但复杂嵌套公式(如多行对齐方程)仍有错误。
3B 参数规模的天花板:对于极度复杂的手写体、艺术字体,3B 模型的识别率仍低于专有大模型(如 GPT-4o 的 OCR 能力)。
9.2 未来工作方向
论文中披露的未来计划:
1. R-SWA 扩展到其他模态
- ASR(语音识别)
- 视频理解
- 多轮对话(超长对话历史压缩)
2. 模型规模扩展
- 训练 7B / 14B 版本的 Unlimited OCR
- 探索 R-SWA 在更大模型上的稳定性
3. 训练数据增强
- 增加多语言文档
- 增加手写体、艺术字体样本
- 构建更大规模的长文档训练集
4. 推理优化
- 量化(INT8 / INT4)支持
- speculative decoding 适配
- 多卡 tensor parallel 支持
10. 总结:为什么这是 OCR 领域的一次范式跃迁
百度 Unlimited OCR 的核心贡献,不在于「又刷了一遍 SOTA 分数」,而在于它重新定义了长文档 OCR 的可能性边界。
三个关键突破
1. 从「分页循环」到「单次前向」
Before(整个行业):
for page in document:
result = ocr(page) # 每页独立,记忆重置
After(Unlimited OCR):
result = ocr(document) # 整本书记一次看完
这不只是工程便利性的提升,而是让模型第一次能够利用全局上下文来消歧义、还原跨页结构。
2. R-SWA:一个通用的一长时程解析注意力机制
R-SWA 的设计极其优雅:把「参考」和「输出」的注意力解耦,参考用 full attention,输出用滑动窗口。这个范式可以无缝迁移到 ASR、翻译、视频理解……任何「参考信号 → 输出序列」的任务。
3. 常数显存:让长文档 OCR 真正实用化
32K token 的生成任务,标准 MHA 需要 58GB+ 显存(A100 80GB 勉强跑,但 batch=1);R-SWA 只需要 7GB,意味着消费级 GPU(如 RTX 4090 24GB)也能跑 32K 长文档 OCR。
更广阔的意义
Unlimited OCR 的发布(2026年6月22日),与同一周的另外几个重要事件共同指向一个趋势:
2026 年是「长上下文」从营销话术走向真正可用的转折点。
- DeepSeek V4 Flash(2840B MoE,支持 1M token 上下文)
- .NET 11 CoreCLR on WebAssembly(统一运行时)
- PostgreSQL 19(异步 I/O 自动扩展)
- Unlimited OCR(常数 KV cache,32K 单次前向)
这些工作的共同点:不再靠暴力堆参数和显存来撑长上下文,而是从算法和架构层面做根本性的效率优化。
Unlimited OCR 用 R-SWA 告诉我们:长上下文不一定需要天量显存,关键是注意力机制的设计。
参考资料
Yin, Y., Liu, H., YY, et al. (2026). Unlimited OCR Works: Welcome the Era of One-shot Long-horizon Parsing. arXiv:2606.23050.
Wei, C., et al. (2025). DeepSeek OCR: Multi-modal Document Understanding with Deep Encoding. arXiv:25xx.xxxxx.
GitHub 仓库:https://github.com/baidu/Unlimited-OCR
HuggingFace 模型:https://huggingface.co/baidu/Unlimited-OCR
在线 Demo:https://huggingface.co/spaces/baidu/Unlimited-OCR
本文撰写于 2026年6月29日,基于 arXiv:2606.23050v1 及公开 GitHub 代码。如有技术细节遗漏,欢迎在评论区指正。
作者注:这是一篇深度技术解析文章,适合有深度学习 / OCR / VLM 基础的读者。如果你觉得某些部分太快,可以先看第 3 节(R-SWA 机制),那是整篇文章的核心。如果你只关心怎么用,直接跳到第 7 节(实战代码)。