You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyTorch下Unlikelihood Training损失实现正确性技术问询

你的Unlikelihood Training损失实现不正确

你当前的代码完全不符合原论文的损失设计逻辑,核心问题如下:

  • 输入语义混淆:原生NLLLoss接收的是log_softmax输出的对数概率,取值范围是(-∞, 0],你代码里直接用1 - logs[i][c[i]]作为权重系数,计算出来的权重会大于1甚至出现异常值,完全不符合加权逻辑。
  • 损失结构错误:原论文的非似然损失是标准NLL损失 + 独立非似然惩罚项的加权和,不是给目标token的NLL项乘一个系数。非似然项的作用是单独压低指定负样本token的生成概率,和目标token的似然计算是独立的两个部分。
  • 负样本参数语义错误:你代码里的c是单个token的形式,但原论文里每个位置需要惩罚的是一整个负样本token集合,非似然项需要对集合内所有token计算惩罚值再聚合,不是取单个token算权重。

原论文中token级非似然损失的核心逻辑为:总损失由两部分组成,第一部分是常规的负对数似然损失,第二部分是非似然惩罚项,对所有需要被规避的负样本token c计算$-log(1-p(c))$的均值,目标是让这些负样本的生成概率p(c)趋近于0,两部分通过权重系数α加权求和。

正确实现参考

import torch
import torch.nn.functional as F

def unlikelihood_loss(logits, targets, neg_token_mask, alpha=0.1):
    """
    Args:
        logits: 模型原始输出logit,形状为 [batch_size, seq_len, vocab_size]
        targets: 真实标签token ID,形状为 [batch_size, seq_len]
        neg_token_mask: 负样本掩码,形状和logits一致,对应位置为1表示该位置的该token需要被惩罚
        alpha: 非似然惩罚项的权重
    """
    log_probs = F.log_softmax(logits, dim=-1)
    probs = torch.exp(log_probs)

    # 计算标准NLL损失
    nll_loss = F.nll_loss(
        log_probs.reshape(-1, log_probs.size(-1)),
        targets.reshape(-1),
        reduction="mean"
    )

    # 计算非似然惩罚项,加1e-8避免log(0)的数值不稳定问题
    ul_per_token = -torch.log(1 - probs + 1e-8)
    ul_loss = (ul_per_token * neg_token_mask).sum() / (neg_token_mask.sum() + 1e-8)

    return nll_loss + alpha * ul_loss

如果要实现论文中用于解决重复生成问题的序列级非似然损失,只需要在构造neg_token_mask时,把每个位置之前已经出现过的token标记为负样本即可,损失计算逻辑不需要改动。


内容的提问来源于stack exchange,提问作者Minions

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 00:33:35