Prhub

#46527 [ROCm][CI] Cache Rust builds by source inputs

原始 PR 作者 AndreasKaratzas 合并时间 2026-07-13 14:14 文件变更 3 提交数 8 评论 4 代码增减 +337 / -37

执行摘要

ROCM CI Rust 构建缓存优化,避免非 Rust 变更时重复编译

PR body 指出 ROCm Docker 路径中即使 PR 未改动 Rust 代码,Rust 构建也会被触发,因为 build_rixl 阶段继承了完整的源代码树,任何仓库变更都会导致 cargo 构建层失效。通过缩小输入范围并引入内容哈希缓存,避免不必要的重复编译。

推荐 CI 和构建团队精读,特别是 Docker 多阶段缓存和内容哈希模式,可复用于其他高频编译模块。

讨论亮点
  • @tjtanaa 询问 AMD CI 是否使用 REMOTE_VLLM=1,作者确认使用但指出历史不清晰。该参数控制从远程仓库克隆代码,影响缓存输入路径。
  • @depthfirst-app[bot] 建议对 curl ... | sh 远程脚本安装增加校验和验证,降低安全风险。作者未回应此建议。

实现拆解

  1. 分离 Rust 工具链与源码输入阶段docker/Dockerfile.rocm):新增 rust_toolchain_input_0/1rust_input_0/1 阶段,分别使用 scratch 拷贝或 git sparse-checkout 仅获取必需的 Rust 文件,最终通过 REMOTE_VLLM 参数选择本地或远程源。

  2. 添加内容哈希计算与缓存参数.buildkite/scripts/ci-bake-rocm.sh):新增 compute_rocm_rust_content_hashcompute_rocm_rust_content_hash_if_needed 函数,计算 Rust 输入文件的哈希值,并设置 --cache-from--cache-to 参数将哈希写入 Docker 缓存标签。

  3. 配置 HCL 缓存函数docker/ci-rocm.hcl):新增 get_cache_from_rocm_rustget_cache_to_rocm_rust 函数,以及 ROCM_RUST_CACHE_TO_MODE 变量,使 Rust 构建层的缓存可独立读取和导出。

配套修改:将 rust-toolchain.toml 等文件加入 CI 基础镜像内容文件列表,确保哈希准确。

文件 模块 状态 重要度
.buildkite/scripts/ci-bake-rocm.sh CI 脚本 modified 5.54
docker/Dockerfile.rocm Dockerfile modified 5.06
docker/ci-rocm.hcl 构建配置 modified 4.32

关键符号

uses_rocm_rust_cache compute_rocm_rust_content_hash compute_rocm_rust_content_hash_if_needed get_cache_from_rocm_rust get_cache_to_rocm_rust

关键源码片段

docker/Dockerfile.rocm infrastructure

Docker 构建定义,重组 Rust 阶段以分离输入,实现精确缓存依赖。

# Rust/protoc toolchain inputs——独立于源码,避免源码变更影响工具链缓存
FROM scratch AS rust_toolchain_input_0
COPY rust-toolchain.toml /rust-toolchain-input/vllm/rust-toolchain.toml
COPY tools/install_protoc.sh /rust-toolchain-input/vllm/tools/install_protoc.sh
​
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 \
       tools/install_protoc.sh \
    && git checkout FETCH_HEAD
