交叉熵损失(eval_loss)详解

交叉熵损失(Cross-Entropy Loss)是 SFT 训练与验证阶段最核心的监控量。Hugging Face Trainer / TRL SFTTrainer 在验证集上计算的 eval_loss,就是该损失在 hold-out 数据上的平均值。

段末注释:Cross-Entropy 衡量模型预测分布与真实 one-hot 标签之间的差异;数值越小,模型对标准答案越「不意外」。

系列索引:微调评估指标导读


一、直观含义

把语言模型在每个 token 位置看成「从词表里选一个词」的分类器。交叉熵回答:

模型给真实下一个 token 分配的概率有多低?

  • loss 高:模型经常「猜错」或给正确答案的概率很小——对标注序列还很「意外」。
  • loss 低:模型能以较高概率重现标注文本——在训练分布上拟合较好。

它度量的是概率拟合质量,不是「业务标签对不对」。生成式情绪分类里,eval_loss 从 0.58 降到 0.12 说明模型更会用训练格式输出标签词,但不等于 test 集 macro F1 必然上升。


二、使用场景与所需数据

场景 是否适用 数据要求
SFT 训练监控 验证集:与训练同格式的 prompt-completion 或 messages
早停 / 选 checkpoint 需独立 validation split,且 metric_for_best_model="eval_loss"
上线决策 否(单独不够) 必须辅以任务指标(F1、EM 等)
模型间横向排名 谨慎 仅当 tokenizer、max_length、loss 掩码规则完全一致时可比

数据形态:tokenized 序列 + label(padding 位置 label 为 -100 不参与计算)。SFTTrainer 配合 completion_only_loss=True 时,只有 completion / assistant 段计入 loss。


三、计算方式

3.1 公式

对长度为 (T) 的序列,在参与 loss 的位置 (t \in \mathcal{T}) 上:

$$
\mathcal{L} = - \frac{1}{|\mathcal{T}|} \sum_{t \in \mathcal{T}} \log p_\theta(y_t \mid y_{<t})
$$

其中 (y_t) 为位置 (t) 的真实 token,(p_\theta) 为模型 softmax 输出概率。

单步交叉熵 (-\log p(y_t)) 的性质:

  • 若 (p(y_t) \to 1),loss (\to 0)
  • 若 (p(y_t) \to 0),loss (\to +\infty)

3.2 与 train loss 的关系

指标 数据 用途
loss 当前 training batch 观察优化是否在进行
eval_loss validation 全集 观察泛化;train↓ val↑ 常为过拟合信号

3.3 代码示例

Trainer 自动记录;手动计算等价逻辑:

1
2
3
4
5
6
7
8
9
10
11
12
13
import torch
import torch.nn.functional as F

# logits: [batch, seq_len, vocab_size]
# labels: [batch, seq_len],padding 为 -100
shift_logits = logits[..., :-1, :].contiguous()
shift_labels = labels[..., 1:].contiguous()

loss = F.cross_entropy(
shift_logits.view(-1, shift_logits.size(-1)),
shift_labels.view(-1),
ignore_index=-100,
)

SFTConfig 中可选 loss_type="chunked_nll"(默认)或 "nll",数学目标相同,实现上 chunked 版更省显存。


四、如何解读

现象 可能含义
train loss 持续下降,eval_loss 同步下降 正常学习,尚未明显过拟合
train loss 很低,eval_loss 回升 过拟合训练集特有模式
eval_loss 长期不降 学习率过大/过小、数据格式错误、可训练参数为 0
eval_loss 骤降后平台 可能已接近该数据规模下的拟合上界

不设 universal 阈值:不同模型规模、词表、任务长度下绝对值不可比。应在同一实验内看相对变化与 train/val 差距。

单 token 标签任务(如六类情绪各输出一个词)中,常见现象是:250 step 内 train loss 从 ~0.58 降至 ~0.12,val loss 同步下降,mean_token_accuracy 升至 ~0.94——三者相互印证。


五、局限性与常见误用

  1. 与生成评估脱节:eval_loss 在 teacher forcing 下算「给定前缀预测下一 token」;实际 generate() 用模型自己生成的前缀,误差会累积。
  2. 不能替代任务指标:loss 低但 F1 不动,常见于过拟合输出格式、或评估 prompt 与训练不一致。
  3. 绝对值跨实验不可比:换 tokenizer、max_length、completion_only_loss 设置后,loss 尺度会变。
  4. 对短 completion 过于乐观:标签仅 1~2 token 时,loss 很快趋近 0,仍需看 macro F1 与混淆矩阵。
  5. 验证集污染:validation 样本若与 train 高度重复,eval_loss 会虚假偏低。

六、与其他指标的关系

指标 关系
Perplexity (\mathrm{PPL} = e^{\mathcal{L}}),单调变换
mean_token_accuracy 同一前向 pass 的不同汇总;accuracy 看 top-1 对错,loss 看概率质量
Accuracy / F1 任务级;需离散化预测后单独计算

七、实践建议

  1. 训练时同时记录 train losseval_losseval_strategy="steps" 设合理间隔。
  2. metric_for_best_model="eval_loss" 保存最优 checkpoint,但最终上线前在 test 集跑任务指标。
  3. 微调前后对比时,不要只贴 eval_loss delta,应并列 accuracy、macro F1、invalid 率 等任务指标。
-------------本文结束感谢您的阅读-------------