Prhub

#33774 [AMD]Stage MI355X nightly by node count

原始 PR 作者 yctseng0211 合并时间 2026-08-06 09:04 文件变更 1 提交数 2 评论 0 代码增减 +54 / -12

执行摘要

按节点数拆分 MI355X nightly 测试为 2N/4N 两阶段

PR body 未填写具体动机(仅为模板内容)。从变更本身看,原 workflow 仅支持 2 节点 1P1D 的 MI355X 配置,本次将 nightly 扩展为同时覆盖 2 节点与 4 节点(-2p1d-ep16)两类拓扑,按节点数分组便于分别调度与控制并行度,并在遇到未识别拓扑时直接失败,避免配置漂移导致漏测。

值得快速浏览。重点看两点:一是按硬件拓扑拆分 CI 矩阵的模式(关键字分组 + 空矩阵跳过 + 未匹配报错),对多节点 nightly 测试有通用参考价值;二是 YAML anchor 复用步骤的写法,可作为团队内部 CI job 模板化的范本。AMD/CI 相关的维护者可精读,其余成员了解即可。

讨论亮点

该 PR 没有 review 评论线程,仅由 bingxche 直接批准。两个 commit([CI] Stage MI355X nightly by node count[CI] Reuse MI355X benchmark steps across stages)体现了先拆分矩阵、再抽取公共步骤的重构顺序,说明作者在实现过程中自行完成了可维护性取舍。

实现拆解

  1. setup 阶段拆分矩阵:在 .github/workflows/nightly-amd-mi355x-disagg.yml 中,将原来只输出 matrix 的步骤改为输出 matrix-2nmatrix-4n 两个结果。内嵌 Python 脚本按配置名关键字 -1p1d / -2p1d-ep16 分组,未匹配的拓扑会触发 SystemExit,防止新增配置被静默漏测。
  2. 2 节点 job 重命名nightly-mi355x-benchmark 更名为 nightly-mi355x-2n,消耗 needs.setup.outputs.matrix-2n,并增加矩阵为空的跳过条件(needs.setup.outputs.matrix-2n != '{"include":[]}'),避免空矩阵空跑。
  3. 新增 4 节点 job:新增 nightly-mi355x-4n,依赖 setupnightly-mi355x-2n,消耗 matrix-4nmax-parallel 设为 1,避免与 2 节点阶段抢同一批 MI355X 自托管节点。
  4. YAML anchor 复用:将 env 定义为 &mi355x-envsteps 定义为 &mi355x-steps,两个 job 通过 *mi355x-env / *mi355x-steps 引用,保证后续调整步骤只改一处。
  5. 结果聚合调整collect-results 改为同时依赖 nightly-mi355x-2nnightly-mi355x-4n,并在 always() 下执行,两个阶段任一失败都会反映到汇总结果。
文件 模块 状态 重要度
.github/workflows/nightly-amd-mi355x-disagg.yml CI 工作流 modified 5.17

关键源码片段

.github/workflows/nightly-amd-mi355x-disagg.yml infrastructure

这是该 PR 唯一修改的文件,承载全部 CI 逻辑:setup 阶段按节点数拆分矩阵、新增 4 节点 job、通过 YAML anchor 复用步骤并调整结果聚合依赖。

# 1) setup job 中,把整份配置矩阵按节点数拆成两个输出
MATRIX="$MATRIX" python3 - <<'PY'
import json
import osmatrix = json.loads(os.environ["MATRIX"])
# "-1p1d" 命中 2 节点拓扑,"-2p1d-ep16" 命中 4 节点拓扑
groups = {
    "matrix-2n": [entry for entry in matrix if "-1p1d" in entry["name"]],
    "matrix-4n": [entry for entry in matrix if "-2p1d-ep16" in entry["name"]],
}
matched = {entry["name"] for entries in groups.values() for entry in entries}
unmatched = [entry["name"] for entry in matrix if entry["name"] not in matched]
if unmatched:
    # 出现未识别拓扑直接失败,防止 nightly 悄悄漏测新配置
    raise SystemExit("Unrecognized MI355X topology for config(s): " + ", ".join(unmatched))with open(os.environ["GITHUB_OUTPUT"], "a") as output:
    for name, entries in groups.items():
        value = {"include": [{"config": entry} for entry in entries]}
        print(f"{name}={json.dumps(value, separators=(',', ':'))}", file=output)
PY# 2) 2 节点与 4 节点 job 通过 YAML anchor 复用环境变量与步骤
nightly-mi355x-2n:
  strategy:
    fail-fast: false
    max-parallel: 2
    matrix: ${{ fromJson(needs.setup.outputs.matrix-2n) }}
  env: &mi355x-env
    FRAMEWORK: sglang
    HW: mi355x
  steps: &mi355x-steps
    - name: Launch MI355X benchmark
      timeout-minutes: 180nightly-mi355x-4n:
  needs: [setup, nightly-mi355x-2n]
  strategy:
    fail-fast: false
    max-parallel: 1
    matrix: ${{ fromJson(needs.setup.outputs.matrix-4n) }}
  env: *mi355x-env
  steps: *mi355x-steps

评论区精华

没有提炼出高价值讨论线程

当前评论区没有形成足够清晰的争议点或结论,后续有更多讨论时会体现在这里。

风险与影响

  • YAML anchor 耦合&mi355x-env / &mi355x-steps 被两个 job 共享,若未来 2N 与 4N 需要差异化运行参数或步骤,需先拆 anchor,否则会互相影响。
  • 矩阵分组依赖配置名:分组逻辑基于配置名中的 -1p1d / -2p1d-ep16 关键字,若 nightly-configs.yaml 新增其他拓扑而未同步更新分组脚本,setup 会直接 SystemExit,导致整个 nightly 失败;这是有意为之的防御,但也提高了后续维护门槛。
  • 4 节点 job 依赖链nightly-mi355x-4n 依赖 2 节点阶段完成,虽然使用 !cancelled() 避免 2N 失败时 4N 被取消,但 2N 失败时 4N 仍会继续申请 MI355X 节点,资源开销可能翻倍。
  • 无配套测试:矩阵拆分逻辑只在真实 nightly 中验证,PR 未包含任何单测或语法校验步骤。
  • 空矩阵判断matrix-4n 为空时的跳过条件写法为字符串比较 !='{"include":[]}',与 setup 输出格式强耦合,格式变化会静默失效。

影响范围严格限于 AMD MI355X 的 nightly CI 流程:从原先只跑 2 节点 1P1D,扩展为同时跑 2 节点与 4 节点(2P1D EP16)两类拓扑,新增了一个持续约数小时的 4 节点测试路径。对端到端推理功能、模型输出和用户 API 无任何影响;对团队而言,AMD nightly 的维护者需要关注新 job 的资源调度与稳定性,自托管 runner 的并发占用会明显增加。

YAML anchor 复用 矩阵分组依赖配置名 新增 4 节点测试路径 collect-results 依赖变更 无配套测试

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论