news 2026/2/28 7:36:41

Chandra OCR实战:Docker Compose编排chandra-ocr+FastAPI服务

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Chandra OCR实战:Docker Compose编排chandra-ocr+FastAPI服务

Chandra OCR实战:Docker Compose编排chandra-ocr+FastAPI服务

1. 为什么你需要一个“懂排版”的OCR

你有没有遇到过这样的场景:

  • 扫描了一堆合同、试卷、带表格的PDF,想直接导入知识库,结果复制粘贴全是乱码和错位?
  • 用传统OCR识别数学公式,出来的是一串看不懂的LaTeX乱码,还得手动重写?
  • 表单里的复选框、手写签名、多栏排版,在识别后全被压成一行文字,结构信息彻底丢失?

Chandra 就是为解决这些问题而生的。它不是又一个“把图变字”的OCR,而是真正理解文档“布局”的视觉语言模型——能一眼看出哪是标题、哪是表格、哪是公式区域、哪是手写批注,并原样保留这些结构信息,直接输出可编辑、可嵌入、可检索的 Markdown。

更关键的是,它不挑硬件。一张 RTX 3060(12GB显存)、甚至带4GB显存的入门级显卡,就能跑起来;不用调参、不用训练,下载即用;输出不是一堆零散文本,而是开箱即用的结构化内容——这才是真正面向工程落地的OCR。

下面我们就用 Docker Compose,把 chandra-ocr 和 FastAPI 服务一起编排起来,做成一个稳定、可复用、支持批量上传的本地OCR API服务。

2. 快速上手:三步完成本地部署

整个部署过程不需要碰任何Python环境配置,也不用担心CUDA版本冲突。我们全程用容器化方式,干净、隔离、可复现。

2.1 准备工作:确认你的机器支持

  • 操作系统:Linux(Ubuntu 22.04 / Debian 12 推荐)或 macOS(Intel/M系列芯片均可,M系列需启用Rosetta兼容模式)
  • GPU:NVIDIA显卡(驱动 ≥535),推荐显存 ≥4GB(RTX 3050/3060/A2000 均可流畅运行)
  • 不支持纯CPU推理(官方未提供CPU优化版本,且性能不可用)

注意:官方明确提示“两张卡,一张卡起不来”——这不是bug,而是vLLM后端对多GPU并行的硬性要求。但别担心,我们只用单卡也能跑,只是要绕过vLLM的多卡检测逻辑。下文会给出安全、稳定的单卡适配方案。

2.2 创建项目目录与基础文件

新建一个空目录,例如chandra-api,然后创建以下三个文件:

mkdir chandra-api && cd chandra-api touch docker-compose.yml touch fastapi_app.py touch requirements.txt

