环境 链接到标题

项目
GPU NVIDIA RTX 4060 Ti 16GB
CUDA 13.0(driver 580.xx)
基础镜像 vllm/vllm-openai:v0.21.0(daocloud 国内镜像)
MinerU 版本 >=3.4.0
模型源 ModelScope(阿里云国内镜像)

基础镜像选择 链接到标题

MinerU 依赖 vLLM 加载 VLM 视觉语言模型,底层的 CUDA 版本必须与宿主机 driver 匹配。选 vllm-openai:v0.21.0 的原因是:

  • 基于 CUDA 13,与本机 driver 对齐
  • 国内拉取用 daocloud 镜像,速度快
  • vLLM 0.21.x 版本稳定性好,FlashAttention 支持完整
# daocloud 镜像加速(国内环境)
docker pull docker.m.daocloud.io/vllm/vllm-openai:v0.21.0

Dockerfile 链接到标题

FROM docker.m.daocloud.io/vllm/vllm-openai:v0.21.0

# 安装中文字体与 OpenGL 依赖(OCR 需要)
RUN apt-get update && \
    apt-get install -y --no-install-recommends \
        fonts-noto-core \
        fonts-noto-cjk \
        fontconfig \
        libgl1 && \
    fc-cache -fv && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

# 安装 MinerU(latest),用阿里云 PyPI 镜像加速
RUN python3 -m pip install -U 'mineru[core]>=3.4.0' \
        -i https://mirrors.aliyun.com/pypi/simple \
        --break-system-packages && \
    python3 -m pip cache purge

# 构建时下载所有模型(pipeline + VLM),约 3.4GB
RUN /bin/bash -c "mineru-models-download -s modelscope -m all"

# 默认使用本地模型
ENTRYPOINT ["/bin/bash", "-c", "export MINERU_MODEL_SOURCE=local && exec \"$@\"", "--"]

构建镜像约 29.7GB,包含完整 CUDA 运行时、PyTorch、MinerU 依赖以及所有模型文件(pipeline + VLM,约 3.4GB)。


模型下载策略 链接到标题

模型在 Docker 构建阶段自动下载,镜像已包含所有模型文件,无需手工下载。

MinerU 模型分类 链接到标题

类型 说明 大小
pipeline 模型 OCR + 版面分析(ONNX,CPU 推理) ~870MB
VLM 模型 视觉语言模型(GPU 推理) ~2.15GB
formula 模型 公式识别(PyTorch) ~589MB

构建时下载 链接到标题

Dockerfile 中 mineru-models-download -s modelscope -m all 会下载全部模型。由于 ModelScope 国内镜像下载速度约 300-500KB/s,VLM 模型(2.15GB)耗时较长,建议用 screentmux 后台构建:

screen -dmS mineru-build docker build -t mineru:latest .

共享模型卷 链接到标题

所有服务共享 mineru-cache volume,模型文件只存一份:

mineru-api ──→ mineru-cache volume(模型数据)
mineru-gradio

常见问题 链接到标题

构建时下载中断:ModelScope 的 .lock/ 目录残留会导致后续重试失败,清理后重新构建即可:

rm -rf ~/.cache/modelscope/hub/.lock/

Docker Compose 编排 链接到标题

services:
  mineru-api:
    image: mineru:latest
    container_name: mineru-api
    ports:
      - "8000:8000"
    environment:
      - MINERU_MODEL_SOURCE=local
    entrypoint: mineru-api
    command:
      - "--host"
      - "0.0.0.0"
      - "--port"
      - "8000"
      - "--allow-public-http-client"
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities: [gpu]
    restart: unless-stopped

  mineru-gradio:
    image: mineru:latest
    container_name: mineru-gradio
    ports:
      - "7860:7860"
    environment:
      - MINERU_MODEL_SOURCE=local
    restart: unless-stopped

关键设计 链接到标题

  • 镜像内置所有模型(pipeline + VLM),无需额外下载
  • MINERU_MODEL_SOURCE=local:从镜像内读取模型
  • NVIDIA GPU 直通:每个服务通过 deploy.resources 声明 GPU 需求

SSRF 安全策略 链接到标题

MinerU v3.4.0 引入了 SSRF 防护:当 mineru-api 绑定到 0.0.0.0 时,默认禁止 *-http-client 后端和 server_url 参数(防止攻击者利用 API 发起内网探测)。

如果 Gradio 提交任务时报错:

Publicly exposed API disables *-http-client backends and server_url by default.
Rebind to 127.0.0.1 or start with --allow-public-http-client if you understand the SSRF risk.

需要在 mineru-api 的 command 中加 --allow-public-http-client

mineru-api:
    command:
      - "--host"
      - "0.0.0.0"
      - "--port"
      - "8000"
      - "--allow-public-http-client"

注意MINERU_API_ALLOW_PUBLIC_HTTP_CLIENT=true 环境变量无效,因为 main() 函数会用 CLI 参数默认值覆盖环境变量。必须通过 CLI flag 传入。

