Unlimited-OCR 实战:百度开源 23K Star 长文档解析模型,把 DeepSeek-OCR 又推进一步

一个开源 OCR 模型,发布不到两个月,GitHub 星标冲到 23.5K,复刻数超过 2400,连 vLLM、SGLang 都主动出适配镜像。在多数人眼里,OCR 是早就卷到头的成熟赛道:扫描件转文字、票据识别、证件提取,传统方案跑了十几年,手机系统甚至自带。可百度 2026 年 6 月开源的 Unlimited-OCR,硬是在这条赛道上又撕开了一个口子,官方口号叫 one-shot long-horizon parsing,一次推理啃完一整份长文档。这篇文章从它解决什么问题讲起,把本地推理、PDF 批处理、服务化部署和踩坑点一次说清。

为什么 OCR 还要再做一个模型

传统 OCR 工具链处理一份几十页的扫描 PDF,走的是分页识别加后处理拼接的路子:每页先做版面分析,找出文字、表格、图片区域,再逐块识别,最后按坐标重排。这套流程在单页票据、身份证上表现稳定,一旦遇到整本论文、技术手册、财报年报,问题就暴露出来。一是分页之间没有上下文,前一页的表格栏位和下一页的内容对不上;二是双栏排版、跨页表格、公式混排这类复杂版式,规则引擎很难还原原始阅读顺序;三是输出只有孤立的文本块,丢掉了文档结构,后续做知识库入库还要自己写一堆清洗逻辑。

Unlimited-OCR 换了一条思路:把整页甚至整份文档作为输入交给大模型,让模型自己理解版面、表格、公式和阅读顺序,直接输出接近原始排版的 markdown 结构。这个方向的代表作是 DeepSeek-OCR,而 Unlimited-OCR 的目标就是把它再推进一步:上下文窗口做到 32768,支持多页图片连续解析,还内置了 ngram 去重机制压制长文档里最容易出现的重复输出。

本地跑起来:transformers 是最快路径

先不用管服务化,本地验证效果最直接的方式是 transformers 加载模型。官方 README 给了完整的依赖清单,核心就几个:torch、transformers、Pillow、pymupdf 负责 PDF 转图,einops 和 addict 是模型内部依赖。环境建议 Python 3.12 加 CUDA 12.9,显存至少 16G,因为默认用 bfloat16 加载。

python 复制代码
import torch
from transformers import AutoModel, AutoTokenizer

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()

model.infer(
    tokenizer,
    prompt='<image>document parsing.',
    image_file='your_image.jpg',
    output_path='your/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,
)

这里有个细节值得注意:infer 内部会自动处理图片缩放和裁剪,返回的结果会保存到 output_path 目录,包含识别出的 markdown 文本。第一次运行会从 Hugging Face 下载模型权重,几个 G 的体量,建议提前配好镜像加速。

两种图像配置:gundam 还是 base

单张图片推理时,官方提供了两套图像配置,参数不同,适用场景也不同。

配置 适用场景 图片尺寸 裁剪模式 ngram 窗口
gundam 单页文档、清晰扫描件 640 开启 128
base 多页 PDF、整份文档 1024 关闭 1024

选择逻辑很简单:只处理一张图,用 gundam,速度快、省显存;要处理多页或者整本 PDF,必须切到 base,否则长文本容易丢上下文。官方明确说明多页解析只支持 base 配置,这是硬约束,不是建议。

多页 PDF:先转图,再一次性解析

处理 PDF 时,模型不直接读 PDF 文件,需要先用 PyMuPDF 把每一页渲染成图片,再交给 infer_multi 做多页连续解析。官方示例里把这一步封装成了函数,300 dpi 是推荐的渲染精度,太低会丢细节,太高只是白白增加内存。

python 复制代码
import os, tempfile, fitz

def pdf_to_images(pdf_path, dpi=300):
    doc = fitz.open(pdf_path)
    tmp_dir = tempfile.mkdtemp(prefix='pdf_ocr_')
    mat = fitz.Matrix(dpi / 72, dpi / 72)
    paths = []
    for i, page in enumerate(doc):
        out = os.path.join(tmp_dir, f'page_{i+1:04d}.png')
        page.get_pixmap(matrix=mat).save(out)
        paths.append(out)
    doc.close()
    return paths

model.infer_multi(
    tokenizer,
    prompt='<image>Multi page parsing.',
    image_files=pdf_to_images('your_doc.pdf', dpi=300),
    output_path='your/output/dir',
    image_size=1024,
    max_length=32768,
    no_repeat_ngram_size=35, ngram_window=1024,
    save_results=True,
)

infer_multi 和 infer 的差别在于输入从单张图变成图片列表,模型会把多页内容当作一个连续序列解析,页码之间的表格、脚注、章节标题都能保持连贯。这是传统分页 OCR 做不到的。

