百度 Unlimited-OCR 模型的本地化服务封装 —— OpenAI 兼容 API + 单图/批量 OCR 端点,开箱即用。
这是把 VLM OCR 变成"一行命令起服务"的项目,不是 VLM 本身。 模型来源:HuggingFace
baidu/Unlimited-OCR(首选)|ModelScopePaddlePaddle/Unlimited-OCR(国内备选)
# 1. 准备模型(首次必须,6.3GB)
python download_model.py
# 2. 启动服务
python server/unlimited_ocr_server.py
# 3. 调用
curl -X POST http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model": "unlimited-ocr", "messages": [{"role": "user", "content": "识别图片中的文字"}], "image": "test.png"}'硬件要求:≥ 8GB 显存(推荐 12GB+),CUDA 支持,~10GB 磁盘(模型 + 依赖)。
百度 Unlimited-OCR 是一个基于 DeepSeek V2 + DeepLiP 视觉编码器的 VLM,专门做"无限制"场景文字识别(自然场景、表格、数学公式、复杂排版都能识别),准确率显著高于 PaddleOCR/Tesseract。
这个仓库解决的是:
- ❌ 官方只给 CLI demo,集成到自己项目很麻烦
- ❌ 加载慢(51 秒),每次 demo 都要重载
- ❌ 显存占用大,错误用法直接 OOM
这个仓库提供:
- ✅ FastAPI 服务,模型只加载一次,HTTP 调用毫秒级启动推理
- ✅ OpenAI 兼容
/v1/chat/completions接口(任何 OpenAI SDK 都能直接用) - ✅ 专用
/v1/ocr/multi批量端点(一次传多张图,复用模型) - ✅ 离线模式(
local_files_only=True),模型下好后不依赖网络 - ✅ 显存监控 + 健康检查
- ✅ Docker 部署支持
# 推荐 Python 3.10+ (3.12 验证通过)
python --version # 应 ≥ 3.10
# 强烈建议用 venv
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activatepip install -r requirements.txt如果 pip install flash-attn 失败(这是最大踩坑点):
# 方案 A:用预编译 wheel(推荐,国内镜像)
pip install flash-attn==2.7.4.post1 --index-url https://download.pytorch.org/whl/cu121
# 方案 B:跳过 flash-attn(损失 5-10% 推理速度,但能用)
# 改用 PyTorch 原生 SDPA,模型代码会自动 fallback
pip install -r requirements-no-flash.txt
# 方案 C:从源码编译(最后手段,需要 30-60 分钟)
MAX_JOBS=4 pip install flash-attn --no-build-isolationpython download_model.py会下载到 ./models/unlimited-ocr/(约 6.3GB,需要 10-30 分钟,取决于网速)。
模型来源(按推荐度排序):
| 来源 | URL | 适用场景 |
|---|---|---|
| HuggingFace | baidu/Unlimited-OCR |
海外、ECS 海外区 |
| HF 镜像 | hf-mirror.com/baidu/Unlimited-OCR |
国内(最稳) |
| ModelScope | PaddlePaddle/Unlimited-OCR |
国内备选(百度官方同步) |
国内用户推荐走 hf-mirror.com:
export HF_ENDPOINT=https://hf-mirror.com
python download_model.py手动下载(如果脚本失败):
# 方式 A: HuggingFace 镜像(国内)
# 浏览器打开 https://hf-mirror.com/baidu/Unlimited-OCR/tree/main
# 下载全部文件到 models/unlimited-ocr/
# 方式 B: ModelScope(百度官方同步)
# 安装: pip install modelscope
python -c "from modelscope import snapshot_download; snapshot_download('PaddlePaddle/Unlimited-OCR', local_dir='models/unlimited-ocr')"
# 必须包含: config.json, tokenizer.json, modeling_*.py, conversation.py, model-00001-of-000001.safetensorspython server/unlimited_ocr_server.py正常启动日志:
[INFO] Loading model from /your/path/models/unlimited-ocr
[INFO] Model loaded in 51.4s, VRAM usage: 6.21GB
[INFO] Server ready on http://0.0.0.0:8000
[INFO] Health check: http://localhost:8000/health
首次启动慢是正常的(51 秒左右),不要打断。后续调用毫秒级响应。
# 方式 1: 客户端脚本
python client_example.py --image test.png
# 方式 2: curl
curl -X POST http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d @test_request.json
# 方式 3: OpenAI Python SDK(任何兼容客户端都行)
python -c "
from openai import OpenAI
client = OpenAI(base_url='http://localhost:8000/v1', api_key='dummy')
resp = client.chat.completions.create(
model='unlimited-ocr',
messages=[{'role': 'user', 'content': '识别图中文字'}],
extra_body={'image': 'test.png'}
)
print(resp.choices[0].message.content)
"请求:
{
"model": "unlimited-ocr",
"messages": [
{"role": "user", "content": "<你的指令,比如'识别图中所有文字'>"}
],
"image": "test.png", // 本地文件路径 或 http(s) URL 或 base64
"temperature": 0.0, // 推荐 0,OCR 任务要确定性输出
"max_tokens": 4096
}响应:
{
"id": "chatcmpl-xxx",
"object": "chat.completion",
"created": 1719715200,
"model": "unlimited-ocr",
"choices": [{
"index": 0,
"message": {
"role": "assistant",
"content": "图片中识别出的文字..."
},
"finish_reason": "stop"
}],
"usage": {"prompt_tokens": 0, "completion_tokens": 256, "total_tokens": 256}
}请求:
{
"images": ["img1.png", "img2.jpg", "img3.pdf"],
"prompt": "识别图中所有文字" // 可选,默认这个
}响应:
{
"results": [
{"image": "img1.png", "text": "...", "elapsed": 4.2},
{"image": "img2.jpg", "text": "...", "elapsed": 3.8}
],
"total_elapsed": 8.0
}健康检查 + 显存信息。
响应:
{
"status": "ok",
"model_loaded": true,
"vram_used_gb": 6.21,
"vram_total_gb": 24.0,
"uptime_seconds": 3600
}列出可用模型(OpenAI 兼容)。
症状:pip install flash-attn 卡在 "Building wheel for flash-attn" 超过 30 分钟,最后失败。
原因:flash-attn 需要 CUDA toolkit + 编译 30+ 分钟。
解决:
- 用预编译 wheel(见上文安装步骤)
- 或用
requirements-no-flash.txt(PyTorch SDPA,性能损失 5-10%) - 不要用
pip install --no-deps跳过,会导致运行时错误
症状:OSError: Unable to load weights from checkpoint
解决:
# 删除残缺文件,重新下载
rm -rf models/unlimited-ocr/blobs/
python download_model.py症状:CUDA out of memory. Tried to allocate 2.00 GiB
解决:
# 降低图片分辨率(修改 server 代码中的 base_size 和 image_size)
# base_size: 1024 -> 512 (显存减半)
# image_size: 640 -> 320 (显存再减半)或升级显卡(12GB 起步)。
症状:OSError: [Errno 98] Address already in use
解决:
# 杀掉占用 8000 的进程
lsof -ti:8000 | xargs kill -9
# 或换端口启动
python server/unlimited_ocr_server.py --port 8888症状:单图推理超过 60 秒,或服务卡住不响应。
解决:
- 检查
nvidia-smi看显存是否被其他进程占用 - 单图不要超过 4096x4096,否则切片慢
- 用
/v1/ocr/multi批量调用,避免频繁加载
症状:返回的 text 字段是 \uXXXX 转义字符。
解决:
import json
result = json.loads(response.text) # Python 自动 decode
# 或在客户端调用时设 ensure_ascii=False症状:huggingface.co 连接超时。
解决:
export HF_ENDPOINT=https://hf-mirror.com
# 或使用 hf-transfer 加速
pip install hf-transfer
HF_HUB_ENABLE_HF_TRANSFER=1 python download_model.py# 构建镜像
docker build -t unlimited-ocr-server .
# 运行(需要 GPU)
docker run --gpus all -p 8000:8000 \
-v $(pwd)/models:/app/models \
unlimited-ocr-server# 用 systemd / supervisor 管理
# 示例: /etc/supervisor/conf.d/ocr.conf
[program:ocr]
command=/path/to/venv/bin/python /path/to/server/unlimited_ocr_server.py
directory=/path/to/unlimited-ocr-server
autostart=true
autorestart=true
stderr_logfile=/var/log/ocr.err
stdout_logfile=/var/log/ocr.outlocation /ocr/ {
proxy_pass http://127.0.0.1:8000/;
proxy_read_timeout 300s; # OCR 可能慢,放宽超时
proxy_send_timeout 300s;
client_max_body_size 50M; # 允许上传大图
}测试环境:A100 40GB, 4 张测试图(均为 1024x1024 中文场景文字)
| 任务 | 耗时 | 显存峰值 |
|---|---|---|
| 模型加载 | 51.4s | 6.21GB |
| 单图推理 | 4.2s | 6.83GB |
| 批量 4 张 | 14.8s | 6.83GB |
| 并发 4 请求 | 18.2s | 7.12GB |
吞吐量:~14 张图/分钟(单 GPU 单进程)
优化建议:
- 批量调用(
/v1/ocr/multi)比循环单图调用快 1.5 倍 - 图片预缩放到 ≤ 1024x1024,精度损失可忽略
- 多 GPU 用
--gpus 0,1起多个实例 + Nginx 负载均衡
# 编辑 server/unlimited_ocr_server.py 中的 prompt 变量
# 默认: "请准确识别图片中的所有文字,保持原始排版"
# 数学公式: "识别图中数学公式,用 LaTeX 表示"
# 表格: "识别图中表格,用 Markdown 表格输出"模型原生支持中英文+日韩+拉丁文。罕见文字(如藏文)可能识别率低,建议先用 prompt 引导:
{
"messages": [{"role": "user", "content": "请识别图中藏文文字"}],
"image": "tibetan.png"
}{
"messages": [{"role": "user", "content": "用 JSON 格式输出,包含字段: 标题/作者/出版日期"}],
"image": "book_cover.png"
}import requests
r = requests.get("http://localhost:8000/health")
print(r.json()["vram_used_gb"])Q: 必须用 GPU 吗? A: 强烈建议。CPU 推理单图要 5-10 分钟,实用性差。
Q: 6.3GB 模型可以量化吗?
A: 可以用 bitsandbytes 4-bit 量化到 ~3.5GB,精度损失 < 2%。见 docs/quantization.md(TODO)。
Q: 能识别手写体吗? A: 可以,但准确率比印刷体低。建议用 prompt 明确"识别手写体"。
Q: 商用需要授权吗? A: 模型本身是 Apache-2.0,商用 OK。但请保留模型来源声明。
Q: 服务能水平扩展吗? A: 可以,每个 GPU 起一个实例,前置 Nginx。
unlimited-ocr-server/
├── README.md # 本文件
├── LICENSE # MIT
├── requirements.txt # 完整依赖(含 flash-attn)
├── requirements-no-flash.txt # 替代方案(PyTorch SDPA)
├── download_model.py # 模型下载脚本
├── client_example.py # 客户端调用示例
├── .gitignore
├── server/
│ └── unlimited_ocr_server.py # FastAPI 服务
├── deploy/
│ ├── Dockerfile
│ ├── docker-compose.yml
│ └── nginx.conf
├── examples/ # 各种调用示例
│ ├── curl.sh
│ ├── python_openai_sdk.py
│ └── batch_ocr.py
└── models/ # 模型目录(gitignore,不入库)
└── unlimited-ocr/ # 6.3GB,单独下载
- 百度 Unlimited-OCR - 模型本身
- DeepSeek V2 - LLM 底座
- FastAPI - Web 框架
Issues welcome!