Q1689项目实战与企业级真题解析通用与软实力AgentAlpha 社区真题库约 8 分钟更新 2026-09-29

八股:大模型预测token的损失是怎么算的?有哪几种常见的损失函数

八股:大模型预测token的损失是怎么算的?有哪几种常见的损失函数

1️⃣ 考察意图

面试官想验证你对大模型训练最底层的理解是否扎实,而非只会调库。考察类型是“背概念+工程取舍”。刁钻点在于:多数人只会背“交叉熵”,但说不清为什么交叉熵是默认选择、在预训练和SFT中计算细节有何不同、以及如何处理padding token。答好了能展示你对损失函数本质(概率分布对齐)和训练工程细节(mask机制、数值稳定性)的硬实力,直接区分“调参侠”和“真懂训练的人”。

2️⃣ 标准答

核心计算:交叉熵损失(Cross-Entropy Loss)

大模型预测下一个token,本质是一个多分类问题。对于每个位置,模型输出一个logits向量(维度=词表大小V),经softmax后得到概率分布p。真实标签是one-hot向量q(目标token索引处为1,其余为0)。损失计算:

  • 单token损失:-log(p_target),即目标token预测概率的负对数。
  • 序列损失:对所有有效token(排除padding)的损失取平均(或求和,取决于实现)。

为什么是交叉熵? 它等价于最小化预测分布p与真实分布q之间的KL散度(因为q是one-hot,KL散度退化为交叉熵)。交叉熵在数学上等价于最大化对数似然(MLE),且梯度形式简洁(p - q),数值稳定,是分类问题的标准选择。

常见损失函数及场景

  1. 交叉熵损失(Cross-Entropy Loss)
  • 预训练(MLM/Causal LM):标准选择。例如GPT系列、LLaMA。
  • SFT(监督微调):同上,但需注意忽略padding token。
  • 工程细节:实现时用ignore_index=-100(PyTorch)或label_smoothing=0.1(如PaLM)来提升泛化。
  • 坑:直接对logits计算交叉熵时,若logits数值过大(如>100),softmax会溢出。解法:使用torch.nn.CrossEntropyLoss内置的log-softmax+ NLL组合,保证数值稳定性。
  1. 负对数似然(NLL Loss)
  • 本质与交叉熵相同(交叉熵 = NLL + 熵项,但真实分布熵为0)。
  • 区别:NLL直接对log-probabilities操作,常用于生成任务评估(如perplexity计算)。
  • 使用场景:在推理时计算困惑度(PPL),公式为exp(NLL / token_count)。
  1. KL散度(KL Divergence)
  • 知识蒸馏:学生模型分布p_s逼近教师模型分布p_t,损失为KL(p_t || p_s)。
  • RLHF中的PPO:KL惩罚项防止策略模型偏离参考模型太远。
  • 工程取舍:KL散度不对称(KL(p||q) ≠ KL(q||p)),蒸馏时通常用前向KL(学生拟合教师),而PPO用反向KL(鼓励模式覆盖)。选错会导致生成多样性崩溃。
  1. 对比损失(Contrastive Loss)
  • 句子表示学习:如SimCSE、BERT-flow。拉近正样本对(同一句子不同dropout),推远负样本对(batch内其他句子)。
  • 公式:-log( exp(sim_i / τ) / Σ exp(sim_j / τ) ),其中sim是余弦相似度,τ是温度系数。
  • 坑:τ过小(<0.05)导致梯度爆炸,过大(>0.5)导致所有样本相似。经验值τ=0.05~0.1。
  1. 辅助损失(Auxiliary Losses)
  • 对比学习辅助:在SFT时加入对比损失,增强模型对相似指令的区分能力(如InstructGPT)。
  • 稀疏化损失:如MoE模型中的负载均衡损失(load_balancing_loss),鼓励专家使用均匀。
  • 实际落地:在训练LLaMA时,常将交叉熵损失与辅助损失加权(权重0.01~0.1),避免主任务被稀释。

计算细节:忽略padding token

  • 实现:在损失计算前,用attention mask标记padding位置,将其logits对应的标签设为ignore_index(如-100)。PyTorch的CrossEntropyLoss会自动忽略这些位置。
  • 为什么平均而非求和? 平均使损失不随序列长度变化,便于跨batch比较。但若batch内序列长度差异大,平均会偏向短序列。解法:使用“有效token数”加权平均,或动态padding到相同长度。

