Prhub

#49365 Detect ROCm wheel variant from environment for precompiled wheels.

原始 PR 作者 aarushjain29 合并时间 2026-08-14 12:19 文件变更 2 提交数 9 评论 16 代码增减 +302 / -12

执行摘要

修复 ROCm 预编译 wheel variant 检测,安装时按环境解析校验

PR body 明确指出:"Fixes AMD: Python-only Installation failing because ROCm precompiled wheels on wheels.vllm.ai use a different path layout than CUDA." 旧代码中 determine_wheel_url_rocm 只有一条 TODO("When we have ROCm nightly wheels, we can update this logic.")并回退到 AMD PyPI;如今 wheels.vllm.ai 已发布 ROCm nightly wheels(目录为 /rocm/{commit}/{variant}/,且 torch、triton、aiter、flash-attn 等多个包并列存放),原安装逻辑无法解析该布局,导致 AMD Python-only 安装失败。

值得 ROCm 相关维护者和构建基础设施工程师精读。核心设计亮点是「环境检测 × 发布集合 × 用户 override」三方交叉校验的 variant 解析策略,以及从 review 讨论中催生的 torch ABI 警告 UX(给出可复制的 pip/uv 命令)。可以关注 resolve_rocm_wheel_variant 的拒绝策略与 warn_if_rocm_torch_version_mismatch 的消息构造方式,对同类安装器/依赖解析代码有借鉴意义。

讨论亮点

核心讨论发生在 tjtanaa 对 setup.py 的 review 评论(line 840):他指出 wheels.vllm.ai 自定义的 PyPI endpoint 中存放了 torch、triton、aiter、flash-attn、vllm 等所有自定义包,而 "we are using a custom pytorch build. The torch-ABI might not match any official release even if we claim that we are at torch 2.11 here",因此要求增加检查:确保用户 torch 版本与 wheels.vllm.ai 发布版本一致,否则在警告信息中给出完整的 pip/uv 安装命令让用户从 vLLM 索引安装 torch 与 triton。aarushjain29 回复 "Fixed!",随后 tjtanaa 自己提交了 950d4d("complete the torch abi check logic")并合并进本 PR,最终 APPROVE。没有遗留未解决疑虑,但安装时仅警告不阻断的取舍值得注意。

实现拆解

  1. 扩展 metadata 拉取逻辑setup.pyprecompiled_wheel_utils.fetch_metadata_for_variant 新增 rocm: bool = False 关键字参数。CUDA 路径保持原行为;ROCm 路径下用新增的 LinkParser(HTMLParser 子类)抓取 https://wheels.vllm.ai/rocm/{commit}/{variant_dir} 页面中所有一级包目录(vllm、torch、triton、aiter 等),逐个拉取 metadata.json 并合并成单一列表,适配 ROCm 多包并存的布局。
  2. 新增 variant 检测与解析函数族rocm_version_to_variant(如 7.2.3 -> rocm723)、detect_system_rocm_variant(优先 get_rocm_version(),回退 torch.version.hip)、fetch_available_rocm_variants(正则 rocm\d+ 抓取发布集合)、resolve_rocm_wheel_variant(环境 variant 与用户 override、发布集合三方交叉校验,不匹配即返回 None)。
  3. 重构 determine_wheel_url_rocm:在本地 wheel 查找之后,新增从 wheels.vllm.ai 的 ROCm 布局解析 wheel 的路径:判断 commit 有效性、解析 variant、拉取合并 metadata,并在 metadata 中按 package_name == "vllm" 与架构匹配选取 wheel URL。variant 解析失败时不再依赖 AMD PyPI 的旧路径行为(原 AMD PyPI fallback 逻辑保留与否存在不确定性)。
  4. 新增 warn_if_rocm_torch_version_mismatch:对比当前安装的 torch 版本与 wheels.vllm.ai 发布的自定义 torch 构建版本,不一致时打印包含 torch 与 triton 精确版本的 pip/uv 安装命令,提示 ABI 可能不匹配。该逻辑源自 review 中 tjtanaa 的反馈,并由后续 commit 补全。
  5. 同步更新 tests/standalone_tests/python_only_compile.sh:预检脚本在 ROCm 环境(VLLM_TARGET_DEVICE=rocm 或存在 /opt/rocm 或 rocminfo)下,通过内嵌 Python 用 ctypes 读取 librocm-core.sogetROCmVersion 得到系统 ROCm 版本,与 wheels.vllm.ai 该 commit 的发布 variant 集合比对,构造正确的 metadata.json URL;环境 variant 无法检测或不匹配时直接报错退出。
  6. 测试配套:未新增独立单元测试,验证依赖 ROCm CI 中的 standalone 预检脚本(python_only_compile.sh)在真实构建环境下的执行,属于 CI 集成验证而非单测覆盖。
