物流行业网站模板天津做优化的网站有多少家
2026/4/15 9:08:25 网站建设 项目流程
物流行业网站模板,天津做优化的网站有多少家,做ppt兼职网站,建站公司 长沙和西安如何用FastAPI集成DeepSeek-OCR#xff1f;OpenAI协议兼容实现 1. 背景与目标 在当前自动化文档处理、票据识别和内容数字化的场景中#xff0c;高性能OCR能力已成为关键基础设施。DeepSeek-OCR作为一款基于深度学习的国产自研光学字符识别引擎#xff0c;具备高精度中文识…如何用FastAPI集成DeepSeek-OCROpenAI协议兼容实现1. 背景与目标在当前自动化文档处理、票据识别和内容数字化的场景中高性能OCR能力已成为关键基础设施。DeepSeek-OCR作为一款基于深度学习的国产自研光学字符识别引擎具备高精度中文识别、多语言支持、复杂版式还原等优势广泛应用于金融、教育、物流等领域。然而许多现有系统已基于OpenAI API设计了工作流若能将DeepSeek-OCR以OpenAI协议兼容的方式暴露服务接口则可实现无缝迁移与快速集成。本文将详细介绍如何使用FastAPI搭建一个兼容/v1/chat/completions接口规范的OCR服务并提供简洁WebUI用于交互测试。最终目标✅ 实现 OpenAI 风格的chat.completions接口✅ 支持 Base64、本地路径、HTTP URL 多种图片输入方式✅ 提供静态 Web 前端上传图片并获取结构化文本结果✅ 可部署于单卡 GPU 环境如 4090D支持边缘或本地化运行2. 技术架构概览2.1 整体架构设计本方案采用前后端分离架构------------------ --------------------- | Web Browser | --- | FastAPI Backend | | (static/ui.html) | | (app.py) | ------------------ -------------------- | v ----------------------- | DeepSeek-OCR Model | | (transformers torch)| -----------------------前端单页 HTML 文件 (ui.html)通过 FileReader 将图片转为 data URI 发送至后端后端FastAPI 应用提供/v1/chat/completions兼容接口调用本地加载的 DeepSeek-OCR 模型进行推理模型层基于 HuggingFace Transformers 加载deepseek-ai/DeepSeek-OCR或本地路径模型启用trust_remote_codeTrue2.2 核心功能模块模块功能说明/v1/models返回可用模型列表固定返回deepseek-ocr/v1/chat/completionsOpenAI 兼容接口接收图文消息并返回 OCR 结果/parserToText表单上传接口支持文件 文本提示/health健康检查接口/ui跳转到 WebUI 页面/static静态资源目录存放ui.html3. 环境准备与依赖安装3.1 系统要求Python 3.12PyTorch 2.6.0CUDA 12.x推荐用于 GPU 加速显存建议 16GBFP16 推理3.2 创建虚拟环境并安装依赖conda create -n deepseekocr python3.12.9 conda activate deepseekocr pip install \ torch2.6.0 \ transformers4.46.3 \ tokenizers0.20.3 \ einops addict easydict \ python-multipart \ uvicorn fastapi \ Pillow torchvision \ requests可选优化若安装flash-attn可在部分场景下提升推理速度并降低显存占用。4. 项目结构组织推荐如下目录结构project/ ├── app.py # FastAPI 主服务文件 ├── static/ │ └── ui.html # 前端交互页面 └── README.md该结构清晰简洁便于部署与维护。5. 后端服务实现详解5.1 初始化 FastAPI 与 CORS 配置from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware app FastAPI(titleOpenAI-Compatible OCR Service) app.add_middleware( CORSMiddleware, allow_origins[*], allow_credentialsTrue, allow_methods[*], allow_headers[*], )启用 CORS 是为了允许前端跨域请求适用于独立部署的 UI。5.2 挂载静态资源STATIC_DIR os.getenv(STATIC_DIR, static) os.makedirs(STATIC_DIR, exist_okTrue) app.mount(/static, StaticFiles(directorySTATIC_DIR), namestatic) app.get(/ui) async def ui_redirect(): return HTMLResponse(meta http-equivrefresh content0; url/static/ui.html /)通过/ui可直接访问 WebUI提升用户体验。5.3 模型加载与设备适配MODEL_NAME os.getenv(DEEPSEEK_OCR_PATH, /home/qwt/models/DeepSeek-OCR) tokenizer AutoTokenizer.from_pretrained(MODEL_NAME, trust_remote_codeTrue) model AutoModel.from_pretrained(MODEL_NAME, trust_remote_codeTrue, use_safetensorsTrue) # 设备与精度自动适配 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) except Exception: model model.to(torch.float32) else: device torch.device(cpu) model model.eval().to(device)此段代码确保在不同硬件环境下均能正常运行优先使用 BF16/FP16 提升性能。6. 图像输入处理机制6.1 支持三种图像来源类型示例说明Data URIdata:image/png;base64,...前端推荐方式无需额外服务本地路径/path/to/image.jpg或file:///...适用于服务器本地文件HTTP(S) URLhttps://example.com/img.png自动下载至临时文件6.2 统一转换为本地临时文件def _download_to_temp(url: str) - str: if _is_data_uri(url): header, b64 url.split(,, 1) ext .png if image/png in header else .jpg raw base64.b64decode(b64) return _save_bytes_to_temp(raw, suffixext) elif _is_local_like(url): p _to_local_path(url) with open(p, rb) as f: data f.read() ext os.path.splitext(p)[1] or .img return _save_bytes_to_temp(data, suffixext) else: resp requests.get(url, timeout30) resp.raise_for_status() ctype resp.headers.get(Content-Type, ) ext mimetypes.guess_extension(ctype) or .img return _save_bytes_to_temp(resp.content, suffixext)所有输入最终统一为本地临时文件路径便于模型调用。7. OpenAI 协议兼容接口实现7.1 请求格式解析遵循 OpenAI 的messages数组结构{ model: deepseek-ocr, messages: [ { role: user, content: [ {type: text, text: 请以 Markdown 输出识别结果}, {type: image_url, image_url: {url: data:image/png;base64,...}} ] } ] }7.2 提取文本与图像def _extract_text_and_first_image_from_messages(messages): all_text [] image_path None for msg in messages: content msg.get(content) if isinstance(content, str): all_text.append(content) elif isinstance(content, list): for part in content: if part[type] text: all_text.append(part[text]) elif part[type] image_url and not image_path: url part[image_url][url] image_path _download_to_temp(url) prompt \n.join(all_text) return prompt, image_path仅取第一张图片文本拼接所有text片段。7.3 调用模型推理def _run_ocr_infer(prompt: str, image_path: str) - str: full_prompt fimage\n{prompt}.strip() res model.infer( tokenizer, promptfull_prompt, image_fileimage_path, base_size1024, image_size640, crop_modeTrue, save_resultsFalse, test_compressTrue, eval_modeTrue, ) if isinstance(res, dict): return res.get(text, ) or str(res) return str(res)输出结果可为纯文本、Markdown 或 JSON 结构取决于输入提示。8. 核心接口定义8.1 健康检查app.get(/health) async def health_check(): return {status: healthy}8.2 模型列表app.get(/v1/models) async def list_models(): return { object: list, data: [{id: deepseek-ocr, object: model, created: int(time.time()), owned_by: owner}] }8.3 推理接口app.post(/v1/chat/completions) async def chat_completions(request: Request): payload await request.json() messages payload.get(messages) prompt_text, image_path _extract_text_and_first_image_from_messages(messages) answer _run_ocr_infer(prompt_text, image_path) # 清理临时文件 if image_path and os.path.exists(image_path): os.unlink(image_path) return JSONResponse({ id: fchatcmpl_{uuid.uuid4().hex[:24]}, object: chat.completion, created: int(time.time()), model: deepseek-ocr, choices: [{ index: 0, message: {role: assistant, content: answer}, finish_reason: stop }], usage: { prompt_tokens: len(tokenizer.encode(prompt_text)), completion_tokens: len(tokenizer.encode(answer)), total_tokens: len(tokenizer.encode(prompt_text answer)) } })9. 前端 WebUI 实现9.1 功能特性图片上传预览预设指令选择Markdown / 纯文本 / JSON自定义提示输入Markdown 实时预览请求耗时统计9.2 关键逻辑片段const fileToDataURI (file) { return new Promise((resolve) { const reader new FileReader(); reader.onload () resolve(reader.result); reader.readAsDataURL(file); }); }; runBtn.addEventListener(click, async () { const dataUri await fileToDataURI(f); const textMsg presetText(presetEl.value) \n\n (promptEl.value || ); const body { model: deepseek-ocr, messages: [ { role: user, content: [ { type: text, text: textMsg }, { type: image_url, image_url: { url: dataUri } } ]} ] }; const resp await fetch(/v1/chat/completions, { method: POST, headers: { Content-Type: application/json }, body: JSON.stringify(body) }); const json await resp.json(); rawEl.textContent json.choices[0].message.content; if (window.marked) mdEl.innerHTML marked.parse(json.choices[0].message.content); });10. 客户端调用示例使用 OpenAI SDK兼容模式from openai import OpenAI client OpenAI(base_urlhttp://127.0.0.1:8001/v1, api_keysk-x) resp client.chat.completions.create( modeldeepseek-ocr, messages[ {role: user, content: [ {type: text, text: 请输出标准 Markdown 格式的表格和标题}, {type: image_url, image_url: {url: /path/to/invoice.png}} ]} ] ) print(resp.choices[0].message.content)只需更改base_url即可复用现有 OpenAI 调用逻辑。11. 总结本文详细介绍了如何使用 FastAPI 构建一个与 OpenAI 协议兼容的 DeepSeek-OCR 服务实现了以下核心价值协议兼容性暴露/v1/chat/completions接口支持主流 LLM 工具链直接接入多源图像支持兼容 Data URI、本地路径、HTTP URL 输入方式轻量级部署单文件后端 单页前端适合本地或边缘设备部署工程实用性包含健康检查、CORS、临时文件管理、异常处理等生产级特性易扩展性强可轻松替换为其他视觉语言模型VLM或添加缓存、鉴权等功能该方案已在实际项目中验证可用于票据识别、文档数字化、表单自动化等场景显著降低人工录入成本。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询