    def rescale_gradients(self) -> Optional[float]:
        """
        Performs gradient rescaling. Is a no-op if gradient rescaling is not enabled.

        Returns the norm of the gradients if `grad_norm` is `True` or a `float`,
        otherwise returns `None`.
        """
        if not isinstance(self._grad_norm, bool):
            if self._scaler is not None:
                # Need to first unscale gradients in order to clip as usual.
                self._scaler.unscale_(self.optimizer)
            # Sometimes logic for clipping has to implemented within the model, like
            # with FairScale's FullyShardedDataParallel.
            if self._ddp_wrapped_model is not None:
                return self._ddp_wrapped_model.clip_grad_norm_(self._grad_norm).item()
            else:
                parameters_to_clip = [p for p in self.model.parameters() if p.grad is not None]
                return clip_grad_norm_(parameters_to_clip, self._grad_norm).item()
        elif self._grad_norm:
            parameters_to_clip = [p for p in self.model.parameters() if p.grad is not None]
            return torch.norm(
                torch.stack([torch.norm(p.grad.detach()) for p in parameters_to_clip])
            ).item()
        else:
            return None
Performs gradient rescaling. Is a no-op if gradient rescaling is not enabled.

Returns the norm of the gradients if `grad_norm` is `True` or a `float`,
otherwise returns `None`.
allennlp/training/gradient_descent_trainer.py