文件 模块 状态 重要度
setup.py 安装配置 modified 8.69
tests/standalone_tests/python_only_compile.sh 安装测试 modified 5.66

关键符号

rocm_version_to_variant detect_system_rocm_variant fetch_available_rocm_variants resolve_rocm_wheel_variant warn_if_rocm_torch_version_mismatch fetch_metadata_for_variant determine_wheel_url_rocm get_rocm_version

关键源码片段

tests/standalone_tests/python_only_compile.sh test-coverage

CI 预检脚本同步实现 ROCm variant 解析,确保 Python-only 安装测试在 ROCm 环境下检查正确的 metadata.json URL;无编译器环境下通过 ctypes 读取 librocm-core.so 获取系统 ROCm 版本。

# 仅在 ROCm 环境(目标设备或本机 ROCm 安装)下执行 variant 解析预检
if [[ "${_vllm_target_lower}" == "rocm" ]] || [[ -d /opt/rocm ]] || command -v rocminfo >/dev/null 2>&1; then
    # 内嵌 Python:通过 ctypes 读取 librocm-core.so 的 getROCmVersion,
    # 在无编译器、无 torch 的环境中也能拿到系统 ROCm 版本
    _rocm_env_variant="$(python3 - <<'PY'
import ctypes
import os
from pathlib import Path
​
​
def get_rocm_version() -> str | None:
    # 依次尝试 ROCM_HOME / ROCM_PATH / 默认安装路径 /opt/rocm
    rocm_home = os.environ.get("ROCM_HOME") or os.environ.get("ROCM_PATH") or "/opt/rocm"
    try:
        librocm_core = Path(rocm_home) / "lib" / "librocm-core.so"
        if not librocm_core.is_file():
            return None
        librocm = ctypes.CDLL(str(librocm_core))
        get_rocm_core_version = librocm.getROCmVersion
        major = ctypes.c_uint32()
        minor = ctypes.c_uint32()
        patch = ctypes.c_uint32()
        if get_rocm_core_version(
            ctypes.byref(major), ctypes.byref(minor), ctypes.byref(patch)
        ) == 0:
            return f"{major.value}.{minor.value}.{patch.value}"
    except Exception:
        return None
    return None
​
​
version = get_rocm_version()
if version:
    # 输出形如 rocm723 的 variant 名
    print(f"rocm{version.replace('.', '')}", end="")
PY
)"
    # 从 wheels.vllm.ai 拉取该 commit 已发布的 ROCm variant 集合
    _available_variants="$(curl -sf "https://wheels.vllm.ai/rocm/${merge_base_commit}/" \
        | grep -oP 'rocm\d+' | sort -u | tr '\n' ' ' || true)"    # 用户显式指定的 variant 必须与系统环境一致,否则直接报错退出
    if [[ -n "${VLLM_PRECOMPILED_WHEEL_VARIANT:-}" ]]; then
        _rocm_variant="${VLLM_PRECOMPILED_WHEEL_VARIANT}"
        if [[ -n "${_rocm_env_variant}" && "${_rocm_variant}" != "${_rocm_env_variant}" ]]; then
            echo "ERROR: VLLM_PRECOMPILED_WHEEL_VARIANT=${_rocm_variant} does not match detected environment ROCm variant ${_rocm_env_variant}" >&2
            exit 1
        fi
    else
        _rocm_variant="${_rocm_env_variant}"
    fi    # 环境 variant 必须存在于发布集合,否则预检失败
    if [[ -z "${_available_variants}" ]] \
            || [[ " ${_available_variants} " != *" ${_rocm_variant} "* ]]; then
        echo "ERROR: Environment ROCm variant '${_rocm_variant}' is not published for commit ${merge_base_commit} (available:${_available_variants:-none})" >&2
        exit 1
    fi    # 构造正确的 metadata.json URL,注意 ROCm 的路径布局与 CUDA 不同
    meta_json_url="https://wheels.vllm.ai/rocm/${merge_base_commit}/${_rocm_variant}/vllm/metadata.json"