3️⃣ 答题模板(30 秒电梯版)

“这个问题我从三个层面回答:第一,核心计算是交叉熵损失,对每个token取目标概率的负对数,然后对有效token平均。第二,常见损失函数有交叉熵(预训练/SFT)、KL散度(蒸馏/RLHF)、对比损失(表示学习),以及辅助损失(MoE负载均衡)。第三,工程细节上必须忽略padding token,用ignore_index实现,并注意数值稳定性。总结一句:交叉熵是默认选择,其他损失用于特定目标,但核心都是对齐预测分布与真实分布。”

4️⃣ 高频追问 & 应对

追问 1:为什么预训练用交叉熵,而RLHF用KL散度?两者本质区别是什么?

交叉熵最小化预测分布与one-hot真实分布的距离,适合监督学习(有明确标签)。RLHF中,我们不想让模型偏离参考模型太远(否则生成失控),所以用KL散度作为惩罚项,约束策略分布与参考分布的距离。本质区别:交叉熵是“硬对齐”(目标确定),KL散度是“软约束”(分布接近)。工程上,交叉熵梯度直接,KL散度需要调权重(如PPO中KL系数0.01~0.2)。

追问 2:如果训练时序列长度差异很大(如512和2048),平均损失会有什么问题?怎么解决?

平均损失会偏向短序列(因为短序列的每个token贡献更大)。例如,512长度序列的损失平均后,每个token权重是1/512,而2048序列是1/2048,短序列的梯度更新幅度更大。解法:① 使用“有效token数”加权平均(即每个序列的损失乘以序列长度再求和,最后除以总token数)。② 动态padding到batch内最大长度(但浪费计算)。③ 采用“bucket padding”(按长度分桶,每个桶内padding到相同长度)。

追问 3:在知识蒸馏中,为什么常用KL散度而不是交叉熵?如果教师模型和学生模型词表不同怎么办?

KL散度能传递教师模型的“软标签”(概率分布),包含类别间相似性信息(如“猫”和“狗”的概率接近),而交叉熵只关注硬标签。词表不同时,需要对齐输出空间:① 共享词表(最常见,如DistilBERT)。② 投影层:将学生logits通过线性层映射到教师词表维度。③ 使用对比损失替代KL散度,只对齐共享token的表示(如MiniLM)。工程上,词表不同会导致计算复杂度剧增,通常优先选择共享词表。

5️⃣ 避坑 · 常见错误答法

  • ❌ “损失函数就是交叉熵,没有别的。”→ ✅ 补充KL散度(蒸馏/RLHF)、对比损失(表示学习)、辅助损失(MoE),并说明各自场景。面试官想看你知识广度。
  • ❌ “损失计算时对所有token求和。”→ ✅ 必须说明忽略padding token(ignore_index),并解释平均 vs 求和的取舍。这是工程细节,暴露是否真写过训练代码。
  • ❌ “交叉熵和NLL完全一样。”→ ✅ 区分:交叉熵 = NLL + 熵项,但真实分布熵为0时等价。NLL直接对log-probabilities操作,常用于PPL计算。面试官会追问“那为什么PyTorch里CrossEntropyLoss和NLLLoss不同?”

6️⃣ 简历呼应

  • 如果你有RAG项目:从“检索结果排序的损失函数”切入,对比交叉熵(排序)和对比损失(表示对齐),说明如何用KL散度蒸馏检索模型。
  • 如果你只做过传统NLP:用“文本分类的交叉熵”类比,迁移到“序列生成的多分类”,强调padding mask和序列平均的工程细节。
  • 如果你是校招无项目:聚焦“GPT-2复现”或“MiniLM蒸馏实验”,展示你手动实现过交叉熵损失、KL散度,并对比过不同温度系数的影响。
  • 《Attention Is All You Need》中交叉熵损失与label smoothing的讨论
  • 《DistilBERT, a distilled version of BERT》中KL散度蒸馏的具体实现
  • 《SimCSE: Simple Contrastive Learning of Sentence Embeddings》中对比损失的温度系数调参经验
  • PyTorch官方文档:CrossEntropyLoss与ignore_index参数详解
  • 《Scaling Laws for Neural Language Models》中损失与模型规模的关系分析

—— 本场面试完 ——

我们不做玩具级 Demo 教学。训练营的作业是开源项目和论文——我们想陪伴你,做出能改变生活、最后改变世界的项目。