2.3 编写 FastAPI 服务入口(fastapi_app.py

这个文件负责接收图片/PDF上传、调用 chandra-ocr CLI、返回结构化结果。代码简洁,无依赖污染,全部通过 subprocess 调用容器内已安装的chandra-ocr命令:

# fastapi_app.py import os import tempfile import subprocess import json from pathlib import Path from fastapi import FastAPI, UploadFile, File, HTTPException from fastapi.responses import JSONResponse from pydantic import BaseModel app = FastAPI(title="Chandra OCR API", version="1.0") class OCRResult(BaseModel): markdown: str html: str json: dict @app.post("/ocr", response_model=OCRResult) async def run_ocr(file: UploadFile = File(...)): # 临时保存上传文件 suffix = Path(file.filename).suffix.lower() if suffix not in [".png", ".jpg", ".jpeg", ".pdf"]: raise HTTPException(400, "仅支持 PNG/JPG/PDF 格式") with tempfile.NamedTemporaryFile(delete=False, suffix=suffix) as tmp: content = await file.read() tmp.write(content) tmp_path = Path(tmp.name) try: # 调用 chandra-ocr CLI,强制单卡模式(--gpu-memory-utilization 0.95) result = subprocess.run( [ "chandra-ocr", str(tmp_path), "--output-format", "all", "--device", "cuda:0", "--gpu-memory-utilization", "0.95", "--max-model-len", "8192" ], capture_output=True, text=True, timeout=120 ) if result.returncode != 0: raise HTTPException(500, f"OCR执行失败:{result.stderr[:200]}") # 解析输出目录(chandra 默认输出到同名目录 + _chandra) output_dir = tmp_path.parent / f"{tmp_path.stem}_chandra" md_file = output_dir / "output.md" html_file = output_dir / "output.html" json_file = output_dir / "output.json" return { "markdown": md_file.read_text(encoding="utf-8") if md_file.exists() else "", "html": html_file.read_text(encoding="utf-8") if html_file.exists() else "", "json": json.loads(json_file.read_text(encoding="utf-8")) if json_file.exists() else {} } finally: # 清理临时文件 for p in [tmp_path, output_dir]: if p.exists(): if p.is_file(): p.unlink() else: import shutil shutil.rmtree(p, ignore_errors=True)

2.4 编写依赖清单(requirements.txt

只保留最精简的核心依赖,避免与 chandra 内置环境冲突:

fastapi==0.115.0 uvicorn[standard]==0.32.0 pydantic==2.9.2

2.5 编写 Docker Compose 编排文件(docker-compose.yml

这是核心——我们将 chandra-ocr 镜像作为基础环境,再叠加 FastAPI 服务层,实现“模型即服务”:

# docker-compose.yml version: '3.8' services: ocr-api: image: datalabto/chandra-ocr:latest platform: linux/amd64 # 确保使用x86_64镜像(M系列Mac需额外设置) restart: unless-stopped ports: - "8000:8000" volumes: - ./fastapi_app.py:/app/fastapi_app.py - ./requirements.txt:/app/requirements.txt - /tmp/chandra_cache:/root/.cache/huggingface # 共享HF缓存,加速重复加载 working_dir: /app command: > sh -c " pip install -r requirements.txt && uvicorn fastapi_app:app --host 0.0.0.0:8000 --port 8000 --workers 2 --reload " deploy: resources: reservations: devices: - driver: nvidia count: 1 capabilities: [gpu]

小技巧:/tmp/chandra_cache是为了复用 HuggingFace 模型缓存。首次启动会自动下载约 3.2GB 权重(ViT-Encoder+Decoder),后续启动秒级加载。

3. 一键启动:从零到API只需一条命令

确保你已安装 Docker Desktop(含 NVIDIA Container Toolkit)并启用 WSL2(Windows)或 Rosetta(macOS)。

chandra-api目录下执行:

docker compose up -d --build

等待约 90 秒(首次需拉取镜像+安装依赖),然后访问:

http://localhost:8000/docs

你会看到 FastAPI 自动生成的交互式文档界面。点击/ocr→ “Try it out” → 上传一张带表格的PDF截图,几秒后就能拿到结构完整的 Markdown 输出。

成功标志:

  • 日志中出现Uvicorn running on http://0.0.0.0:8000
  • docker compose ps显示ocr-api状态为running
  • curl -X POST http://localhost:8000/ocr返回 422(说明API已就绪,只是没传文件)

4. 实战效果:三类典型文档实测对比

我们用同一台 RTX 3060(12GB)实测了三类高难度文档,全部在 3–8 秒内完成,输出质量远超传统OCR。

4.1 扫描版数学试卷(含手写批注+公式)

输入输出亮点
A4扫描件(300dpi),含手写解题步骤、LaTeX公式、页眉页脚公式完整转为$\int_0^1 x^2 dx = \frac{1}{3}$
手写部分单独标注为<handwritten>...区块
页眉“2025年期中考试”识别为一级标题

对比测试:Tesseract 5.3 识别同一试卷,公式全部崩坏为乱码,手写部分被忽略,页眉误判为正文段落。

4.2 多栏企业合同(含复选框+签名区)

输入输出亮点
PDF合同(双栏排版),含 ☐ 同意条款、签名线、公司LOGO自动识别复选框状态(空/勾选),生成☐ 第三条款☑ 第三条款
签名区保留为<signature-area x="120" y="450" width="200" height="60"/>
双栏内容按阅读顺序拼接,非左右割裂

4.3 表格密集的财务报表(含合并单元格+斜体注释)

输入输出亮点
Excel导出PDF,含跨行表头、货币符号、小字号脚注合并单元格准确还原为colspan="2"/rowspan="3"
“¥”、“%”等符号原样保留,不转义
脚注以<sup>[1]</sup>形式嵌入,并在文末生成[^1]: 数据来源:2024年报

所有输出均同时生成.md.html.json三份,JSON 中包含每个元素的坐标(bbox: [x1,y1,x2,y2]),方便后续做 RAG 切片或可视化标注。

5. 进阶用法:批量处理+自定义输出格式

chandra-ocr 原生命令行已足够强大,无需修改代码即可满足多数生产需求。

5.1 批量处理整个文件夹

在容器内直接执行(进入容器后):

# 处理当前目录下所有PDF,输出到 ./batch_output chandra-ocr ./input_pdfs --output-dir ./batch_output --output-format markdown # 支持通配符,跳过已处理文件 chandra-ocr ./scans/*.jpg --skip-existing

5.2 自定义输出:只生成HTML(适合嵌入网页)

修改 FastAPI 调用命令,去掉--output-format all,改为:

chandra-ocr input.pdf --output-format html --no-markdown --no-json

对应地,API响应模型也只需返回html: str字段,减少传输体积。

5.3 降低显存占用:适用于4GB显存设备

docker-compose.ymlcommand中加入参数:

--gpu-memory-utilization 0.7 \ --max-model-len 4096 \ --enforce-eager

实测 RTX 3050(4GB)可稳定处理 A4尺寸PDF(单页≤1500词),速度下降约30%,但精度无损。

6. 常见问题与稳定运行建议

6.1 “CUDA out of memory” 怎么办?

这不是模型问题,而是 vLLM 默认预分配显存过高。解决方案有三:

  • 首选:在chandra-ocr命令中添加--gpu-memory-utilization 0.75(推荐0.7–0.85区间)
  • 次选:改用--device cpu(仅限调试,速度极慢,不推荐生产)
  • 避免:强行修改vllm源码或重编译——chandra 已深度集成,破坏兼容性风险高

6.2 PDF识别为空白?检查这三点

  • 是否为纯图像PDF(无文本图层)?→ chandra 只处理图像型PDF,扫描件OK,Office导出的“可选文本PDF”需先转为图像
  • 文件路径是否含中文或空格?→ FastAPI 临时文件路径已做urllib.parse.quote处理,但建议原始文件名用英文+下划线
  • 是否启用了 NVIDIA Container Toolkit?→ 运行nvidia-smi确认宿主机可见GPU,再执行docker run --rm --gpus all nvidia/cuda:12.2.0-base-ubuntu22.04 nvidia-smi测试容器内GPU可用性

6.3 如何长期稳定运行?

  • 设置日志轮转:在docker-compose.yml中添加
logging: driver: "json-file" options: max-size: "10m" max-file: "3"
  • 添加健康检查:
healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8000/health"] interval: 30s timeout: 10s retries: 3
  • 配合 Nginx 反向代理(可选):添加 gzip 压缩、请求限流、HTTPS 终止,提升生产健壮性。

7. 总结:让OCR真正“可用”的关键一步

Chandra 不是又一个实验室玩具。它的 83.1 分 olmOCR 综合得分背后,是真实场景的硬核能力:

  • 表格识别精度 88.0(第一)→ 合同、财报、课表,结构零丢失
  • 手写体支持 → 扫描试卷、审批单、医疗记录,不再拒识
  • 公式识别 → 数学、物理、化学文档,告别LaTeX重写
  • 开源商用友好 → Apache 2.0 代码 + OpenRAIL-M 权重,初创公司免费用

而本文带你走完最关键的一环:从单机CLI,到可部署、可监控、可集成的API服务
用 Docker Compose 编排,不是为了炫技,而是为了——

  • 📦 环境彻底隔离,不污染本机Python
  • ⚙ GPU资源精准分配,多服务共存不抢显存
  • 启动/重启/升级,一条命令全部搞定
  • 对接任何前端、RAG系统、低代码平台,零改造成本

你现在拥有的,不是一个“能跑的demo”,而是一个随时可接入业务流水线的OCR基础设施模块。


获取更多AI镜像

想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/12 23:29:24

ChatGLM-6B高效运行:Transformers版本配置建议

ChatGLM-6B高效运行&#xff1a;Transformers版本配置建议 1. 为什么ChatGLM-6B值得你认真对待 很多人第一次听说ChatGLM-6B&#xff0c;是被它“开源”“双语”“62亿参数”这几个词吸引。但真正用过的人才知道&#xff0c;它的价值远不止这些标签——它是一个能在普通GPU上…

作者头像 李华
网站建设 2026/2/21 20:34:36

GLM-4.7-Flash vs Qwen3:30B模型性能实测对比(附部署教程)

GLM-4.7-Flash vs Qwen3&#xff1a;30B模型性能实测对比&#xff08;附部署教程&#xff09; 1. 开篇直击&#xff1a;为什么这场30B对决值得你花5分钟看完 你是不是也遇到过这些情况&#xff1a; 想在本地跑一个真正能写代码、调工具、生成UI的30B级模型&#xff0c;结果发…

作者头像 李华
网站建设 2026/2/26 11:46:42

HY-Motion 1.0快速上手:十亿参数DiT模型的文本→3D动作全流程详解

HY-Motion 1.0快速上手&#xff1a;十亿参数DiT模型的文本→3D动作全流程详解 1. 这不是“动图”&#xff0c;是真正能驱动3D角色的骨骼动画 你有没有试过在3D软件里调一个走路循环&#xff0c;花掉两小时却总觉得膝盖转动不自然&#xff1f;或者想给游戏角色加一段“单手扶墙…

作者头像 李华
网站建设 2026/2/26 6:02:14

DeerFlow实战教程:比特币价格分析自动化流程搭建

DeerFlow实战教程&#xff1a;比特币价格分析自动化流程搭建 1. DeerFlow是什么&#xff1a;你的个人深度研究助理 DeerFlow不是另一个简单的聊天机器人&#xff0c;而是一个能真正帮你“做研究”的智能系统。它像一位熟悉Python、懂网络搜索、会调用API、还能写报告甚至生成…

作者头像 李华
网站建设 2026/2/19 21:28:43

隐私无忧!Chandra+Ollama构建企业级安全对话系统指南

隐私无忧&#xff01;ChandraOllama构建企业级安全对话系统指南 在AI应用爆发式增长的今天&#xff0c;一个尖锐的矛盾日益凸显&#xff1a;企业渴望大模型带来的智能增效&#xff0c;却对数据外泄、API调用风险、第三方服务不可控等隐患如履薄冰。当主流云服务要求上传用户对…

作者头像 李华