Prhub

#52593 [Build] Propagate vLLM version to Rust binaries

原始 PR 作者 BugenZhao 合并时间 2026-08-18 14:37 文件变更 24 提交数 6 评论 14 代码增减 +135 / -39

执行摘要

构建系统将 vLLM 源版本注入 Rust 二进制与版本接口

PR body 明确指出:Rust artifacts currently identify themselves using workspace crate metadata, which stays at 0.1.0 and does not identify the corresponding nightly or release vLLM source revision. 这意味着用户无法从 Rust 侧工具版本追溯到对应的 vLLM 源码修订,影响排障和版本对齐。该 PR 在编译 Rust 前解析源版本,并通过 VLLM_RS_BUILD_VERSION 传入,同时让 get_vllm_version() 先于 Rust 构建执行,使 VLLM_VERSION_OVERRIDESETUPTOOLS_SCM_PRETEND_VERSION 同样作用于 Rust 工件。

值得精读。该 PR 展示了跨语言构建链路中版本信息传递的完整设计:以 setuptools_scm 为单一事实来源,通过环境变量注入 Rust 编译期常量,并在 Docker 多阶段构建中优雅处理 Git 元数据缺失(.git.git_archival.txt 兼容)与 partial worktree 误判 dirty 的问题。对于从事 vLLM 构建系统、Rust 前端或 Docker 镜像维护的工程师,本 PR 的 prepare_build_environment 函数和 build-info crate 模式可直接作为版本注入的参考实现。

讨论亮点

核心讨论围绕 ROCm 镜像的 Git 元数据可用性展开。AndreasKaratzas 提出担忧:"The problem I think is that ROCm may not ship with .git such that we reduce size and also optimize docker caching",即 ROCm 镜像为减小体积、优化缓存通常不携带 .git,可能导致版本解析失效。BugenZhao 回应已增加轻量共享 stage:"I've managed to add a lightweight shared stage for retrieving the version by calling setuptools_scm there in ROCm Dockerfile, which should automatically handle different cases like when .git is present or from .git_archival.txt",并补充验证结果 "Verified that the Rust binaries from all images here (CUDA, ROCm, CPU) correctly reports 0.27.2rc1.dev192+g2db2a2484"。AndreasKaratzas 最终确认 "Yep it is indeed lightweight. ROCm modification LGTM"。该讨论已解决,无未关闭疑虑。

实现拆解

  1. 版本解析入口:在 tools/build_rust.py 中新增 prepare_build_environment(),优先读取 VLLM_RS_BUILD_VERSION 环境变量,否则调用 setuptools_scm.get_version(root=ROOT_DIR) 从 Git 元数据解析源版本,并将结果写回环境变量;main()build_binary() 前调用该函数,让本地 bash build_rust.sh 和 setuptools-rust 构建路径都拿到版本。

  2. Python 打包时序保证:在 setup.pysetup() 调用前先执行 vllm_version = get_vllm_version(),再执行 rust_build.prepare_build_environment()。这是因为 get_vllm_version() 可能设置 SETUPTOOLS_SCM_PRETEND_VERSION,而 prepare_build_environment() 内部依赖该变量来解析出与 Python 包一致的版本,保证 nightly/release wheel 构建中 Rust 版本与 Python 版本同步。

  3. Rust 侧版本接入:新增 rust/src/build-info crate,在 lib.rs 中定义 pub const VERSION: &str,优先读取编译期环境变量 VLLM_RS_BUILD_VERSION,缺失时回退到 CARGO_PKG_VERSION(0.1.0)。随后将 vllm-build-info 加入 rust/Cargo.toml workspace,并为 rust/src/cmd/Cargo.tomlrust/src/bench/Cargo.toml 添加依赖;vllm-rsvllm-bench 的 clap #[command(version = vllm_build_info::VERSION)] 改为使用该常量,rust/src/server/src/routes/version.rsrust_frontend_version 字段同样改为该常量,引擎上报的 version 字段保持不变。

  4. Docker 构建路径适配:在 docker/Dockerfile.cpu.rocm.rocm_gfx1250.xpu 中增加获取源码版本逻辑。由于 selective-copy 阶段会省略部分 tracked 文件,若不处理会让 Git 错误地把 partial worktree 标记为 dirty,因此构建阶段显式设置 dirty=false。ROCm 场景因镜像可能不携带 .git(为减小体积和优化缓存),BugenZhao 新增了一个轻量共享 stage,调用 setuptools_scm 自动区分 .git 存在或仅存在 .git_archival.txt 的情况。.buildkite/scripts/ci-bake-rocm.sh 同步调整了 bake 时的版本解析参数。

  5. 测试与验证配套tests/entrypoints/openai/test_uds.pytests/entrypoints/serve/instrumentator/test_basic.py 在启用 VLLM_USE_RUST_FRONTEND 时新增断言 rust_frontend_version == VLLM_VERSION;Rust 端 rust/src/server/src/routes/tests.rs 的版本路由测试改为断言 vllm_build_info::VERSION。作者在 CI 中验证 CUDA/ROCm/CPU 镜像的 Rust 二进制均报告 0.27.2rc1.dev192+g2db2a2484,准确对应源提交。

文件 模块 状态 重要度
tools/build_rust.py 构建工具 modified 6.68
rust/src/build-info/src/lib.rs 构建信息 added 5.97
setup.py 打包脚本 modified 5.39
rust/src/cmd/src/cli.rs 命令行入口 modified 4.98
rust/src/bench/src/main.rs 基准工具 modified 4.82
rust/src/server/src/routes/version.rs 版本接口 modified 4.82
docker/Dockerfile.rocm 镜像构建 modified 4.08
tests/entrypoints/openai/test_uds.py 端到端测试 modified 4.55