风险:启用后,API 允许用户指定远程 HTTP 推理端点,存在 SSRF 风险。内网可控环境可接受,公网暴露的服务不建议开启。


2 个服务的作用 链接到标题

服务 端口 用途 必要性
mineru-api 8000 文档解析 API(/file_parse 必需
mineru-gradio 7860 Web UI(交互式解析) 可选

解析后端对比 链接到标题

MinerU 提供 5 个解析后端,按资源占用和精度分类:

后端一览 链接到标题

后端 GPU 占用 精度 语言支持
pipeline 0(CPU+ONNX) 一般 多语言
vlm-engine ~7.7GB 最高 中英文
hybrid-engine ~7.7GB 多语言

pipeline 后端 链接到标题

curl -X POST http://localhost:8000/file_parse \
  -F "files=@document.jpg" \
  -F "backend=pipeline"
  • 推理在 CPU 上执行(ONNX Runtime)
  • 不占 GPU 内存
  • 与 openai-server 可并行运行
  • 适合生产环境批量解析

vlm-engine 后端 链接到标题

curl -X POST http://localhost:8000/file_parse \
  -F "files=@document.jpg" \
  -F "backend=vlm-engine"
  • 纯 VLM 视觉语言模型解析,精度最高
  • 占用约 7.7GB VRAM
  • 只支持中文和英文文档
  • 内部启动 vLLM,与 openai-server 的 vLLM 互斥(16GB 放不下两个)

hybrid-engine 后端 链接到标题

curl -X POST http://localhost:8000/file_parse \
  -F "files=@document.jpg" \
  -F "backend=hybrid-engine"
  • VLM + OCR 混合解析,支持多语言
  • 占用约 7.7GB VRAM
  • 通过 effort=medium|high 切换速度/精度
  • 同样与 openai-server 互斥

vlm-engine 后端 链接到标题

curl -X POST http://localhost:8000/file_parse \
  -F "files=@document.jpg" \
  -F "backend=vlm-engine"
  • 加载 VLM 模型到 GPU 推理
  • 占用约 7.7GB VRAM
  • 与 pipeline 可并行(VLM 独占 GPU,pipeline 用 CPU)
  • 不能与 openai-server 同时运行
  • 解析质量最高,支持图文分析

实测数据 链接到标题

测试图片为一张中文报纸版面(光明日报头版),各后端分别跑 3 次,取后 2 次平均耗时:

后端 GPU 占用 单次耗时(后2次平均) 解析质量
pipeline 0(CPU+ONNX) 1.94s 一般(规则驱动)
vlm-engine ~7.7GB 10.99s 最高(VLM 理解)
hybrid-engine ~7.7GB

性能分析 链接到标题

pipeline 快的原因:传统 CV+OCR 流程,版面检测 → OCR 识别 → 规则重组,每个步骤都是轻量 ONNX 模型在 CPU 上执行,1-2 秒完成。

VLM-engine 慢的原因:使用 7B 参数视觉语言模型,每次推理需要:

  1. 视觉编码器提取图像特征
  2. LLM 逐 token 自回归生成版面描述和文本内容

即使模型已加载到 GPU,每次都要完整过一遍 transformer 前向传播 + 逐 token 生成,这是本质上的计算量差异。~11s 对 7B VLM 来说已算很快。

原始测试数据:

后端 第1次 第2次 第3次 后2次平均
pipeline 1.94s 1.96s 1.92s 1.94s
vlm-engine 60.18s* 11.01s 10.97s 10.99s

*VLM 第1次包含模型加载到 GPU 的时间(~7.7GB),后续稳定 ~11s。

GPU 内存管理建议 链接到标题

16GB 显存放一个 vLLM 引擎(~7.7GB)绰绰有余。按需选择后端即可:

  • 追求精度vlm-engine(纯 VLM,中英文)
  • 多语言场景hybrid-engine(VLM + OCR 混合)
  • 生产批量pipeline(CPU+ONNX,不占 GPU)

服务验证 链接到标题

健康检查 链接到标题

# mineru-api
curl http://localhost:8000/health
# {"status":"healthy","version":"3.4.0",...}

# mineru-gradio
curl -o /dev/null -w "%{http_code}" http://localhost:7860/
# 200

vlm-engine 解析测试 链接到标题

curl -s -X POST http://localhost:8000/file_parse \
  -F "files=@test.jpg" \
  -F "backend=vlm-engine" \
  -F "return_md=true" | python3 -m json.tool | head -20

实测解析一张新闻版面图片(光明日报),耗时约 11 秒,返回完整 Markdown 内容(含标题、正文、图片引用)。


已知约束 链接到标题

  • vlm-engine / hybrid-engine 各需 ~7.7GB VRAM,16GB 显存放一个绰绰有余
  • 生产场景推荐 pipeline 后端(CPU+ONNX,不占 GPU)
  • --allow-public-http-client 不能通过环境变量设置,必须通过 CLI flag 传入
  • MinerU v3.4.0 要求 CUDA 12+,驱动版本 525+

参考 链接到标题