def apply_exponential_smoothing(avg_params: Tensor,
                                updated_params: Tensor,
                                steps: int,
                                beta: float=0.9999,  # noqa: E252
                                ref_target_words: Optional[int]=None,  # noqa: E252
                                actual_target_words: Optional[int]=None):  # noqa: E252
    r'''
        Applies exponential smoothing on a model's parameters, updating them in place.
        Can provide improved performance compared to inference using a single checkpoint.

        .. math::
            s_{t+1} = \beta \cdot s_t + (1-\beta) \cdot p_{t+1}
        where :math:`s_t` are the smoothed params (`avg_params`) at time :math:`t` and :math:`p_{t+1}` are the incoming
        updated_parameters from the most recent step (time :math:`t+1`).

        Args:
            avg_params List[Tensor]:
                Model parameters derived using the repeated average for all t < steps. Updated in-place.
            updated_params List[Tensor]:
                Model parameters from the latest update.
            steps int:
                Number of optimizer steps taken.
            beta float:
                Parameter that controls the decay speed. Default = 0.9999
            ref_target_words Optional[int]:
                Reference number of target labels expected in a batch.
            actual_target_words Optional[int]:
                The actual number of target labels in this batch.
        '''

    if ref_target_words is not None and actual_target_words is not None:
        beta = beta ** (actual_target_words / ref_target_words)
        steps = max(steps, steps * (actual_target_words / ref_target_words))  # BUG: does not account for changing batch size

    # Decay parameters more quickly at the beginning to avoid retaining the random initialization
    decay_by = min(beta, (steps + 1.) / (steps + 10))

    # Equivalent to: decay_by * avg_params + (1.0 - decay_by) * updated_params
    updated_params = updated_params.to(avg_params.dtype)
    avg_params.copy_(decay_by * (avg_params - updated_params) + updated_params)

        Applies exponential smoothing on a model's parameters, updating them in place.
        Can provide improved performance compared to inference using a single checkpoint.

        .. math::
            s_{t+1} = \beta \cdot s_t + (1-\beta) \cdot p_{t+1}
        where :math:`s_t` are the smoothed params (`avg_params`) at time :math:`t` and :math:`p_{t+1}` are the incoming
        updated_parameters from the most recent step (time :math:`t+1`).

        Args:
            avg_params List[Tensor]:
                Model parameters derived using the repeated average for all t < steps. Updated in-place.
            updated_params List[Tensor]:
                Model parameters from the latest update.
            steps int:
                Number of optimizer steps taken.
            beta float:
                Parameter that controls the decay speed. Default = 0.9999
            ref_target_words Optional[int]:
                Reference number of target labels expected in a batch.
            actual_target_words Optional[int]:
                The actual number of target labels in this batch.
        
trainer/utils/misc.py