环境 链接到标题

项目
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

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

构建镜像约 24.7GB,包含完整 CUDA 运行时、PyTorch 和 MinerU 依赖。


模型下载策略 链接到标题

为什么不在 Dockerfile 里下载 链接到标题

构建阶段下载模型有两个问题:

  1. 超时:模型文件动辄几百 MB,Docker build 的 RUN 层有网络超时限制,大文件下载经常中断
  2. 缓存失效:每次改一行代码都要重新下载,构建时间不可接受

所以模型下载移到了容器首次启动时执行。

MinerU 模型分类 链接到标题

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

下载命令 链接到标题

# 进入容器
docker exec -it mineru-api bash

# 下载 pipeline 模型(OCR + 版面分析)
mineru-models-download -s modelscope -m pipeline

# 下载 VLM 模型
mineru-models-download -s modelscope -m vlm

首次下载 pipeline 模型约 30 分钟(含网络波动),VLM 模型约 10 分钟。

ModelScope 模型源的坑 链接到标题

mineru-models-download 使用 modelscope 库下载,存在两个已知问题:

  1. lock 文件残留:下载中断后会留下 .lock/ 目录,下次 resume 会报 FileDownloadError,即使文件物理上已存在
    • 解决:rm -rf ~/.cache/modelscope/hub/.lock/ 后再重试
  2. 临时目录残留._____temp/ 目录同样会导致误判
    • 解决:清理后重新下载
  3. VLM 路径注入失败get_local_models_dir()model-source=local 模式下返回 None,导致 VLM 路径没有写入 mineru.json
    • 解决:手动将 VLM 模型路径写入 mineru.jsonvlm 字段

共享模型卷 链接到标题

所有 3 个服务共享同一个 Docker volume(mineru-cache),模型只下载一次:

mineru-api ──┐
             ├──→ mineru-cache volume(模型数据)
mineru-openai-server ──┤
             └──→ mineru-config volume(mineru.json 配置)

Docker Compose 编排 链接到标题

services:
  mineru-api:
    image: mineru:latest
    container_name: mineru-api
    ports:
      - "8000:8000"
    volumes:
      - mineru-cache:/root/.cache
      - mineru-config:/root/mineru.json:ro
    environment:
      - MINERU_MODEL_SOURCE=local
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities: [gpu]
    restart: unless-stopped

  mineru-openai-server:
    image: mineru:latest
    container_name: mineru-openai-server
    ports:
      - "30000:30000"
    volumes:
      - mineru-cache:/root/.cache
      - mineru-config:/root/mineru.json:ro
    environment:
      - MINERU_MODEL_SOURCE=local
    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"
    volumes:
      - mineru-cache:/root/.cache
      - mineru-config:/root/mineru.json:ro
    environment:
      - MINERU_MODEL_SOURCE=local
    restart: unless-stopped

volumes:
  mineru-cache:
  mineru-config:

关键设计 链接到标题

  • mineru-cache volume:挂载到所有 3 个容器的 /root/.cache,模型文件只存一份
  • mineru-config volume:mineru.json 只读挂载,所有服务共享同一份配置
  • MINERU_MODEL_SOURCE=local:从本地共享卷读模型,不重复下载
  • NVIDIA GPU 直通:每个服务通过 deploy.resources 声明 GPU 需求

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

服务 端口 用途
mineru-api 8000 文档解析 API(/file_parse
mineru-openai-server 30000 OpenAI 兼容接口(/v1/chat/completions
mineru-gradio 7860 Web UI(交互式解析)

解析后端对比 链接到标题

MinerU 提供两个解析后端,性能和资源占用差异很大:

pipeline 后端 链接到标题

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

hybrid-auto-engine 后端 链接到标题

curl -X POST http://localhost:8000/file_parse \
  -F "files=@document.jpg" \
  -F "backend=hybrid-auto-engine"
  • 加载 VLM 模型到 GPU 推理
  • 占用约 7.7GB VRAM
  • 不能与 openai-server 同时运行(两者各需 7.7GB,合计 15.4GB,超出 16GB 总量)
  • 适合对解析质量要求高的场景

实测数据 链接到标题

后端 GPU 占用 并行性 解析结果
pipeline 0 ✅ 可与 openai-server 并行 ✅ 正常
hybrid-auto-engine ~7.7GB ❌ 需先停 openai-server ✅ 单独运行时正常

hybrid-engine 使用注意事项 链接到标题

由于 GPU 内存冲突,使用 hybrid-auto-engine 前需要先停掉 openai-server:

docker stop mineru-openai-server
# 运行解析
curl -X POST http://localhost:8000/file_parse -F "backend=hybrid-auto-engine" ...
# 解析完恢复
docker start mineru-openai-server

常见问题 链接到标题

openai-server 启动崩溃 链接到标题

现象:启动后立即退出,日志 AttributeError: 'NoneType' object has no attribute 'get'

原因/root/mineru.json 不存在于容器内

解决:确保 mineru-config volume 已挂载,且 mineru.json 已写入 volume:

docker volume inspect mineru-config
# 确认 Mountpoint 存在且包含 mineru.json

VLM 路径未写入配置 链接到标题

现象mineru.json 中缺少 vlm 字段

原因mineru-models-download 调用 get_local_models_dir() 时,在 model-source=local 模式下返回 None

解决:手动写入:

docker exec mineru-api bash -c \
  'jq ".vlm = \"/root/.cache/modelscope/hub/models/.../MinerU2___5-Pro-2605-1___2B\"" \
   /root/mineru.json > /tmp/mineru.json && mv /tmp/mineru.json /root/mineru.json'

ModelScope 下载中断 链接到标题

现象FileDownloadError,但文件物理上已存在

原因.lock/ 目录或 ._____temp/ 目录残留

解决

# 清除 lock
rm -rf ~/.cache/modelscope/hub/.lock/
# 清除临时目录
rm -rf ~/.cache/modelscope/hub/._____temp/
# 重新下载
mineru-models-download -s modelscope -m pipeline

模型文件名过长 链接到标题

ModelScope 下载的目录名含 ___ 分隔符(如 MinerU2___5-Pro-2605-1___2B),部分工具识别有问题。

解决:在共享卷内创建软链接:

ln -s MinerU2___5-Pro-2605-1___2B MinerU2.5-Pro-2605-1.2B

服务验证 链接到标题

健康检查 链接到标题

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

# mineru-openai-server
curl http://localhost:30000/health
# {"status":"healthy",...}

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

pipeline 解析测试 链接到标题

curl -X POST http://localhost:8000/file_parse \
  -F "files=@test.jpg" \
  -F "backend=pipeline" \
  -F "return_md=true" \
  -F "return_content_list=true"

openai-server 接口测试 链接到标题

curl http://localhost:30000/v1/models

已知约束 链接到标题

  • hybrid-auto-engine 与 openai-server 不能同时运行(GPU 内存 16GB 不够)
  • 生产场景推荐 pipeline 后端(CPU+ONNX,不占 GPU,可并行)
  • ModelScope 下载稳定性一般,大文件建议用 screen/tmux 后台运行
  • MinerU v3.4.0 要求 CUDA 12+,驱动版本 525+

参考 链接到标题