ByteNoteByteNote

字节笔记本

2026年8月28日

Ollama 跑 glm-ocr:本地 OCR 不用上传

API中转
¥120

合同扫描件、发票、带公式的论文页,很多云 OCR 一传上去就出了本机。Ollama 现在直接收了智谱这套 GLM-OCR:本机 ollama pull glm-ocr,图留在硬盘上,识别也在 localhost。

它到底能认什么

GLM-OCR 是面向复杂文档的多模态 OCR,不是「拍个路牌读几个字」那种通用视觉模型。官方定位是文档理解:印刷和手写、表格结构、公式、印章、代码块、再按提示吐结构化结果。

架构上它走 GLM-V 的 encoder–decoder:CogViT 视觉编码器、轻量跨模态连接器,再加上约 0.5B 的 GLM 解码器,合计大约 0.9B 参数。完整流水线还会先用 PP-DocLayout-V3 做版面分析,再并行认各个区域。Ollama 这条路径把模型本身跑在本机,版面那一步要完整 SDK 才有。

发布时它在 OmniDocBench V1.5 拿到 94.62,总分第一。这是他们自己报的基准,本地效果还是以你手头的扫描件为准。

许可证分两块:模型权重 MIT,仓库代码 Apache-2.0

规格速览

参数量约 0.9B
Ollama 标签glm-ocr:latest(2.2GB)、glm-ocr:q8_0(1.6GB)、glm-ocr:bf16(2.2GB)
上下文官方库页写 128K,文本 + 图像
输入PNG / JPG,官方 SDK 还能吃 PDF
输出纯文本、Markdown、按提示的 JSON
语言中英为主,文档还列了法、西、俄、德、日、韩等

机器只要能跑普通本地模型就够。CPU 也能转,慢一些。

安装和拉取

先装 Ollama。macOS / Linux 常见装法:

bash
curl -fsSL https://ollama.com/install.sh | sh
ollama --version

然后拉模型(官方部署文档用的是带 tag 的名字):

bash
ollama pull glm-ocr:latest
ollama list

服务一般会自己起来,默认听 http://localhost:11434。没有的话:

bash
ollama serve

库页上也写了 ollama run glm-ocr,和 glm-ocr:latest 是同一条。磁盘紧就换成 glm-ocr:q8_0

终端里直接认图

Ollama 库页给了三种提示,路径换成你自己的图:

bash
ollama run glm-ocr Text Recognition: ./scan.png
ollama run glm-ocr Table Recognition: ./table.png
ollama run glm-ocr Figure Recognition: ./chart.png

终端里也能把图片拖进去。提示词写清楚任务,比只丢一句「OCR 一下」稳:发票就说「抽字段,按 JSON 输出」;论文页就说「公式用 LaTeX,正文用 Markdown」。

用原生 API 脚本化

官方 Ollama 部署说明写得很死:视觉请求走他们的 OpenAI 兼容口(/v1/chat/completions)容易不稳,甚至直接 502。脚本请打原生 /api/generate,图片用 base64 放进 images

bash
IMG_B64=$(base64 -w0 ./scan.png)

curl http://localhost:11434/api/generate -d "{
  \"model\": \"glm-ocr:latest\",
  \"prompt\": \"Text Recognition: 把图中文字按阅读顺序输出为 Markdown。表格用 Markdown 表格。\",
  \"images\": [\"${IMG_B64}\"],
  \"stream\": false
}"

要固定 JSON 结构,加上 "format": "json",并在 prompt 里把字段写死:

bash
curl http://localhost:11434/api/generate -d "{
  \"model\": \"glm-ocr:latest\",
  \"prompt\": \"从这张发票提取 seller、buyer、total、date,只输出 JSON。\",
  \"images\": [\"${IMG_B64}\"],
  \"format\": \"json\",
  \"stream\": false
}"

Python 里同样走 generate,不要默认去调 chat completions:

python
import base64
import json
import urllib.request

with open("scan.png", "rb") as f:
    img = base64.b64encode(f.read()).decode()

payload = {
    "model": "glm-ocr:latest",
    "prompt": "Table Recognition: 把表格转成 Markdown。",
    "images": [img],
    "stream": False,
}

req = urllib.request.Request(
    "http://localhost:11434/api/generate",
    data=json.dumps(payload).encode(),
    headers={"Content-Type": "application/json"},
)
print(json.load(urllib.request.urlopen(req))["response"])

第一次请求要等模型装进内存。官方 SDK 把超时放到 300 秒,自己写脚本也别把超时设成 10 秒。

接到官方 SDK(要版面分析时)

只认单张图,上面的 CLI / API 就够。整本 PDF、先切栏再认、要 Markdown + 版面 JSON 一起出,用仓库里的 SDK,后端仍指向本机 Ollama。

bash
pip install "glmocr[selfhosted]"

config.yaml 关键几项(摘自官方 Ollama 部署说明):

yaml
pipeline:
  maas:
    enabled: false
  ocr_api:
    api_host: localhost
    api_port: 11434
    api_path: /api/generate
    model: glm-ocr:latest
    api_mode: ollama_generate

api_mode: ollama_generate 不能省,SDK 靠它把内部的 OpenAI 风格请求转成 Ollama 的 generate 格式。然后:

bash
glmocr parse ./scan.png --config config.yaml --output ./results/
python
from glmocr import GlmOcr

with GlmOcr(config_path="config.yaml") as parser:
    result = parser.parse("scan.png")
    print(result.markdown_result)
    result.save(output_dir="./results")

高并发或要吃完整 PDF 流水线,官方更推荐 vLLM / SGLang 自托管。Ollama 适合本机和 CPU。

几个容易踩的坑

  1. 走错接口。 报 502、空响应、图像被吃掉,先确认打的是 /api/generate,不是 /v1/chat/completions
  2. 上下文不够。 有人默认 num_ctx 还停在 4096,大图会直接崩。请求里把 options.num_ctx 拉到 16384 或更高再试。
  3. Ollama 太旧。 这个模型对运行时有要求,很老的版本 pull 可能 412。先 ollama --version,不行就升级。
  4. 和云端 API 别混。 docs.z.ai 的 GLM-OCR 是托管 layout_parsing,要 key,文件会出本机。本地这条不走那套计费。

文档和仓库

日常扫合同、发票、笔记,本机一条 ollama pull 就够用。要整份 PDF 的版面和 Markdown,再把 SDK 指到同一条本地 generate 接口。

分享: