Prhub

#38632 [AMD][CI] Consolidate AMD workflows and retire ROCm 7.0 CI

原始 PR 作者 bingxche 合并时间 2026-09-15 23:45 文件变更 17 提交数 18 评论 1 代码增减 +1133 / -4875

执行摘要

AMD CI 合并为一对 workflow 并退役 ROCm 7.0

PR body 明确指出目标是 「Consolidate AMD workflows to one pair of yml files」 并 「Removes the duplicate ROCm 7.0 workflows」,让每个受支持的 ROCm 版本共用同一套标准 PR/Nightly 流程。Issue 评论中 michaelzhang-ai 补充了关键背景: 「Rocm7 is retired and still takes lots of computation resource」,即 ROCm 7.0 已不再需要维护,但其定时 Job 仍持续消耗 GPU 计算资源,因此需要尽快合并并释放资源。

值得精读,尤其适合负责多硬件平台 CI 的工程师。三个设计点值得借鉴:一是用「单一 workflow + rocm_version matrix + 调度 cron 区分版本组合」替代「每版本一套 workflow」的重复布局,将约 3900 行重复配置收敛为一份;二是 _filter_legacy_amd_job_rows 的「历史 job 名识别 + 旧数据不污染当前 streak」的过滤策略,是 workflow 改名场景下的实用技巧;三是通过 fromJson 让上游 check-changes 输出版本数组、下游所有测试 job 统一展开矩阵的编排方式。NPU、Intel 等平台 CI 若面临类似的多版本多 workflow 重复问题,可直接复用此模式。

讨论亮点

本 PR 的 review 评论为空,三位 reviewer(HaiShaw、michaelzhang-ai、yctseng0211)直接 APPROVED,yctseng0211 评价「LGTM, AMD specific change」,说明变更范围被明确限定在 AMD CI 域内。核心讨论集中在 Issue 评论中:michaelzhang-ai 请求尽快合并,理由是「Rocm7 is retired and still takes lots of computation resource」,并 @ 了多位维护者推动合入。此外,commit 历史中的拆分决策也值得注意:[AMD][CI] Split workflow reference cleanup into follow-up 表明作者有意将 workflow 引用的后续清理与本次合并主变更解耦,避免一次变更耦合过多清理工作。

实现拆解

实现按五个步骤完成,核心是「一套 workflow + rocm_version 矩阵」的架构替换原先「每版本一套 workflow」的重复布局:

  1. 重写主 PR workflow(.github/workflows/pr-test-amd.yml):workflow 名从「PR Test ROCm 7.0 (AMD)」改为「PR Test (AMD)」,新增 rocm_version 输入(all / rocm10 / rocm724 / rocm720,默认 rocm10);调度 cron 改为 0 */12 * * * 每日两次跑 ROCm 10、30 17 * * * 每日一次跑 ROCm 7.2.4 与 7.2.0;check-changes job 新增 rocm_versions 输出,按事件类型推导版本数组;各测试 job(sgl-kernel-unit-test-amd、stage-a-test-1-gpu-small-amd、jit-kernel-unit-test-amd 等)全部改为 strategy.matrix + fromJson(needs.check-changes.outputs.rocm_versions) 展开,并把 --rocm-version 传给容器启动脚本。

  2. 合并 Nightly workflow(.github/workflows/nightly-test-amd.yml):吸收原 nightly-test-amd-rocm720.yml 的 2392 行内容,改为同一文件内按 rocm_version 矩阵跑 ROCm 10 / 7.2.4 / 7.2.0,同时删除重复的 nightly-test-amd-rocm720.yml 与 pr-test-amd-rocm720.yml(合计约 3900 行)。

  3. 退役 ROCm 7.0 产物链:删除 release-docker-amd-nightly.yml(ROCm 7.0 专属镜像构建),并在 release-docker-amd.yml 的 matrix 与 rocm_tag 分支中移除 rocm700 选项,产品镜像从 8 个 flavor(含 7.0 双架构)减为 6 个(ROCm 10 / 7.2.4 / 7.2.0 × gfx942 / gfx950)。

  4. 同步监控与分析配套:amd-ci-job-monitor.yml 删除 pr_rocm700_jobs / nightly_rocm700_jobs 两组矩阵报告 job,workflow 参数统一改写为 pr-test-amd.yml / nightly-test-amd.yml;scripts/ci_monitor/ci_failures_analysis.py 中 SGLangFailuresAnalyzer.main 的 workflow_filter 全部从 pr-test-amd-rocm720.yml / nightly-test-amd-rocm720.yml 切换为新文件名,同时扩展 _filter_legacy_amd_job_rows 的 legacy_callers 集合(新增 call-nightly-amd-rocm720 与 call-pr-test-amd-rocm720)并增加 rocm700 行跳过逻辑,防止旧名与历史行污染 streak 统计;对应测试文件 test_ci_failures_analysis.py 随之删除。

  5. 周边引用与脚本更新:amd-aiter-scout.yml 由同时调用 4 个 workflow 简化为 2 个调用并传 rocm_version: all;scripts/ci/amd/amd_ci_start_container.sh 与 amd_ci_start_container_disagg.sh 增加 --rocm-version 参数支持指定镜像;pr-states.yml、release-branch-cut.yml、bot-bump-sglang-version.yml、pr-test-amd-extra.yml 与 .claude/skills/babysit-pr-to-pass-ci/SKILL.md 中的 workflow 文件名引用同步更新。

文件 模块 状态 重要度
.github/workflows/pr-test-amd.yml CI 流程 modified 6.14
.github/workflows/nightly-test-amd.yml CI 流程 modified 5.69
scripts/ci_monitor/ci_failures_analysis.py CI 监控 modified 6.27
scripts/ci_monitor/test_ci_failures_analysis.py CI 监控 removed 6.33
.github/workflows/pr-test-amd-rocm720.yml CI 流程 removed 5.86
.github/workflows/nightly-test-amd-rocm720.yml CI 流程 removed 5.53
.github/workflows/amd-ci-job-monitor.yml CI 监控 modified 5.22
.github/workflows/amd-aiter-scout.yml CI 流程 modified 4.47
.github/workflows/release-docker-amd.yml 镜像发布 modified 4.16
scripts/ci/amd/amd_ci_start_container.sh CI 脚本 modified 4.16

关键符号

_filter_legacy_amd_job_rows SGLangFailuresAnalyzer.get_recent_runs SGLangFailuresAnalyzer.main

关键源码片段

scripts/ci_monitor/ci_failures_analysis.py core-logic

CI 连续失败分析器的核心逻辑文件:workflow_filter 全部切换到新命名,_filter_legacy_amd_job_rows 扩展 legacy_callers 并新增 rocm700 历史行过滤,直接决定合并后 streak 统计的准确性。

def _filter_legacy_amd_job_rows(job_data: Dict[str, Dict]) -> Dict[str, Dict]:
    """丢弃 AMD workflow 规范化前的旧 job 名,避免历史行污染当前 streak。"""
​
    # AMD workflow 合并后,以下外层 caller 名称已被新命名取代。
    # 仍要识别它们的旧拼写,防止旧记录并入当前连续失败统计。
    legacy_callers = {
        "call-nightly-amd-rocm720",
        "call-pr-test-amd-extra-rocm720",
        "call-pr-test-amd-rocm720",
    }
    filtered = {}
    for full_name, data in job_data.items():
        # job 全名按 " / " 分层:外层是调用链,末段是叶子 job 名。
        # 只要外层出现任一旧 caller,整行直接丢弃。
        name_parts = full_name.split(" / ")
        if any(part in legacy_callers for part in name_parts[:-1]):
            continue
​
        leaf_name = name_parts[-1]
        # 管理类叶子 job 不参与测试统计:等待门、gate、finish 汇总等
        if leaf_name.startswith(("wait-for-stage-a-amd", "wait-for-stage-b-amd")):
            continue
        if leaf_name in {
            "call-gate", "call-pr-test-amd-extra", "check-all-jobs",
            "check-changes", "pr-gate", "pr-test-amd-extra-finish",
            "pr-test-amd-finish",
            "pr-test-amd-rocm720-finish", # 规范化前的旧 teardown job
        }:
            continue
​
        # 旧命名风格是叶子名带 -rocm<digits> 后缀,但后缀版本不可信
        # (例如 -rocm720 的 PR job 实际可能跑 rocm724),一律丢弃。
        stem = leaf_name.split(" (", 1)[0]
        _, separator, version = stem.rpartition("-rocm")
        if separator and version.isdigit():
            continue
