执行摘要
- 一句话:添加PyTorch nightly构建与测试流水线,支持CUDA 13.0和递归依赖处理。
- 推荐动作:建议CI维护者关注此PR,特别是构建脚本中的安全问题和参数设计,以及依赖处理的递归变更,这些对于确保nightly测试的稳定性和安全性至关重要。
功能与动机
根据关联Issue #310,目标是重新启用PyTorch nightly构建和测试流水线,确保vLLM与最新PyTorch版本的兼容性,及早发现潜在问题。PR body中提到这是vllm-project/ci-infra#310的伴侣PR,用于添加vLLM侧的Docker构建脚本和测试配置。
实现拆解
- 新增PyTorch nightly构建脚本:创建
.buildkite/image_build/image_build_torch_nightly.sh,脚本包含ECR登录、buildx设置、镜像存在检查,并使用CUDA 13.0基础镜像和特定torch_cuda_arch_list构建Docker镜像。关键变更:设置 PYTORCH_NIGHTLY=1 和扩展的CUDA架构列表。影响:为nightly测试提供专用镜像。
- 修复依赖脚本以递归处理requirements:修改
use_existing_torch.py 中的glob模式,从 requirements/*.txt 改为 requirements/**/*.txt 并启用 recursive=True。原因:此前未处理子目录(如 requirements/test/cuda.in)中的文件,导致torchvision版本冲突。影响:确保所有requirements文件中的torch依赖被正确剥离,兼容nightly构建。
- 更新测试配置以加入nightly流水线:在
.buildkite/test_areas/models_language.yaml 和 models_basic.yaml 中,将 torch_nightly: true 移至 mirror: torch_nightly: {},使得测试步骤在nightly流水线中镜像运行。同时升级ROCm AMD镜像中的causal-conv1d版本从v1.5.2到v1.6.0。影响:基础语言模型和混合模型测试现在会在PyTorch nightly环境下执行。
- 伴随更改:提交历史中包含多个修复提交,如调整causal-conv1d版本以确保依赖一致性;无直接测试文件变更,但配置调整影响CI执行流程。
关键文件:
.buildkite/image_build/image_build_torch_nightly.sh(模块 CI构建脚本;类别 infra;类型 core-logic): 新增构建脚本,核心实现PyTorch nightly Docker镜像的构建逻辑,是流水线入口。
use_existing_torch.py(模块 依赖管理;类别 source;类型 core-logic;符号 main): 修改依赖处理逻辑,递归查找requirements子目录文件,确保所有torch依赖被剥离以兼容nightly构建。
.buildkite/test_areas/models_language.yaml(模块 测试配置;类别 config;类型 configuration): 更新测试配置,将语言模型测试步骤标记为torch_nightly镜像运行,纳入nightly流水线。
.buildkite/test_areas/models_basic.yaml(模块 测试配置;类别 config;类型 configuration): 更新测试配置,将基础模型测试步骤标记为torch_nightly镜像运行,纳入nightly流水线。
关键符号:main
关键源码片段
.buildkite/image_build/image_build_torch_nightly.sh
新增构建脚本,核心实现PyTorch nightly Docker镜像的构建逻辑,是流水线入口。
#!/bin/bash
set -euo pipefail
# 构建vLLM测试镜像,安装PyTorch nightly版本。
# 由流水线生成器的"vLLM Against PyTorch Nightly"组调用。
if [[ $# -lt 5 ]]; then
echo "Usage: $0 <registry> <repo> <commit> <branch> <image_tag>"
exit 1
fi
REGISTRY=$1
REPO=$2 # 注意:此参数在脚本中未使用,可能存在设计瑕疵
BUILDKITE_COMMIT=$3
BRANCH=$4 # 注意:此参数在脚本中未使用,可能存在设计瑕疵
IMAGE_TAG=$5
# ECR登录
echo "--- :key: ECR login"
aws ecr-public get-login-password --region us-east-1 \
| docker login --username AWS --password-stdin "$REGISTRY"
aws ecr get-login-password --region us-east-1 \
| docker login --username AWS --password-stdin 936637512419.dkr.ecr.us-east-1.amazonaws.com # 安全风险:硬编码AWS账户ID
# 设置buildx
echo "--- :docker: Setting up buildx"
docker buildx create --name vllm-builder --driver docker-container --use || true
docker buildx inspect --bootstrap
docker buildx ls
# 检查镜像是否已存在
echo "--- :mag: Checking if image already exists"
if docker manifest inspect "$IMAGE_TAG" >/dev/null 2>&1; then
echo "Image found: $IMAGE_TAG — skipping build"
exit 0
fi
echo "Image not found, proceeding with build..."
# Nightly构建使用CUDA 13.0,而常规CI使用CUDA 12.9
NIGHTLY_CUDA_VERSION="13.0.0"
NIGHTLY_BUILD_BASE_IMAGE="nvidia/cuda:${NIGHTLY_CUDA_VERSION}-devel-ubuntu22.04"
NIGHTLY_FINAL_BASE_IMAGE="nvidia/cuda:${NIGHTLY_CUDA_VERSION}-base-ubuntu22.04"
echo "--- :docker: Building torch nightly image (CUDA ${NIGHTLY_CUDA_VERSION})"
docker buildx build --file docker/Dockerfile \
--build-arg max_jobs=16 \
--build-arg buildkite_commit="$BUILDKITE_COMMIT" \
--build-arg USE_SCCACHE=1 \
--build-arg PYTORCH_NIGHTLY=1 \
--build-arg CUDA_VERSION="${NIGHTLY_CUDA_VERSION}" \
--build-arg BUILD_BASE_IMAGE="${NIGHTLY_BUILD_BASE_IMAGE}" \
--build-arg FINAL_BASE_IMAGE="${NIGHTLY_FINAL_BASE_IMAGE}" \
--build-arg torch_cuda_arch_list="8.0 8.9 9.0 10.0 12.0" \ # 注意:在review中提到了大小写问题,这里已修正为小写
--tag "$IMAGE_TAG" \
--push \
--target test \
--progress plain .
echo "--- :white_check_mark: Torch nightly image build complete: $IMAGE_TAG"
use_existing_torch.py
修改依赖处理逻辑,递归查找requirements子目录文件,确保所有torch依赖被剥离以兼容nightly构建。
def main(argv):
parser = argparse.ArgumentParser(
description="Strip torch lib requirements to use installed version."
)
parser.add_argument(
"--prefix",
action="store_true",
help="Strip prefix matches only (default: False)",
)
args = parser.parse_args(argv)
# 使用递归glob模式查找requirements目录下的所有.txt和.in文件,包括子目录
for file in (
*glob.glob("requirements/**/*.txt", recursive=True),
*glob.glob("requirements/**/*.in", recursive=True),
"pyproject.toml",
):
with open(file) as f:
lines = f.readlines()
if "torch" in "".join(lines).lower():
with open(file, "w") as f:
for line in lines:
# 根据参数决定是否仅匹配前缀或包含"torch"字符串
if (
args.prefix
and not line.lower().strip().startswith(TORCH_LIB_PREFIXES)
or not args.prefix
and "torch" not in line.lower()
):
f.write(line)
else:
print(f">>> removed from {file}:", line.strip())
评论区精华
风险与影响
- 风险:- 安全风险:硬编码AWS账户ID可能暴露内部基础设施,增加安全威胁。
- 构建失败风险:构建参数不匹配(如
TORCH_CUDA_ARCH_LIST vs torch_cuda_arch_list)可能导致镜像构建使用默认值,而非预期的CUDA架构,影响性能或兼容性。
- 维护复杂性:新增脚本和配置增加了CI流水线的维护负担,尤其是nightly构建可能因PyTorch不稳定而频繁失败。
- 依赖冲突风险:尽管修复了递归glob,但若其他子目录中有未处理的依赖文件,仍可能导致版本冲突。
- 影响:- 对用户:无直接用户影响,这是内部CI改进。
- 对系统:扩展了测试矩阵,使用PyTorch nightly可以提前检测与未来PyTorch版本的兼容性问题,提升软件质量。
- 对团队:开发团队能更早获得反馈,但需要处理nightly构建可能的失败,增加了CI运维工作量。
- 风险标记:硬编码敏感信息, 构建参数不匹配, 未使用参数
关联脉络
- PR #310 [CI] Re-enable PyTorch nightly build and test in nightly CI/CD: 伴侣PR,在ci-infra仓库中定义流水线生成逻辑,与此PR协同工作以启用nightly测试。
参与讨论