Prhub

#49925 [ROCm] Add TheRock preview docker updates, Keep Python 3.12 and Ubuntu 22.04

原始 PR 作者 rasmith 合并时间 2026-09-01 00:09 文件变更 7 提交数 72 评论 68 代码增减 +1384 / -7

执行摘要

ROCm 镜像切换到 TheRock 7.14 构建,保持 Python 3.12/Ubuntu 22.04

AMD 团队希望让 vLLM 的 ROCm 镜像使用 TheRock 7.14 提供的预编译 wheels,替代基于 rocm/dev-ubuntu-22.04:7.2.3-complete 的 legacy 构建。评论中 njhill 明确指出 TheRock 包含 legacy ROCm 构建缺失的关键修复(ROCm/rocm-systems#2451),这是 extensible kvcache 功能落地的前置条件。PR body 也说明这是 preview 版本,CI 中仍有 MI355 Language Models Tests 与 Entrypoints Integration (Pooling) 两组失败待处理。

值得精读,尤其适合维护 CI/发布管线的工程师。重点关注三处设计:一是 Dockerfile.rock 的 REMOTE_VLLM 双模式源码获取与 Rust 分层缓存,二是 triton constraints 解决 resolver 反复替换版本的工程细节,三是 TheRock pip 化 SDK 方案的运行时 hack。合并时 RCCL 多 GPU 问题仍未闭环,建议持续跟踪后续 AMD CI 是否出现 gfx1201 相关回归。

讨论亮点
  1. AITER 内核预编译开关:tjtanaa 质疑 AITER_PREBUILD_AITER_KERNELS=0 会让 AITER 在运行时 JIT 编译 C++ 代码导致极慢,AndreasKaratzas 表示 100% 同意;rasmith 解释 draft 阶段仅为开发便利,随后直接移除了该选项。
  2. bitsandbytes 兼容性:AndreasKaratzas 追问为何必须绕过 PyPI 指到 rasmith 的 fork,rasmith 说明一是被 bitsandbytes-foundation/bitsandbytes#1889 修复(影响 TheRock),二是 HIP backend 检测失败只有 CPU backend;最终切换为官方 bitsandbytes==0.50.0。
  3. Triton 版本 resolver 陷阱:rasmith 自述在 Dockerfile.rock 中至少有 5 处会被 resolver 把 ROCm 版 triton 换成 3.7.1 或降级到 CUDA 版 2.13,必须用 constraints 文件锁定,且源码安装缺 METADATA/RECORD 会导致无法阻止的 reinstall,需要 in-place 补丁。
  4. RCCL 多 GPU 启动失败(未闭环):tanpinsiang 报告在 gfx1201(Radeon AI PRO R9700)上 TP4/TP8 均报 "HIP failure: invalid device pointer",无模型参与的 torch.distributed all-reduce 即可复现,而 nightly 与 rocm7.14.0 dev 镜像正常;rasmith 请求提供 reproducer。合并者 dllehr-amd 的结论是:"If we can recreate the rccl error lets tackle it. Otherwise lets go"。
  5. MORI 版本调整:Rohan138 询问为什么 pin 到 f95cd5e,rasmith 解释该 commit 修复了 TheRock 下 MORI CMake 找不到 numa 的问题,并提到 ROCm/mori#541。

实现拆解

实现分四步:

  1. 新增 TheRock base 镜像构建(docker/Dockerfile.rock_base,+360 行):放弃 rocm/dev-ubuntu-22.04:7.2.3-complete 基础镜像,改为从 ubuntu:22.04 起步,通过 pip 安装 rocm[libraries,devel]==7.14.0 并执行 rocm-sdk init 生成 SDK 布局;随后按 PYTORCH_ROCM_ARCH 逐架构安装 amd-torch-device-<arch> 与 rocm-sdk-device-<arch> 预编译设备包,并附带多处 TheRock 运行时修复(rtld_global 改为 False、librocm_smi64.so.7 符号链接、ld.so.conf 写入 SDK 库路径)。

  2. 新增完整 vLLM 构建镜像(docker/Dockerfile.rock,+992 行):核心是 REMOTE_VLLM 双模式源码获取(本地 COPY 或远端稀疏克隆),以及 Rust 工具链/源码/版本探测三个独立阶段以最大化 Docker 层缓存复用;同时引入 sccache 可选缓存、AITER/MORI/flash-attention 内核构建、Triton 版本 constraints(防止 resolver 把 ROCm 版 triton 换成 CUDA 版 3.7.1)等。

  3. 构建依赖版本对齐(requirements/build/rocm.txt、requirements/build/rock.txt):index-url 从 https://download.pytorch.org/whl/rocm7.1 切换到 https://repo.amd.com/rocm/whl-multi-arch/,torch 升到 2.12.0+rocm7.14.0、torchvision 0.27.0、triton 3.7.1+git0263a6a6、packaging>=26.2;新增 rock.txt 以独立承载 TheRock 依赖链。

  4. 测试依赖修复与配置配套(requirements/test/rocm.in、pyproject.toml):在 rocm.in 中加入 bitsandbytes==0.50.0(TheRock 下 0.49.2 无法正确启用 HIP backend),并同步更新 rocm.txt lock 文件;pyproject.toml 的 typos 配置补充 a63ede7 哈希串白名单。

文件 模块 状态 重要度
docker/Dockerfile.rock_base 镜像构建 added 6.38
docker/Dockerfile.rock 镜像构建 added 6.1
requirements/test/rocm.in 测试依赖 modified 3.28
requirements/build/rock.txt 构建依赖 added 3.19
requirements/build/rocm.txt 构建依赖 modified 2.8
pyproject.toml 项目配置 modified 2.53
requirements/test/rocm.txt 测试依赖 modified 2.19

关键源码片段

docker/Dockerfile.rock_base infrastructure

新增 TheRock 基础镜像构建文件,是本次迁移的核心:从 ubuntu:22.04 + Python 3.12 起步,通过 pip 安装 ROCm 7.14 SDK 与逐架构设备包,并内嵌多处 TheRock 运行时修复。

# ------------------------------------------------------------------
# TheRock 方案:不再使用 rocm/dev-ubuntu-22.04:7.2.3-complete 作为 base,
# 而是从 ubuntu:22.04 起步,用 pip 安装 ROCm 7.14 SDK 的 wheel 包。
# ------------------------------------------------------------------
ARG SITE_PACKAGES=/usr/local/lib/python${PYTHON_VERSION}/dist-packages
ARG ROCM_RELEASE_WHEELS_MULTIARCH_URL="https://repo.amd.com/rocm/whl-multi-arch/"
ARG ROCM_NIGHTLY_WHEELS_MULTIARCH_URL="https://rocm.nightlies.amd.com/whl-multi-arch/"
ARG ROCM_SDK_VERSION=7.14.0
​
# 安装 ROCm SDK:libraries+devel 两个 extra 提供运行时与编译工具链,
# rocm-sdk init 负责生成统一的 SDK 目录布局(_rocm_sdk_core / _rocm_sdk_devel)。
RUN pip install --index-url ${ROCM_RELEASE_WHEELS_MULTIARCH_URL} \
    --extra-index-url ${ROCM_NIGHTLY_WHEELS_MULTIARCH_URL} \
    "rocm[libraries,devel]${ROCM_SDK_VERSION:+==${ROCM_SDK_VERSION}}" \
    && rocm-sdk init
​
# 按 PYTORCH_ROCM_ARCH 逐个安装 AMD 预编译设备包:
# amd-torch-device-<arch> 让 PyTorch 在对应 GPU 上可直接运行,
# rocm-sdk-device-<arch> 补齐该架构的设备库;arch 列表覆盖 CDNA 与 RDNA。
RUN TORCH_VER=$(python3 -c "import torch; print(torch.__version__)") \
    && for arch in $(echo "${PYTORCH_ROCM_ARCH}" | tr ';' ' '); do \
        echo "Installing device packages for ${arch}" \
        && pip install --index-url ${ROCM_RELEASE_WHEELS_MULTIARCH_URL} \
            --extra-index-url ${ROCM_NIGHTLY_WHEELS_MULTIARCH_URL} \
            amd-torch-device-${arch}==${TORCH_VER} \
            rocm-sdk-device-${arch}==${ROCM_SDK_VERSION}; \
    done
​
# TheRock 运行时修复:
# 1) rtld_global 改为 False,避免 RTLD_GLOBAL 污染符号解析;
# 2) 为 librocm_smi64 建立 .so.7 符号链接,兼容既有依赖版本;
# 3) 把 SDK 库目录写入 ld.so.conf,让动态链接器能找到 TheRock 的 pip 安装库。
RUN if [ -f "${SITE_PACKAGES}/rocm_sdk/__init__.py" ]; then \
        sed -i 's/rtld_global: bool = True/rtld_global: bool = False/g' \
            "${SITE_PACKAGES}/rocm_sdk/__init__.py"; \
    fi \
    && if [ -f "${SITE_PACKAGES}/_rocm_sdk_core/lib/librocm_smi64.so.1" ] \
        && [ ! -e "${ROCM_PATH}/lib/librocm_smi64.so.7" ]; then \
        ln -sfn "${SITE_PACKAGES}/_rocm_sdk_core/lib/librocm_smi64.so.1" \
            "${ROCM_PATH}/lib/librocm_smi64.so.7"; \
    fi \
    && printf '%s\n%s\n' "${ROCM_PATH}/lib" "${SITE_PACKAGES}/_rocm_sdk_core/lib" \
        > /etc/ld.so.conf.d/rocm-pip.conf \
    && ldconfig
docker/Dockerfile.rock infrastructure

新增完整 vLLM 构建镜像文件,承载 REMOTE_VLLM 双模式源码获取、Rust 分层缓存、sccache、AITER/MORI/FA 内核构建及 triton 约束,是 TheRock 生产构建的入口。

# 双模式源码获取:REMOTE_VLLM=0 直接 COPY 本地工作区;
# REMOTE_VLLM=1 则按 VLLM_REPO/VLLM_BRANCH 稀疏克隆远端仓库。
# 两种模式最终汇入同一个 fetch_vllm 阶段,保证下游构建入口一致。
FROM base AS fetch_vllm_0
ONBUILD COPY ./ vllm/
​
FROM base AS fetch_vllm_1
ARG VLLM_REPO
ARG VLLM_BRANCH
ONBUILD RUN git clone ${VLLM_REPO} \
    && cd vllm \
    && git fetch -v --prune -- origin ${VLLM_BRANCH} \
    && git checkout FETCH_HEAD \
    && if [ ${VLLM_REPO} != "https://github.com/vllm-project/vllm.git" ]; then \
        git remote add upstream "https://github.com/vllm-project/vllm.git" \
        && git fetch upstream; \
    fi
​
FROM fetch_vllm_${REMOTE_VLLM} AS fetch_vllm
​
# Rust 工具链输入单独成阶段:只携带 rust-toolchain.toml,
# 这样 Rust 源码变更不会使携带工具链的 ci_base 长寿命镜像失效。
FROM scratch AS rust_toolchain_input_0
COPY rust-toolchain.toml /rust-toolchain-input/vllm/rust-toolchain.toml
​
FROM base AS rust_toolchain_input_1
ARG VLLM_REPO
ARG VLLM_BRANCH
RUN git clone --no-checkout --filter=blob:none ${VLLM_REPO} /rust-toolchain-input/vllm \
    && cd /rust-toolchain-input/vllm \
    && git fetch -v --prune -- origin ${VLLM_BRANCH} \
    && git sparse-checkout init --no-cone \
    && git sparse-checkout set rust-toolchain.toml \
    && git checkout FETCH_HEAD
​
FROM rust_toolchain_input_${REMOTE_VLLM} AS rust-toolchain-input

评论区精华

AITER 内核是否应在构建期预编译 设计

tjtanaa 质疑新增的 AITER_PREBUILD_AITER_KERNELS=0 默认值:"Is this really intended to not prebuild? JIT is extremely slow when we still compile C++ code in AITER";AndreasKaratzas 回应 100% 同意。rasmith 说明 draft 阶段仅为开发便利,随后直接移除了该选项。

结论:移除预编译开关,回归 AITER 构建期预编译默认行为。 · 已解决

bitsandbytes 版本与 TheRock 兼容性 正确性

AndreasKaratzas 质疑为何必须用 fork 而非 PyPI 版本:"I don't get why the current version does not work with therock";rasmith 解释 bitsandbytes-foundation/bitsandbytes#1889 修复了 TheRock 下的问题,且 0.49.2 出现只有 CPU backend 的失败。最终切换到官方 bitsandbytes==0.50.0。

结论:采用官方 bitsandbytes==0.50.0,放弃 fork 依赖。 · 已解决

Triton 版本被 resolver 反复覆盖 设计

rasmith 自述在 Dockerfile.rock 中至少有 5 处会因 torch pin 的 triton==3.7.1 与 ROCm wheel 版本不匹配,导致 resolver 把想要的 triton 换掉,甚至安装 CUDA 版 triton 2.13;必须使用 constraints 文件,并对源码安装缺失的 METADATA/RECORD 做 in-place 补丁。Rohan138 随后建议与 PR#52819 的 pybind 3.0.4 和新 triton commit 对齐。

结论:保留 constraints 方案,并吸收 PR#52819 中的 pybind 与 triton pin。 · 已解决

RCCL 多 GPU 启动失败(gfx1201) 正确性

tanpinsiang 报告该 PR CI 镜像在 Radeon AI PRO R9700 上 TP4/TP8 均于 rank 1 报 "HIP failure: invalid device pointer",无模型的 torch.distributed all-reduce 可复现,而 vllm-openai-rocm:nightly 与 rocm7.14.0 dev 镜像无此问题;rasmith 请求提供 reproducer。合并者 dllehr-amd 表示若能复现则处理,否则先合并。

结论:合并时未复现、未定位根因,作为已知问题遗留。 · 待处理

MORI 版本 pin 的缘由 question

Rohan138 询问为什么 MORI pin 到 f95cd5e,rasmith 解释该 commit 修复了 TheRock 下 MORI 的 CMake 无法找到 numa 的问题,并提到 MORI 上游有 ROCm/mori#541,但合入下个版本更稳妥。

结论:维持 f95cd5e pin,等待 MORI 后续版本统一支持 TheRock。 · 已解决

风险与影响

  1. RCCL 启动失败未定位根因(gfx1201 多卡场景):TP4/TP8 均报 HIP failure: invalid device pointer 且与模型无关,合并时未复现、未闭环,可能影响新 RDNA 架构(gfx1201)的多卡用户。
  2. 全新镜像构建链路:Dockerfile.rock/rock_base 为从零新增,构建时间、缓存命中率、镜像体积均与旧链路不同;rust-input/toolchain 分层设计依赖 Docker 多阶段缓存行为,远端构建可能存在不确定性。
  3. 依赖跨大版本升级:torch 2.11 -> 2.12+rocm7.14.0、triton 3.6 -> 3.7.1 会改变 kernel 行为与算子实现;requirements/build/rocm.txt 同时影响非 TheRock 的 ROCm 构建,风险面不止新镜像。
  4. TheRock 运行时 hack 的脆弱性:sed 修改 rocm_sdk/__init__.py 的 rtld_global、手工建立 librocm_smi64.so.7 符号链接,都属于对上游 wheel 的 in-place 修改,上游一旦变更布局这些 hack 会静默失效。

影响范围是整个 AMD ROCm 用户群体与发布管线:合并后 vLLM 的 ROCm 镜像/CI 将以 TheRock 7.14 + torch 2.12 为基线,与 legacy ROCm 7.2.3 形成双轨(Rohan138 明确表示会同时发布两个版本一段时间)。对团队的直接影响是 AMD CI 全部改用新镜像,构建脚本维护成本转移;对用户的间接影响是后续 ROCm nightly 容器会携带 TheRock 修复(如 rocm-systems#2451),这是 extensible kvcache 等新功能在 AMD 上落地的前置条件。Python 3.12 与 Ubuntu 22.04 保持不变,兼容面受控。

RCCL 启动失败未闭环 全新镜像构建链路 跨大版本依赖升级 TheRock 运行时 hack 脆弱

关联 Issue

未识别关联 Issue

当前没有检测到明确关联的 Issue 链接,后续同步到相关引用后会出现在这里。

完整报告

参与讨论