​
        # 中间态 nightly 命名只有 ROCm flavor,没有 runner;
        # 当前标准命名必须同时包含 flavor 与 runner。
        if leaf_name.endswith(")") and " (" in leaf_name:
            details = leaf_name.rsplit(" (", 1)[1][:-1]
            if details.startswith("rocm") and details[4:].isdigit():
                continue
​
            # 合并后的 workflow 复用了已退役 ROCm 7.0 workflow 的历史记录,
            # 在 lookback 窗口内不能让这些旧行计入多版本当前 streak。
            if details.split(",", 1)[0] == "rocm700":
                continue
​
        filtered[full_name] = data
​
    return filtered

评论区精华

ROCm 7.0 退役与合并紧迫性 设计

michaelzhang-ai 在 Issue 评论中 @ 多位维护者请求合并:「Rocm7 is retired and still takes lots of computation resource」,说明退役后的 ROCm 7.0 定时 Job 仍在持续消耗计算资源。

结论:三位 reviewer 全部 APPROVED,yctseng0211 以「LGTM, AMD specific change」确认变更范围可控,PR 随后合入。 · 已解决

workflow 引用清理拆分策略 设计

commit be45838 标记为「Split workflow reference cleanup into follow-up」,表明作者有意将外围 workflow 引用清理从主合并变更中拆出,避免一次 PR 耦合过多清理项。

结论:后续多个 commit(pr-states.yml、release-branch-cut.yml、bot-bump-sglang-version.yml 等)实际仍纳入本 PR 同步完成,拆分意图在最终合入版本中被吸收。 · 已解决

风险与影响

  1. PR 阶段多版本覆盖下降:合并后普通 pull_request 事件只默认跑 ROCm 10(rocm_versions 推导中 pull_request fall through 到 rocm10),ROCm 7.2.4 / 7.2.0 的回归验证仅靠每日定时调度覆盖。若某 PR 修改了仅在旧版本暴露的兼容性问题,PR 门禁无法拦截,属于有意为之的权衡但需要团队知晓。
  2. 监控 streak 统计正确性:ci_failures_analysis.py 的 workflow_filter 从 pr-test-amd-rocm720.yml 切换到 pr-test-amd.yml 后,GitHub Actions 历史 lookback 窗口内的旧 workflow 行将不再被拉取;同时 _filter_legacy_amd_job_rows 对 rocm700 的过滤依赖 job 名括号内第一个字段恰好为 rocm700,若未来 job 命名再次调整,存在漏过滤导致 streak 虚高或误合并的风险。
  3. 引用断裂风险:一次性删除 3 个 workflow 共约 4150 行,任何未同步的外部引用(bot、其他 workflow 的 uses:)都会导致运行时错误「workflow does not exist」。本 PR 已同步 pr-states.yml、release-branch-cut.yml、bot-bump-sglang-version.yml,但仓库内是否还有其他引用点(如文档、脚本)无法从本次 diff 完全确认。
  4. AITER Scout 资源放大:amd-aiter-scout.yml 现在对 nightly-test-amd.yml 传 rocm_version: all,每周会同时展开三个版本的完整 nightly,即使并行执行,GPU 占用总时长仍明显高于此前单版本模式。

影响范围集中在 AMD CI 基础设施,对运行时产品代码零影响。对开发者而言,PR 页面上的 AMD 检查项名称从「PR Test ROCm 7.0 / ROCm 7.2」变为统一的「PR Test (AMD)」,调度节奏从 ROCm 7.0 每两天一次变为 ROCm 10 每日两次;对 AMD CI 维护者而言,后续新增或调整 ROCm 版本只需修改 pr-test-amd.yml / nightly-test-amd.yml 的矩阵与 cron,不再需要复制整套 workflow;对 CI 监控系统而言,job 名的 streak 统计跨版本合并方式发生改变,ci_failures_analysis.py 的过滤逻辑需要持续跟随命名规范。总体影响属于「工程流程收敛」,显著降低维护成本并释放 ROCm 7.0 占用的 GPU 计算资源。

PR 阶段多版本覆盖下降 CI 监控过滤逻辑变更 大量 workflow 删除 AITER Scout 资源放大

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论