Indra OCR 实测:1M 参数的本地 OCR 很香,但我被模型下载卡了两回
写这篇的时候是 2026 年 10 月。Indra OCR 刚发布没几天(10 月 13 日),我拿它想给自己写的一个本地求职记录工具加「截图识别岗位」功能。工具本身挺香,但环境和模型下载前前后后把我卡了两回——先是国内网络下不动,下完了又发现中文一个字都识别不出来。记录下来给后面想尝鲜的朋友避坑。
为什么是它
我在做一个纯本地的求职记录小工具(HTML + Python 本地服务),想加一个功能:用户把 BOSS 直聘的岗位截图扔进来,自动识别出公司名、岗位、薪资、工作地点,省得手打。
需求很明确:
- 本地跑,截图不能传云,隐私;
- 中文识别要准,岗位卡片全是中文;
- 轻量,不想为了个 OCR 装 1GB 的 PyTorch;
之前考虑过的几个方案:
| 方案 | 问题 |
|---|---|
| Tesseract | 中文准确率拉胯,排版稍乱就不行 |
| PaddleOCR | 准是准,但一上来就一堆依赖,动辄几个 G |
| 云端 OCR(百度/阿里) | 要 API Key、要联网、截图传出去 |
然后刷到了 Datalab 发的 Indra OCR,几个数字一下抓住我:
- 1M 参数的小模型;
- 不依赖 PyTorch,走 onnxruntime;
- CPU 上号称 49 页/秒,单页延迟 ~230ms;
- 支持中文简繁;
- 输出不只是文字,还有排版块、坐标框、阅读顺序,可以直接给 markdown。
这几乎是为我这种小工具量身定做的。装!
快速上手
安装本身很简单:
pip install indra-ocr
装完后依赖列出来一看,心里踏实了——onnxruntime、opencv-headless、pypdfium2、huggingface_hub,没有 PyTorch、没有 TensorFlow。整个包轻得不像话。
Python API 也很直接:
import indra_ocr
conv = indra_ocr.load() # 第一次会下载模型
for idx, page in conv.convert("job_card.png"):
for line in page.lines:
print(line.text)
注意:convert() 返回的是生成器,每个元素是 (索引, Page) 元组,不是直接拿 Page 对象。我一开始按官方文档写 for page in conv.convert(...),报 'tuple' object has no attribute 'markdown',翻了半天才发现要解包。
到这里一切都很美好。然后真正的坑开始了。
坑一:pip 装完了,python 找不到模块
第一条报错:
ModuleNotFoundError: No module named 'indra_ocr'
我当时是在一个带沙箱的命令行环境里跑的,pip install 装到了系统的 Python313,但直接敲 python 调用的是沙箱自带的另一个 Python。两个 Python 不是一个家,pip 装的东西自然找不到。
排查方法很简单:
(Get-Command python).Source
(Get-Command pip).Source
一看路径对不上就明白了。解决办法是用系统 Python 的完整路径跑脚本:
& "C:\Users\xxx\AppData\Local\Programs\Python\Python313\python.exe" your_script.py
教训:在带沙箱/虚拟环境的机器上,pip 和 python 不一定是同一个环境。装完包第一时间 python -c "import 包名" 验证一下,别着急往下走。
坑二:模型下载,才是真的地狱
indra_ocr.load() 第一次运行要从 HuggingFace 拉模型。我以为这事儿 30 秒能搞定,结果:
第一轮:直连 huggingface.co
ConnectTimeout: [WinError 10060] 连接方在一段时间后没有正确答复
国内网络直连 HuggingFace,懂的都懂。
第二轮:换 hf-mirror 镜像
设了环境变量:
$env:HF_ENDPOINT="https://hf-mirror.com"
小文件 HEAD 请求开始疯狂重试,大文件走的是 HuggingFace 的 xethub CDN(cas-server.xethub.hf.co),这个域名镜像站没覆盖,直接 401。也就是说镜像能帮你下元数据和小文件,但真正的模型权重文件它绕不过去。
后来我让有代理的流程帮忙下了 5 个基础文件(det.onnx、rec.onnx、order.onnx、lm.npz、meta.json)到本地目录 D:\models\indra-ocr\,设环境变量 INDRA_OCR_MODEL_DIR=D:\models\indra-ocr 绕开在线下载。
模型加载是成功了,1.9 秒。但跑识别一看——中文全没了。
坑三:中文一个字都识别不出来
这是最坑的。我拿一张清晰的中文测试图去识别,结果:
Javast
18-20K
4 5-10
XXX 09:00-18:00
英文和数字都对,中文汉字一个都没有。
我翻了 indra_ocr 的源码(pipeline.py)才搞明白:Indra 的识别器是分脚本组的,基础包只带拉丁字母识别器(rec.onnx),中文需要单独的三个文件:
| 文件 | 作用 | 大小 |
|---|---|---|
script.onnx | 脚本分类器,判断每行是中文还是英文 | 191KB |
rec_cjk.onnx | 中文识别器 | 10.2MB |
lm_cjk.npz | 中文语言模型(beam search 用) | 19MB |
这三个文件在 HuggingFace 仓库里有,但默认下载列表里没列全。我用 huggingface_hub 库走镜像把它们补下到模型目录后,重新跑:中文全部正确。
教训:Indra 的多语言是"基础包 + 语言包"模式,不是一个模型包打天下。要用中文,除了基础的 5 个文件,还得手动补 script.onnx、rec_cjk.onnx、lm_cjk.npz 这三个 CJK 专用文件。
最终集成效果
补全模型后,我把 OCR 接口接进了本地工作台:
- 后端
POST /api/ocr:接收截图 → indra_ocr 识别 → 返回文本 - 前端「📷 截图录入」按钮:上传 BOSS 岗位卡片截图 → 自动正则提取公司、岗位、薪资、地点、学历、HR → 打开新增表单预填
实测 BOSS 移动端岗位卡片截图识别结果:
公司、岗位、薪资、地点、学历、HR 全部识别出来,正则提取后自动填进表单,省得手打。
和老方案对比一下
官方 benchmark 里的数据,我搬过来结合自己感受说:
| 维度 | Indra OCR | Tesseract | PaddleOCR PP-Structure |
|---|---|---|---|
| 单页耗时 | ~230ms | ~5500ms | ~41000ms |
| 依赖大小 | 轻(onnxruntime) | 中 | 重(含 PyTorch) |
| 中文支持 | ✅ 简繁(需补 CJK 模型) | 一般 | ✅ |
| 布局/表格识别 | ✅ | ❌ | ✅ |
| 输出 markdown | ✅ | ❌ | 部分 |
| CPU 友好 | ✅ | ✅ | 一般 |
| 国内模型下载 | 难(需手动补文件) | 一般 | 一般 |
看表格 Indra 几乎全赢,但这个"赢"是建立在你把模型文件凑齐的前提上。下不下来、文件没补全,再好也白搭。
它不适合什么
客观说几个局限:
- 手写体识别基本不行(官方自己说的,8% 左右);
- 复杂表格(多级表头、合并单元格)结构会乱;
- 阿拉伯文、泰文、日文假名这些在图片 OCR 模式下不支持,只能处理数字 PDF 的文本层——但中文在支持列表里,我们不受影响;
- 多语言要补对应模型文件,不是开箱即用;
- 太新了(我写这篇时才发布 10 天),API 可能变,遇到问题只能去 GitHub 提 issue。
总结
Indra OCR 是我最近见过的最适合塞进个人小工具的 OCR:轻、快、中文好、输出结构化,不绑架你的环境。如果你在做本地笔记、文档解析、截图提取这类小项目,它值得一试。
但现在(2026 年 10 月)有两个坑要提前知道:
- 国内网络下模型难:huggingface.co 直连超时,hf-mirror 镜像大文件走 xethub CDN 401。建议挂代理一次性下完,或者手动从镜像把文件拉到本地目录,用
INDRA_OCR_MODEL_DIR指定; - 中文要补 CJK 模型:基础包只有拉丁识别器,中文需要额外下
script.onnx、rec_cjk.onnx、lm_cjk.npz三个文件,放同一个目录里。
凑齐文件后就是纯本地离线工具,截图识别岗位、文档提取文字都很香。
标签:OCR、Python、本地部署、开源工具、Indra、中文识别