文章

语言模型训练中的熵指标:如何理解模型预测的不确定性

语言模型训练中的熵指标:如何理解模型预测的不确定性

一句话总结

在语言模型训练中,entropy 衡量的是模型对下一个 token 概率分布的“不确定性”:熵越高,说明概率越分散、模型越犹豫;熵越低,说明概率越集中、模型越自信。


什么是熵

熵(Entropy)来自信息论,用来衡量一个概率分布的不确定性。

放到语言模型里,它描述的是:模型在预测“下一个 token”时,到底是很确定地把概率压在少数 token 上,还是把概率分散给了很多候选 token。

  • 熵越低:输出分布越集中,模型越自信
  • 熵越高:输出分布越分散,模型越不确定

例如,当模型认为下一个 token 大概率就是 A,其他 token 的概率都很小,此时熵较低;如果模型在 A/B/C 等多个 token 之间摇摆不定,此时熵较高。


计算方式

语言模型通常先输出一组 logits,再通过 softmax 转成概率分布:

1
probs = softmax(logits)

然后对这个概率分布计算熵:

\[H = - \sum_i p_i \log(p_i)\]

其中:

  • $p_i$:模型认为第 $i$ 个 token 是正确下一个 token 的概率
  • $\log$:通常使用自然对数
  • $\sum$:对词表中所有 token 的概率求和

对应到代码可以写成:

1
2
probs = softmax(logits)
entropy = -(probs * log(probs)).sum()

这表示单个位置上的预测熵。对于 SFT 或普通语言模型训练,实际记录的 entropy 通常不是只算一个 token,而是对所有参与 loss 的 token 分别计算熵,再取平均:

\[\text{mean entropy} = \frac{1}{N}\sum_{t=1}^{N} H_t\]

这里的 $N$ 是有效训练 token 的数量。


有效 token:哪些位置会参与统计

在训练代码里,很多位置并不会参与 loss。例如 padding token、prompt 部分,或者被显式 mask 掉的位置,通常会在 labels 中标记为 -100

如果训练配置里使用了:

1
completion_only_loss=True

那么一般只有 completion,也就是答案部分的 token 会参与 loss。对应地,entropymean_token_accuracy 这类 token 级训练指标,也大概率只统计这些有效 token。

因此,看到一个训练日志里的 entropy 时,要先弄清楚它统计的是:

  1. 全部 token
  2. 只统计 labels 不是 -100 的 token
  3. 只统计 completion/答案部分 token

不同统计口径下,数值不能直接横向比较。


一个小例子

假设模型对下一个 token 的预测概率是:

1
2
3
A: 0.7
B: 0.2
C: 0.1

那么熵为:

\[H = -(0.7\log 0.7 + 0.2\log 0.2 + 0.1\log 0.1)\]

如果模型非常确定:

1
2
3
A: 0.99
B: 0.005
C: 0.005

熵会很低,因为概率几乎都集中在 A 上。

如果模型很不确定:

1
2
3
A: 0.33
B: 0.33
C: 0.34

熵会更高,因为模型把概率分散给了多个候选。


如何理解 entropy = 1.83

假设训练日志里出现:

1
{'entropy': 1.8333333333333333}

它可以理解为:模型在有效训练 token 上的平均预测不确定性约为 1.83

它不是准确率,也不是 loss,但和模型“有多犹豫”有关。一般来说,随着训练推进,如果模型对训练数据越来越熟悉,entropy 往往会逐渐下降。

不过,熵越低并不总是越好。过低的熵可能表示模型非常自信,但如果这种自信建立在错误预测或过拟合之上,验证集效果反而可能变差。


和困惑度的关系

如果使用自然对数,可以把 entropy 转换成一个直觉上的困惑度:

\[\text{perplexity} = \exp(\text{entropy})\]

当:

1
entropy = 1.83

则:

1
perplexity = exp(1.83) ≈ 6.25

直觉上可以理解为:模型平均每个 token 像是在大约 6 个候选 token 之间犹豫。

但这只是帮助理解的近似说法,并不是严格表示模型真的只在 6 个词里做选择。真实语言模型的词表可能有几万到几十万个 token。


值多大算正常

entropy 没有固定的“合适值”。它取决于词表大小、任务难度、训练阶段、数据质量,以及是否只统计答案 token。

对于 SFT 训练,entropy ≈ 1.83 单看并不异常。可以用下面的范围做一个粗略参考:

entropy 范围大致含义
< 1非常确定,可能学得很好,也可能过拟合或输出太固定
1 - 3比较常见,模型有一定确定性
3 - 6不确定性较高,可能任务较难、模型没学好或数据噪声较大
> 6很不确定,通常需要检查训练是否正常

这个表只能用来建立直觉,不能当成硬阈值。更重要的是看训练过程中的趋势。


和 loss、accuracy 一起看

entropy 最好不要单独看,而要和 lossmean_token_accuracy 一起观察。

比较健康的训练趋势通常是:

  • loss 下降
  • mean_token_accuracy 上升
  • entropy 适度下降

这说明模型不仅更自信了,而且更可能自信在正确 token 上。

需要警惕的情况包括:

现象可能含义
entropy 很高且 loss 不下降模型没有学进去,或数据噪声较大
entropy 很低但验证集效果差可能过拟合,或答案模式过于固定
entropy 下降很快但 accuracy 不上升模型变自信了,但可能自信地预测错
loss 下降但 entropy 异常波动需要检查学习率、数据分布或统计口径

一个训练日志的解读

假设有这样一组训练指标:

1
2
3
4
5
train_loss ≈ 1.90
entropy ≈ 1.83
mean_token_accuracy ≈ 0.646
epoch = 3
num_tokens = 504

可以这样理解:

  • train_loss ≈ 1.90:模型在训练 token 上还有一定预测误差
  • entropy ≈ 1.83:模型的平均输出分布不算特别分散,已经有一定确定性
  • mean_token_accuracy ≈ 0.646:约 64.6% 的有效 token 预测正确
  • num_tokens = 504:样本量非常小,更像是调试训练

这组指标本身看起来不像明显异常,但由于有效 token 只有 504 个,统计波动会比较大。此时不建议过度解读单次日志,更应该增加数据量或加入验证集,再观察多轮训练趋势。


实践建议

entropy 时,可以按下面的顺序判断:

  1. 先确认统计口径:是否只统计 labels 不是 -100 的 token,是否只统计 completion 部分
  2. 再看趋势:不要只看某一步的值,观察它是否随训练稳定变化
  3. 结合 accuracy:熵下降必须配合准确率上升才更有意义
  4. 检查验证集:训练集熵很低但验证集差,往往说明泛化不足
  5. 注意样本量:几百个 token 的训练日志只能作为调试信号,不能作为稳定结论

总结

entropy 是理解语言模型训练状态的一个辅助指标。它回答的问题不是“模型对不对”,而是“模型有多确定”。

在 SFT 训练中,entropy ≈ 1.83 通常可以理解为模型在有效答案 token 上已经有一定确定性;如果同时看到 loss 下降、mean_token_accuracy 上升,那么整体训练趋势大概率是正常的。

但单个 entropy 值意义有限。真正可靠的判断方式,是把它和 loss、token accuracy、验证集表现、有效 token 数量一起看。

本文由作者按照 CC BY 4.0 进行授权