百度 Unlimited OCR 深度解析:端到端架构、R-SWA 常数量化 KV Cache,以及让 AI 像人一样"抄书"的工程革命
2026 年 6 月,百度开源 Unlimited OCR,5 天 GitHub Star 破万,登顶 GitHub Daily Trending、HuggingFace 模型总榜、多模态榜四榜第一。核心突破:Reference Sliding Window Attention(R-SWA)把解码器 KV Cache 从"线性增长"压成"常数",单次前向传播可连续解析数十页文档。本文从架构原理、注意力机制、代码实战到工程优化,完整拆解这套系统。
一、引言:OCR 的长文档困境
OCR(Optical Character Recognition,光学字符识别)并不是新技术。早在 20 世纪 90 年代,基于模板匹配和特征工程的 OCR 系统就已经商用。但今天的 OCR 面临一个全新挑战:长文档。
一本 300 页的 PDF 书籍、一份 50 页的年度财报、一叠扫描的合同文件——传统 OCR 流程(先检测文字框,再逐框识别)在处理这类长文档时,效率会断崖式下跌。根本原因是:大语言模型作为解码器时,KV Cache 随序列长度线性增长。
用人话解释:AI "抄书"时,每多抄一个字,就要把之前所有字都"记"一遍,文档越长,记忆负担越重,速度越慢,显存吃掉越多。而人类抄书,瞄几眼刚写的字就能继续,几百页下来节奏稳定。
百度 Unlimited OCR 的核心目标就是:让 AI 也具备这种"工作记忆"能力。
二、端到端 OCR 的革命:从级联到统一
2.1 传统两阶段 OCR 的宿命
传统 OCR pipeline 分为两个完全独立的阶段:
图像 → 文本检测(Detection)→ 文字框坐标 → 文本识别(Recognition)→ 文本序列
检测阶段用目标检测模型(如 YOLO、CTPN、PSENet)找出图像中文字的区域,输出 bounding box;识别阶段把每个框内的图像 patch 送入 CRNN 或 Transformer 识别成文字。
这个流程有三个结构性缺陷:
- 信息瓶颈:检测框的坐标精度直接决定识别上限,检测偏一点,识别就丢字符;
- 计算冗余:每个文字框独立跑一次识别模型,重复计算量巨大;
- 无法建模全局依赖:识别阶段看不到整页语义,面对模糊字符无法利用上下文消歧。
2.2 端到端 OCR:统一神经网络架构
端到端(End-to-End)OCR 的核心思想是:用一个统一的神经网络,直接从输入图像映射到输出文本序列,摒弃"先检测、再识别"的级联结构。
这类似于 Seq2Seq 机器翻译的思路,只不过输入从文本变成了图像。架构通常是:
图像 → Vision Encoder(视觉编码器)→ 视觉 Token 序列 → LLM Decoder(语言模型解码器)→ 文本序列
DeepSeek OCR 是这一方向的里程碑:它用 DeepEncoder(基于 ViT 的视觉编码器)+ MoE(混合专家)解码器,在多项基准上大幅超越传统两阶段方法。
但 DeepSeek OCR 继承了一个 LLM 的固有缺陷:自回归解码时 KV Cache 线性增长。
三、Unlimited OCR 核心架构深度解析
Unlimited OCR 以 DeepSeek OCR 为基线,在保持端到端架构优势的同时,通过 R-SWA(Reference Sliding Window Attention) 彻底解决了长文档场景下的 KV Cache 膨胀问题。
3.1 整体架构
输入:文档图像(支持 1024×1024 及更大)
│
▼
【DeepEncoder】← 两级视觉编码 + 16× Token 压缩
│ 输出:256 个视觉 Token(1024×1024 图像)
▼
【Embedding 投影层】← 视觉 Token → 语言模型空间
│
▼
【MoE 解码器】← R-SWA Attention(常数量化 KV Cache)
│ 总参数:3B,激活参数:~570M
▼
输出:文本序列(支持最长 32K Token)
3.2 DeepEncoder:两级视觉编码与 16× 压缩
DeepEncoder 负责把高分辨率图像编码成紧凑的视觉 Token 序列。设计要点:
第一级:高分辨率局部特征提取
用 ViT(Vision Transformer)处理图像 patch。对于 1024×1024 图像,若 patch size = 16,则原始视觉 Token 数量为:
$$(1024 / 16)^2 = 4096 \text{ 个 Token}$$
4096 个 Token 送入 LLM 解码器,光预填充阶段就要消耗大量显存,更别提解码时的 KV Cache 了。
第二级:跨 patch 全局融合 + 16× 压缩
DeepEncoder 在连接阶段执行 16 倍 Token 压缩,把 4096 个 Token 压缩到 256 个:
$$4096 \xrightarrow{16\times \text{压缩}} 256$$
压缩方式不是简单的池化,而是通过可学习的压缩 Transformer 层,让每个压缩后的 Token "看到"多个原始 patch 的信息。这样 1024×1024 的 PDF 页面,只需要 256 个视觉 Token 就能表征,从源头减轻了解码器的负担。
# 概念性代码:DeepEncoder 的压缩逻辑(非实际代码)
# 来源:根据百度技术报告描述还原
import torch
import torch.nn as nn
class DeepEncoder(nn.Module):
def __init__(self, patch_size=16, compress_ratio=16):
super().__init__()
self.patch_embed = ViTPatchEmbed(patch_size=patch_size)
# 第一级:局部特征提取
self.local_transformer = TransformerBlocks(num_layers=12)
# 第二级:压缩 Transformer
self.compress = nn.Linear(
compress_ratio * patch_size * patch_size * 3,
hidden_dim
)
self.global_transformer = TransformerBlocks(num_layers=6)
def forward(self, images):
# images: [B, 3, 1024, 1024]
patches = self.patch_embed(images)
# patches: [B, 4096, hidden_dim]
patches = self.local_transformer(patches)
# 16× 压缩:每 16 个相邻 patch 合并成一个 Token
B, N, D = patches.shape
compressed = patches.view(B, N // 16, 16, D).mean(dim=2)
# compressed: [B, 256, hidden_dim]
compressed = self.global_transformer(compressed)
return compressed
3.3 MoE 解码器:3B 总参数,570M 激活参数
Unlimited OCR 的解码器基于 LLM 架构,但采用 MoE(Mixture of Experts,混合专家) 设计:
- 总参数量:30 亿(3B)
- 推理时激活参数:约 5.7 亿(570M)
MoE 的核心思想是:模型里有多个"专家"前馈网络(FFN),每次推理只激活其中少数几个,大部分参数处于"休眠"状态。
输入 Token → Router(路由网络)→ 选择 Top-K 个专家 → 加权求和输出
假设有 32 个专家,每次只激活 2 个(Top-2),则激活参数量约为总参数量的 2/32 = 1/16。这就是 3B 总参数却只需激活 570M 的原因。
MoE 在 OCR 中的优势:
- 容量大而推理快:模型"知道"很多知识,但推理时计算量不大;
- 多模态友好:不同专家可以分别擅长处理视觉特征、语言先验、版式分析等;
- 训练稳定:MoE 的负载均衡损失(load balance loss)迫使路由分布均匀,避免专家退化。
# 概念性代码:MoE FFN 层
class MoEFFN(nn.Module):
def __init__(self, num_experts=32, top_k=2, hidden_dim=2048):
super().__init__()
self.experts = nn.ModuleList([
FeedForwardNetwork(hidden_dim)
for _ in range(num_experts)
])
self.router = nn.Linear(hidden_dim, num_experts)
self.top_k = top_k
def forward(self, x):
# x: [B, seq_len, hidden_dim]
B, L, D = x.shape
# 路由:为每个 Token 计算专家得分
router_logits = self.router(x) # [B, L, num_experts]
top_k_logits, top_k_indices = torch.topk(router_logits, self.top_k, dim=-1)
top_k_weights = torch.softmax(top_k_logits, dim=-1)
# 加权求和各专家的输出
output = torch.zeros_like(x)
for i in range(self.top_k):
expert_idx = top_k_indices[..., i] # [B, L]
expert_weight = top_k_weights[..., i:i+1] # [B, L, 1]
for e_idx in range(len(self.experts)):
mask = (expert_idx == e_idx)
if mask.any():
expert_out = self.experts[e_idx](x[mask])
output[mask] += expert_weight[mask] * expert_out
return output
四、R-SWA 技术细节:Reference Sliding Window Attention
这是 Unlimited OCR 最核心的创新,也是本文最值得深入的技术点。
4.1 传统 LLM 解码器的 KV Cache 之痛
标准 Transformer 解码器在自回归生成时,每个时间步 t 都要计算:
$$\text{Attention}(Q_t, K_{1:t}, V_{1:t}) = \text{softmax}\left(\frac{Q_t K_{1:t}^T}{\sqrt{d_k}}\right) V_{1:t}$$
其中 $K_{1:t}$ 和 $V_{1:t}$ 是过去所有时间步的 Key 和 Value 向量。这些向量必须缓存起来,否则每生成一个新 Token 都要重新计算整个序列的 K。
问题:缓存大小随序列长度 $t$ 线性增长。
假设每个 Token 的 KV Cache 占用 2KB(以 Llama 7B 为例测算),则:
| 序列长度 | KV Cache 大小 |
|---|---|
| 1K Token | ~2 MB |
| 8K Token | ~16 MB |
| 32K Token | ~64 MB |
| 100K Token | ~200 MB |
对 OCR 来说,一本 300 页的书籍,Token 序列轻松超过 100K,显存消耗让消费级 GPU 直接 OOM。
4.2 R-SWA 的核心思想
Reference Sliding Window Attention(参考滑动窗口注意力) 的灵感来自人类的工作记忆机制。
人类抄书时,并不是把整本书都背下来再写,而是:
- 看一眼原文(参考);
- 瞄一眼自己刚写了什么(滑动窗口);
- 继续写。
R-SWA 把这套策略翻译成注意力机制:
对于每个生成位置 t:
1. 计算对"参考序列"(编码器输出)的全量注意力 ← 这部分 KV 可以复用,不增长
2. 计算对"滑动窗口"(最近 W 个 Token)的局部注意力 ← 窗口大小固定,KV Cache 常数
3. 两者融合,得到最终输出
关键:参考序列(编码器输出的视觉 Token)的 KV 只需要计算一次,之后每次解码直接复用;滑动窗口的 KV Cache 大小上限是 $W$(窗口大小),不会随序列变长而增长。
结果:整个解码过程的 KV Cache 大小 = 常数(参考序列 KV + 滑动窗口 KV),与生成长度无关。
4.3 R-SWA 的数学描述
对于解码器第 $t$ 个生成位置,Query 向量 $q_t$ 的注意力计算为:
$$\text{R-SWA}(q_t) = \text{softmax}\left(\frac{q_t \cdot [K_{ref} \parallel K_{t-W:t}]^T}{\sqrt{d_k}}\right) [V_{ref} \parallel V_{t-W:t}]$$
其中:
- $K_{ref}, V_{ref}$:编码器输出(参考序列)的 Key/Value,只需计算一次
- $K_{t-W:t}, V_{t-W:t}$:滑动窗口内最近 $W$ 个 Token 的 Key/Value
- $\parallel$:拼接操作
KV Cache 总量:
$$\text{Memory} = |K_{ref}| + |V_{ref}| + W \times (|K_{token}| + |V_{token}|)$$
与生成长度 $t$ 无关,是常数。
# 概念性代码:R-SWA Attention 实现
class RSWAAttention(nn.Module):
"""
Reference Sliding Window Attention
常数量化 KV Cache 的 Attention 实现
"""
def __init__(self, hidden_dim, num_heads, window_size=512):
super().__init__()
self.hidden_dim = hidden_dim
self.num_heads = num_heads
self.head_dim = hidden_dim // num_heads
self.window_size = window_size
self.q_proj = nn.Linear(hidden_dim, hidden_dim)
self.k_proj = nn.Linear(hidden_dim, hidden_dim)
self.v_proj = nn.Linear(hidden_dim, hidden_dim)
self.out_proj = nn.Linear(hidden_dim, hidden_dim)
def forward(self, q, ref_kv=None, past_kv=None):
"""
q: [B, 1, D] 当前 Token 的 Query(自回归,一次一个)
ref_kv: Tuple(K_ref, V_ref) 编码器输出的 KV,一次性计算
past_kv: Tuple(K_past, V_past) 滑动窗口内的 KV
"""
B, T, D = q.shape
q = self.q_proj(q).view(B, T, self.num_heads, self.head_dim).transpose(1, 2)
if ref_kv is not None:
K_ref, V_ref = ref_kv
# ref_kv 不参与 past_kv 的累积,单独处理
K_ref = K_ref.unsqueeze(0).expand(B, -1, -1, -1)
V_ref = V_ref.unsqueeze(0).expand(B, -1, -1, -1)
# 当前 Token 的 K, V
k = self.k_proj(q).view(B, T, self.num_heads, self.head_dim).transpose(1, 2)
v = self.v_proj(q).view(B, T, self.num_heads, self.head_dim).transpose(1, 2)
# 维护滑动窗口 KV Cache
if past_kv is not None:
K_past, V_past = past_kv
# 拼接历史窗口
k_full = torch.cat([K_past, k], dim=2)
v_full = torch.cat([V_past, v], dim=2)
# 截断:只保留最近 window_size 个
if k_full.shape[2] > self.window_size:
k_full = k_full[:, :, -self.window_size:, :]
v_full = v_full[:, :, -self.window_size:, :]
else:
k_full = k
v_full = v
# 注意力:参考序列 + 滑动窗口
# [B, H, T, D] @ [B, H, ref_len+D, D]^T
attn_ref = torch.matmul(q, K_ref.transpose(-2, -1)) / (self.head_dim ** 0.5)
attn_win = torch.matmul(q, k_full.transpose(-2, -1)) / (self.head_dim ** 0.5)
attn = torch.cat([attn_ref, attn_win], dim=-1)
attn = torch.softmax(attn, dim=-1)
# 加权求和
V_ref_expanded = V_ref # [B, H, ref_len, D]
v_full_expanded = v_full # [B, H, win_len, D]
output = torch.matmul(attn, torch.cat([V_ref_expanded, v_full_expanded], dim=2))
output = output.transpose(1, 2).contiguous().view(B, T, D)
output = self.out_proj(output)
# 返回更新后的滑动窗口 KV(用于下次解码)
return output, (k_full, v_full)
4.4 为什么 R-SWA 是通用机制
论文特别强调:R-SWA 不只是 OCR 技术,它是一个通用的解析注意力机制。
任何"输入序列 → 输出序列"的任务,只要输入序列在解码过程中可以被当作"参考"(不需要修改、全局可见),都可以用 R-SWA 常量化 KV Cache:
| 任务 | 参考序列 | 适用场景 |
|---|---|---|
| OCR | 视觉 Token(编码器输出) | 长文档解析 |
| ASR(语音识别) | 音频特征序列 | 长音频转写 |
| 机器翻译 | 源语言 Token | 长文档翻译 |
| 视频字幕生成 | 视频帧特征 | 长视频字幕 |
五、性能基准与实测数据
5.1 OmniDocBench v1.6:93.92% SOTA
OmniDocBench 是专门针对端到端 OCR 模型设计的综合基准测试,覆盖:
- 多栏排版文档
- 表格、公式混排
- 手写 + 印刷混排
- 多语言(中、英、日、韩等)
- 低质量扫描件
Unlimited OCR 在 v1.6 版本上取得 93.92% 综合得分,超过所有已公开的端到端 OCR 模型。
5.2 长文档实测:单次前向传播数十页
由于 R-SWA 的 KV Cache 是常数,Unlimited OCR 在标准 32K Token 最大长度限制下,可以单次前向传播连续解析数十页文档,而不需要把文档切成小块分别处理。
这意味着:
- 不再有"分页断层"问题(上一页的上下文无法传递到下一页);
- 推理延迟大幅降低(只需一次模型加载和编码器前向传播);
- 全局版式理解能力提升(模型"看到"了整份文档的视觉特征)。
5.3 与主流 OCR 方案对比
| 方案 | 架构 | 长文档支持 | 多语言 | 版式理解 |
|---|---|---|---|---|
| Tesseract 5 | 传统两阶段 | ❌ 需分段 | ✅ 100+ | ❌ |
| PaddleOCR v3 | 两阶段 + 方向分类 | ⚠️ 有限 | ✅ 80+ | ⚠️ 简单版式 |
| DeepSeek OCR | 端到端 + LLM 解码器 | ⚠️ KV Cache 线性增长 | ✅ | ✅ |
| Unlimited OCR | 端到端 + R-SWA | ✅ 常数 KV Cache | ✅ | ✅ 全局 |
六、代码实战:本地部署与使用 Unlimited OCR
6.1 环境准备
# 推荐环境:Python 3.10+, PyTorch 2.0+, CUDA 12.1
# 显存需求:推理约 6GB(570M 激活参数)
# 克隆仓库
git clone https://github.com/baidu/Unlimited-OCR.git
cd Unlimited-OCR
# 安装依赖
pip install -r requirements.txt
# 下载模型权重(HuggingFace)
# 模型大小约 12GB(3B 参数,BF16)
huggingface-cli download baidu/Unlimited-OCR --local-dir ./weights
6.2 基础推理:单张图像识别
import torch
from PIL import Image
from model import UnlimitedOCRModel
from config import ModelConfig
# 加载模型
config = ModelConfig.from_pretrained("./weights")
model = UnlimitedOCRModel.from_pretrained("./weights", config=config)
model.cuda().eval()
# 预处理图像
image = Image.open("document_page.png").convert("RGB")
# 模型支持动态分辨率,但推荐 1024×1024 以获得最佳压缩比
image = image.resize((1024, 1024), Image.LANCZOS)
# 推理
with torch.no_grad():
pixel_values = model.image_processor(image)
pixel_values = pixel_values.unsqueeze(0).cuda()
# encoder 前向(只需一次)
encoder_outputs = model.encoder(pixel_values)
# decoder 自回归生成
generated_ids = model.generate(
encoder_outputs=encoder_outputs,
max_length=32768, # 支持 32K Token 长文档
num_beams=1, # 贪心解码,速度最快
do_sample=False,
)
# 解码输出
pred_text = model.tokenizer.batch_decode(generated_ids, skip_special_tokens=True)
print(pred_text[0])
6.3 批量处理:多页 PDF 文档
from pdf2image import convert_from_path
import tempfile
def ocr_pdf(pdf_path, model, image_processor, tokenizer, dpi=200):
"""
批量 OCR 处理 PDF 文档
R-SWA 优势:多页可以合并成一个长序列,单次生成
"""
# PDF → 图像
pages = convert_from_path(pdf_path, dpi=dpi)
results = []
# 批量编码器前向(可以 batch>1,视显存而定)
batch_pixel_values = []
for page in pages:
pv = image_processor(page)
batch_pixel_values.append(pv)
batch_pixel_values = torch.stack(batch_pixel_values).cuda()
with torch.no_grad():
# 批量编码
encoder_outputs = model.encoder(batch_pixel_values)
# 逐页生成(未来版本支持跨页长序列生成)
for i, enc_out in enumerate(encoder_outputs.last_hidden_state):
generated = model.generate(
encoder_outputs=enc_out.unsqueeze(0),
max_length=4096, # 单页约 500-2000 Token
)
text = tokenizer.decode(generated[0], skip_special_tokens=True)
results.append(f"=== 第 {i+1} 页 ===\n{text}\n")
return "\n".join(results)
# 使用
result = ocr_pdf("report_2026.pdf", model, image_processor, tokenizer)
with open("report_2026_ocr.txt", "w") as f:
f.write(result)
print(f"OCR 完成,共 {len(results)} 页")
6.4 高级用法:自定义提示词(Prompt Engineering)
Unlimited OCR 支持通过提示词引导识别策略,类似于 LLM 的 System Prompt:
# 指定识别语言
prompt_lang = "请识别以下文档中的简体中文和英文文本:"
# 指定输出格式(Markdown / 纯文本 / 保留版式)
prompt_format = "请以 Markdown 格式输出,保留标题层级和表格结构:"
# 指定专注区域(未来版本支持 bounding box 提示)
prompt_region = "请重点识别文档右侧栏的内容:"
# 组合提示词
prompt = f"{prompt_lang}\n{prompt_format}"
# 将 prompt 作为特殊 Token 前缀送入解码器
七、工程实践与性能优化
7.1 显存优化:FP16/BF16 量化
3B 总参数的模型,BF16 格式下约占用 6GB 显存。激活参数 570M,解码时额外显存主要来自 KV Cache(但 R-SWA 已将其常量化)。
# BF16 推理(推荐,数值稳定性优于 FP16)
model = model.to(torch.bfloat16)
# 如果显存仍然紧张,可以对编码器做 INT8 量化
# 注意:解码器量化需谨慎,R-SWA 对精度较敏感
from torch.ao.quantization import quantize_dynamic
model.encoder = quantize_dynamic(model.encoder, {torch.nn.Linear}, dtype=torch.qint8)
7.2 推理速度调优
R-SWA 让 KV Cache 变成了常数,但解码速度还受其他因素影响:
# 1. 使用 FlashAttention-2(如果 CUDA 版本支持)
# R-SWA 的滑动窗口注意力可以高效实现为 FlashAttention 的变体
# 2. 增大 batch size(编码器支持并行)
# 编码器是双向 Transformer,可以 batch>1 并行编码多页
encoder_outputs = model.encoder(pixel_values) # pixel_values: [B, 3, 1024, 1024]
# 3. 提前终止(Early Stopping)
# 如果某页文档已识别完毕(模型输出了 [EOS]),提前终止解码
generated = model.generate(
encoder_outputs=enc_out,
max_length=4096,
eos_token_id=tokenizer.eos_token_id,
early_stopping=True,
)
7.3 实际场景适配
场景一:扫描版 PDF(图像内嵌)
# 直接用 pdf2image 转图像,送入模型
# 注意 DPI 设置:打印版 PDF 推荐 200-300 DPI
pages = convert_from_path("scan.pdf", dpi=250)
场景二:数字版 PDF(可选中文字)
# 数字版 PDF 优先用 pdfplumber 提取文字,
# 仅在提取失败或需要保留版式时才用 OCR
import pdfplumber
with pdfplumber.open("digital.pdf") as pdf:
for page in pdf.pages:
text = page.extract_text()
if text and len(text) > 100:
# 文字层完整,跳过 OCR
continue
else:
# 文字层缺失,需要 OCR
image = page.to_image(resolution=200).original
# ... OCR 处理
场景三:表格密集文档
Unlimited OCR 在 OmniDocBench 上的 SOTA 成绩说明它对表格有较好的理解能力,但复杂表格仍建议后处理:
# 后处理:用 Camelot/python-docx 对 OCR 输出的 Markdown 表格进行校验
import camelot
# 对比 OCR 结果与 Camelot 提取的表格,取置信度高的
tables_camelot = camelot.read_pdf("report.pdf", pages="1")
# ... 比对逻辑
八、R-SWA 的通用价值:超越 OCR
R-SWA 最令人兴奋的地方在于它的通用性。一旦把一个任务的"输入表征"当作参考序列,任何序列到序列的任务都能受益。
8.1 应用于 ASR(自动语音识别)
语音识别的本质也是"序列到序列":输入是音频特征序列(Mel-spectrogram),输出是文字序列。
标准 ASR 模型(如 Whisper)用 Transformer 解码器,长音频(比如 2 小时会议录音)的 KV Cache 同样会爆炸。
用 R-SWA:把音频编码器的输出作为"参考序列",解码器只需维护一个固定大小的滑动窗口 KV Cache,就能实现无限时长的语音转写。
8.2 应用于长文档翻译
机器翻译中,长文档翻译一直是个难题。现有方案要么截断(丢失上下文),要么分段(段落之间不连贯)。
R-SWA 可以直接把整篇文档(比如一篇 50 页的技术手册)的源语言编码结果作为参考序列,解码器生成目标语言时,随时可以"回头看"任意远的源语言句子,实现真正的全局上下文翻译。
九、总结与展望
Unlimited OCR 的核心贡献可以归纳为一句话:它找到了让端到端 OCR 模型在长文档场景下保持恒定显存占用的注意力机制。
从工程角度看,这项工作有三点重要启示:
端到端架构是 OCR 的未来。两阶段流程的信息瓶颈无法通过工程技巧彻底解决,统一神经网络架构才是正道。
KV Cache 常量化是长序列生成的关键。R-SWA 提供了一个通用范式:把"不随时间增长的参考表征"和"固定大小的滑动窗口"分开建模。
MoE 是平衡模型容量和推理效率的利器。3B 总参数、570M 激活参数的设计,让 Unlimited OCR 在保持 SOTA 性能的同时,推理成本可控。
未来方向:
- R-SWA 在更多模态(视频、多轮对话)上的验证;
- 与多维注意力机制(如 MQA、GQA)的结合;
- 面向移动端的 INT4/INT8 全量化方案;
- 支持"边识别边翻译"的多任务联合训练。
参考资料
- Yin Y, Liu H, Xie Q, et al. Unlimited OCR Works. arXiv:2606.23050, 2026.
- DeepSeek OCR Technical Report. deepseek-ai, 2025.
- OmniDocBench v1.6 Benchmark. HuggingFace, 2026.
- GitHub: https://github.com/baidu/Unlimited-OCR
- 模型权重:https://huggingface.co/baidu/Unlimited-OCR
本文撰写于 2026 年 7 月,基于 Unlimited OCR 技术报告(arXiv:2606.23050v1)及公开技术资料。代码部分为概念性还原,实际实现请以官方仓库为准。