前言

最近 OCR 方向又火了起来,尤其是端到端 OCR、多模态大模型解析 PDF、图片文档、表格和长文档的能力,已经不只是“识别几个字”这么简单了。
传统 OCR 通常要经历:
图片预处理 → 版面分析 → 文本检测 → 文本识别 → 表格还原 → Markdown / JSON 后处理
而新一代文档解析模型,更倾向于直接把图片、PDF 页面输入模型,然后输出结构化文本、Markdown 或可编辑内容。
百度开源的 Unlimited-OCR 就是这类模型中的一个代表。它的定位不是普通单页 OCR,而是面向 长文档、长上下文、一次性解析、多页 PDF 的文档解析模型。
一、Unlimited-OCR 是什么?
Unlimited-OCR 是百度开源的一个文档解析模型,项目标题是 Unlimited OCR Works,官方描述是面向 One-shot Long-horizon Parsing,也就是“一次性长文档解析”。
它的核心目标可以理解为:
让 OCR 不再只能一页一页、分块分段地识别,而是尽可能在一次前向推理中解析更长的文档内容。
传统长文本 OCR:
输出越长 → KV Cache 越大 → 显存越高 → 速度越慢
Unlimited-OCR:
通过 R-SWA 控制注意力范围 → 降低长序列推理成本 → 更适合长文档解析
二、传统 OCR 与 Unlimited-OCR 有什么不同?

传统 OCR 更像一条固定流水线:
检测文字区域 → 识别文字 → 排版恢复 → 后处理
它的优点是成熟、稳定、速度快,但面对复杂版面时,经常会遇到:
- 表格结构丢失
- 段落顺序错乱
- 多栏文本识别混乱
- 图片、公式、标题层级难以还原
- 长 PDF 需要拆页、拆块处理
Unlimited-OCR 更像是“文档理解模型”:
图片 / PDF 页面 → 视觉编码器 → 多模态语言模型解码 → Markdown / 文本结果
它不仅识别文字,还尝试理解版面结构,并输出更接近可阅读、可编辑的结果。
三、技术工作流

从整体流程看,Unlimited-OCR 的处理链路可以理解为:
图片 / PDF 页面
↓
PDF 页面转图片
↓
视觉编码器提取图像与版面特征
↓
R-SWA 控制长上下文注意力
↓
语言模型生成 Markdown / 文本
↓
结果保存、入库、检索或进入 RAG
其中比较关键的是 R-SWA。它的目标是降低长文档解析时的注意力计算压力,让模型在长序列输出时更稳定。
四、模型基本信息
| 项目 | 内容 |
|---|---|
| 模型名称 | baidu/Unlimited-OCR |
| 任务类型 | Image-Text-to-Text |
| 框架 | Transformers |
| 权重格式 | Safetensors |
| 许可证 | MIT |
| 模型规模 | 约 3B 参数 |
| 上下文长度 | 32768 |
| 典型输出 | 文本 / Markdown |
| 主要能力 | 图片 OCR、多页解析、PDF 解析、长文档解析 |
| 推理方式 | Transformers、vLLM、SGLang、Docker |
五、环境准备
1. 推荐环境
建议使用 Linux + NVIDIA GPU 环境:
操作系统:Ubuntu 22.04 / 24.04
Python:3.12
GPU:NVIDIA 显卡
CUDA:按本机驱动选择
显存:建议 8GB 以上起步,生产环境越大越好
2. 创建虚拟环境
mkdir unlimited-ocr-demo
cd unlimited-ocr-demo
python3 -m venv .venv
source .venv/bin/activate
pip install -U pip setuptools wheel
如果你使用的是 Windows,也建议通过 WSL2 Ubuntu 来跑,尤其是涉及 GPU、CUDA、vLLM 时,Linux 环境会少很多坑。
六、安装依赖
先安装基础依赖:
pip install transformers accelerate safetensors pillow pymupdf requests
然后根据自己的 CUDA 版本安装 PyTorch。
示例:
pip install torch torchvision --index-url https://download.pytorch.org/whl/cu121
如果你是 CUDA 12.4、12.6 或 12.9,需要根据 PyTorch 官方提供的 wheel 版本来选择。
七、使用 Transformers 进行单图 OCR
import os
import torch
from transformers import AutoModel, AutoTokenizer
MODEL_NAME = "baidu/Unlimited-OCR"
OUTPUT_DIR = "./ocr_outputs"
os.makedirs(OUTPUT_DIR, exist_ok=True)
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()
image_path = "your_image.jpg"
model.infer(
tokenizer,
prompt="<image>document parsing.",
image_file=image_path,
output_path=OUTPUT_DIR,
base_size=1024,
image_size=640,
crop_mode=True,
max_length=32768,
no_repeat_ngram_size=35,
ngram_window=128,
save_results=True,
)
print("OCR 完成,结果已保存到:", OUTPUT_DIR)
这里有几个关键点:
| 参数 | 说明 |
|---|---|
trust_remote_code=True | 允许加载模型仓库中的自定义代码 |
prompt="<image>document parsing." | 提示词必须带 <image> |
base_size=1024 | 图像基础尺寸 |
image_size=640 | 单图模式下的图像尺寸 |
crop_mode=True | 开启裁剪模式 |
max_length=32768 | 最大生成长度 |
no_repeat_ngram_size=35 | 减少重复生成 |
ngram_window=128 | 单图推荐窗口 |
八、PDF 解析:先转图片,再多页识别