关键符号

prepare_build_environment

关键源码片段

tools/build_rust.py dependency-wiring

新增 `prepare_build_environment()`,是版本解析与注入的入口,负责从 setuptools-scm 解析源版本并写入 `VLLM_RS_BUILD_VERSION` 环境变量,决定整个构建链的版本来源。

# tools/build_rust.py 中新增的版本解析与注入逻辑VLLM_RS_BUILD_VERSION = "VLLM_RS_BUILD_VERSION"
​
​
def prepare_build_environment() -> str | None:
    """设置 Rust 工件使用的设备无关 vLLM 源版本。"""
    # 优先读取外部显式传入的版本,例如 CI 通过环境变量指定
    version = os.getenv(VLLM_RS_BUILD_VERSION) or None
    if version is None:
        try:
            # 从 Git 元数据或 .git_archival.txt 解析源版本
            version = get_version(root=ROOT_DIR)
        except LookupError:
            # 既无 .git 也无 .git_archival.txt 时返回 None,
            # 调用方将回退到 Rust crate 版本(0.1.0)
            return None
​
    # 写回环境变量,供 setuptools-rust / cargo 在编译期读取
    os.environ[VLLM_RS_BUILD_VERSION] = version
    return version
​
​
def main() -> None:
    # 必须在 build_binary 之前解析版本,
    # 否则 RustExtension 编译时拿不到 VLLM_RS_BUILD_VERSION
    prepare_build_environment()
    build_binary(sys.argv[1:])
rust/src/build-info/src/lib.rs core-logic

新增的 `vllm-build-info` crate 是 Rust 侧版本暴露的核心,通过 `VERSION` 常量统一了 vllm-rs、vllm-bench 和 Rust 前端 /version 接口的版本来源。

// rust/src/build-info/src/lib.rs/// 构建系统注入的 vLLM 源版本。
///
/// 直接使用 `cargo build` 且未设置 `VLLM_RS_BUILD_VERSION` 时,
/// 回退到 workspace crate 版本(0.1.0)。
pub const VERSION: &str = match option_env!("VLLM_RS_BUILD_VERSION") {
    Some(version) => version,
    None => env!("CARGO_PKG_VERSION"),
};

评论区精华

ROCm 镜像可能不携带 .git 导致版本解析失败 设计

AndreasKaratzas 提出 ROCm 为减小镜像体积和优化 Docker 缓存,可能不会随镜像携带 `.git`,这会破坏基于 Git 元数据的版本解析。

结论:BugenZhao 在 ROCm Dockerfile 中新增轻量共享 stage,调用 `setuptools_scm` 自动处理 `.git` 存在或仅存在 `.git_archival.txt` 的情况;验证 CUDA/ROCm/CPU 三类镜像均正确报告 `0.27.2rc1.dev192+g2db2a2484` 后,AndreasKaratzas 确认 ROCm 改动 LGTM。 · 已解决

跨平台版本一致性验证 测试

BugenZhao 在 CI 中验证了来自 CUDA、ROCm、CPU 三个镜像的 Rust 二进制均报告相同的 vLLM 源版本,确认版本注入与平台无关。

结论:验证通过,三个平台输出一致,确认设备无关设计成立。 · 已解决

pre-commit 检查与 CI 触发 other

mergify bot 多次提示 pre-commit 检查失败,后续通过合并 main 与修复后重新触发 CI(Buildkite #84196、#84283、#84299、#84323)最终通过。

结论:经过多轮修复和重新触发,CI 全部通过。 · 已解决

风险与影响

主要风险集中在构建链路和环境依赖上:1)若构建环境既无 .git 也无 .git_archival.txtsetuptools_scm 会抛 LookupErrorprepare_build_environment() 返回 None,Rust 版本将回退到 crate 版本 0.1.0,与 Python 包版本不一致,可能误导用户;2)Docker selective-copy 阶段设置 dirty=false 会压制 partial worktree 的 dirty 标记,使版本号不含 dirty 后缀,精度略有损失;3)VLLM_RS_BUILD_VERSION 是新的构建期环境变量,直接 cargo build 时若未显式设置且没有 Git 元数据,输出仍为 0.1.0,与 wheel 行为存在差异;4)本次改动覆盖 5 个 Dockerfile(Dockerfile、.cpu、.rocm、.rocm_gfx1250、.xpu)及 bake 脚本,任何平台镜像构建路径的调整都可能导致构建失败或版本错误,依赖 CI 完整验证;5)重新打包预编译 Rust 二进制会保留构建时嵌入的版本,若二进制与 wheel 来自不同构建,版本可能不完全同步,属于已知且可接受的行为。运行时性能无影响。

对用户:vllm-rs --versionvllm-bench --version 和 Rust 前端 GET /versionrust_frontend_version 字段将报告真实 vLLM 源版本,便于在问题反馈和日志排查中快速定位对应的源码修订。对系统:无运行时行为变化,仅影响构建期和版本报告路径;Python 分发版本(含 CPU/CUDA/ROCm/TPU/XPU 平台后缀)保持不变。对团队:统一了 Python 与 Rust 工件的版本语义,消除了 Rust 侧长期停留在 0.1.0 的盲区;同时为 Docker 多平台构建引入了可复用的版本解析 stage,后续新增平台镜像时可复用该模式。影响范围覆盖所有发布构建产物,属于基础设施层的系统性改进,但风险可控。

多平台 Dockerfile 变更 Git 元数据缺失时版本回退歧义 partial worktree dirty 状态被压制 构建期环境变量依赖 预编译二进制版本与 wheel 可能不一致

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论