diff --git a/docker/.dockerignore b/docker/.dockerignore new file mode 100644 index 0000000..02f49fb --- /dev/null +++ b/docker/.dockerignore @@ -0,0 +1,4 @@ +# 预克隆的仓库目录在构建时 COPY 进镜像,不要忽略 +!aiter +!flash-attention +!vllm diff --git a/docker/Dockerfile b/docker/Dockerfile index 1dcfa12..c0a91ac 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -144,39 +144,34 @@ RUN if [ -d /opt/rocm/share/amd_smi ]; then \ fi # =========================================================================== -# 阶段 7:amd-aiter + flash_attn +# 阶段 7:amd-aiter + flash_attn(宿主机预克隆,COPY 进镜像) # =========================================================================== +# 构建前请先在宿主机 docker/ 目录下克隆: +# git clone --depth 1 --recursive https://github.com/ROCm/aiter.git +# git clone --depth 1 https://github.com/Dao-AILab/flash-attention.git +# cd flash-attention && git checkout bba578d43974c1d3ba157ab597124dd0fe2ccdb4 +# git submodule update --init --depth 1 && cd .. +# =========================================================================== +COPY aiter/ /opt/aiter/ +COPY flash-attention/ /opt/flash-attention/ RUN set -ex && \ - # git 通过代理访问 GitHub - git config --global http.proxy ${GIT_PROXY} && \ - git config --global https.proxy ${GIT_PROXY} && \ - git config --global http.version HTTP/1.1 && \ - git config --global http.postBuffer 524288000 && \ # aiter(AMD 优化的 attention 算子) - cd /opt && git clone --recursive --depth 1 https://github.com/ROCm/aiter.git && \ ${VENV}/bin/pip install --no-cache-dir -e /opt/aiter && \ # flash_attn(Triton AMD 后端,锁定已验证的 commit) - cd /opt && git clone --recursive https://github.com/Dao-AILab/flash-attention.git && \ - cd flash-attention && git checkout bba578d43974c1d3ba157ab597124dd0fe2ccdb4 && \ ${VENV}/bin/pip install --no-cache-dir --no-build-isolation -e /opt/flash-attention && \ # 验证 PyTorch 没被覆盖 ${VENV}/bin/python -c "import torch; v=torch.__version__; assert 'rocm' in v, f'PyTorch overwritten: {v}'; print('PyTorch OK:', v)" # =========================================================================== -# 阶段 8a:编译 vllm(git clone + cmake + ninja,最耗时,单独一层缓存) +# 阶段 8a:编译 vllm(宿主机预克隆 + COPY,cmake + ninja,最耗时,单独一层缓存) +# 构建前请在宿主机 docker/ 目录下克隆: +# git clone --depth 1 https://github.com/vllm-project/vllm.git # =========================================================================== +COPY vllm/ /opt/vllm/ RUN set -ex && \ - # git 通过代理访问 GitHub(国内不通) - git config --global http.proxy ${GIT_PROXY} && \ - git config --global https.proxy ${GIT_PROXY} && \ - # 代理下大仓库容易断,改用 HTTP/1.1 + 加大 buffer - git config --global http.version HTTP/1.1 && \ - git config --global http.postBuffer 524288000 && \ # setuptools 升级(PEP 639 兼容) ${VENV}/bin/pip install --no-cache-dir -U \ "setuptools>=77.0.3" setuptools_scm setuptools_rust wheel && \ - # 克隆 vllm main - cd /opt && git clone --depth 1 https://github.com/vllm-project/vllm.git && \ # 补丁 5:注释掉 vllm mamba 模块的 operator+ 定义(可能已被 vllm 移除) cd /opt/vllm && \ if [ -f csrc/mamba/mamba_ssm/selective_scan.h ]; then \ diff --git a/docker/ISSUES.md b/docker/ISSUES.md new file mode 100644 index 0000000..1ea1fb2 --- /dev/null +++ b/docker/ISSUES.md @@ -0,0 +1,198 @@ +# Docker 构建问题汇总 + +> 目标:Ubuntu 24.04 + ROCm 7.2.1 + vllm + MinerU Docker 镜像 +> 环境:原生 Linux + RX 9070 (gfx1201) + Privoxy (127.0.0.1:8118) + +--- + +## 1. 网络类 + +### 1.1 Docker Hub 拉基础镜像超时 + +**现象**:`dial tcp [2a03:2880:...]:443 i/o timeout` + +**原因**:`docker.io` 被墙,IPv6 直连超时 + +**解决**:Docker daemon 配置代理 + 国内镜像加速器 + +```bash +# /etc/systemd/system/docker.service.d/http-proxy.conf +Environment="HTTP_PROXY=http://127.0.0.1:8118" +Environment="HTTPS_PROXY=http://127.0.0.1:8118" + +# /etc/docker/daemon.json +{ + "registry-mirrors": ["https://docker.1panel.live", ...], + "ipv6": false +} +``` + +### 1.2 容器内无法访问国内镜像 + +**现象**:`Could not resolve 'mirrors.tuna.tsinghua.edu.cn'` + +**原因**:Docker 默认 bridge 网络无法路由到外网 + +**解决**:`docker-compose.yml` 构建时加 `network: host`(非代理,只是共享宿主机网络栈) + +### 1.3 GitHub 直连失败 + +**现象**:`git clone github.com` → `GnuTLS recv error` / `TLS connection non-properly terminated` + +**原因**:GitHub 在国内不通,无可靠国内镜像 + +**解决**:git/wget 通过 Privoxy 代理访问 GitHub(**仅 GitHub**,其他源用国内镜像) + +```dockerfile +ARG GIT_PROXY=http://127.0.0.1:8118 +git config --global http.proxy ${GIT_PROXY} +# wget: export http_proxy=${GIT_PROXY} +``` + +### 1.4 git clone 代理断连 + +**现象**:`RPC failed; curl 92 HTTP/2 stream 5 was not closed cleanly: CANCEL` + +**原因**:HTTP/2 通过代理传大仓库不稳定 + +**解决**:禁用 HTTP/2 + 加大 buffer + +```bash +git config --global http.version HTTP/1.1 +git config --global http.postBuffer 524288000 +``` + +--- + +## 2. Dockerfile 语法类 + +### 2.1 ENV 行内注释导致解析失败 + +**现象**:`Syntax error - can't find = in "\ "`,行号为 `HSA_ENABLE_SDMA=1 \ # 注释` + +**原因**:Docker ENV 不允许行内 `#` 注释 + +**解决**:删除行内注释,或移到单独 `#` 行 + +### 2.2 多行 `python -c "..."` 被误解析 + +**现象**:`dockerfile parse error: unknown instruction: import` / `unknown instruction: from` + +**原因**:Docker 解析器把 Python `-c` 的多行字符串当作 Dockerfile 指令(`from x import y` → 误认为 `FROM`;`import x` → 误认为未知指令) + +**解决**:复杂 Python 代码写成独立脚本,用 `COPY` 进入镜像后 `python /opt/xxx.py` 执行 + +涉及的文件: +- `scripts/apply_mineru_patches.py` — MinerU RDNA 适配补丁 +- `scripts/patch_vllm_platform.py` — vllm 平台检测补丁 + +--- + +## 3. ROCm 兼容性类 + +### 3.1 版本号锁定失效 + +**现象**:`Version '1.0.0.70201-38~24.04' for 'rocminfo' was not found` + +**原因**:AMD 仓库更新后精确版本号过期 + +**解决**:改用 apt pinning 策略,不锁死版本号 + +```bash +# /etc/apt/preferences.d/rocm-pin-600 +Package: * +Pin: release o=repo.radeon.com +Pin-Priority: 600 +``` + +### 3.2 hipcc.pl 符号链接创建损坏链接 + +**现象**:cmake 报 `Can't find CUDA or HIP installation`(PyTorch 的 `LoadHIP.cmake:179`) + +**原因**:`ln -sf /usr/bin/hipcc.pl /opt/rocm/bin/hipcc`,`/usr/bin/hipcc.pl` 在原生 Linux 上不存在,创建了损坏的符号链接 + +**解决**:条件创建,源文件不存在时跳过 + +```bash +([ -f /usr/bin/hipcc.pl ] && ln -sf /usr/bin/hipcc.pl /opt/rocm/bin/hipcc) || echo "hipcc.pl not found" +``` + +### 3.3 缺 rocm-cmake 导致 find_package(HIP) 失败 + +**现象**:PyTorch `LoadHIP.cmake:179` 调用 `find_package_and_print_version` 找不到 HIP + +**原因**:未安装 `rocm-cmake` 包,缺少 HIP cmake 发现模块 + +**解决**:在阶段 6 加装 `rocm-cmake` + +### 3.4 vllm mamba operator+ 补丁失效 + +**现象**:`sed: can't read csrc/mamba/mamba_ssm/selective_scan.h: No such file or directory` + +**原因**:vllm 上游已移除 mamba 模块 + +**解决**:改为条件判断,文件不存在就跳过 + +```bash +if [ -f csrc/mamba/mamba_ssm/selective_scan.h ]; then sed ...; else echo "skipping"; fi +``` + +### 3.5 原生 Linux 需要 amdsmi + 平台检测补丁 + +**现象**(社区反馈):`ModuleNotFoundError: amdsmi` → `current_platform = UnspecifiedPlatform` → `Device string must not be empty` + +**原因**:amdsmi 未安装,且 `logger.warning_once()` 触发 vllm 循环导入 + +**解决**: +1. 安装 amdsmi(原生 Linux 上可用,WSL2 不需要) +2. 补丁 6:`platforms/__init__.py` 加 `torch.version.hip` 兜底 +3. 补丁 7:`platforms/rocm.py` 中 `logger.warning_once()` → `sys.stderr.write()` + +### 3.7 cmake 需显式设 HIP 编译器路径 + +**现象**:仅设 `PATH` + `HIP_ROOT_DIR` + `ROCM_PATH` 不足以让 cmake 发现 HIP + +**解决**:显式指定 + +``` +-DCMAKE_HIP_COMPILER=/opt/rocm/llvm/bin/clang++ # (非 hipcc,CMake 4.0 拒绝) +-DHIP_COMPILER=/opt/rocm/llvm/bin/clang++ # PyTorch LoadHIP 也需要 +-DHIP_PATH=/opt/rocm +-DCMAKE_PREFIX_PATH="/opt/rocm;..." +``` + +--- + +## 4. Docker 缓存策略 + +### 4.1 vllm 编译+验证同层导致缓存丢失 + +**现象**:ninja 编译 30 分钟成功后被后面验证失败拖垮,全部重来 + +**解决**:拆为 8a(编译)和 8b(安装+验证) + +| 层 | 内容 | 缓存行为 | +|:--|:--|:--| +| 8a | git clone + cmake + ninja | 编译成功即缓存,**永不丢失** | +| 8b | pip install + PyTorch 修复 + 平台补丁 | 失败可重试,不影响 8a | + +### 4.2 缓存失效条件 + +任一 RUN 层的指令或上下文变化都会导致该层及之后所有层重建。修改 `ARG`、`ENV`、`COPY` 文件内容均会触发。 + +--- + +## 5. 网络策略总览 + +| 资源 | 访问方式 | +|:--|:--| +| Docker Hub | daemon 代理 + 国内镜像加速器 | +| Ubuntu apt | 清华镜像 `mirrors.tuna.tsinghua.edu.cn` | +| PyPI pip | 清华镜像 `pypi.tuna.tsinghua.edu.cn/simple` | +| AMD ROCm apt | `repo.radeon.com` 直连 | +| PyTorch ROCm wheels | `download.pytorch.org` 直连 | +| GitHub (git/wget) | **Privoxy 代理 127.0.0.1:8118**(唯一例外) | + +--- + +*最后更新: 2026-06-04* diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 68a821d..95e84ab 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -18,8 +18,6 @@ services: # gfx1101 = RX 7800 XT / 7700 XT # gfx1030 = RX 6950 / 6900 / 6800 系列 ARCH: gfx1201 - # ---- Git 代理(仅 GitHub 需要,国内无镜像)---- - GIT_PROXY: http://127.0.0.1:8118 container_name: mineru-rocm stdin_open: true tty: true