很多实际业务不是识别单张图片,而是识别 PDF,比如:
- 合同 PDF
- 招投标文件
- 扫描报告
- 论文
- 产品手册
- 发票合集
- 舆情材料汇编
Unlimited-OCR 的常见做法是:
PDF → 每页转成 PNG 图片 → 多页图片一起输入模型 → 输出 Markdown / 文本
下面是完整示例:
import os
import tempfile
import fitz
import torch
from transformers import AutoModel, AutoTokenizer
MODEL_NAME = "baidu/Unlimited-OCR"
PDF_PATH = "your_doc.pdf"
OUTPUT_DIR = "./pdf_ocr_outputs"
os.makedirs(OUTPUT_DIR, exist_ok=True)
def pdf_to_images(pdf_path: str, dpi: int = 300):
"""
将 PDF 每一页转成 PNG 图片
:param pdf_path: PDF 文件路径
:param dpi: 渲染清晰度,300 比较适合 OCR
:return: 图片路径列表
"""
doc = fitz.open(pdf_path)
tmp_dir = tempfile.mkdtemp(prefix="pdf_ocr_")
matrix = fitz.Matrix(dpi / 72, dpi / 72)
image_paths = []
for page_index, page in enumerate(doc):
image_path = os.path.join(
tmp_dir,
f"page_{page_index + 1:04d}.png"
)
pix = page.get_pixmap(matrix=matrix)
pix.save(image_path)
image_paths.append(image_path)
doc.close()
return image_paths
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()
image_files = pdf_to_images(PDF_PATH, dpi=300)
model.infer_multi(
tokenizer,
prompt="<image>Multi page parsing.",
image_files=image_files,
output_path=OUTPUT_DIR,
image_size=1024,
max_length=32768,
no_repeat_ngram_size=35,
ngram_window=1024,
save_results=True,
)
print("PDF OCR 完成,输出目录:", OUTPUT_DIR)
九、vLLM 部署方式
如果只是本地测试,Transformers 方式已经够用。
但如果你想把 Unlimited-OCR 做成一个服务,比如:
前端上传 PDF → 后端调用 OCR 服务 → 返回 Markdown → 存入数据库 / 知识库
那就需要 vLLM 或 SGLang 这类推理服务框架。
1. 拉取 vLLM 镜像
默认 CUDA 13.0 镜像:
docker pull vllm/vllm-openai:unlimited-ocr
Hopper GPU / CUDA 12.9 镜像:
docker pull vllm/vllm-openai:unlimited-ocr-cu129
2. 启动 vLLM 服务
docker run --rm \
--gpus all \
--network host \
--ipc host \
vllm/vllm-openai:unlimited-ocr \
baidu/Unlimited-OCR \
--trust-remote-code \
--logits_processors vllm.model_executor.models.unlimited_ocr:NGramPerReqLogitsProcessor \
--no-enable-prefix-caching \
--mm-processor-cache-gb 0
3. Python 客户端调用
from openai import OpenAI
client = OpenAI(
api_key="EMPTY",
base_url="http://localhost:8000/v1",
timeout=3600
)
messages = [
{
"role": "user",
"content": [
{
"type": "text",
"text": "<image>document parsing."
},
{
"type": "image_url",
"image_url": {
"url": "file:///data/test.jpg"
}
}
]
}
]
response = client.chat.completions.create(
model="baidu/Unlimited-OCR",
messages=messages,
max_tokens=8192,
temperature=0.0,
extra_body={
"skip_special_tokens": False,
"vllm_xargs": {
"ngram_size": 35,
"window_size": 128
}
}
)
print(response.choices[0].message.content)
十、SGLang 部署方式
除了 vLLM,也可以使用 SGLang 部署 Unlimited-OCR。
python -m sglang.launch_server \
--model baidu/Unlimited-OCR \
--served-model-name Unlimited-OCR \
--attention-backend fa3 \
--page-size 1 \
--mem-fraction-static 0.8 \
--context-length 32768 \
--enable-custom-logit-processor \
--disable-overlap-schedule \
--skip-server-warmup \
--host 0.0.0.0 \
--port 10000
SGLang 更适合你想做高性能推理、自定义调度、自定义服务端参数的场景;vLLM 更适合想快速做 OpenAI API 兼容服务的场景。
十一、生产系统架构建议