else
    # CUDA 及默认路径保持原布局
    meta_json_url="https://wheels.vllm.ai/${merge_base_commit}/vllm/metadata.json"
fi

评论区精华

wheels.vllm.ai 自定义 torch 构建的 ABI 兼容性检查 正确性

tjtanaa 在 setup.py line 840 评论:wheels.vllm.ai 的索引中存放了 torch、triton、aiter、flash-attn、vllm 等自定义包,且 "we are using a custom pytorch build. The torch-ABI might not match any official release even if we claim that we are at torch 2.11 here"。要求检查用户 torch 版本与发布版本是否一致,否则在警告中提供从 vLLM 索引安装 torch 和 triton 的完整 pip/uv 命令。

结论:已实现 warn_if_rocm_torch_version_mismatch,并在后续 commit 950d4d(tjtanaa 的 "complete the torch abi check logic")中补全;aarushjain29 回复 "Fixed!",tjtanaa 最终 APPROVE。 · 已解决

风险与影响

  1. 安装路径新增网络依赖setup.py 安装阶段会访问 wheels.vllm.ai/rocm/{commit}/ 并解析 HTML(LinkParser)与正则提取 variant;若该页面结构变化、网络不可用或 commit 尚未发布,variant 解析可能返回空或失败,缺少独立单测覆盖这些失败模式。
  2. 更严格的校验可能误伤手动配置用户resolve_rocm_wheel_variant 会拒绝与系统环境不匹配的 VLLM_PRECOMPILED_WHEEL_VARIANT,这是有意设计(避免 ABI 损坏),但可能影响少数故意跨 variant 安装的用户行为。
  3. torch ABI 警告不阻断安装warn_if_rocm_torch_version_mismatch 仅输出 warning,用户可能忽略,后续出现扩展加载错误时排障成本仍高。
  4. bash 预检对 librocm-core.so 的依赖python_only_compile.sh 需要环境存在 librocm-core.sogetROCmVersion 符号;最小化容器或未来 ROCm 版本变更可能导致预检报错退出(fail-fast 行为)。
  5. CUDA 路径兼容性fetch_metadata_for_variant 签名变化但 CUDA 分支保持原逻辑,回归风险低;需确认无其他调用点遗漏新参数(提供了默认值,风险可控)。

用户影响:AMD/ROCm 平台上执行 Python-only 安装(无编译器)的用户是直接受益者,之前会因路径布局不匹配失败,现在可正确解析并校验 wheels.vllm.ai 发布的 ROCm wheel,并在 torch ABI 不匹配时获得明确的修复命令。
系统影响:安装阶段行为改变(新增网络探测与 HTML 解析、更严格的 variant 校验),对 CUDA 路径无影响。
团队影响:ROCm CI 的 standalone 预检脚本同步更新,CI 中 AMD Python-only 作业的失败模式会更早暴露(variant 不匹配直接报错);维护者需持续跟进 wheels.vllm.ai 页面结构变化。
影响程度:仅限 ROCm 平台的安装/CI 链路,运行时推理逻辑零改动,影响范围中等但明确。

安装路径新增网络依赖 ROCm 平台特定变更 缺少独立单元测试 更严格的 variant 校验可能误伤手动配置

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论