引子
刚入门大模型的时候,由于线性代数、概率论和信息论等数学知识的短板,很容易迷失在诸多术语中:logprob(对数概率)、likelihood(似然)、NLL(Negative Log Likelihood,负对数似然)、cross entropy(交叉熵)、perplexity(困惑度)。它们常常出现在论文和文档的各种角落里,但都像点赞之交的朋友,频见其名,不解其意。
后来某天,在慢慢的补过一些最基础的数学知识后,在公司相关的上下文浸淫足够久后,终于在某次和 ChatGPT 的聊天中发现:上面一组概念本质上是同一件事的不同面向的侧写。从概率论的门摸进去叫 NLL,从信息论的门踏进去叫交叉熵,从 PyTorch 的门看进去叫 F.cross_entropy——殊途同归,本质上都是在试图刻画"模型当前输出离预期还有多远"。
“横看成岭侧成峰”,在大模型这种高维上下文的领域中,这种盲人摸象的感觉所在多有。不过我们这种三维生物,也只能靠长久的浸淫,才能靠着不同领域知识的交叉验证,才会突然有一天顿悟——嗷,原来这是同一座山。
本文想做的,就是想聊聊大模型领域中最基础概念——交叉熵这个损失函数的“一花各表”。

作者:木鸟杂记 https://www.qtmuniao.com/2026/03/29/llm-loss/ 转载请注明出处
从"续写"到 NLL —— 概率视角下的损失函数
讨论损失函数前,我们先从最直给的方式感知下大模型的工作原理。先不用被 Agent、推理、多模态、世界模型等上层建筑迷了眼。其地基上其实只是在做一件事:给定上下文,预测下一个词元(token)。 比如你问"法国的首都是",模型会觉得"巴黎"很合理,"东京"就不太对劲,“数据库"则更是离谱。当前所谓"语言模型”,本质上就是一台判断"该如何续写"的机器。
这个角度很关键,因为后面所有的 prob、logprob、loss,都是围绕这个动作展开的——模型接续写的对不对,我要用什么尺子来卡。
有了这个起点,我们继续拆解语言模型的训练目标。设有样本,前缀(prefix)是"退款多久到账?",后缀(suffix )是标准答案。我们关心的指标就转化成了:看到这个 prefix,模型有多大概率把这个 suffix 说出来? 用条件概率来表达,写成符号,便是
但模型在回答时,并非“绣口一吐,就半个盛唐”。也即模型不是一口气把整段答案吐出来的,它是一个 token 一个 token 往后续写的。第一步看到 prefix,预测第一个 token1;第二步看到 prefix+token1,预测第二个 token2;如此往复。
举个例子,当大模型生成“法国的首都是巴黎”这句话时:
首先利用“法国的首都是”作为上下文,生成“巴黎”。
再利用“法国的首都是巴黎”作为上下文,生成“。”。
这就像密室逃脱,每扇门都要你答对暗号才能通过。一句话答对,可以拆解为这句话中的每个词都续对。 所以续写对整个句子(prefix)的概率,就是预测对每步中下一个词(token)条件概率的连乘:
但连乘带来一个致命的工程问题——最终概率数值会小得离谱。一句话 100 个 token,每步平均预测对概率是 0.1,整段概率就是
原来一长串小数连乘,现在变成数累加,更稳定、好分析、方便按 token 拆解。这和投资时的记账是一个道理——你通常不会说"我的现在的资产是前年本金乘以 1.05 再乘以 0.97 再乘以 1.12",你可能会说"我的投资,前年赚了 5 个点,去年亏了 3 个点,今年到现在为止,浮盈 12 个点"。用累加法记变化,远比用乘法记总量更清爽。 ,即我们并不需要精确的关注总量,变化的累加已经能让我们对你的投资能力有个大致的把握了。所以工程里更常见的是取对数的概率估计( logprob),而不是直接概率累乘(prob)。你可以先粗糙地把 logprob 理解成模型倾向于输出某个答案的"总分数"。
到这一步,事情变得漂亮了。如果让我们设计一个大模型训练损失函数(loss function,可以粗浅理解为模型训练的目标就是最小化损失值),它需要符合两个直觉:模型续写出正确答案的概率高,则损失(loss)小;概率低,则损失大。由于
为什么我们曲曲折折造的这个函数可用呢?这就是我们在对问题进行数学建模时的最基本方法——我们常倾向用满足各种性质的(比如单调性也就是趋势、比如变化速率也就是导数等等)最简洁形式,来构造公式。
而
- 其一,做对了不罚——当
时, ,这是变化趋势对。 - 其二,做错了重罚,越错罚越狠——这是
曲线最有意思的地方。 时 loss 只有 0.105, 时涨到 2.303, 时飙到 4.605。越往低概率走,惩罚越狠。这很像弹簧——轻拉没感觉,拉到极限时反弹力剧增,这就是变化速率对。 - 其三,和概率建模天然一致——我们本来想最大化模型续写出正确答案概率,也即
,等价于最大化其对数 ,再转化成最优化问题中更常见的最小化形式,便是 。
所以这个损失函数并不是拍脑袋拍出来的,而是从如何衡量"模型能于续写出正确的答案"这个朴素想法中一步步长出来的。
到此我们就得到了一个看起来很奇怪的名字——NLL,Negative Log Likelihood,负对数似然。也就是刚才说的:模型续写答案时犯错的概率,我们所谓之大模型“训练”,就是试图通过海量的数据,将其降到最低的过程。
对模型写出的整个段落来说,其
即续写每个词元犯错概率的累加,再除以段落中词元数量,就是平均每个词元的损失。概念本身不算太复杂,之所以看着吓人,不过是因为"负对数似然"这五个字把一件简单的事给包了三层。拆开来看——负号、对数、似然——每一层我们刚才聊过了(似然就是续写地看起来对的概率)。
交叉熵 —— 信息论视角重新审视
如果说负对数似然是从概率论的这条路登上的庐山,那交叉熵就是从信息论的这条路上山的。
信息论诞生于通信领域——香农的《通信的数学理论》中。它不关心消息在语义上说了什么,而试图在统计意义上量化一条消息包含多少“信息量”。用计算机的话说,就是传递该消息所需的最小比特数。
那么我们如何确定一条消息的信息量呢?
-
离散法。用我们计算机中常见的一种方法就是,通过二分的方法,不断消除消息的不确定性。每二分一次,就引入一比特进行编码。
-
连续法。使用函数去拟合。用概率去表征消息的不确定性 p(x),用负对数来表征趋势——越确定(概率越大),信息量越少,且是对数级减少。即
。在信息论中,该值又被称为“自信息”
进而,我们可以引出信息论中最基础的概念——熵(entropy,或称信息熵,热力熵有很深的联系,他们都可以联系到熵增)。它被定义为“一个系统中所有信息的期望(加权平均)信息量”。也即,信息量是指单个事件
举个例子就是,设一个系统包含三个事件 a,b,c,a 发生的概率是 0.1,b 发生的概率是 0.4,c 发生的概率是 0.5。则该系统的熵是
也就是对所有事件的信息量加权求平均,即信息量的期望(E)。
然后我们来说说交叉熵,它在描述两个系统的分布的一致性的问题:如果真实世界(系统1)按某种分布(规律)
也即:
再举个例子——你去一座陌生城市,手里拿着一张旧地图(模型分布
那它和 NLL 到底什么关系?我们构造一个语言系统,在这个系统中有一个词表,每个事件就是一个词元(token)。在数据世界中,我们所有的文本都可以表示为词表中词元的某种序列。大模型在进行推理时(也就是续写下一个词元时),其实就是在训练出的分布中,基于当前的状态,在词表中选一个最大概率的词元(token)。而这个分布可以用什么来进行终极刻画呢?对了,就是“熵”。那我们如何衡量大模型训练的是否符合真实分布呢?对了,就是最小化“交叉熵”。也就是我们训练出来的这个“世界地图”,是能用在对物理世界进行行路预测的。
回到公式上,我们来做一步地桥接。我们每次在续写下一个词时,已有的词会构成一个“当前截面”的系统,站在我们当前的系统的状态上,我们要选择下一个词时,对词表中每个词元有个选择的概率。在该暂态系统中,每个词元就是信息,词元选择时的概率分布,对应的
在进行语言模型训练时,其实可以归类为一个分类问题。即,具体到每一个训练样时,固定前缀,且下一个词元是确定的,此时其概率 1,其他词元的概率都为 0,我们称之为 one-hot。代入交叉熵公式
这里有一个容易踩的坑,值得单独说一句:交叉熵衡量的不是两段文字在语义上像不像——那是需要通过比较语义向量做的事。它看的是更底层的东西:对于真实序列中的每一个 token,模型有没有给它分配足够高的概率。 也即统计意义上的对齐,而非单个句子上的相似。
那为什么大模型的损失函数偏偏是
小结
把这篇文章压成一句话:我们想知道模型离正确答案有多远;最自然的做法是看它给所有确答案分了多大概率;对这个概率取负对数,就得到一个既符合概率论、又符合信息论、又方便优化的损失函数——概率论叫它 NLL,信息论叫它交叉熵,是同一件事。
如果你是从系统、数据、Infra 方向转来学习大模型的,不必急着把信息论教科书从头啃一遍。先固定几个基本直觉:模型最直接的工作方式就是“预测下一个词”,损失函数就是试图在量化模型"离正确答案有多远",交叉熵看的是概率对齐而非语义相似,logprob 是让概率计算变稳定的关键工具。
有的很多公式推导,为了方便理解没有做准确推导,不合适地方,欢迎指出。
