MiniCPM-OCR
MiniCPM-V 多模态系列
MiniCPM-OCR 1.0
下面的示例需要先启动识别服务。SDK 与推理后端使用独立的 Python 环境。
整篇文档 解析
在 SDK 环境中安装解析包与 GPU 版面检测依赖:
Bash
pip install uv
uv venv .minicpm-ocr --python 3.12 --seed
source .minicpm-ocr/bin/activate
python -m pip install "minicpm-ocr[all]==1.0.2"
python -m pip install "paddlepaddle-gpu==3.3.0" \
-i https://www.paddlepaddle.org.cn/packages/stable/cu129/
minicpmvocr parse \
--device cuda:0 \
--server-url http://127.0.0.1:18499 \
--model minicpm-ocr \
--input doc.pdf \
--output doc.md
在克隆的 MiniCPM-OCR 仓库根目录运行解析命令。SDK 会检查 models/PP-DocLayoutV3_infer/ 并自动补全缺失的版面模型。输入可换为 PDF、PNG 或 JPG,输出 Markdown 中保留 HTML 表格与 LaTeX 公式。
单区域识别
已经裁剪好区域时,可直接调用兼容 OpenAI 的服务。先安装 openai,并准备 sample.png。
Bash
pip install openai
Python
import base64
from pathlib import Path
from openai import OpenAI
client = OpenAI(base_url="http://127.0.0.1:18499/v1", api_key="EMPTY")
image = base64.b64encode(Path("sample.png").read_bytes()).decode("utf-8")
response = client.chat.completions.create(
model="minicpm-ocr",
messages=[{"role": "user", "content": [
{"type": "image_url", "image_url": {"url": f"data:image/png;base64,{image}"}},
{"type": "text", "text": "Text Recognition:"},
]}],
temperature=0.01,
top_p=0.001,
max_tokens=2048,
stream=False,
)
print(response.choices[0].message.content)
print("finish_reason:", response.choices[0].finish_reason)
EMPTY 对应上述未启用鉴权的本地服务。接入带鉴权的服务时,替换为服务方提供的地址、密钥与模型 ID。若 finish_reason 为 length,应检查截断,并在服务允许的范围内增加输出预算。
| 区域类型 | 提示词 |
|---|---|
| 文字 | Text Recognition: |
| 表格 | Table Recognition: |
| 公式 | Formula Recognition: |
| 印章 | Seal Recognition: |
| 图表 | Chart to Table: |
关键信息抽取
Plain Text
Extract the "store_name", "amount". Format the output as a JSON object with keys: "store_name", "amount". If an item is not in the image, use "###".
将识别提示词替换为这段指令即可抽取字段,两处字段名应保持一致。模型返回的是文本,接入下游系统前应解析 JSON 并校验字段值。
MiniCPM-OCR Jev
启动服务后,提交裁剪区域与对应 OCR 文本。下面使用内置渲染器的 Docker 服务。
单区域评分
Python
import base64
import json
import urllib.request
from pathlib import Path
image = base64.b64encode(Path("region.png").read_bytes()).decode("utf-8")
payload = {
"input_form": "ternary",
"items": [{
"case_id": "blk-001",
"image": f"data:image/png;base64,{image}",
"ocr_text": "The OCR text to be scored",
"category": "text",
}],
}
request = urllib.request.Request(
"http://127.0.0.1:8030/v1/rm/score",
data=json.dumps(payload).encode("utf-8"),
headers={"Content-Type": "application/json"},
)
with urllib.request.urlopen(request) as response:
result = json.load(response)["results"][0]
if result["verdict"] == "scored":
print(result["prob_yes"])
else:
print(result["verdict"], result.get("detail", ""))
category 应按区域实际内容设为 text、formula 或 table。类型错误可能不会报错,但会影响分数。JPEG 图片应使用对应 MIME 前缀。