如果要把 Unlimited-OCR 接入企业系统,可以参考下面的架构:
上传文件 → 对象存储 → OCR 任务队列 → 推理服务 → 结果入库 → 检索 / RAG / 人工校验
这种设计的好处是:
- OCR 服务和业务系统解耦
- 文件可以异步处理
- 失败任务可以重试
- 结果可以全文检索
- 后续可以接入 RAG、知识库、智能问答
十二、参数速查表

| 场景 | 推荐方式 | 关键参数 |
|---|---|---|
| 单张图片 | model.infer | image_size=640、crop_mode=True、ngram_window=128 |
| 多页图片 | model.infer_multi | image_size=1024、ngram_window=1024 |
| PDF 文件 | PDF → PNG → infer_multi | dpi=200~300、max_length=32768 |
| 服务部署 | vLLM / SGLang | OpenAI API、自定义 logits processor |
十三、常见问题
1. 为什么必须加 trust_remote_code=True?
因为 Unlimited-OCR 使用了自定义模型结构,不是 Transformers 内置的普通模型类。加载时需要允许执行模型仓库里的自定义 Python 代码。
注意:这也意味着你应该只对可信来源使用 trust_remote_code=True。
2. 为什么输出为空?
常见原因有几个:
| 问题 | 解决办法 |
|---|---|
prompt 没有 <image> | 必须使用 <image>document parsing. |
没有设置 skip_special_tokens=False | vLLM 调用时需要设置 |
| 没有传 ngram 参数 | 设置 ngram_size=35 |
| 多页 PDF 仍用单图窗口 | 多页建议 window_size=1024 |
| 图片路径错误 | 检查文件是否存在 |
| 显存不足 | 降低页数、降低 DPI、换更大显卡 |
3. PDF 识别很慢怎么办?
可以从几个方向优化:
1. 降低 PDF 转图片 DPI
2. 控制单次输入页数
3. 使用 vLLM / SGLang 服务化
4. 做任务队列异步处理
5. 多 GPU 并发处理不同文件
6. 结果落库,避免重复 OCR
如果是生产系统,不建议用户上传后直接阻塞等待,可以采用:
上传文件 → 生成任务 ID → 后台 OCR 队列 → 推理服务 → 结果入库 → 前端轮询 / WebSocket 通知
十四、适合落地的业务方向
Unlimited-OCR 不只是一个 Demo 模型,实际可以尝试落地到很多系统中。
1. 企业文档解析
合同、报告、扫描件、内部制度、项目文档
解析成 Markdown 后,可以进入知识库。
2. 招投标文档解析
标书 PDF → OCR → 章节结构 → 关键字段抽取 → 风险提示
适合政企项目、采购系统。
3. 舆情材料入库
截图 / PDF / 网页打印件 → OCR → 结构化文本 → Elasticsearch 检索
适合舆情系统、网信系统、内容审核系统。
4. RAG 知识库构建
PDF → Markdown → 分块 → Embedding → 向量库 → 智能问答
这是目前大模型应用中非常常见的一条链路。
十五、总结
Unlimited-OCR 的价值不只是“识别文字”,而是把 OCR 往 长文档解析、Markdown 生成、结构化理解、知识库构建 方向推进了一步。
它比较适合:
- 多页 PDF 解析
- 扫描文档识别
- 文档转 Markdown
- 企业知识库建设
- OCR + RAG 应用
- 文档智能处理平台
如果你正在做文档解析、知识库、智能办公、PDF 结构化、合同识别或 OCR 服务化,Unlimited-OCR 非常值得测试。
65

被折叠的 条评论
为什么被折叠?