服务化部署:vLLM 与 SGLang

本地验证通过之后,要接入业务就要起服务。官方同时给了 vLLM 和 SGLang 两条路线,都是 OpenAI 兼容接口,切换成本很低。

部署方式 镜像/安装 接口 适合场景
vLLM docker pull vllm/vllm-openai:unlimited-ocr OpenAI 兼容 生产环境、GPU 集群
SGLang 本地 wheel + uv 安装 OpenAI 兼容、流式 高吞吐批处理

vLLM 路线最简单,拉官方镜像就能起服务,Hopper 显卡用 cu129 版本,其余用默认版本。SGLang 路线更灵活,支持流式输出,适合做批量任务,但需要先安装本地 wheel 再固定 kernels 版本,环境要求更高。两条路线都要求显存能装下模型,16G 起步比较稳。

批量处理:一行命令跑整个目录

仓库里自带的 infer.py 把 SGLang 服务启动和并发请求封装到了一起,处理图片目录或者整本 PDF 都只要一条命令。

shell 复制代码
# 处理整个图片目录,8 并发
python infer.py \
    --image_dir ./examples/images \
    --output_dir ./outputs \
    --concurrency 8 \
    --image_mode gundam

# 处理整本 PDF
python infer.py \
    --pdf ./examples/document.pdf \
    --output_dir ./outputs \
    --concurrency 8 \
    --image_mode gundam

concurrency 参数控制并发请求数,显存够的情况下调高能明显提速。注意 infer.py 默认假设模型在 Hugging Face 上可以访问,离线环境要先用 --model_dir 指定本地模型路径。

评估长文档解析:OmniDocBench 的坑

官方用 OmniDocBench 做基准评估,但直接拿原始输出跑分数会偏低,因为输出里带着坐标标记。模型解析时会输出类似 det 标记的结构化标签,包含每个文本块的类别和坐标,评估前必须用官方提供的 remove_det 函数把这些标记剥掉,把属于同一块的行合并、不同块之间用空行分隔,才能得到干净的文本去比分数。

这个后处理细节很容易被忽略,社区里不少复现分数对不上,一半原因就是少了这步清洗。

踩坑清单与使用建议

把实践中的几个关键点汇总一下。

现象 解法
依赖版本不匹配 导入报错或推理崩溃 严格按 README 的版本装:torch 2.10、transformers 4.57
显存不足 加载即 OOM 换 gundam 配置、降低并发,或改 bf16 加载
PDF 转图太糊 识别率明显下降 dpi 提到 300,关闭压缩渲染
输出重复文本 长文档出现整段重复 调大 no_repeat_ngram_size 或 ngram_window
评估分数偏低 与官方数字对不上 先跑 remove_det 后处理再比对
离线部署失败 拉不到模型权重 先手动下载,--model_dir 指向本地目录

整体判断:如果你只需要偶尔识别几张票据,传统 OCR 和在线 API 足够;如果业务里是整本论文、合同、技术手册这类长文档,并且需要保留表格结构和阅读顺序,Unlimited-OCR 是目前开源方案里最值得试的那一个。它把长文档解析从流水线工程变成了一个模型调用,接入成本远低于自己拼一套版面分析加表格重建的链路。

最后提醒一句:模型还在快速迭代,官方仓库的 Release 更新很频繁,vLLM、SGLang 的适配也在跟进,上手前先看一遍 README 的 Release 列表,别拿旧教程的依赖版本直接套。

相关推荐
9i编程1 小时前
AI 只解决眼前那个坑【下篇】:写进skills了,重建还是踩坑
人工智能·openai·ai编程
蒟蒻的贤1 小时前
AG-news分类任务
人工智能·分类·数据挖掘
vivo互联网技术1 小时前
从一键检测到 AI 修复:我们如何把无障碍检查做进研发流程
前端·人工智能
珐恩AI-人工智能1 小时前
生成式引擎优化(GEO)全解:2026年AI检索时代企业长效流量运营方法论
大数据·人工智能·产品运营·流量运营·geo优化
圈圈的AI工程笔记1 小时前
+14.6%超越Opus 4.8,阿里通义发现:最好的GUI Agent,有一半时间在敲命令行
人工智能
桃西西呀1 小时前
读懂 Harbor 前,先背下这 6 个词
人工智能
ppwangGS1 小时前
我的AI应用实践之路:从工作流到智能体(系列规划与第一篇)
人工智能·ai·学习方法
花生智源1 小时前
Java集成Milvus向量数据库完整教程——从Docker部署到生产级混合检索
人工智能
贵慜_Derek1 小时前
vLLM-07|MegaMoE 与 FusedMoE:路由相同,算 expert 完全不同
人工智能·算法·llm