def METHOD_NAME(
    self, outputs, targets, masks=None, label_smoothing=0.0, name="loss", factor=1.0
):
    """
    outputs: batch x len x d_model
    targets: batch x len
    masks:   batch x len
    policy_logprob: if there is some policy
        depends on the likelihood score as rewards.
    """
    def mean_ds(x: Tensor, dim=None) -> Tensor:
        return (
            x.float().mean().type_as(x)
            if dim is None
            else x.float().mean(dim).type_as(x)
        )
    if masks is not None:
        outputs, targets = outputs[masks], targets[masks]
    if masks is not None and not masks.any():
        nll_loss = torch.tensor(0)
        loss = nll_loss
    else:
        logits = F.log_softmax(outputs, dim=-1)
        if targets.dim() == 1:
            losses = F.nll_loss(logits, targets.to(logits.device), reduction="none")
        else:  # soft-labels
            losses = F.kl_div(logits, targets.to(logits.device), reduction="none")
            losses = losses.sum(-1)
        nll_loss = mean_ds(losses)
        if label_smoothing > 0:
            loss = (
                nll_loss * (1 - label_smoothing) - mean_ds(logits) * label_smoothing
            )
        else:
            loss = nll_loss
    loss = loss * factor
    return {"name": name, "loss": loss, "nll_loss": nll_loss, "factor": factor}