Skip to content

【No.11】Relax Straggler 分析能力建设 - RFC #334

Description

@hongwei-2026
字段 内容
RFC 状态 待评审(活动看板 #321 已挂 RFC #334:待评审
对应任务 【No.11】Relax Straggler 分析能力建设(⭐⭐⭐⭐,需 RFC)
团队 @hongwei-2026(队长)、@hongming-2026
导师 @Lemon-412
认领 / 本 RFC 同日提交,满足「认领后 7 天内交 PR 或 RFC(从认领当天起算)」
基线 commit 0651812093e3cd730302709b3db35ce0bb199e4bmain
原型证据 2 卡 bench overhead 0.479%interval=10);检测 rank1 forward ≈1.94×

Decision(请导师扫一眼即可)

议题 提案
v1 范围 只观测:采样 CUDA Event + 跨 rank 标量汇总 + straggler/* 上报
不做 踢卡 / 改调度 / LD_PRELOAD 拦 NCCL / 论文级 what-if / 常开 torch.profiler
挂点 train_one_stepmodel.py),不停在外层 actor_train
开销控制 默认关;开启后 interval=10;阶段中不 sync;汇总不走训练 NCCL
attention/MoE 预留 stage + 可选 flag,主路径先 fwd/bwd/optim/comm
上报失败 warning,不阻断训练(与可观测类任务同一条底线)

1. 摘要

做一套默认关闭、可随训练常开的轻量慢卡分析:

  • 按间隔采样,用 device_utils.Event 记粗粒度阶段 GPU 耗时
  • 各 rank 汇总标量后标出慢卡,并提示主要卡在哪一段
  • 指标走现有 tracking_utils / MetricsService(straggler/*),与 perf/* 并存
  • 目标:平均开销 < 0.5%,不改 loss,尽量不动通算 overlap

API 形态对齐业界常用写法:with analyzer.section("forward"): ...(类似 Megatron / NVRx 的 context section),内部才是 Event。


2. 相关实践与取舍(不绑死某一家实现)

任务参考了 OSDI / 知乎背景文;落地时对照几类已公开方案,只借「轻量观测」这一层,不把缓解系统整包搬进 Relax。

来源 可借鉴 本 RFC 的取舍
Megatron StragglerDetector CUDA Event + context;log_interval 再 report;rank0 打 min/max+rank;默认 --log-straggler 关闭 采用 Event / context / 间隔上报 / 默认关。不做 power/temp/clock、ctrl 端口热开关(复杂度高,非验收必需)
NVIDIA Resiliency Ext straggler detection_sectionprofiling_interval 降开销;relative score;gather_on_rank0stop_if_detected=False;预期 <1% 采用 section API、interval、相对慢速比、只观测不停车。汇总默认 gather 到 metrics rank,与 Relax tracking 一致
Falcon-Detect 用 Event 量通信;阈值约 1.1×median;检测侧平均开销约 0.39% 采用「通信阶段可观测 + 相对阈值」。不做 LD_PRELOAD 拦 NCCL、训练挂起验证、自适应缓解(S1–S4)——超出本期且易伤 overlap
任务所列 OSDI'25 方向 细粒度归因 / what-if 记为后续;v1 先交付可常开的粗粒度定位,满足验收三条

和 Relax 内已有能力的分工:

已有 位置 本模块补什么
Timer relax/utils/timer.py 墙钟累加 → perf/*(primary);找不到慢卡 / 拆不开 GPU 阶段
TrainProfiler relax/utils/profile_utils.py 偶发重 profile;不能常开
Metrics / tracking tracking_utils / MetricsService 本模块只多一类 straggler/* 字段

3. 问题定义(对照现状代码)

3.1 现有计时够不到「哪张卡慢」

log_perf_data_rawtrain_metric_utils.py)只在 primary 把 Timer 打成 perf/*actor.py 外包的 timer("actor_train") 只能看整段 train。缺的是「每张卡 × 粗粒度阶段 × 可常开」的 GPU 时间画像。

3.2 挂点必须进 Megatron step

with timer("actor_train"):          # actor.py ~1678
  train(...)                        # model.py:1411
    for step_id: train_one_step()   # model.py:1545-1559
      forward_backward_func(...)    # model.py:1283(含 streaming 1267-1280)
      optimizer.step()              # model.py:1315

阶段计时落在 train_one_step;外层只负责「是否在训」。

3.3 验收映射

验收 本方案
开销 < 0.5% 默认关;开启后默认每 10 step 采 1 次;非采样步零 Event;采样步末尾 sync 一次
不影响精度 / loss 不计时逻辑不改计算图;同 seed A/B
不影响通算 overlap 阶段中不插 synchronize / 额外 barrier;不新增训练路径 collective;汇总走 object/Gloo
实时上报、便于定位 straggler/*tracking_utils.log;慢 rank + 阶段 + bottleneck + hints
观测故障不伤训练 汇总/上报异常只 warning(对齐「可观测不阻断」底线)

4. 目标与非目标

4.1 目标

  1. 默认可关;开启后可持续运行,平均开销 < 0.5%。
  2. 标出慢 rank,并给出粗粒度阶段耗时(fwd / bwd / optim / comm)。
  3. attention / MoE:预留名与可选 hook,默认关。
  4. 指标进入现有 tracking / MetricsService。
  5. 正确性 gate 先于开销 gate。

4.2 非目标(v1)

  • 不自动隔离 / 踢卡 / 改 DP·PP 拓扑(Falcon-Mitigate 整层不做)。
  • 不 LD_PRELOAD / 不挂起训练做校验。
  • 不常开 torch.profiler / Nsight。
  • 不复刻 OSDI 全量 what-if。
  • 不默认包装整个 ProcessGroup。
  • 不改 loss、默认 recipe、DCS / 权重同步。
  • 不做跨节点墙钟对齐;不做 GPU power/temp 采集。

5. 设计不变量

  1. 未开 --straggler-analysis → 训练路径近似零开销(nullcontext)。
  2. 仅采样步创建/record Event。
  3. 阶段中间不 sync;读数集中在采样 step 末尾一次。
  4. 汇总用 all_gather_object 或独立 Gloo,占训练 NCCL 热路径(actor 长度汇总已有 object gather 先例)。
  5. Timer / TrainProfiler 并存,职责不抢。
  6. Event 统一走 relax.utils.device.Event
  7. 观测失败不抛穿训练主路径。

6. 设计

6.1 模块

模块 路径 作用
StragglerConfig relax/utils/straggler/config.py 开关、间隔、阈值、可选 module stages
StageTimer relax/utils/straggler/stages.py Event 记起止
StragglerAnalyzer relax/utils/straggler/detector.py section API、采样、汇总、判定(单例,类似 Megatron)
reporter relax/utils/straggler/reporter.py tracking_utils.log

对外用法(便于接入,不强迫用户手写 Event):

with analyzer.section("forward"):
    ...
with analyzer.section("optimizer"):
    optimizer.step()

6.2 阶段与挂法

stage 挂法(基线)
forward forward_step 边界 record,按 microbatch 累加
backward 与 forward 成对的反传路径 record
optimizer 包住 optimizer.step()model.py:1315
communication 包在已有 collective 外,不加新 barrier
attention / moe --straggler-enable-module-stages 打开后挂模块边界

PP 说明: PP>1 时 schedule 会交织 fwd/bwd。v1 指标解读为「本 rank 花在对应 kernel 上的累加 GPU 时间」,声称等于无 overlap 的纯阶段墙钟。streaming schedule 与标准路径共用 Analyzer API。

6.3 采样与计时

非采样步: section → nullcontext
采样步: record start/end(不 sync)→ step 末尾 sync 一次 → gather → 判定 → log

默认 sample_interval=10(对齐 NVRx profiling_interval 降开销的思路)。

6.4 跨 rank 汇总

只比各卡本地阶段耗时,不需要 NTP。默认 gather 到 metrics/primary rank 再 tracking_utils.log

6.5 判定

slow if t[r,s] >= ref[s] * relative_threshold
      or t[r,s] - ref[s] >= absolute_ms_threshold
  • 默认 ref = meanrelative_threshold=1.2(略宽于 Falcon 的 1.1×median,先降误报;可用 flag 切 median / 1.1
  • 另输出 NVRx 风格 relative_score ≈ ref/t(0–1,越小越慢),方便扫一眼

额外:likely_bottleneck = argmax(max-ref)、一行 hints

communication:collective 调用耗时(可含等慢 peer),判「是不是堵在等」,不当纯带宽。

6.6 指标

straggler/{stage}/local_ms
straggler/{stage}/mean_ms
straggler/{stage}/max_ms
straggler/{stage}/slowdown_ratio
straggler/{stage}/relative_score
straggler/{stage}/top_rank
straggler/{stage}/num_stragglers
straggler/likely_bottleneck
straggler/hints

6.7 参数

--straggler-analysis                         # default: false
--straggler-interval 10
--straggler-relative-threshold 1.2
--straggler-absolute-ms-threshold 5.0
--straggler-ref {mean,median}                # default: mean
--straggler-enable-module-stages             # attention/moe,default: false

--use-pytorch-profiler 并列:后者偶发重 profile,前者常开轻量观测。


7. 流程

dataflow

sequenceDiagram
    participant TrainLoop as TrainOneStep
    participant A as StragglerAnalyzer
    participant T as StageTimer
    participant R as OtherRanks
    participant M as TrackingUtils

    TrainLoop->>A: begin_step(step)
    alt non_sample
        A-->>TrainLoop: skip
    else sample
        TrainLoop->>T: section record events
        TrainLoop->>A: end_step(step)
        A->>T: sync once and read ms
        A->>R: gather scalars via object or Gloo
        A->>A: mark stragglers
        A->>M: emit straggler metrics
    end
Loading

architecture


8. 改动范围

文件 改动
relax/utils/straggler/* 新库
tests/utils/test_straggler_detector.py CPU 单测
scripts/tools/bench_straggler_overhead.py 多卡开销 / 注入
relax/utils/arguments.py flags,默认关
relax/backends/megatron/model.py train_one_step 挂 section
relax/backends/megatron/actor.py 仅必要时透传生命周期
docs 用法、与 Timer/Profiler 分工、PP 语义

不改:loss、默认 recipe、DCS、权重同步、TransferQueue。


9. 验证计划(正确性 → 开销)

  1. CPU 单测:采样门控、阈值、关闭路径、metrics 字段
  2. 慢卡注入:对应 stage 被标出
  3. loss 对照:同 seed 开关一致
  4. 开销 A/B:(B-A)/A < 0.5%interval=10
  5. overlap 抽检:无额外中途 sync / 新 barrier
  6. 上报失败注入:训练继续

已有机制验证(2×GPU,interval=10):短 step 2.201%(参考);更长 step 0.479%,rank1 forward ≈1.94×。
业界同量级:Falcon-Detect 平均约 0.39%、NVRx 预期 <1%——说明「Event + 间隔」路线本身可过 0.5% gate。

overhead

完整 Relax recipe A/B,等导师指定脚本后在官方镜像补。

PYTHONPATH=. pytest -q tests/utils/test_straggler_detector.py

torchrun --standalone --nproc_per_node=2 \
  scripts/tools/bench_straggler_overhead.py \
  --steps 80 --interval 10 --batch 32 --dim 4096

10. 分期

  1. 库 + 单测 + bench(默认关)
  2. train_one_step:fwd / bwd / optim / comm
  3. 官方 recipe A/B
  4. 可选 attention / MoE
  5. 内部平台 schema(导师给字段后)
  6. (可选后续)更细归因 / 缓解——不进本期验收

回退:关 --straggler-analysis;必要时 revert 接入 commit。


11. 交付

  • 本 RFC
  • 原型库、单测、2 卡 bench
  • PR1:库 + 测试(默认关)
  • PR2:挂点 + 文档
  • recipe A/B 日志
  • (可选)平台 adapter

12. 请导师确认

  1. Decision 表是否按此拍板(只观测、不缓解、不 LD_PRELOAD)?
  2. attention/MoE 是否「预留 + 可选 flag」?
  3. 阈值默认 mean×1.2,是否改成 Falcon 风格 median×1.1
  4. PP>1 的 fwd/bwd 按「本 rank 累加 GPU 时间」解读是否可接受?
  5. 正式开销验收指定哪条官方小模型 recipe?内部平台有无现成字段,还是先 tracking_utils

@Lemon-412 老师,正文已按 Decision 表收拢;统一评审窗口 10/12–14,麻烦看下范围能否这么定。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions