已合并
dualpipev dw detach #2154
zhao-yifan27创建于 2025年4月3日
dualpipev dw detach #2154
已合并
zhao-yifan27创建于 2025年4月3日
refs/pull/2154/head合入到core_r0.8.0
4 个文件变更+11-4
@@ -15,7 +15,8 @@ DualPipe流水不仅可以创造跨microbatch计算通信并行的条件,实
15![dualpipev](../../sources/images/dualpipev.png)15![dualpipev](../../sources/images/dualpipev.png)
16图中0~9和10~19代表同一个microbatch在同一张卡上的两个stage。绿色部分代表不同microbatch的前反向并行,开启跨micro batch前反向通信掩盖后,All2All通信和P2P通信都可以被没有依赖关系的计算掩盖,该特性的详细介绍参见[MoE跨microbatch前反向通信掩盖](megatron_moe/megatron-moe-fb-overlap.md)。16图中0~9和10~19代表同一个microbatch在同一张卡上的两个stage。绿色部分代表不同microbatch的前反向并行,开启跨micro batch前反向通信掩盖后,All2All通信和P2P通信都可以被没有依赖关系的计算掩盖,该特性的详细介绍参见[MoE跨microbatch前反向通信掩盖](megatron_moe/megatron-moe-fb-overlap.md)。
17 17 
18-在warmup阶段,MindSpeed实现了尽可能多得P2P通信掩盖。在cooldown阶段,DualPipeV实现中PP尾卡会连续计算PP_size个反向stage,在对应的dw计算完成之前,激活值并不会完全释放,这会导致在重计算或其他内存特性场景下,cooldown阶段的峰值内存被大大拉高。因此MindSpeed实现中取消了cooldown阶段的dw分离,以较小的性能代价降低了重计算场景下内存峰值。18+在warmup阶段,MindSpeed实现了尽可能多得P2P通信掩盖。在cooldown阶段,DualPipeV实现中PP尾卡会连续计算PP_size个反向stage,在对应的dw计算完成之前,激活值并不会完全释放,这会导致在某些重计算或其他内存特性场景下,cooldown阶段的峰值内存被大大拉高。因此MindSpeed实现中默认取消了cooldown阶段的dw分离,以较小的性能代价降低了重计算场景下内存峰值。同时也给出了dw分离的参数选项,开启dw分离时的流水如下图所示。
19+![dualpipev_dw_detach](../../sources/images/dualpipev_dw_detach.png)。
19 20 
20下图展示了在DeepseekV3 671B模型上采用PP8 TP2 EP32 DualPipeV策略采集的PP通信组profiling。21下图展示了在DeepseekV3 671B模型上采用PP8 TP2 EP32 DualPipeV策略采集的PP通信组profiling。
21![dualpipev_profiling](../../sources/images/dualpipev_profiling.png)22![dualpipev_profiling](../../sources/images/dualpipev_profiling.png)
@@ -50,6 +51,8 @@ DualPipe流水不仅可以创造跨microbatch计算通信并行的条件,实
50## 使用方法51## 使用方法
51在启动脚本中添加`--schedules-method dualpipev``--moe-fb-overlap`52在启动脚本中添加`--schedules-method dualpipev``--moe-fb-overlap`
52 53 
54+在启动脚本中额外添加`--dualpipev-dw-detach` 来开启cooldown阶段的dw分离。
55+ 
53使用DualPipeV时,模型层数设置应为`PP*2`的倍数。同时每个PP组的micro batch数至少设置为`PP*2`56使用DualPipeV时,模型层数设置应为`PP*2`的倍数。同时每个PP组的micro batch数至少设置为`PP*2`
54 57 
55 58 
@@ -708,7 +708,6 @@ def forward_backward_pipelining_with_cutinhalf(
708):708):
709 args = get_args()709 args = get_args()
710 args.moe_fb_overlap = True710 args.moe_fb_overlap = True
711- args.dualpipe_no_dw_detach = True
712 711 
713 set_shared_embedding_from_dual_chunk(model[0], model[1])712 set_shared_embedding_from_dual_chunk(model[0], model[1])
714 assert (713 assert (
@@ -1435,7 +1434,7 @@ def forward_backward_pipelining_with_cutinhalf(
1435 input_tensor_bwd = merged_input_tensors.pop(0)[1]1434 input_tensor_bwd = merged_input_tensors.pop(0)[1]
1436 output_tensor_bwd, bwd_model_chunk_id = merged_output_tensors.pop(0)1435 output_tensor_bwd, bwd_model_chunk_id = merged_output_tensors.pop(0)
1437 1436 
1438- if not args.dualpipe_no_dw_detach:1437+ if args.dualpipev_dw_detach:
1439 WeightGradStore.start_decouple()1438 WeightGradStore.start_decouple()
1440 1439 
1441 if args.moe_fb_overlap:1440 if args.moe_fb_overlap:
@@ -1449,7 +1448,7 @@ def forward_backward_pipelining_with_cutinhalf(
1449 input_tensor_bwd, output_tensor_bwd, output_tensor_grad_bwd, model_type, config1448 input_tensor_bwd, output_tensor_bwd, output_tensor_grad_bwd, model_type, config
1450 )1449 )
1451 1450 
1452- if not args.dualpipe_no_dw_detach:1451+ if args.dualpipev_dw_detach:
1453 WeightGradStore.end_decouple()1452 WeightGradStore.end_decouple()
1454 1453 
1455 if i == pp_size - 1:1454 if i == pp_size - 1:
@@ -14,12 +14,17 @@ class DualpipeVFeature(MindSpeedFeature):
14 group = parser.add_argument_group(title=self.feature_name)14 group = parser.add_argument_group(title=self.feature_name)
15 group.add_argument('--schedules-method', type=str,15 group.add_argument('--schedules-method', type=str,
16 default=None, choices=['dualpipev'])16 default=None, choices=['dualpipev'])
17+ group.add_argument('--dualpipev-dw-detach', action='store_true',
18+ help='detach dw in cooldown to reduce bubble')
17 19 
18 def validate_args(self, args):20 def validate_args(self, args):
19 if args.schedules_method == "dualpipev":21 if args.schedules_method == "dualpipev":
20 if args.num_layers_per_virtual_pipeline_stage is not None:22 if args.num_layers_per_virtual_pipeline_stage is not None:
21 raise AssertionError(23 raise AssertionError(
22 "The dualpipev and virtual_pipeline are incompatible.")24 "The dualpipev and virtual_pipeline are incompatible.")
25+ if args.pipeline_model_parallel_size == 1:
26+ raise AssertionError(
27+ "pipeline_model_parallel_size should be larger than 1 with dualpipev schedules")
23 if args.num_layers < args.pipeline_model_parallel_size * 2:28 if args.num_layers < args.pipeline_model_parallel_size * 2:
24 raise AssertionError(29 raise AssertionError(
25 'number of layers must be at least 2*pipeline_model_parallel_size in dualpipe')30 'number of layers must be at least 2*pipeline_model_parallel_size in dualpipe')