@@ -203,6 +203,7 @@ def __init__(self,
203203 self ._gradient_clipping = gradient_clipping
204204 self ._grad_accumulation_steps = grad_accumulation_steps
205205 self ._grad_counter = 0
206+ self ._grad_stepped = True
206207 self ._clip_by_global_norm = clip_by_global_norm
207208 self ._ignore_param_not_requiring_grad = ignore_param_not_requiring_grad
208209 self ._parvi = parvi
@@ -221,6 +222,16 @@ def __init__(self,
221222 self .name = NewClsName + "_" + str (NewCls .counter )
222223 NewCls .counter += 1
223224
225+ @common .add_method (NewCls )
226+ def zero_grad (self , * args , ** kwargs ):
227+ """Only zero the gradients if the last ``step()`` has taken effect.
228+
229+ In the case of grad accumulation, we should avoid zeroing the gradients
230+ before accumulation is done.
231+ """
232+ if self ._grad_stepped :
233+ super (NewCls , self ).zero_grad (* args , ** kwargs )
234+
224235 @common .add_method (NewCls )
225236 def _clone_params (self , capacity_ratio : float ):
226237 """clone the parameters
@@ -351,6 +362,7 @@ def step(self, closure=None):
351362 p .grad .mul_ (1.0 / self ._grad_accumulation_steps )
352363 else :
353364 # Do nothing while the grad is still being accumulated
365+ self ._grad_stepped = False
354366 return
355367
356368 if self ._lr_scheduler is not None :
@@ -419,6 +431,7 @@ def step(self, closure=None):
419431 alf .summary .scalar ("capacity_ratio" , capacity_ratio )
420432
421433 self ._first_stepping_done = True
434+ self ._grad_stepped = True
422435
423436 @common .add_method (NewCls )
424437 def _parvi_step (self ):
0 commit comments