执行摘要
- 一句话:CUDA 构建移除 Ubuntu 分支,统一改用 manylinux 镜像
- 推荐动作:值得发布工程与基础设施负责人精读 docker/Dockerfile 的 base 阶段:以 glibc floor 对齐 PyTorch 官方 wheel 作为构建基线决策是清晰的工程原则,单一构建路径消减双分支维护的收益明显。普通模型与推理工程师可略过。关注点:无自动化兼容性测试时如何用真实 release build 把关,以及 dnf 环境与 Ubuntu 环境的软件版本差异对 C++ 扩展编译的潜在影响。
功能与动机
PR body 直接声明 "Implemented the CUDA manylinux-only build path"。Dockerfile 中新增注释解释了关键动机:旧方案以 Ubuntu 22.04 为编译基线,glibc 版本被固化为 2.35,编译产物无法在 glibc 更低的发行版上运行;而 PyTorch 官方 wheel 以 manylinux2_28(glibc 2.28)为基线,只有对齐该基线才能保证 vLLM wheel 的广泛可移植性。同时移除 BUILD_OS 分支可消除 Dockerfile 中 apt/dnf 双路维护成本。
实现拆解
-
收敛 Dockerfile 构建基线:docker/Dockerfile 删除 ARG BUILD_OS、Ubuntu 分支的 apt 安装、gcc-11 update-alternatives、deadsnakes Python 引导等逻辑;系统依赖统一改为 dnf 安装,uv venv 固定使用 /opt/python/cpXY-cpXY/ 解释器;BUILD_BASE_IMAGE 默认值改为 pytorch/manylinux2_28-builder:cuda13.0。这是本 PR 的核心,后续所有构建方都依赖该镜像的 dnf 环境与预装 Python。
-
更新发布流水线:.buildkite/release-pipeline.yaml 移除 4 个 wheel 构建命令中的 BUILD_OS=manylinux 参数;将 CUDA 13.0/12.9 的 release image 构建的 BUILD_BASE_IMAGE 从 nvidia/cuda:-devel-ubuntu 改为 manylinux builder,并为原先依赖默认值的 CUDA 12.9 步骤显式补上该参数,避免默认值变化引起的漂移。
-
同步辅助构建入口:.buildkite/image_build/image_build_torch_nightly.sh 的 NIGHTLY_BUILD_BASE_IMAGE、.buildkite/scripts/hardware_ci/run-gh200-test.sh 与 .buildkite/image_build/image_build_arm64.sh 均补充或切换为 manylinux builder 镜像,保持 nightly 与硬件 CI 与主链路一致。
-
元数据与文档配套:docker/versions.json 更新 BUILD_BASE_IMAGE 默认值并删除 BUILD_OS 键;docs/getting_started/installation/gpu.cuda.inc.md 更新用户构建示例;重新生成 docs/assets/contributing/dockerfile-stages-dependency.png 依赖图。测试配套缺失:无自动化测试,仅依赖 Buildkite CI #82484 与 release-v2 #4740 真实构建验证。
关键文件:
docker/Dockerfile(模块 构建镜像;类别 infra;类型 infrastructure): 核心变更文件:移除 BUILD_OS 参数及所有 Ubuntu/manylinux 分支,构建依赖统一走 dnf,venv 引导固定使用 manylinux 自带 Python,BUILD_BASE_IMAGE 默认值改为 manylinux builder。整个 CUDA 构建链路的基线在此收敛。
.buildkite/release-pipeline.yaml(模块 发布流水线;类别 config;类型 configuration): 发布流水线关键配套:移除 wheel 构建命令中的 BUILD_OS 参数,将 release image 构建基镜像从 Ubuntu 切换为 manylinux,并为 CUDA 12.9 步骤显式补上 BUILD_BASE_IMAGE,直接影响正式发布产物。
docker/versions.json(模块 构建镜像;类别 infra;类型 infrastructure): 构建参数元数据同步:BUILD_BASE_IMAGE 默认值改为 manylinux,删除 BUILD_OS 键,避免后续调用方依赖已废弃的 Ubuntu 默认值。
.buildkite/image_build/image_build_torch_nightly.sh(模块 夜间构建;类别 other;类型 core-logic): 夜间构建入口同步:NIGHTLY_BUILD_BASE_IMAGE 指向 manylinux builder,保证 nightly 镜像与发布链路构建基线一致。
.buildkite/scripts/hardware_ci/run-gh200-test.sh(模块 硬件 CI;类别 infra;类型 infrastructure): GH200 硬件 CI 构建补上 BUILD_BASE_IMAGE,否则会因 Dockerfile 默认值变化而隐式切换构建基线。
docs/getting_started/installation/gpu.cuda.inc.md(模块 安装文档;类别 docs;类型 documentation): 用户文档同步:更新 aarch64/GB300 构建示例为 manylinux builder 镜像,避免用户按旧文档构建出基线不一致的镜像。
关键符号:未识别
关键源码片段
docker/Dockerfile
核心变更文件:移除 BUILD_OS 参数及所有 Ubuntu/manylinux 分支,构建依赖统一走 dnf,venv 引导固定使用 manylinux 自带 Python,BUILD_BASE_IMAGE 默认值改为 manylinux builder。整个 CUDA 构建链路的基线在此收敛。
# base 阶段:统一使用 PyTorch manylinux 构建镜像
# 该镜像自带 /opt/python/cpXY-cpXY/ 解释器并启用 EPEL,
# 因此系统依赖一律走 dnf,不再需要 BUILD_OS 分支。
# manylinux2_28 的 glibc 基线是 2.28,与 PyTorch 官方 wheel 对齐,
# 保证编译出的 wheel 在老发行版上也能运行。
ARG BUILD_BASE_IMAGE=pytorch/manylinux2_28-builder:cuda13.0
FROM ${BUILD_BASE_IMAGE} AS base
ARG CUDA_VERSION
ARG PYTHON_VERSION
# 安装构建工具链;ccache 由 manylinux 镜像启用的 EPEL 仓库提供。
# rdma-core-devel 提供 libibverbs 头文件,供 RDMA/KV connector 编译使用。
RUN dnf install -y --setopt=install_weak_deps=False \
ccache git curl sudo rdma-core-devel \
&& dnf clean all \
&& rm -rf /var/cache/dnf
# 安装 uv 并引导 /opt/venv:直接使用 manylinux 自带的
# /opt/python/cpXY-cpXY/ 解释器,而不是让 uv 重新下载托管 Python。
# 所有下游 stage(rust-build、csrc-build 等)继续复用 /opt/venv,
# 因此 venv 路径保持 distro-agnostic。
RUN mkdir -p "${UV_PYTHON_INSTALL_DIR}" "${UV_CACHE_DIR}" "${UV_INSTALL_DIR}" \
&& chmod -R a+rX /opt/uv \
&& curl -LsSf https://astral.sh/uv/install.sh | sh \
&& PYV_NODOT=$(echo ${PYTHON_VERSION} | tr -d '.') \
&& MANYLINUX_PY=/opt/python/cp${PYV_NODOT}-cp${PYV_NODOT}/bin/python${PYTHON_VERSION} \
&& uv venv --seed /opt/venv --python "$MANYLINUX_PY" \
&& rm -f /usr/bin/python3 /usr/bin/python3-config /usr/bin/pip \
&& ln -sf /opt/venv/bin/python3 /usr/bin/python3 \
&& ln -sf /opt/venv/bin/python3-config /usr/bin/python3-config \
&& ln -sf /opt/venv/bin/pip /usr/bin/pip
评论区精华
该 PR 的 review 无实质性技术讨论:claude[bot] 仅为自动提示,tlrmchlsmth 与 Harry-Chen 直接 APPROVED,没有 inline 评论。唯一的外部动作是 khluu 触发 Buildkite CI #82484 与 release-v2 #4740,说明变更通过发布构建验证后被合入,但也意味着 glibc 基线切换的兼容性结论主要依赖发布构建而非专项测试。
风险与影响
- 风险:
- 编译环境差异风险:docker/Dockerfile 从 Ubuntu apt 切换到 AlmaLinux 8 dnf 环境,GCC 版本、C++20 兼容性(原 Ubuntu 分支显式安装 gcc-11 并设置 alternatives,manylinux 镜像自带 GCC 需确认不低于 11.3,PyTorch C++20 头文件要求)、numactl-devel 等包在 dnf 源的可用性均需实测。风险集中在 docker/Dockerfile 的 base 阶段。
-
runtime 镜像纯净性风险:release image 构建阶段改用 manylinux,但 FINAL_BASE_IMAGE 仍为 nvidia/cuda:-base-ubuntu,若编译产物通过 RPATH 或动态链接引入构建期库的 glibc 依赖,存在运行时不匹配的可能;多数 CUDA 依赖为静态或捆绑式,但仍需在真实环境验证。
-
发布流程回归面:.buildkite/release-pipeline.yaml 中 CUDA 12.9 的 release image 构建此前依赖 Dockerfile 默认 Ubuntu base,现在显式指定 manylinux builder;若镜像 tag 命名(cuda12.9 vs cuda13.0)或构建器行为有差异,会影响发布产物。
-
测试证据缺失:PR body 的 Test Plan 为空,无 wheel 兼容性回归测试,合并依据主要是 release-v2 #4740 与常规 CI 成功。
- 影响:用户侧:CUDA wheel 的 glibc 基线从 2.35 降至 2.28,兼容范围扩大到更老的主流 Linux 发行版,对 pip 安装用户是正向变化,行为无其他影响。系统侧:Dockerfile 分支复杂度显著下降,未来只维护 dnf 单路,但任何需要 apt 专属包的新依赖都无法再在该构建阶段使用;versions.json 默认值已改,遗漏 BUILD_BASE_IMAGE 参数的调用会直接报错而非静默回退 Ubuntu。团队侧:CI/release/文档多处需手工同步更新,后续新增构建入口必须引用 manylinux 基线,否则构建行为与主链路不一致。
- 风险标记:构建链路基线变更, 发布流水线改动, 缺少测试覆盖, 编译环境切换(apt 到 dnf)
关联脉络
参与讨论