已开启
[Benchmark] Qwen3-8B-lite fully_shard 性能对比(torch_npu 原生 vs hyper torch/ms) #192
changzherui创建于 6月8日
6月8日 修改标题为 “[Benchmark] Qwen3-8B-lite fully_shard 性能对比(torch_npu 原生 vs hyper torch/ms)”,原标题为“[Benchmark] Qwen3-8B-lite fully_shard:torch_npu 原生 vs hyper (torch/ms) 性能对比”
6月8日 修改标题为 “[Benchmark] Qwen3-8B-lite fully_shard 性能对比(torch_npu 原生 vs hyper torch/ms)”,原标题为“[Benchmark] Qwen3-8B-lite fully_shard:torch_npu 原生 vs hyper (torch/ms) 性能对比”
6月8日 修改了issue 的描述
6月8日 修改了issue 的描述
6月8日 修改了issue 的描述
6月8日 修改了issue 的描述
6月8日 修改了issue 的描述
6月8日 将 changzherui1 设为负责人
6月8日 修改了issue 的描述
6月8日 修改了issue 的描述
6月8日 修改了issue 的描述
6月8日 修改了issue 的描述
6月8日 修改了issue 的描述
6月8日 修改了issue 的描述
Qwen3-8B-lite fully_shard 性能优化实验全记录
零、执行摘要
prefetch(1/1)+ PR707 → 542 ms/step(FSDP8)prefetch是质变(-17%);comm_fusion单独开更慢;P0/P1 让 cf+prefetch 追平原生post_backward:norm(~190 ms,不宜拆 wrap)、pre_backward prefetch:layers.7(~107 ms)性能演进(FSDP8 hyper torch,ms/step):
一、测试方法与配置
1.1 对比路径
torch_npu.distributed.fsdp.fully_shardhyper_parallel+HYPER_PARALLEL_PLATFORM=torchhyper_parallel+ MindSpore 后端1.2 统一参数
(8,)/ HSDP24(2,4)align_data_8b/:init_weights.pt+preset_batches.pt,seed=42torch.npu.synchronize()平均1.3 Profiler 采集
torch_npu.profiler,Level0,with_stack=Falseschedule(wait=2, warmup=1, active=2, repeat=1)→ 分析 rank0 step 3–4ASCEND_PROFILER_OUTPUT/step_trace_time.csv+operator_details.csv1.4 开关说明
prefetchset_modules_to_forward/backward_prefetch)comm_fusionhyper_parallel/platform/torch/fully_shard/源码优化hsdp_scheduler.py:hook 顺序unshard → prefetch(PR #707)二、实验全景(11 项 e2e + 11 项 profiler)
2.1 端到端实验(无 Profiler,steps=20)
baseline_8card/torch_native_8b_8card_fsdp_s4096.jsonpure_fsdp2_8card/hyper_torch_8b_8card_fsdp_s4096.jsonpure_fsdp2_8card/mindspore_8b_8card_fsdp_s4096.jsonhyper_torch_prefetch/..._prefetch.jsonpr707_hyper_torch_prefetch/..._pr707.jsonhyper_torch_comm_fusion/..._comm_fusion.jsontorch_native_hsdp24/..._foreach_false.jsonbaseline_8card/torch_align_..._hsdp24.jsonbaseline_8card/mindspore_align_..._hsdp24.jsonhyper_torch_prefetch/..._hsdp24_prefetch.jsonhyper_torch_comm_fusion/..._hsdp24_comm_fusion.json2.2 Profiler 实验(steps=8,含 profiler 开销)
profiler/torch_native_fsdp8/profiler/hyper_torch_fsdp8/profiler/hyper_torch_fsdp_prefetch/profiler/hyper_torch_fsdp_prefetch_pr707/profiler/hyper_torch_fsdp_prefetch_fwd1_bwd2/profiler/hyper_torch_fsdp_prefetch_split_norm_lm_head/profiler/..._comm_fusion_prefetch/profiler/..._prefetch_p0/profiler/..._prefetch_p1/profiler/torch_native_hsdp24/profiler/hyper_torch_hsdp24/profiler/hyper_torch_hsdp24_prefetch/三、优化过程(按阶段)
阶段 0:基线对比(T1/T2/T7/T8)
发现:hyper 默认比原生慢 17%(FSDP8)/ 30%(HSDP24),但 loss 完全对齐。
阶段 1:Profiler 根因定位(P1/P2/P9/P10)
假设:hyper 计算慢?→ 否定。
FSDP8 rank0 分解(step 3–4):
HSDP24 同理:hyper Computing 515.6 ms < 原生 626.1 ms,但 Comm(未重叠) 505.4 ms >> 原生 165.6 ms。
根因闭环:逐参数 collective + 无 prefetch → 通信几乎不与计算重叠。
阶段 2:开启 prefetch(T4/T10,P3/P11)
措施:
train_hyper_torch.py增加--prefetch,正反向各 1 层。prefetch 是质变级优化:FSDP8 超越原生,HSDP24 追平。
阶段 3:comm_fusion 路径优化(P6→P7→P8,P0/P1 源码)
背景:
comm_fusion单独开启更慢(T6: 701 ms);但 collective 次数与原生对齐(38/40),适合大模型。P0 措施(
state.py,param_group.py):post_backward_for_comm_fusion()流水线重排:先 issue 当前层 RS,再 drain 上一层_reduce_scatter_handle独立存储reduce_scatter_copy_in():torch.cat+ 单次 copyensure_flat_param_buffer()延迟初始化P1 措施(
param_group.py,param.py,state.py):foreach_all_gather_copy_out()AG view 零拷贝release_unshard_buffers()在shard()时释放_reduce_scatter_input跨 step 复用split_with_sizes_copy45.6 msaten::copy_153→115 mssplit_with_sizes_copy→0 ms阶段 4:调度微调(P4/P5,PR707 + prefetch 深度)
PR #707:
hsdp_scheduler.pyforward/backward pre-hook 从prefetch→unshard改为unshard→prefetch。unshard:tok_embeddingsdeviceprefetch:layers.7deviceprefetch 深度扫描 P5(fwd=1, bwd=2):
加深 prefetch 无收益(差 0.3%,噪声内)。
阶段 5:norm/lm_head 拆 wrap 验证(P12)❌ 负向结果
假设:
post_backward:norm(~186 ms)因 norm 与 lm_head 绑在同一 FSDP 单元,RS 粒度过粗;拆分后可降低尾部 RS 耗时。措施:
train_hyper_torch.py新增--split-norm-lm-head,将fully_shard([norm, lm_head]) # 默认改为
fully_shard(norm); fully_shard(lm_head) # 各自独立 wrap配置:FSDP8 + prefetch + PR707,其余与 P4 相同。
Hook 变化(device ms,rank0,2 step):
post_backward:normpost_backward:lm_headpost_backward:layers.7根因:
layers.7post_backward 从 20→76 ms结论:❌ 保持默认
fully_shard([norm, lm_head]),不要拆分。四、Profiler 深度分析
4.1 FSDP8 配置横向对比(rank0)
4.2 HSDP24 配置横向对比(rank0)
HSDP prefetch 后 Comm(未重叠) 仍高于原生(224 vs 166 ms),是 HSDP 残余差距来源。
4.3 Hook 热点(device 累计 ms,2 step,rank0)
post_backward:normpost_backward:lm_headpre_backward prefetch:layers.7post_backward:layers.7post_backward:layers.*(其他层)post_backward:layers.7解读:
post_backward:norm实为 norm+lm_head 绑定单元的一次 RSlayers.7backward prefetch AG 是固定尾部开销(~107 ms)五、结论与配置推荐
5.1 核心结论
5.2 配置推荐
prefetch=True, comm_fusion=False(+PR707)prefetch=True, comm_fusion=True(P0/P1)prefetch=True六、复现命令
source ~/env.sh cd dev/test/qwen3_8b_hsdp2 # ── 端到端 ── ./run_baseline_8card.sh # T1/T8 等基线 ./run_pure_fsdp2_8card.sh # T2/T3 hyper 默认 ./run_hyper_torch_prefetch.sh # T4/T10 +prefetch ./run_hyper_torch_comm_fusion.sh # T6/T11 comm_fusion # ── PR707 验证(本地 hyper-parallel 已 apply patch)── python train_hyper_torch.py --nproc 8 --mesh fsdp --prefetch --prefetch-layers 1 \ --align-dir align_data_8b --steps 20 \ --output-json results/pr707_hyper_torch_prefetch/out.json # ── Profiler ── ./run_torch_native_fsdp8_profile.sh # P1 ./run_hyper_torch_fsdp8_profile.sh # P2(若脚本存在) ./run_hyper_torch_prefetch_profile.sh fsdp # P3 ./run_hyper_torch_comm_fusion_prefetch_profile.sh fsdp # P6/P7/P8 ./run_torch_native_hsdp24_profile.sh # P9 ./run_hyper_torch_hsdp24_profile.sh # P10/P11 # ── prefetch 深度扫描 ── python train_hyper_torch.py --nproc 8 --mesh fsdp --prefetch \ --prefetch-forward-layers 1 --prefetch-backward-layers 2 \ --npu-profiler --profiler-dir results/profiler/hyper_torch_fsdp_prefetch_fwd1_bwd2 ...七、结果文件索引
八、后续 TODO
本文档由
dev/test/qwen3_8b_hsdp2/全部实验数据自动汇总生成。