执行摘要
- 一句话:统一 193 个 AMD CI 任务命名,修复 MI300 超时
- 推荐动作:建议 CI / 测试基础设施负责人精读:本文是大规模 CI 配置重构的样板,重点看命名唯一性策略、CPU 任务转 GPU 的取舍与注释保留方式;khluu 对 PR body 与 diff 不一致的核查也值得作为 review 流程范例。普通工程师仅需了解超时与路径修复即可,无需深入。
功能与动机
PR body 明确了主要动机:'Standardize all 193 .buildkite/test-amd.yaml labels on :amd: (<Device>) <Purpose> [Shard %N], matching the convention introduced for test_areas in #52659',即与 test_areas 区引入的设备级命名约定对齐,同时移除旧式 GPU 计数与跨平台后缀。khluu 在评论中补充了超时修复的真实背景:main 分支 #84629 / #84630 的多模态任务在 50 分钟超时(原始 + 重试)均失败,因此需将 MI300 任务超时提升到 70 分钟。
实现拆解
- 统一命名约定:在
.buildkite/test-amd.yaml 中将全部 193 个测试任务 label 规范为 :amd: (<Device>) <Purpose> [Shard %N],与 #52659 为 test_areas 引入的约定对齐;移除旧式 GPU 计数与跨平台后缀,改用语义限定符保证唯一性,避免依赖 label 的过滤与通知失效。
- CPU 任务转 GPU 并保留备份:将 7 个活动的 CPU 任务(如 Basic Models Other、Multimodal Processor、V1 Others、Async Engine/Inputs/Utils/Worker/Config 等)替换为等效 MI250 ROCm GPU 任务,显式保留 1 个 MI250 GPU;原始 CPU 定义以
no_gpu: true、optional: true 注释形式保留在文件末尾并标记 # TBD。提交历史 Restore CPU-only AMD test groups 表明该方案经过返工,最终选择“替换 + 注释保留”而非直接删除。
- 配套修复:
.buildkite/test_areas/models_multimodal.yaml:MI300 Multimodal Models (Standard) 4 的 timeout_in_minutes 从 50 提升到 70,修复 main 分支 #84629 / #84630 的持续超时;
.buildkite/test_areas/distributed.yaml:multi-API server 测试路径从 entrypoints/openai/test_multi_api_servers.py 更新为 entrypoints/launchers/api_server/test_multi_api_servers.py,与当前仓库目录结构对齐;
tests/models/test_vision.py:4 处分布式视觉测试 worker 的设备字符串从 current_platform.device_name 改为 current_platform.device_type。
- 验证与收敛:多次触发 AMD CI 与主 CI(Buildkite AMD CI #12247、#12249、#12250、#12264 与主 CI #84656、#84691),MI300 多模态任务在超时提升后以 44m55s 通过,MI355 paired job 以 32m23s 通过;重复 PR #52991 被关闭并合入本 PR。
关键文件:
.buildkite/test-amd.yaml(模块 CI 编排;类别 config;类型 configuration): 核心变更文件,193 个任务标签统一标准化,7 个 CPU 任务替换为 MI250 GPU 任务并注释保留,同时更新文件头 mirror_hardwares 语义。
tests/models/test_vision.py(模块 视觉测试;类别 test;类型 test-fix;符号 run_dp_sharded_vision_model_vs_direct, run_dp_sharded_mrope_vision_model_vs_direct, run_dp_sharded_mrope_vision_model_empty_input_worker, run_dp_sharded_mrope_vision_model_uneven_load_worker): 本次唯一的源码级改动,4 处分布式视觉测试 worker 的设备选择从 device_name 调整为 device_type,适配 AMD 平台。
.buildkite/test_areas/models_multimodal.yaml(模块 多模态 CI;类别 config;类型 configuration): MI300 多模态标准任务超时 50→70 分钟,修复 main #84629 / #84630 的真实超时失败,且该变更与 PR body 描述不一致,是 review 争论焦点。
.buildkite/test_areas/distributed.yaml(模块 分布式测试;类别 config;类型 configuration): 更新 multi-API server 测试路径,与当前仓库目录结构对齐,避免 NVIDIA / AMD 镜像中的路径失效。
关键符号:run_dp_sharded_vision_model_vs_direct, run_dp_sharded_mrope_vision_model_vs_direct, run_dp_sharded_mrope_vision_model_empty_input_worker, run_dp_sharded_mrope_vision_model_uneven_load_worker
关键源码片段
tests/models/test_vision.py
本次唯一的源码级改动,4 处分布式视觉测试 worker 的设备选择从 device_name 调整为 device_type,适配 AMD 平台。
def run_dp_sharded_vision_model_vs_direct(
local_rank: int, world_size: int, batch_size: int, master_port: int
):
"""验证 run_dp_sharded_vision_model 与直接调用模型的输出一致。"""
set_random_seed(0)
# 设备字符串改用 device_type 而非 device_name,以适配 AMD CI 的设备选择方式;
# 设备号由 local_rank 拼接,最终形如 "<device_type>:<rank>"
device = f"{current_platform.device_type}:{local_rank}"
torch.accelerator.set_device_index(device)
torch.set_default_device(device)
update_environment_variables(
{
"RANK": str(local_rank),
"LOCAL_RANK": str(local_rank),
"WORLD_SIZE": str(world_size),
"MASTER_ADDR": "localhost",
"MASTER_PORT": str(master_port),
}
)
# 初始化分布式环境与 2 卡 tensor parallel,随后对比直接推理与分片推理结果
init_distributed_environment()
with ensure_current_vllm_config():
initialize_model_parallel(tensor_model_parallel_size=world_size)
image_input = torch.randn(batch_size, 3, 224, 224)
vision_model = SimpleLinearModel()
with torch.inference_mode():
direct_output = vision_model(image_input)
with torch.inference_mode():
sharded_output = run_dp_sharded_vision_model(image_input, vision_model)
# 剩余部分:在 rank 0 上断言两者形状一致且 torch.allclose
评论区精华
核心讨论来自 khluu 的合并前把关:她指出 PR body 声称超时不变,但 diff 实际将 MI300 Multimodal Models (Standard) 4 超时从 50 提升至 70 分钟(失败证据为 main #84629 / #84630 在 50 分钟窗口内原始与重试均超时),并要求合并前更正描述;同时确认 head 提交 1656b2782c 的修复覆盖在 AMD CI #12250 上通过(MI300 44m55s、MI355 32m23s),并关闭了重复 PR #52991。提交历史还揭示了两个设计反思:Restore CPU-only AMD test groups 表明最初删除 CPU 任务的方案被推翻,改为“GPU 替换 + 注释保留”;Avoid invalid Buildkite step keys 说明重命名过程中同步处理了 step key 合法性约束。最终 reviewer dllehr-amd 直接批准。
- PR body 与超时改动不一致 (correctness): 合并前需更正 PR 描述;调整后 AMD CI #12250 以 44m55s 通过,修复得到验证。
- CPU-only 任务替换为 MI250 GPU 任务的设计 (design): 采用“GPU 替换 + 注释保留 + optional”方案,保留区标记
# TBD 供后续决策。
- vision worker 设备字符串 device_name → device_type (question): 已随 AMD CI 与主 CI 验证通过,但缺少针对设备选择语义的专项测试。
风险与影响
- 风险:
.buildkite/test-amd.yaml 单文件 700+ 行重排,193 个 label 全部变化,依赖旧 label 的 Buildkite 通知、过滤规则或外部脚本可能失效。
- 7 个 CPU-only 任务转为 MI250 GPU 任务,AMD GPU 资源占用显著增加;保留的 CPU 注释区(
no_gpu: true)与 GPU 替换版(device: mi250_1)共存,存在误读误配风险,且保留区均标记 optional: true,不参与默认调度。
tests/models/test_vision.py 的 device_name → device_type 只随全量 CI 回归验证,缺少针对设备选择语义的专项测试;若某平台 device_type 返回不合法前缀,会导致 2 卡视觉测试失败。
- 超时提升至 70 分钟会让真正卡死的任务多等待 20 分钟,且该变更未在 PR body 中披露,属于 review 盲区(已被 khluu 指出)。
- 三次 merge main 带来的冲突掩盖风险,已由 head 上的 AMD CI 与主 CI 双绿解除。
- 影响:面向最终用户无行为变化,全部影响集中在 CI 基础设施:job 命名从碎片化格式(含 GPU 计数、跨平台后缀)收敛为统一模板 :amd: (<Device>) <Purpose> [Shard %N],Buildkite dashboard 的可读性与可筛选性提升,并与 #52659 的 test_areas 约定对齐;AMD CI 资源模型变化,7 个任务从 CPU 转向 GPU,多模态任务超时窗口延长;团队后续新增 AMD 任务可直接套用命名模板,降低心智成本;重复 PR #52991 被关闭,避免维护分叉。
- 风险标记:大规模 CI 配置重命名, CPU 转 GPU 资源变化, 超时与描述不一致, 设备选择变更缺少专项验证
关联脉络
- PR #52659 (title unavailable) test_areas AMD device label convention: PR body 明确本 PR 的命名约定是 matching the convention introduced for test_areas in #52659,是本次标准化的模板来源。
- PR #52991 (title unavailable) Duplicate of #52976, closed by khluu: khluu 在评论中确认关闭了窄范围重复 PR #52991,将相关改动并入本 PR。
参与讨论