AiSSN.com ©

在线Ai关键词排名GEO优化工具,让你的信息出现在Ai的回答中

语言模型训练的损失函数怎么选:Cross-Entropy、Label Smoothing与困惑度解读
原始问题:

本文是《Ai大模型训练教程》系列实战篇,详解语言模型训练中损失函数如何选择:交叉熵/负对数似然的优化目标、Label Smoothing 的作用与参数建议,以及困惑度PPL与loss的换算与正确评估方式,并给出可直接落地的实验对照与排查清单。

语言模型训练的损失函数怎么选:Cross-Entropy、Label Smoothing与困惑度解读

Ai大模型训练教程 这套系列里,损失函数(loss)是把“模型输出得好不好”量化成一个可优化目标的核心部件。对语言模型而言,最常见的是 Cross-Entropy(交叉熵)/ Negative Log-Likelihood(负对数似然)。但当你把模型做大、数据变复杂、训练更久之后,会遇到一些实际问题:训练集 loss 降得很快但泛化一般;模型对某些 token 预测过于自信;PPL(困惑度)看起来很好但生成质量不一定同步提升。

本文聚焦“语言模型训练该怎么选损失函数”,并把 Cross-Entropy、Label Smoothing(标签平滑)困惑度 PPL 的关系讲清楚,给出可落地的选择建议、实现步骤与排查思路。


1. 语言模型的训练目标:最大似然与 token 级预测

以自回归语言模型为例,训练目标是让模型在给定上下文时,把下一个 token 的概率分布预测得尽可能接近真实分布。对于一段 token 序列:

[
(x_1, x_2, \dots, x_T)
]

模型学习条件概率:

[
P(x_t | x_{<t})
]

如果把真实 token 视作 one-hot 标签,那么最常用的损失就是 token 级的负对数似然:

[
\mathcal{L} = -\sum_{t=1}^{T} \log p_\theta(x_t | x_{<t})
]

这等价于交叉熵(Cross-Entropy)在 one-hot 标签下的形式。

1.1 为什么“默认选交叉熵”是合理的

  • 统计意义清晰:最大化训练数据似然(MLE)。
  • 实现稳定:框架都高度优化(softmax + log + NLL)。
  • 指标直观:与困惑度 PPL 可直接对应,便于训练监控。

但交叉熵也有典型副作用:当数据存在噪声、标签并非严格确定(语言其实有多种合理下一个 token),模型可能被迫学成“过于自信”的尖峰分布,从而影响校准(calibration)与泛化。


2. Cross-Entropy(交叉熵)到底在优化什么

对单个位置 t,设词表大小为 V,模型输出 logits (z\in\mathbb{R}^V),softmax 后得到概率 (p)。真实 token 为 i,则交叉熵损失:

[
\mathcal{L}_t = -\log p_i
]

其中:

[
p_i = \frac{e^{z_i}}{\sum_{j=1}^{V} e^{z_j}}
]

2.1 一个非常具体的数值直觉

  • 如果模型给正确 token 的概率是 0.9:loss = -log(0.9) ≈ 0.105
  • 如果概率是 0.5:loss ≈ 0.693
  • 如果概率是 0.1:loss ≈ 2.303

loss 对“低概率正确答案”惩罚非常重,这有助于快速纠正错误,但也会鼓励模型把概率推到极端(尤其在训练后期)。

2.2 训练实现的关键细节(实操)

