66
77from deepspeed .runtime .zero .utils import _initialize_parameter_parallel_groups
88from deepspeed .runtime .fp16 .loss_scaler import LossScaler , DynamicLossScaler
9- from deepspeed .runtime .utils import get_grad_norm , CheckOverflow
9+ from deepspeed .runtime .utils import get_grad_norm , CheckOverflow , is_model_parallel_parameter
1010from deepspeed .runtime .zero .config import ZERO_OPTIMIZATION_OPTIMIZER_STATES
1111from deepspeed .utils import logger , log_dist
1212
@@ -642,7 +642,7 @@ def step(self, closure=None):
642642 partition_id = dist .get_rank (group = self .dp_process_group )
643643 for i , group in enumerate (self .fp16_groups ):
644644 #TODO RS: update get grad norm to support sub partitions
645- norm_groups .append (get_grad_norm (group , mpu = self .mpu ))
645+ # norm_groups.append(get_grad_norm(group, mpu=self.mpu))
646646
647647 #RS: update free grads w.r.t. sub partitions
648648 #free gradients for all the parameters that are not updated by this process
@@ -667,6 +667,11 @@ def step(self, closure=None):
667667 self .free_grad_in_param_list (
668668 self .params_in_rank_sub_partitions [i ][partition_id ])
669669
670+ # calculate grad norm w.r.t. local sub partitions
671+ norm_groups .append (
672+ self .get_grad_norm_sub_partitions (local_grad_sub_partitions ,
673+ mpu = self .mpu ))
674+
670675 local_sub_partitions_grad_groups .append (local_grad_sub_partitions )
671676
672677 #RS: update unscale/clip with sub partitions
@@ -706,6 +711,40 @@ def step(self, closure=None):
706711
707712 return self .overflow
708713
714+ def get_grad_norm_sub_partitions (self , sub_partitions , mpu ):
715+ norm_type = 2.0
716+ total_norm = 0.
717+ for partition in sub_partitions :
718+ if mpu is not None :
719+ # if (mpu.get_model_parallel_rank() == 0
720+ # ) or is_model_parallel_parameter(p):
721+ # param_norm = p.grad.data.float().norm(norm_type)
722+ # total_norm += param_norm.item()**norm_type
723+ raise NotImplementedError (
724+ "support grad norm of model parallel parameters" )
725+ else :
726+ param_norm = partition .data .float ().norm (norm_type )
727+ total_norm += param_norm .item ()** norm_type
728+
729+ # Sum across all DP ranks who each have different grad sub-partitions
730+ total_norm_cuda = torch .cuda .FloatTensor ([float (total_norm )])
731+ torch .distributed .all_reduce (total_norm_cuda ,
732+ op = torch .distributed .ReduceOp .SUM ,
733+ group = self .dp_process_group )
734+
735+ if mpu is not None :
736+ # Sum across all model parallel GPUs.
737+ torch .distributed .all_reduce (total_norm_cuda ,
738+ op = torch .distributed .ReduceOp .SUM ,
739+ group = mpu .get_model_parallel_group ())
740+
741+ total_norm = total_norm_cuda [0 ].item ()** (1. / norm_type )
742+ if total_norm == float (
743+ 'inf' ) or total_norm == - float ('inf' ) or total_norm != total_norm :
744+ total_norm = - 1
745+
746+ return total_norm
747+
709748 def unscale_and_clip_grads (self , grad_groups_flat , norm_groups ):
710749 total_norm = 0.0
711750 for norm in norm_groups :
0 commit comments