Prhub

#2578 fix: Improve Qwen3 FSDP long CI perf

原始 PR 作者 guapisolo 合并时间 2026-08-17 02:35 文件变更 1 提交数 4 评论 1 代码增减 +3 / -0

执行摘要

Qwen3 FSDP CI 改用动态 token 批处理,超时测试降至 2295 秒

PR body 明确指出:release CI run 31862426780 的 stage-c-2-gpu-h200 shard 1 超时,test_qwen3_0.6B_fsdp_colocated_2xGPU.py 在 3750 秒时仅完成部分 rollout。根因拆解为三点:execute 配置 global batch 256 但未启用动态 token batching;--micro-batch-size 默认为 1,导致每 rank 128 个 micro-batch;actor_train 在 60-rollout 工作负载完成前耗尽预算。

建议快速浏览该 PR,重点学习其验证方法:先定位 micro-batch 爆炸根因,再通过实测 token 上限边界(32768 通过、65536/100000 OOM)确定安全值,最后用 unpinned main CI 全量验证。这种『根因-边界-全链路验证』的排查思路值得借鉴;但变更本身仅为测试参数,无需精读。

讨论亮点

该 PR 没有实质性的 reviewer 讨论:唯一的 review 来自 claude[bot],仅提示此仓库配置为手动 review,并告知可评论 @claude review 触发。PR body 的 Review Focus 指出 perf_args 是唯一需要关注的点:它改变了调度方式但不减少 workload 或验收标准。作者在 Issue 评论中补充了 unpinned main CI 的全量验证结果(28 pass / 7 skipped / 0 fail),作为主要说服依据。

实现拆解

本次变更为单文件测试参数调整,按以下步骤完成:

  1. 诊断与定位:在 tests/e2e/short/test_qwen3_0.6B_fsdp_colocated_2xGPU.pyexecute() 中发现训练参数组合导致 micro-batch 数量爆炸,结合 release CI 超时日志确认瓶颈。
  2. 引入动态 token 批处理:新增 perf_args = "--use-dynamic-batch-size --max-tokens-per-gpu 32768 ",并在 train_argsfsdp_args 之后插入 f"{perf_args} "。该参数让训练器按 token 数打包 micro-batch,而不是固定 micro-batch size,从而将每 rank micro-batch 数从 128 降至 3-4。
  3. 验证 token 上限边界:在 2xH200 上实测,32768 时仍有至少 4744 MiB 空闲内存;65536 和 100000 均在首次 log-prob 前向中 OOM,因此确定 32768 为安全上限。
  4. 验证 CI 全链路:未 pin 的 main 栈 CI run 31932513930 中,专属 job 36m45s 通过,整体 workflow 1h05m12s 完成,28 pass / 7 skipped / 0 fail;CI registry 与 policy 测试 87 项通过,pre-commit 通过。
  5. 演进过程:提交历史显示曾尝试为 colocated FSDP 添加专属 CI selector(commit c6123d2),但最终 revert(commit 48bd44c),保持本 PR 只改动态 token batching,避免影响 nightly 和 image 的测试注册范围。

无产品源码、配置或部署配套改动。

文件 模块 状态 重要度
tests/e2e/short/test_qwen3_0.6B_fsdp_colocated_2xGPU.py E2E 测试 modified 3.92

关键符号

execute

关键源码片段

tests/e2e/short/test_qwen3_0.6B_fsdp_colocated_2xGPU.py test-coverage

唯一变更文件。在 execute() 中新增 perf_args 并插入 train_args,启用动态 token 批处理,是本次性能修复的全部内容。

# tests/e2e/short/test_qwen3_0.6B_fsdp_colocated_2xGPU.py 中 execute() 的核心配置段def execute(): # 2xGPU 共置 FSDP 训练的入口,组装并启动训练
    # ...(ckpt_args、rollout_args、optimizer_args、grpo_args 等在上方定义)
​
    fsdp_args = (
        # SHARDED_STATE_DICT 模式(默认),更新权重 buffer 512 MB
        "--update-weight-buffer-size 536870912 "
    )
​
    # 本次修复核心:启用动态 token 批处理,将每 rank 的 micro-batch 数
    # 从 128(global batch 256 / micro-batch 1)降到 3-4 个,
    # 避免 actor 前向在 60 个 rollout 完成前耗尽 CI 时间预算。
    # 32768 是 2xH200 上经实测的 token 上限:更高(65536/100000)首轮 log-prob 即 OOM。
    perf_args = "--use-dynamic-batch-size --max-tokens-per-gpu 32768 "
​
    ci_args = (
        "--ci-test "
        "--ci-disable-kl-checker "
        "--ci-metric-checker-key eval/gsm8k "
        "--ci-metric-checker-threshold 0.71 " # 60 步下的宽松阈值
    )
​
    misc_args = "--actor-num-nodes 1 " "--actor-num-gpus-per-node 2 " "--colocate " "--train-backend fsdp "
​
    train_args = (
        f"{ckpt_args} "
        f"{rollout_args} "
        f"{optimizer_args} "
        f"{grpo_args} "
        f"{sglang_args} "
        f"{U.get_default_wandb_args(__file__)} "
        f"{eval_args} "
        f"{fsdp_args} "
        f"{perf_args} " # 插入 train_args,替代固定 micro-batch 的默认调度
        f"{ci_args} "
        f"{misc_args} "
    )
​
    U.execute_train(
        train_args=train_args,
        num_gpus_per_node=2,
        megatron_model_type=None,
    )

评论区精华

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

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

风险与影响

风险集中在以下几点:

  • OOM 边界依赖硬件:32768 的 token 上限是在 2xH200 上实测的,若 CI 环境更换 GPU 型号或显存缩水,可能复现 OOM,需要重新校准该值。
  • 测试参数与生产配置漂移:该参数对齐了生产 Qwen3 FSDP launcher 的 9216 token 配置(后提升至 32768),但测试脚本与生产启动器若后续不同步演进,可能掩盖真实性能回归。
  • 无源码逻辑覆盖:本次仅调整测试参数,不涉及产品代码,因此不影响训练框架本身,但也不增加对动态 batching 功能的单元测试覆盖。
  • 回归风险:改动极小且经验证,风险低;但若 CI 时间预算后续收紧,仍需重新评估。

对用户无直接影响;对团队而言,Qwen3 0.6B FSDP colocated 2xGPU 的 E2E 测试从频繁超时变为稳定通过(2295 秒 vs 3750 秒上限),显著降低 release CI 的等待和重试成本。同时,该 PR 明确了 2xH200 在 FSDP 共置模式下的动态 token 内存边界,为后续类似 CI 测试的参数选择提供了可复用的经验数据。

OOM 边界依赖硬件 仅测试参数变更 无源码逻辑覆盖

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论