在大模型训练中,你通常不会手写 softmax,而是使用融合算子:

  • PyTorch:torch.nn.CrossEntropyLoss(内部包含 log_softmax + nll_loss
  • Hugging Face:labels 传入后模型内部返回 loss

实操注意点:

  1. ignore_index(忽略 padding):batch 对齐时 padding token 不应参与 loss。
  2. shift(标签右移):自回归 LM 训练要让位置 t 预测 t+1。
  3. 混合精度:用 bf16/fp16 时,优先使用框架提供的融合交叉熵,避免数值不稳定。

3. Label Smoothing(标签平滑):它解决什么问题

Label Smoothing 的核心思想:不要把真实标签当作 100% 确定的 one-hot,而是给其他类别留一点点概率质量,防止模型变得过度自信。

3.1 数学形式

对词表大小 V,平滑系数 (\varepsilon\in[0,1]),真实 token 为 i。原 one-hot 分布 q:

  • (q_i = 1)
  • (q_{j\ne i} = 0)

平滑后分布 q':

  • (q'_i = 1 - \varepsilon)
  • (q'_{j\ne i} = \varepsilon/(V-1))

损失变为:

[
\mathcal{L}_t = - \sum_{j=1}^{V} q'_j \log p_j
]

3.2 语言模型里为什么特别有用

语言任务天然有多解:

  • “我今天要去 ___” 可能是 “上班/学校/超市/旅行…”
  • 数据里标注只有一个 token,但其他 token 并非完全错误

Label Smoothing 相当于承认“标注并不完美”,从而:

  • 降低过拟合与过度自信
  • 改善概率校准(输出概率更可信)
  • 在一些任务上提升泛化(尤其小数据、噪声数据、或强正则需求时)

3.3 代价与误区

  • 困惑度可能变差:因为你不再严格优化 one-hot 的 NLL,训练 loss 的可比性会变复杂。
  • 过大 ε 会伤害可分性:模型学不到“就应该把正确 token 概率打得很高”。
  • 对极大词表的均匀平滑并不总是最优:V 很大时,把 ε 均匀摊到 V-1 个 token 上,单个 token 的概率极小,但正则项仍会影响梯度结构。

3.4 实操:ε 取多少更合理

经验建议(从易到难):

  • 小模型/数据较少/噪声较多ε=0.05 ~ 0.2
  • 中大型 LM 预训练:更常见 ε=0.01 ~ 0.1,需要结合验证集指标选
  • 已经有很强正则(大量数据 + dropout + weight decay + 早停):可以从 ε=0 开始做对照实验

推荐你在训练脚本里做一个最小网格:ε ∈ {0, 0.05, 0.1},只跑 5%~10% 训练步数先看趋势,再决定是否全量训练。

3.5 PyTorch 实现步骤(可直接改进训练代码)

做法 A:直接使用支持 label smoothing 的交叉熵(较新版本 PyTorch 支持):

  • torch.nn.CrossEntropyLoss(label_smoothing=ε, ignore_index=pad_id)

做法 B:自己构造 smoothed target(更灵活,可做非均匀平滑),伪步骤:

  1. 得到 log_probs = log_softmax(logits)
  2. 初始化 q'ε/(V-1)
  3. 将正确 token 位置设为 1-ε
  4. loss = -(q' * log_probs).sum(dim=-1)
  5. 对 padding 位置 mask 掉,再按 token 数量求平均

大模型训练中通常更推荐做法 A(融合算子更快),除非你要做“按同义词集合平滑”等高级策略。


4. 困惑度(Perplexity, PPL)怎么解读:它与 loss 的关系

困惑度是语言模型最常用的可读指标之一。对平均 token 级交叉熵(以自然对数为底)(\bar{\mathcal{L}}),困惑度定义为:

[
\mathrm{PPL} = \exp(\bar{\mathcal{L}})
]

如果你用的是以 2 为底的对数(bit),则是 (2^{\bar{\mathcal{L}}})。大多数深度学习框架里的交叉熵默认是自然对数,因此常见写法是 ppl = exp(loss)

4.1 PPL 的直观含义

可以把 PPL 理解成“模型平均每一步有多少种等可能的选择”。

  • PPL=1:完美预测(每步都确定)
  • PPL=10:相当于每步有 10 个差不多的候选

注意:这只是直觉类比,不是严格等价。

4.2 为什么 PPL 低不等于生成质量一定好

PPL 衡量的是对数据分布的拟合程度,但生成质量还受以下影响:

  • 解码策略(greedy / beam / top-k / top-p / temperature)
  • 偏好对齐(RLHF/DPO 等会改变“人类偏好”的输出而非纯似然)
  • 数据质量与分布:拟合了“坏数据”也能有低 PPL
  • 长文本一致性:PPL 是 token 级平均,可能掩盖长程问题

因此在预训练/续训阶段,PPL 是硬指标;但在指令微调或偏好对齐阶段,PPL 往往不是主目标。

4.3 Label Smoothing 下 PPL 还能直接用吗

需要谨慎。

  • 如果你训练用的是 label smoothing 的 loss,那么这个 loss 不再等同于真实数据 one-hot 的 NLL。
  • 正确做法:评估时用标准 NLL/CE(ε=0)在验证集上算 PPL

实操建议:

  1. 训练时可以用 label smoothing
  2. 验证时固定用标准 CE(不平滑)计算 val_lossval_ppl
  3. 这样 PPL 才可与其他实验可比

5. 怎么选:Cross-Entropy vs Label Smoothing(决策清单)

下面给出更工程化的选择建议,你可以直接对照自己的项目。

5.1 默认方案:预训练/续训优先 Cross-Entropy

适用:

  • 大规模干净语料预训练
  • 你追求极致的 PPL 与训练稳定
  • 你需要与公开基线严格可比

做法:

  • 用标准 CE
  • 重点调:学习率、warmup、weight decay、batch size、梯度裁剪、数据去噪

5.2 何时考虑 Label Smoothing

满足以下任意一条就值得尝试:

  1. 数据噪声较多(爬虫语料、OCR、ASR 转写等)
  2. 数据量偏小(垂直领域继续训练,语料有限)
  3. 观察到过度自信

    • 训练 loss 很低,但验证 loss 不降或反弹
    • 输出分布过尖,top-1 概率经常接近 1
  4. 你更关心泛化/鲁棒性/校准,而不是极限 PPL

推荐起步:ε=0.05

5.3 一个可执行的实验模板(省时间)

  1. 固定数据、模型、训练步数、随机种子
  2. 跑 3 组:ε=0 / 0.05 / 0.1
  3. 每组记录:

    • 标准验证 CE(ε=0)
    • 验证 PPL
    • 下游任务/人工评测(如果有)
    • 生成时的“胡编率/重复率/毒性”等质量指标(如你们有内部评测)
  4. 如果 ε=0.05 在验证 CE 与下游质量上更优或持平,则保留;否则回退到 CE

6. 常见坑与排查:loss/PPL 看不懂时怎么处理

6.1 训练 loss 降得很快,但验证 PPL 不降

排查顺序:

  1. 数据泄漏/切分问题:训练与验证是否重复或分布差异极大
  2. tokenizer 不一致:训练/验证是否用了同一 tokenizer、同一 special tokens
  3. padding 与 mask:padding 是否被正确 ignore
  4. label shift 是否正确:是否预测了当前 token 而不是下一个 token
  5. 过拟合:加 dropout/weight decay,或尝试 label smoothing

6.2 PPL 数值异常大或异常小

  • 异常大:通常是 logits 数值爆炸、学习率过高、未做梯度裁剪、或 label/shift 错位。
  • 异常小:可能是验证集泄漏、或把 padding 也算进了 loss(padding token 很容易被预测对,从而虚假降低 loss)。

6.3 训练用了 label smoothing,验证也用了导致 PPL “看起来更好”

这是误导性结果。务必在验证阶段用 ε=0 的标准 CE 来算 PPL,保证可比性。


7. 小结:把选择落到“可复现的指标体系”

Ai大模型训练教程 的工程实践中,建议你把损失函数选择当作一个“可复现的实验问题”来做,而不是凭感觉:

  • Cross-Entropy:预训练/大数据/追求基线可比性时的默认最优解
  • Label Smoothing:数据噪声、数据少、或需要更好泛化与概率校准时的有效正则
  • 困惑度 PPL:用标准 CE(ε=0)在验证集计算,作为最硬的训练质量指标之一;但不要把 PPL 当作生成质量的唯一标准

下一步你可以在现有训练脚本中加入 label_smoothing 开关,并建立“训练 loss + 标准验证 PPL + 下游评测”的三件套仪表盘,这会比单看训练 loss 更接近真实可落地效果。

语言模型训练的损失函数怎么选:Cross-Entropy、Label Smoothing与困惑度解读
https://aissn.com/92.html