​
FROM rust_toolchain_input_${REMOTE_VLLM} AS rust-toolchain-input# Rust build inputs——仅包含编译 Rust 前端所需的文件
FROM scratch AS rust_input_0
COPY requirements/build/rust.txt /rust-input/vllm/requirements/build/rust.txt
COPY rust/Cargo.lock rust/Cargo.toml /rust-input/vllm/rust/
COPY rust/proto /rust-input/vllm/rust/proto
COPY rust/src /rust-input/vllm/rust/src
COPY rust-toolchain.toml /rust-input/vllm/rust-toolchain.toml
COPY tools/build_rust.py /rust-input/vllm/tools/build_rust.py
COPY build_rust.sh /rust-input/vllm/build_rust.sh
​
FROM base AS rust_input_1
ARG VLLM_REPO
ARG VLLM_BRANCH
RUN git clone --no-checkout --filter=blob:none ${VLLM_REPO} /rust-input/vllm \
    && cd /rust-input/vllm \
    && git fetch -v --prune -- origin ${VLLM_BRANCH} \
    && git sparse-checkout init --no-cone \
    && git sparse-checkout set \
       requirements/build/rust.txt \
       rust/Cargo.lock \
       rust/Cargo.toml \
       rust/proto/** \
       rust/src/** \
       rust-toolchain.toml \
       tools/build_rust.py \
       build_rust.sh \
    && git checkout FETCH_HEAD
​
FROM rust_input_${REMOTE_VLLM} AS rust-input
docker/ci-rocm.hcl infrastructure

HCL 配置文件,定义 Rust 缓存导入 / 导出函数,与 Shell 脚本配合生成正确的 --cache-from/to 参数。

# 从注册表拉取 Rust 构建缓存(精确提交、父提交、合并基、分支标签)
function "get_cache_from_rocm_rust" {
  params = []
  result = compact([
    BUILDKITE_COMMIT != "" ? "type=registry,ref=${DOCKERHUB_CACHE_REPO}:rust-rocm-${BUILDKITE_COMMIT}" : "",
    PARENT_COMMIT != "" ? "type=registry,ref=${DOCKERHUB_CACHE_REPO}:rust-rocm-${PARENT_COMMIT}" : "",
    VLLM_MERGE_BASE_COMMIT != "" ? "type=registry,ref=${DOCKERHUB_CACHE_REPO}:rust-rocm-${VLLM_MERGE_BASE_COMMIT}" : "",
    ROCM_CACHE_BRANCH_TAG != "" ? "type=registry,ref=${DOCKERHUB_CACHE_REPO}:rust-rocm-branch-${ROCM_CACHE_BRANCH_TAG}" : "",
    ROCM_CACHE_UPSTREAM_BRANCH_TAG != "" ? "type=registry,ref=${DOCKERHUB_CACHE_REPO}:rust-rocm-branch-${ROCM_CACHE_UPSTREAM_BRANCH_TAG}" : "",
  ])
}# 导出 Rust 构建缓存到注册表(精确提交和分支标签,模式由变量控制)
function "get_cache_to_rocm_rust" {
  params = []
  result = compact([
    BUILDKITE_COMMIT != "" ? "type=registry,ref=${DOCKERHUB_CACHE_REPO}:rust-rocm-${BUILDKITE_COMMIT},mode=${ROCM_RUST_CACHE_TO_MODE}" : "",
    ROCM_CACHE_BRANCH_TAG != "" ? "type=registry,ref=${DOCKERHUB_CACHE_REPO}:rust-rocm-branch-${ROCM_CACHE_BRANCH_TAG},mode=${ROCM_RUST_CACHE_TO_MODE}" : "",
  ])
}

评论区精华

AMD CI 是否使用 REMOTE_VLLM=1 question

tjtanaa 询问 AMD CI 是否使用 REMOTE_VLLM=1 参数,该参数决定使用远程克隆还是本地拷贝。

结论:AndreasKaratzas 确认 AMD CI 确实使用 REMOTE_VLLM=1,但指出历史不明确。 · 已解决

远程安装脚本安全风险 安全

depthfirst-app[bot] 指出 curl 管道安装 rustup 缺少校验和验证,建议先下载并验证。

结论:未在 PR 中解决,但严重性标记为 LOW。 · unresolved

风险与影响

  • 缓存逻辑复杂,新增多个阶段和哈希计算,可能引入缓存未命中或构建失败的风险,尤其是 REMOTE_VLLM=1 的网络依赖。
  • 安全建议未采纳:rustup 安装脚本直接管道执行,理论上存在被篡改风险,但 CI 环境通常可控。
  • 影响范围仅限 ROCm 后端 CI,其他平台无影响。
  • 用户:降低 ROCm Docker 镜像构建时间,减少 CI 资源消耗。
  • 系统:通过内容哈希缓存避免全量 Rust 重编译,提升构建效率。
  • 团队:后续维护需注意 Dockerfile.rocm 中阶段命名和缓存标签的兼容性。
远程脚本无校验和 REMOTE_VLLM 依赖网络稳定性 缓存阶段命名硬编码

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论