本地部署DeepSeek-OCR:基于FastAPI构建OpenAI兼容的WebUI服务
1. 背景与目标
在文档数字化、自动化处理日益普及的今天,光学字符识别(OCR)技术已成为企业降本增效的关键工具。DeepSeek OCR作为一款高性能国产自研OCR大模型,在中文文本识别精度、复杂场景鲁棒性以及多语言支持方面表现出色,尤其适用于票据、证件、表格等结构化内容的提取。
然而,许多开发者希望将OCR能力快速集成到现有系统中,而无需深入理解底层模型细节。为此,构建一个符合OpenAI API协议标准的服务接口,不仅能降低接入门槛,还能复用大量已有的客户端工具和SDK。
本文将详细介绍如何通过FastAPI搭建一个本地化的 DeepSeek-OCR 服务,实现以下核心功能:
- ✅ 兼容 OpenAI
/v1/chat/completions接口 - ✅ 支持 Base64、本地路径、HTTP URL 多种图片输入方式
- ✅ 提供简洁可用的静态 WebUI 界面
- ✅ 实现自动清理临时文件的安全机制
- ✅ 支持跨域请求(CORS),便于前端调用
最终成果是一个可一键启动、开箱即用的本地OCR服务,适合部署于边缘设备或私有云环境。
2. 技术架构设计
2.1 整体架构概览
整个系统采用典型的前后端分离架构,分为三个主要模块:
- 后端服务层:基于 FastAPI 构建 RESTful API,负责接收请求、解析图像、调用模型推理并返回结果。
- 模型执行层:加载 DeepSeek-OCR 模型,使用
transformers库进行推理,支持trust_remote_code=True。 - 前端交互层:单页 HTML 页面,提供图片上传、提示词输入、结果展示与 Markdown 预览功能。
+------------------+ HTTP POST +--------------------+ | | -----------------> | | | WebUI | | FastAPI Server | | (static/ui.html) | <----------------- | (app.py) | | | JSON Response | | +------------------+ +----------+---------+ | v +---------------------+ | DeepSeek-OCR Model | | (HuggingFace) | +---------------------+该设计具备良好的扩展性,未来可轻松替换为其他视觉语言模型(VLM),如 Qwen-VL、PaddleOCR-Large 等。
2.2 核心依赖说明
| 依赖库 | 作用 |
|---|---|
fastapi | 构建高性能异步API服务 |
uvicorn | ASGI服务器,运行FastAPI应用 |
transformers | 加载并运行DeepSeek-OCR模型 |
torch | PyTorch深度学习框架 |
Pillow | 图像处理基础库 |
python-multipart | 支持文件上传解析 |
requests | 下载远程图片 |
建议使用 Python 3.12+ 和 Conda/venv 虚拟环境管理依赖,避免版本冲突。
3. 后端服务实现详解
3.1 目录结构规划
合理的项目结构有助于维护和部署:
project/ ├── app.py # 主服务脚本 ├── static/ │ └── ui.html # 前端页面 └── requirements.txt # 依赖列表(可选)所有静态资源放置在static/目录下,由 FastAPI 自动挂载。
3.2 模型加载与设备适配
模型加载是服务初始化的核心环节。考虑到不同硬件配置,代码中实现了智能精度降级策略:
if torch.cuda.is_available(): device = torch.device("cuda:0") model = model.eval().to(device) try: model = model.to(torch.bfloat16) except Exception: try: model = model.to(torch.float16) log.info("BF16 不可用,已回退到 FP16") except Exception: model = model.to(torch.float32) log.info("FP16 不可用,已回退到 FP32") else: device = torch.device("cpu") model = model.eval().to(device) log.warning("未检测到 CUDA,将在 CPU 上推理。")此逻辑确保在无GPU或显存不足时仍能正常运行,提升服务健壮性。
提示:若安装了
flash-attn,可通过_attn_implementation="flash_attention_2"进一步提升推理速度并减少显存占用。
3.3 图像输入统一处理
为了兼容多种图像来源(Base64、本地路径、HTTP链接),我们封装了_download_to_temp函数,统一转换为本地临时文件路径:
输入类型支持:
- ✅
data:image/png;base64,...:前端常用的 Data URI - ✅
/path/to/image.jpg或file:///path/to/image.jpg:本地文件 - ✅
http://example.com/image.png:远程URL
处理流程:
- 判断输入类型
- 解码或下载图像数据
- 保存至临时文件(
tempfile.NamedTemporaryFile) - 返回绝对路径供模型调用
关键优势在于:无论来源如何,最终都归一化为本地文件路径,简化模型调用逻辑。
3.4 OpenAI 兼容接口实现
服务暴露两个核心接口:
GET/v1/models
返回固定模型信息,满足 OpenAI 客户端探测需求:
{ "object": "list", "data": [ { "id": "deepseek-ocr", "object": "model", "created": 1712345678, "owned_by": "owner" } ] }POST/v1/chat/completions
完全兼容 OpenAI 协议,接收如下格式请求:
{ "model": "deepseek-ocr", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "请以Markdown格式输出" }, { "type": "image_url", "image_url": { "url": "data:image/jpeg;base64,..." } } ] } ] }响应结构也保持一致,包含choices,usage,id,created等字段,确保与 OpenAI SDK 无缝对接。
4. 前端WebUI设计与交互逻辑
4.1 功能特性
static/ui.html是一个独立的单页应用,具备以下功能:
- 🖼️ 图片上传与预览(使用
FileReader.readAsDataURL) - 🔤 预设提示词选择(Markdown / 纯文本 / JSON 结构)
- ✍️ 自定义提示词输入
- ⚡ 提交至
/v1/chat/completions获取结果 - 📄 双模式结果展示:原始文本 & Markdown 渲染预览
- 🕒 请求耗时统计
4.2 关键交互流程
sequenceDiagram participant User participant UI participant API participant Model User->>UI: 选择图片 UI->>UI: 显示预览(Data URI) User->>UI: 输入提示词并点击“识别” UI->>API: POST /v1/chat/completions API->>Model: 调用 infer() 方法 Model-->>API: 返回OCR结果 API-->>UI: JSON响应 UI->>UI: 展示文本 + Markdown渲染4.3 Markdown 实时预览实现
借助 CDN 引入的marked.js,实现 Markdown 内容的浏览器端渲染:
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>if (window.marked && content) { mdEl.innerHTML = marked.parse(content); } else { mdEl.textContent = content; }用户可在“原始文本”与“Markdown预览”之间切换,直观查看版式还原效果。
5. 快速部署与使用指南
5.1 环境准备
# 创建虚拟环境 conda create -n deepseekocr python=3.12.9 conda activate deepseekocr # 安装依赖 pip install torch==2.6.0 transformers==4.46.3 tokenizers==0.20.3 \ einops addict easydict python-multipart uvicorn fastapi \ Pillow torchvision requests5.2 启动服务
python app.py服务默认监听http://0.0.0.0:8001,可通过环境变量调整:
CUDA_VISIBLE_DEVICES=0:指定GPU卡号DEEPSEEK_OCR_PATH=/path/to/model:指定本地模型路径
5.3 访问方式
| 地址 | 用途 |
|---|---|
http://localhost:8001/ui | 打开WebUI界面 |
http://localhost:8001/health | 健康检查 |
http://localhost:8001/v1/models | 查看模型信息 |
http://localhost:8001/v1/chat/completions | OCR推理接口 |
6. 客户端调用示例
6.1 使用 OpenAI SDK(推荐)
from openai import OpenAI client = OpenAI(base_url="http://127.0.0.1:8001/v1", api_key="sk-x") resp = client.chat.completions.create( model="deepseek-ocr", messages=[ { "role": "user", "content": [ {"type": "text", "text": "描述一下图片内容:"}, {"type": "image_url", "image_url": {"url": "/home/user/test.png"}} ], } ], ) print(resp.choices[0].message.content)6.2 使用 curl 调用
curl http://localhost:8001/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "deepseek-ocr", "messages": [ { "role": "user", "content": [ {"type": "text", "text": "请输出纯文本结果"}, {"type": "image_url", "image_url": {"url": "https://example.com/doc.jpg"}} ] } ] }'7. 总结
本文详细介绍了如何基于 FastAPI 将 DeepSeek-OCR 模型封装为一个OpenAI 兼容的本地Web服务,并通过简洁的 WebUI 实现可视化操作。该方案具有以下显著优势:
- 协议兼容性强:完全遵循 OpenAI API 规范,可直接使用其生态中的各类工具链。
- 部署简单:仅需 Python 环境和少量依赖,支持 GPU/CPU 自适应。
- 输入灵活:支持 Data URI、本地路径、HTTP URL 三种图像输入方式。
- 安全可靠:自动清理临时文件,防止磁盘泄露;支持 CORS 控制。
- 易于扩展:前端可独立优化,后端可替换为其他 VLM 模型。
该服务特别适用于需要高精度中文OCR能力的企业内部系统、文档自动化平台或边缘计算场景。结合 CSDN 星图镜像广场提供的预置镜像,更可实现一键部署,极大提升开发效率。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。