diff --git a/docker/Dockerfile b/docker/Dockerfile index 95074ef..14c5591 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -294,27 +294,38 @@ COPY scripts/cache_warmer.py /opt/scripts/cache_warmer.py # =========================================================================== RUN set -ex && \ export http_proxy=${GIT_PROXY} https_proxy=${GIT_PROXY} && \ - # 1) 准备 vllm editable 安装所需构建工具(--no-build-isolation 必须预装) + # 1) 安装构建工具(后续 pip install 需要) ${VENV}/bin/pip install -U "setuptools>=77.0.3" setuptools_scm setuptools_rust wheel && \ - # 2) 注册 vllm 源码包,不让 pip 解析 torch 依赖 + # 2) 手动注册 vllm 为 editable package(阶段 8a 已编译 C++ 扩展,此处不触发 cmake) cd /opt/vllm && \ - ${VENV}/bin/pip install -e . --no-build-isolation --no-deps && \ - # 2) 安装 ROCm PyTorch(后续依赖解析用 ROCm 源补齐 triton-rocm) + mkdir -p vllm.egg-info && \ + cat > vllm.egg-info/PKG-INFO << 'VLLM_EOF' && \ +Metadata-Version: 2.1 +Name: vllm +Version: 0.0.0 +Summary: A high-throughput and memory-efficient inference and serving engine for LLMs +VLLM_EOF + echo "vllm" > vllm.egg-info/top_level.txt && \ + touch vllm.egg-info/dependency_links.txt && \ + touch vllm.egg-info/requires.txt && \ + find vllm -name "*.py" -type f 2>/dev/null | sort > vllm.egg-info/SOURCES.txt && \ + echo "vllm egg-info created (cmake build skipped, C++ extensions from stage 8a)" && \ + # 3) 安装 ROCm PyTorch(后续依赖解析用 ROCm 源补齐 triton-rocm) (${VENV}/bin/pip uninstall -y triton triton-rocm 2>/dev/null || true) && \ ${VENV}/bin/pip install --force-reinstall \ torch==2.11.0+rocm7.2 torchvision pytorch-triton-rocm \ --index-url ${TORCH_INDEX} && \ ${VENV}/bin/python -c "import torch; v=torch.__version__; assert 'rocm' in v, f'PyTorch overwritten: {v}'; print('PyTorch OK:', v)" && \ - # 3) 安装 vllm 运行时依赖;额外加入 ROCm PyTorch 源,避免传递依赖解析 triton-rocm 失败 + # 4) 安装 vllm 运行时依赖;额外加入 ROCm PyTorch 源,避免传递依赖解析 triton-rocm 失败 grep -vE '^(torch|torchvision|torchaudio|triton|triton-rocm|pytorch-triton|setuptools)' requirements/common.txt > /tmp/vllm_deps.txt && \ ${VENV}/bin/pip install -r /tmp/vllm_deps.txt --extra-index-url ${TORCH_INDEX} && \ - # 4) 再次确认 PyTorch 仍是 ROCm 版 + # 5) 再次确认 PyTorch 仍是 ROCm 版 ${VENV}/bin/python -c "import torch; v=torch.__version__; assert 'rocm' in v, f'PyTorch overwritten after vllm deps: {v}'; print('PyTorch still OK:', v)" && \ - # 5) 深度验证 vllm(确保 AsyncEngineArgs、AsyncLLM 等关键模块可导入,缺包直接构建失败) + # 6) 深度验证 vllm(确保 AsyncEngineArgs、AsyncLLM 等关键模块可导入,缺包直接构建失败) ${VENV}/bin/python -c "from vllm.engine.arg_utils import AsyncEngineArgs; from vllm.v1.engine.async_llm import AsyncLLM; print('vllm deep import OK:', __import__('vllm').__version__)" && \ - # 6) 确保 mineru-api 子进程不依赖 PYTHONPATH 也能导入 vllm + # 7) 确保 mineru-api 子进程不依赖 PYTHONPATH 也能导入 vllm echo "/opt/vllm" > ${VENV}/lib/python${PYTHON_VER}/site-packages/vllm.pth && \ - # 7) 锁定 ROCm 关键包版本(不含 setuptools,避免与 vllm/mineru 依赖冲突) + # 8) 锁定 ROCm 关键包版本(不含 setuptools,避免与 vllm/mineru 依赖冲突) ${VENV}/bin/pip freeze | grep -iE "^(torch|vllm|triton|pytorch.triton|torchvision|flash.attn|aiter)" >> ${VENV}/torch-constraint.txt && \ rm -rf /opt/vllm_build diff --git a/docker/ISSUES.md b/docker/ISSUES.md index 6448f18..3d9c782 100644 --- a/docker/ISSUES.md +++ b/docker/ISSUES.md @@ -291,4 +291,94 @@ set_target_properties(miopen PROPERTIES --- -*最后更新: 2026-06-05* +## 6. 构建阶段类 + +### 6.1 阶段 8b `pip install -e .` 触发 cmake 配置失败 + +**现象**:阶段 8a(cmake + ninja 手动编译)成功,但阶段 8b 执行 `pip install -e . --no-build-isolation --no-deps` 时报错: + +``` +TorchConfig.cmake:62 (find_package) + → CMakeLists.txt:95 (find_package) + → Configuring incomplete, errors occurred! + error: failed-wheel-build-for-install + × Failed to build installable wheels for some pyproject.toml based projects + ╰─> vllm +``` + +**排查过程**: + +Dockerfile 设计为阶段 8a 手动执行 `cmake -S ... -B ... -G Ninja`(携带完整 `-D` 参数)编译 vllm C++ 扩展并复制 `.abi3.so` 文件,阶段 8b 再用 `pip install -e .` 注册 Python 包。但 `pip install -e .` 通过 vllm 的 setuptools 构建扩展**再次触发 cmake**,且 vllm 内部的 cmake 调用与手动 cmake 在以下方面不可控: + +1. **尝试一(ENV 透传)**:在 Dockerfile `ENV` 块中添加 `CMAKE_PREFIX_PATH`、`CMAKE_HIP_COMPILER`、`ROCM_PATH` 等 8 个 cmake 环境变量,期望 pip 触发的 cmake 继承这些值。**无效**——vllm 的 `cmake_build_ext` 内部会独立构造 cmake 参数,不完全依赖环境变量。 +2. 错误始终出现在 `TorchConfig.cmake:62` 调用 `find_package(Caffe2)` 时,Caffe2 targets 引用的 ROCm cmake 目标无法被 pip 触发的 cmake 解析。 + +**结论**:`pip install -e .` 触发的 cmake 构建过程与阶段 8a 的手动 cmake 不在同一个可控环境中,且阶段 8b 的 `pip install -e .` 本质上是**冗余的**——C++ 扩展已在阶段 8a 编译完成。 + +**最终解决**:**跳过 pip install -e .,手动创建 vllm editable package 元数据**。 + +核心思路:阶段 8a 负责所有 C++ 编译(`.abi3.so`),阶段 8b 只负责 Python 包注册(不触发 cmake)。 + +具体改动(Dockerfile 阶段 8b): + +```bash +# 替换前(会触发 cmake,失败): +cd /opt/vllm && \ +${VENV}/bin/pip install -e . --no-build-isolation --no-deps && \ + +# 替换后(手动创建 egg-info,不触发 cmake): +cd /opt/vllm && \ +mkdir -p vllm.egg-info && \ +cat > vllm.egg-info/PKG-INFO << 'VLLM_EOF' && \ +Metadata-Version: 2.1 +Name: vllm +Version: 0.0.0 +Summary: A high-throughput and memory-efficient inference and serving engine for LLMs +VLLM_EOF +echo "vllm" > vllm.egg-info/top_level.txt && \ +touch vllm.egg-info/dependency_links.txt && \ +touch vllm.egg-info/requires.txt && \ +find vllm -name "*.py" -type f 2>/dev/null | sort > vllm.egg-info/SOURCES.txt && \ +echo "vllm egg-info created (cmake build skipped, C++ extensions from stage 8a)" && \ +``` + +手动创建的 egg-info 包含以下文件: + +| 文件 | 内容 | 用途 | +|------|------|------| +| `PKG-INFO` | `Name: vllm` + `Version: 0.0.0` | `pip freeze` / `importlib.metadata` 识别 | +| `top_level.txt` | `vllm` | 声明顶层包名 | +| `SOURCES.txt` | 所有 `.py` 文件列表 | 包文件索引 | +| `dependency_links.txt` | 空文件 | 依赖链接(无) | +| `requires.txt` | 空文件 | 运行依赖(由后续 pip install -r 安装) | + +`import vllm` 的路径解析由现有的 `.pth` 文件保证: + +```bash +echo "/opt/vllm" > ${VENV}/lib/python${PYTHON_VER}/site-packages/vllm.pth +``` + +**附:ENV 块新增的 cmake 变量(保留,对阶段 8a 和其他 cmake 调用有益)**: + +```dockerfile +ENV ... \ + CMAKE_PREFIX_PATH=/opt/rocm \ + CMAKE_HIP_COMPILER=/opt/rocm/llvm/bin/clang++ \ + HIP_COMPILER=/opt/rocm/llvm/bin/clang++ \ + HIP_PATH=/opt/rocm \ + HIP_ROOT_DIR=/opt/rocm \ + HIP_INCLUDE_DIR=/opt/rocm/include \ + HIP_PLATFORM=amd \ + ROCM_PATH=/opt/rocm +``` + +**效果**: + +- 阶段 8b 不再触发 cmake,消除了冗余编译(节省约 30 分钟) +- C++ 扩展只在阶段 8a 编译一次,职责清晰 +- `pip list` / `pip freeze` 正常显示 vllm +- `import vllm` 在所有 Python 进程中正常工作 + +--- + +*最后更新: 2026-06-17*