RUST OCR 服务

用 Rust 写了一个中文 OCR 服务:双引擎架构,直接兼容 OpenAI Vision

核心观点

  • 中文优先:基于 PaddleOCR PP-OCRv4,内置 6624 字中文字典
  • 双引擎:R1 本地 ONNX 推理(零费用)+ R2 LLM Vision(复杂场景兜底)
  • 协议兼容:原生支持 OpenAI Vision 格式,ChatBox / Cherry Studio / LobeChat 直接接入
  • 全 Rust:单二进制部署,一个文件跑起来

正文

一、为什么要再造一个 OCR 轮子?

做 AI 应用开发的朋友应该都踩过这些坑:

  1. 开源 OCR 模型不少,跑起来却要配一堆环境。PaddleOCR 效果确实好,但 Python 依赖、CUDA 版本、模型文件路径……配环境能配一下午。
  2. 中文识别是硬伤。很多基于 Tesseract 的方案,中文准确率一言难尽,繁体字、竖排文字直接翻车。
  3. 接入成本高。现有方案大多是库级别的,要自己包 HTTP 服务、写协议适配、做并发控制。如果团队技术栈不是 Python,集成更痛苦。
  4. LLM 多模态很强,但 API 费用和隐私是问题。GPT-4V 识别手写体确实厉害,但每张图几毛钱,量大扛不住;而且数据要出域。

flint-ocr 就是针对这些痛点设计的。

二、双引擎架构:快与准,不再二选一

┌─────────────────────────────────────────────┐
│              HTTP API (Axum)                │
│    /v1/recognize    /v1/chat/completions   │
├─────────────────────────────────────────────┤
│              Pipeline 编排层                 │
│         校验 → 引擎路由 → 排序输出            │
├────────────────────┬────────────────────────┤
│   R1: PaddleEngine │   R2: LlmVisionEngine  │
│   det.onnx +       │   OpenAI / Anthropic   │
│   rec.onnx (ONNX)  │   / 自定义 API          │
│   ~120ms/图        │   ~800ms/图            │
│   零费用 · 离线     │   理解力强 · 自然语言   │
└────────────────────┴────────────────────────┘

R1 模式(默认):本地 ONNX Runtime 推理,4 核 CPU 下单图约 120ms,内存占用约 180MB。适合票据、证件、印刷体等标准场景,完全离线,零 API 费用。

R2 模式:代理转发到外部 LLM Vision API(GPT-4V / Claude / Qwen-VL 等),适合手写体、复杂排版、表格、场景文字。通过 mode=r2 查询参数切换。

一个 OcrEngine trait,两种实现,Pipeline 层完全无感知:

#[async_trait]
pub trait OcrEngine: Send + Sync {
    fn capabilities(&self) -> Capabilities;
    async fn recognize(&self, image_bytes: &[u8], mime: &str) -> Result<OcrOutput>;
}

三、最香的:零改造接入 OpenAI 生态

如果你在用 ChatBox、Cherry Studio 或者 LobeChat,配置里填上:

配置项
API Base URL http://localhost:9001/v1
Model flint-ocr-v1
API Key 留空

直接就能用。因为这些客户端本来就在调 OpenAI 的 /v1/chat/completions,而 flint-ocr 的响应格式与 OpenAI 完全同构:

{
  "id": "ocr-9f1b2c3d",
  "object": "chat.completion",
  "model": "flint-ocr-v1",
  "choices": [{
    "message": {
      "role": "assistant",
      "content": "电话 13800138000\n张伟"
    }
  }]
}

甚至还支持 SSE 流式响应,先完整 OCR,再逐字模拟打字效果,用户体验拉满。

四、快速上手:2 分钟跑起来

方式一:生产部署(推荐)

curl -sL https://github.com/kumustone/flint-ocr/releases/latest/download/flint-ocr-linux-x64.tar.gz | tar xz
cd flint-ocr-linux-x64
./run.sh

浏览器打开 http://localhost:9001/,拖拽图片即可识别。

方式二:Mock 模式(无需模型,体验 API)

cargo run --bin flint-ocr-server --no-default-features --features server,engine-mock

Python 调用示例

import requests

# R1: 专业 OCR,返回结构化数据(含文字框坐标、置信度)
with open("image.png", "rb") as f:
    res = requests.post(
        "http://localhost:9001/v1/recognize",
        headers={"Content-Type": "image/png"},
        data=f.read(),
    )
print(res.json()["text"])

# R2: OpenAI Vision 兼容模式
import base64
with open("image.png", "rb") as f:
    b64 = base64.b64encode(f.read()).decode()

res = requests.post(
    "http://localhost:9001/v1/chat/completions",
    json={
        "model": "flint-ocr-v1",
        "messages": [{
            "role": "user",
            "content": [
                {"type": "text", "text": "提取图片中的文字"},
                {"type": "image_url", "image_url": {"url": f"data:image/png;base64,{b64}"}}
            ]
        }]
    },
)
print(res.json()["choices"][0]["message"]["content"])

五、一些工程细节

Feature Gates 设计精巧

Cargo.toml 里用 feature 做了精细裁剪:

[features]
default = ["server", "engine-paddle"]
server = ["dep:axum", "dep:tower", ...]
engine-paddle = ["dep:ort", "dep:image", "dep:ndarray"]
engine-mock = []
  • 默认:server + paddle(完整服务)
  • 仅 SDK:--no-default-features --features engine-mock(嵌入你的 Rust 项目)
  • 快速体验:--no-default-features --features server,engine-mock(不用下模型)

并发与性能

  • ort::Session 通过 Arc 共享,单例驻留内存
  • CPU 密集推理用 tokio::task::spawn_blocking 包装,不阻塞异步运行时
  • Semaphore(max_parallel) 控制并发上限,避免压垮 CPU

配置热重载

支持 SIGHUP 信号触发配置重载,无需重启服务。生产环境改个参数,发信号立即生效。

零 unwrap()

代码规范:生产代码不允许 unwrap() / expect(),全部用 Result 传播。错误类型基于 thiserror,与调用方类型安全对接。

六、性能数据

环境:AMD EPYC 7B13, 4 vCPU, 8GB RAM

模式 单图耗时 内存占用 适用场景
R1 (PaddleOCR ONNX) ~120ms ~180MB 票据、证件、印刷体
R2 (GPT-4V API) ~800ms (含网络) ~50MB 手写体、复杂排版、表格

模型文件仅 15MB(det 4.7MB + rec 11MB + 字典 26KB),轻量到可以塞进容器镜像。

七、适用场景

  • 私有化部署:数据不出域,本地即可完成 OCR
  • RAG / 知识库:文档扫描件提取文字,喂给 Embedding 模型
  • LLM 客户端插件:ChatBox / Cherry Studio 用户,零配置接入
  • 票据/发票识别:R1 模式速度快、成本低
  • 复杂场景兜底:R2 模式处理手写病历、设计稿、表格等

八、写在最后

flint-ocr 目前还是 v1 阶段,已经能稳定跑通核心链路。后续计划包括 GPU 推理支持、Batch 批量处理、模型热更新、以及更多的多语言字典。

如果你也在做 OCR 相关的项目,或者在找一个轻量、中文友好、能直接接入 OpenAI 生态的本地 OCR 服务,欢迎试试 flint-ocr。

GitHub 地址:https://github.com/kumustone/flint-ocr

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