for p, clip_value in zip(params, clip_values):
    noise = self._generate_noise(clip_value, p)
    if self.loss_reduction == "mean":
        noise /= batch_size
    if self.rank == 0:
        p.grad += noise

the noise is added to the averaged gradient, why should it be divided by the batch size?
since the output is the final grad, should it be added with noise (without being divided) directly?