Files
mineru-rocm/docker/README.md
T
2026-06-12 14:49:07 +08:00

533 lines
17 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# MinerU AMD GPU Docker 部署指南
> **Ubuntu 24.04 + ROCm 7.2.1 + PyTorch 2.11.0+rocm7.2 + vllm main + MinerU 3.2.0**
> 面向原生 Linux,通过 Docker 容器化一键部署
> 实测通过:RX 9070 (gfx1201),其他 RDNA2/3/4 显卡按相同流程套用
---
## 0. 为什么用 Docker
| 方案 | 适用场景 |
|------|---------|
| **裸机部署**([MinerU本地部署教程.md](../MinerU本地部署教程.md)) | 单机开发、追求极致性能 |
| **Docker 部署**(本文) | 团队共享、CI/CD、环境隔离、快速迁移 |
Docker 方案的优势:
- 宿主机只需安装 ROCm 内核驱动 + Docker,不需要污染系统 Python/库
- 镜像一次构建,多机复用
- 模型和 MIOpen 缓存通过卷挂载持久化,容器重建不丢失
- 支持 CLI / WebUI / API 三种运行模式
**与 WSL2 教程的关键区别(原生 Linux 用户看这里)**:
| | WSL2 教程 | 本 Docker 文档 |
|:--|:--|:--|
| librocdxg 编译 | 必需 | **不需要**(原生 KFD 驱动) |
| Windows SDK | 必需 | **不需要** |
| vllm 平台检测补丁(9.10 节) | 必需 | **不需要**(amdsmi 原生可用) |
| Hyper-V / 镜像网络 / DNS | 必需 | **不需要**(Docker 网络独立) |
| ROCm 头文件补丁 | 5 个 | **5 个**(Dockerfile 自动应用) |
| MinerU RDNA 补丁 | 3 个 | **3 个**(Dockerfile 自动应用) |
---
## 1. 宿主机要求
### 1.1 硬件
| 项目 | 最低要求 | 推荐 |
|------|---------|------|
| GPU | AMD RDNA2/3/4 独显 | RX 7900 / RX 9070 / RX 7800 等 |
| 显存 | 8 GB | 16 GB+ |
| 内存 | 16 GB | 32 GB+ |
| 磁盘 | 50 GB | 100 GB+ (SSD) |
### 1.2 软件
| 组件 | 版本 | 说明 |
|------|------|------|
| 操作系统 | Ubuntu 24.04 (noble) | 也支持 22.04 (jammy),但需改用 ROCm 7.1.1 |
| ROCm 内核驱动 | 7.2.x | `amdgpu-dkms` + `rocm-dkms`,容器**共享宿主机内核驱动** |
| Docker | ≥ 24.0 | 需要 GPU 设备透传能力 |
| Docker Compose | ≥ 2.0 | 可选,简化容器管理 |
### 1.3 显卡兼容性
查自己的 gfx 代号:
```bash
rocminfo | grep gfx
```
| 显卡 | gfx 代号 | 编译参数 | 状态 |
|------|---------|---------|:--:|
| RX 9070 XT / 9070 / 9070 GRE | gfx1201 | `ARCH=gfx1201` | 实测通过 |
| RX 9060 XT / 9060 XT LP | gfx1200 | `ARCH=gfx1200` | ROCm 7.2 起正式支持 |
| RX 7900 XTX / XT / GRE | gfx1100 | `ARCH=gfx1100` | 原生支持 |
| RX 7800 XT / 7700 XT | gfx1101 | `ARCH=gfx1101` | ROCm 较新版原生支持 |
| RX 7600 XT / 7600 | gfx1102 | `ARCH=gfx1102` | vllm 支持,可能需伪装 |
| RX 6950 / 6900 / 6800 XT / 6800 | gfx1030 | `ARCH=gfx1030` | 预期可用 |
| RX 6750 XT / 6700 XT | gfx1031 | `ARCH=gfx1030` | 伪装编译 |
不支持的:RDNA1 (gfx1010/gfx1012)、Navi 23 (gfx1032/gfx1034)、APU 核显。
---
## 2. 宿主机准备
### 2.1 安装 ROCm 内核驱动(仅内核部分)
容器里的 ROCm 用户空间库是自带的,但**内核驱动必须在宿主机上**。
```bash
# 添加 AMD ROCm 仓库
wget https://repo.radeon.com/rocm/rocm.gpg.key -O - | \
sudo gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/rocm.gpg > /dev/null
echo 'deb [arch=amd64] https://repo.radeon.com/rocm/apt/7.2.1 noble main' | \
sudo tee /etc/apt/sources.list.d/rocm.list
sudo apt update
# 只装内核驱动部分(不装整个 ROCm 用户空间)
sudo apt install -y amdgpu-dkms rocm-dkms
# 把自己加入 render/video 组
sudo usermod -a -G render,video $USER
# 重启
sudo reboot
```
验证驱动:
```bash
ls /dev/kfd /dev/dri/render* # 三个设备节点都应该存在
/opt/rocm/bin/rocminfo # 如果装了 rocminfo
```
> **如果你已经完整安装过 ROCm 7.2.1**(包括用户空间),不需要重复装内核驱动,直接跳到 2.2。
### 2.2 安装 Docker
```bash
# 官方脚本(推荐)
curl -fsSL https://get.docker.com | sudo sh
# 把自己加入 docker 组,免 sudo
sudo usermod -aG docker $USER
newgrp docker
# 验证
docker run --rm hello-world
```
### 2.3 创建数据目录
```bash
mkdir -p ~/mineru-docker/data/{input,output,models,miopen}
cd ~/mineru-docker
```
将本仓库 `docker/` 目录下的所有文件复制到 `~/mineru-docker/`(或直接在仓库目录下操作)。
目录结构:
```
~/mineru-docker/
├── Dockerfile
├── docker-compose.yml
├── env.example
├── scripts/
│ └── cache_warmer.py
└── data/
├── input/ # 放待处理的 PDF
├── output/ # 处理结果输出
├── models/ # HuggingFace / ModelScope 模型缓存
└── miopen/ # MIOpen kernel 缓存
```
复制 `env.example` 并根据你的 GPU 修改:
```bash
cp env.example .env
# 编辑 .env,将 ARCH=gfx1201 改为你的 gfx 代号
```
---
## 3. 构建镜像
### 3.1 构建
```bash
# 方式一:docker build(直接指定 ARCH)
docker build \
--build-arg ARCH=gfx1201 \
--build-arg GIT_PROXY= \
-t mineru-rocm:7.2.1 \
-f Dockerfile .
# 方式二:docker compose(使用 .env 中的 ARCH)
docker compose build
```
构建时间参考:
- 下载 ROCm 包:~5 分钟
- 编译 vllm:30-45 分钟(LLVM 22,`-j4`)
- 安装 MinerU + 依赖:~3 分钟
- **总计:约 40-60 分钟**(首次,后续利用 Docker 层缓存会快很多)
如果编译中途 OOM 被杀(exit 137),把 Dockerfile 第 155 行的 `ninja -j4` 改成 `ninja -j2`。
### 3.2 关键构建参数
| 参数 | 默认值 | 说明 |
|------|--------|------|
| `ARCH` | `gfx1201` | GPU 架构代号,见 1.3 节表格 |
| `PYTHON_VER` | `3.12` | Python 版本 |
| `VENV` | `/opt/mineru_venv` | 虚拟环境路径 |
| `TORCH_INDEX` | `https://download.pytorch.org/whl/rocm7.2` | PyTorch wheel 源 |
| `GIT_PROXY` | 空 | 仅构建时访问 GitHub 用;例如 `http://host.docker.internal:8118` |
---
## 4. 运行容器
### 4.1 启动 WebUI 服务(默认推荐)
当前 `docker-compose.yml` 默认只启动一个 GPU 直连的 `gradio` WebUI 服务,避免单卡机器因为 `worker1` 或可选 Router 退出导致整组服务不可用:
| 服务 | 宿主机端口 | 容器内端口 | 用途 |
|------|------------|------------|------|
| `gradio` | `10002` | `7860` | WebUI 前端 + 本地推理 |
```bash
docker compose up -d
# 查看容器是否都已启动
docker compose ps -a
# WebUI 健康检查:应返回 HTML 或 HTTP 状态,而不是 Connection refused
curl -v http://localhost:10002/
```
浏览器打开:`http://<宿主机IP>:10002`。
如果 `docker compose ps` 为空或显示 `Exited`,说明服务进程启动后退出,请先看日志:
```bash
docker compose logs --tail=200 gradio
```
> 注意:直接 `docker run mineru-rocm:7.2.1` 使用的是 Dockerfile 默认 `CMD ["bash"]`,只会进入/运行 shell,不会启动 WebUI/API,也就不会监听 `10002`。如需直接 `docker run` 暴露 WebUI,必须显式传入 `mineru-gradio` 命令并映射端口。
### 4.2 交互模式(调试 / 手动处理)
```bash
# docker compose(复用 gradio 的 GPU/卷配置,覆盖 command 进入 bash)
docker compose run --rm gradio bash
# 或 docker run
docker run -it --rm \
--device /dev/kfd --device /dev/dri \
--security-opt seccomp=unconfined \
--group-add video \
--ipc host \
-v ./data/input:/data/input:ro \
-v ./data/output:/data/output \
-v ./data/models:/opt/models \
-v ./data/miopen:/root/.cache/miopen \
mineru-rocm:7.2.1
```
进入容器后,虚拟环境已自动激活,可直接使用:
```bash
# 验证 GPU
python -c "import torch; print(torch.cuda.is_available(), torch.cuda.get_device_name(0))"
# 处理 PDF
mineru -p /data/input/example.pdf -o /data/output -b hybrid-auto-engine
```
### 4.3 CLI 模式(一键处理)
```bash
docker compose run --rm gradio \
mineru -p /data/input/example.pdf -o /data/output -b hybrid-auto-engine
```
或修改 `docker-compose.yml` 的 `command` 为:
```yaml
command: mineru -p /data/input/example.pdf -o /data/output -b hybrid-auto-engine
```
### 4.4 可选:Router API 多 Worker 模式
如果确实需要独立 API Router,可启用 `router-api` profile。默认只启用 `worker0`,避免单卡机器启动 `worker1` 失败:
```bash
docker compose --profile router-api up -d
curl -v http://localhost:8000/
```
双卡时再启用 `dual-gpu` profile,并在 `.env` 中设置:
```env
ROUTER_API_URLS=http://mineru-worker0:8001,http://mineru-worker1:8002
```
```bash
docker compose --profile router-api --profile dual-gpu up -d
```
API 用法参考 [MinerU 官方文档](https://github.com/opendatalab/MinerU)。
### 4.5 中国用户:使用 ModelScope 下载模型
设置环境变量即可切换下载源:
```bash
docker compose run --rm -e MINERU_MODEL_SOURCE=modelscope gradio \
mineru -p /data/input/example.pdf -o /data/output -b hybrid-auto-engine
```
或修改 `.env`:`MINERU_MODEL_SOURCE=modelscope`
---
## 5. MIOpen 缓存预热
容器首次使用前,建议预热 MIOpen kernel 缓存(约 3-4 分钟)。缓存通过卷挂载持久化,只需执行一次。
```bash
# 进入容器
docker compose run --rm gradio bash
# 运行预热
python /opt/scripts/cache_warmer.py --device cuda --max_side 960 --step 32
```
| 输入尺寸 | 冷启动耗时 | 预热后 |
|---------|----------|-------|
| (1, 3, 544, 672) | ~1320 ms | ~30 ms |
| (1, 3, 416, 704) | ~1133 ms | ~30 ms |
缓存存在 `./data/miopen/`,升级 ROCm 版本后需重新预热。
---
## 6. 验证
```bash
docker compose run --rm gradio python -c "
import torch
from vllm.platforms import current_platform
print('=== Environment Check ===')
print(f'PyTorch : {torch.__version__}')
print(f'ROCm : {torch.version.hip}')
print(f'GPU : {torch.cuda.get_device_name(0)}')
print(f'GPU Avail: {torch.cuda.is_available()}')
print(f'Platform : {type(current_platform).__name__}')
print(f'is_rocm : {current_platform.is_rocm()}')
# 快速算力测试
x = torch.randn(100, 100).cuda()
print(f'Compute : {(x @ x).shape} PASS')
"
# 期望输出:
# PyTorch : 2.11.0+rocm7.2
# GPU Avail: True
# Platform : RocmPlatform
# is_rocm : True
# Compute : torch.Size([100, 100]) PASS
```
---
## 7. 性能参考(RX 9070,13 页 example.pdf)
| 阶段 | 耗时 / 速度 |
|:-----|:-----------|
| VLM 推理 (Two Step Extraction) | ~5 秒 (2+ it/s) |
| Layout Predict | 1.2-1.5 秒 |
| OCR-det | ~20 it/s |
| Processing pages | **65-71 it/s** |
| 13 页总耗时 | 5-7 秒 |
得益于 hipBLASLt 在线 GEMM 调优(ROCm 7.2 相比 7.1 提升约 106%)和 RX 9070 的 640 GB/s 显存带宽。
---
## 8. Dockerfile 补丁清单
Dockerfile 自动应用了以下所有补丁,了解即可(排查问题时有用):
| # | 补丁 | 目标文件 | 原因 |
|---|------|---------|------|
| 1 | hipcc/clang 符号链接 | 系统 | `hipcc.pl` 硬编码 `clang-17`,ROCm 7.2 实际带 `clang-22` |
| 2 | `__hip_internal::conditional` | `/opt/rocm/include/hip/*.h` | LLVM 22 不接受此命名空间 |
| 3 | `warpSize` 常量 | `amd_warp_functions.h` | `__AMDGCN_WAVEFRONT_SIZE` 在 LLVM 22 未定义 |
| 4 | `__activemask()` | `amd_warp_sync_functions.h` | 替换为 `__builtin_amdgcn_read_exec()` |
| 5 | mamba `operator+` 冲突 | `vllm csrc/mamba/.../selective_scan.h` | ROCm 7.2 头文件已自带定义 |
| A | imgW 32 对齐 | MinerU `predict_rec.py` | RDNA MIOpen 最优尺寸 |
| B | 批次填充 | MinerU `predict_rec.py` | 避免 MIOpen 冷启动 |
| C | contiguous 检查 | MinerU `predict_det.py` | RDNA 内存布局兼容 |
---
## 9. 常见问题
**Q: `docker: Error response from daemon: could not select device driver`**
Docker 没有 GPU 支持。安装 `nvidia-container-toolkit` 的 AMD 等价物——实际上 ROCm 不需要额外的 container runtime,只要 `/dev/kfd` 和 `/dev/dri` 存在即可。检查宿主机驱动:
```bash
ls /dev/kfd /dev/dri/render*
```
**Q: 容器启动后 `torch.cuda.is_available()` 返回 `False`**
1. 确认容器有 `--device /dev/kfd --device /dev/dri`
2. 确认 `--security-opt seccomp=unconfined`
3. 确认当前用户在宿主机的 `render` 和 `video` 组
4. 容器内运行 `rocminfo` 看能否检测到 GPU
**Q: 启动时报 `Unable to find group render: no matching entries in group file`**
这是因为 Docker Compose 的 `group_add` 使用的是容器内可解析的组名,而当前 Ubuntu 镜像内不一定存在 `render` 组。Compose 默认以 root 运行容器,并已透传 `/dev/kfd` 和 `/dev/dri`,因此默认只保留 `video` 组,不再添加 `render`。如果你改为非 root 用户运行容器,再按宿主机 `/dev/dri/render*` 的实际 GID 使用数字形式添加,例如 `group_add: ["109"]`。
**Q: `mineru-gradio` 启动时报 `ModuleNotFoundError`**
旧镜像只安装了 `mineru[core]`,可能缺少 WebUI CLI 依赖,例如 `click` 或 `gradio`。当前 Dockerfile 已显式安装 `click gradio`,并在构建期验证 `mineru.cli.gradio_app` 可导入、`mineru-gradio --help` 可执行。修改 Dockerfile 后需要重建镜像:
```bash
docker compose build --no-cache gradio
docker compose up -d --force-recreate
```
**Q: 任务失败并提示 `Please install vllm to use the vllm-async-engine backend`**
这通常不是简单的“没安装 vllm”,而是任务进程里 `import vllm` 或 `from vllm.platforms import current_platform` 失败,MinerU 将真实异常包装成了这句提示。先在容器内直接诊断:
```bash
docker compose exec gradio bash -lc '/opt/mineru_venv/bin/python - <<"PY"
import traceback
try:
import torch
import vllm
from vllm.platforms import current_platform
print("torch:", torch.__version__, "hip:", torch.version.hip)
print("vllm:", vllm.__version__)
print("platform:", type(current_platform).__name__, "is_rocm:", current_platform.is_rocm())
except Exception:
traceback.print_exc()
raise
PY'
```
当前入口脚本会在服务启动前执行同样的 vLLM 导入验证;如果验证失败,容器会直接退出并在 `docker compose logs gradio` 中显示真实 traceback,而不是等任务执行时才报泛化错误。
如果日志明确显示 `ModuleNotFoundError: No module named 'vllm'`,常见原因是 vLLM 分发元数据不可见,但 `/opt/vllm` 源码仍在。当前镜像已通过 `PYTHONPATH=/opt/vllm` 和入口脚本兜底保证可导入,避免 editable 安装触发 `pyproject.toml` 元数据校验失败。
```bash
export PYTHONPATH=/opt/vllm:${PYTHONPATH}
/opt/mineru_venv/bin/python -c "import vllm; print(vllm.__version__)"
```
入口脚本也会在启动时自动尝试这个修复。你也可以在旧容器里手动验证/修复一次:
```bash
docker compose exec gradio bash -lc 'export PYTHONPATH=/opt/vllm:${PYTHONPATH}; /opt/mineru_venv/bin/python -c "import vllm; print(vllm.__version__)"'
docker compose restart gradio
```
**Q: 构建时 `ninja` 被 kill(exit 137)**
内存不足。将 Dockerfile 中 `ninja -j4` 改为 `ninja -j2` 或 `ninja -j1`,或给 Docker 分配更多内存。
**Q: 构建在 CMake 下载阶段失败(`wget/curl exit code 4`)**
这通常是构建容器无法访问 GitHub,或把 `GIT_PROXY` 设成了容器内不可达地址(例如 `127.0.0.1:8118` 在多数 Docker 场景下指向容器自己,不是宿主机代理)。建议:
1. 不需要代理时,显式传空:`--build-arg GIT_PROXY=`
2. 需要宿主机代理时,优先用:`http://host.docker.internal:8118`
3. 先单独测试下载连通性,再完整构建
```bash
docker build --build-arg GIT_PROXY= -t mineru-rocm:7.2.1 -f Dockerfile .
# 或(宿主机代理)
docker build --build-arg GIT_PROXY=http://host.docker.internal:8118 -t mineru-rocm:7.2.1 -f Dockerfile .
```
**Q: 构建时 cmake 报 `Failed to find ROCm root directory`**
`/opt/rocm/bin` 不在 PATH 中。检查 Dockerfile 中 `ENV PATH` 是否正确设置。
**Q: 构建时 cmake 报 `roc::hipsparselt target not found`**
`hipsparselt-dev` 没装上。检查 Dockerfile 阶段 6 的 apt install 列表。
**Q: MinerU 运行时很慢(单页 > 10 秒)**
大概率 MIOpen 在冷启动。先跑一次 `cache_warmer.py`。
**Q: HuggingFace 连不上 / 模型下载失败**
切换下载源:`MINERU_MODEL_SOURCE=modelscope`。或设置代理:
```bash
docker compose run --rm -e http_proxy=http://host:port -e https_proxy=http://host:port worker0 bash
```
**Q: WebUI/API 端口无法访问**
检查 `docker-compose.yml` 中 `ports` 是否取消注释。检查宿主机防火墙。
**Q: 显存不足 (Out of Memory)**
- 8GB 显卡设置 `MINERU_VIRTUAL_VRAM_SIZE=6` 触发保守策略
- 或改用 pipeline 后端:`mineru -p input.pdf -o output -b pipeline`
---
## 10. 镜像体积优化(可选)
完整镜像约 25-30 GB(含 ROCm 库、vllm 编译产物、Python 包)。如需优化:
```dockerfile
# Dockerfile 构建完成后追加清理阶段:
RUN rm -rf /opt/vllm_build /opt/vllm/.git /opt/aiter/.git /opt/flash-attention/.git && \
apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* && \
${VENV}/bin/pip cache purge
```
---
## 11. 升级指南
### 升级 MinerU
```bash
docker compose run --rm gradio pip install --upgrade 'mineru[core]'
# 然后重新应用 RDNA 补丁(参考 Dockerfile 阶段 9)
```
### 升级 vllm / ROCm
重新构建镜像即可(补丁在 Dockerfile 中自动重应用):
```bash
docker compose build --no-cache
```
> ROCm 版本的补丁 1-4 需要 sudo 权限,构建时 Docker 容器内默认为 root,无需额外处理。
---
*文档最后更新: 2026-06-03*
*实测环境:Ubuntu 24.04 + AMD RX 9070 (gfx1201) + ROCm 7.2.1 + PyTorch 2.11.0+rocm7.2 + vllm main + MinerU 3.2.0*