↓ Skip to main content
  1. Posts/

为什么 LLM 会一本正经地胡说八道?从 Token Probability 到 Hallucination

·6342 words·13 mins
Note: This article is available in Chinese only. 本文暂无英文版本。 View original

起因
#

之前写 Next-Token Prediction的时候,我把条件概率链式分解、Softmax 输出概率分布这些东西理了一遍。当时觉得逻辑非常自洽:模型在每个位置输出整个词表上的概率分布,概率最高的那个 token 就是模型最有信心的预测。

顺着这个想法,我产生了一个看起来很自然的推论:

如果模型对某个答案给出了 99% 的概率,那是不是意味着这个答案有 99% 的可能性符合事实?

这个推论在直觉上很有说服力。毕竟概率都 99% 了。但继续看 MIT 6.S191 Lecture 6(New Frontiers)关于 LLM Limitations 的部分时,我发现这个推论混淆了两个完全不同的东西。

这篇笔记就是从这个混淆开始,把我在学习过程中遇到的几个问题理清楚。

Token 概率高,不等于事实正确
#

先回到 NTP 的基本设定。语言模型在每个时间步输出的是:

$$ P_\theta(x_{t+1} \mid x_1, \ldots, x_t) $$

这个概率分布是模型参数 \(\theta\) 在给定 context 下,对词表中每个 token 出现可能性的估计。NTP 那篇已经推导过这个条件概率的来源和训练目标,这里不重复。

我需要搞清楚的是:这个概率到底在说什么?

仔细想,这里其实有三个层次的"概率",它们看起来相关,但含义完全不同:

  1. Token 条件概率:给定上文,某个 token 在下一个位置出现的模型概率。
  2. 序列生成概率:一整段文本被模型生成出来的联合概率——各个 token 条件概率的连乘。
  3. 事实正确概率:这段文本所表达的事实陈述,在真实世界中为真的概率。

第一个和第二个之间有明确的数学关系(概率链式法则)。但第二个和第三个之间没有这种关系。

为什么?

模型的参数 \(\theta\) 是通过在训练文本上最小化 cross entropy loss 学出来的。它学到的是训练数据中的统计规律:在什么样的 context 之后,什么样的 token 更可能出现。

这里有一个很容易忽略的前提:训练数据本身不一定全是正确的事实。

构造一个极端但有说明意义的例子(以下是为了解释概念虚构的场景,不是真实数据):假设互联网上有大量网页错误地记载"某国首都是 B 城",但事实上首都是 C 城。模型在这些文本上训练之后,看到"某国的首都是"这个 context,很可能给 B 赋予远高于 C 的概率。

训练文本中的统计规律与事实正确性的关系

这不是模型的 Bug。从优化目标来看,模型忠实地学到了训练数据中的统计分布——这正是 cross entropy loss 鼓励它做的事。但统计分布和事实真值是两回事。

即使退一步,假设训练数据中的每一条事实都是正确的,问题也不会消失。自回归生成是逐 token 进行的。每一步都是条件概率最大化,但连续多步高概率的 token 组合在一起,最终形成的完整陈述未必对应一个真实的事实。模型可能把"作者 A 发表过关于 X 主题的论文"和"Y 会议发表过关于 X 主题的论文"这两条各自正确的信息,拼接成"作者 A 在 Y 会议上发表了关于 X 主题的论文"——一个不存在的事实。

不过我想在这里加一个澄清,因为"LLM 只是在预测下一个 token"这句话经常被用来得出一个过于强烈的结论。

“预测下一个 token"作为训练目标,并不意味着模型不可能学到事实知识或推理能力。 Pre-training 那篇讨论过,为了在各种 context 下都降低 prediction loss,模型会被迫捕获语言中广泛存在的统计规律——包括事实关联、语义结构、甚至一定程度的推理模式。关键在于:这个训练目标能够促使模型学习知识,但不提供事实正确性的无条件保证。模型可以在绝大多数常见知识问题上答对,同时在某些长尾事实上输出高置信度的错误答案。

把 Temperature 调到 0 就不会幻觉了?
#

这是我学到这里时想到的第一个"解决方案”。

既然概率分布中可能有低概率的正确答案和高概率的错误答案,那随机采样就有可能抽到更离谱的结果。如果我把 Temperature 设成 0,强制每一步都选概率最高的 token(Greedy Decoding),是不是就能避免生成错误内容?

先看 Temperature 到底在做什么。标准的 Softmax 输出是:

$$ P_i = \frac{\exp(z_i)}{\sum_j \exp(z_j)} $$

引入 Temperature 参数 \(T\) 后变成:

$$ P_i(T) = \frac{\exp(z_i / T)}{\sum_j \exp(z_j / T)} $$

\(T\) 的作用是缩放 logits。当 \(T \gt 1\) 时,所有 logits 被压缩,概率分布变得更均匀,低概率选项获得更多机会。当 \(T \lt 1\) 时,logits 差异被放大,概率集中到最高的那几个选项上。

用一个具体例子来看。假设模型对某个问题有三个候选答案(以下是为了说明概念构造的示例数据,不是真实模型输出):

候选答案原始 Logits事实
B最高错误
C中等正确
D最低错误

不同 Temperature 下的概率分布大致变化如下:

候选T = 0.3(低)T = 1.0(标准)T = 2.0(高)
B(错误)~95%~70%~50%
C(正确)~4%~20%~30%
D(错误)~1%~10%~20%

当 \(T\) 很小的时候,概率几乎全部集中在 B 上。Greedy Decoding 会稳定地选择 B。

但 B 是错误的。

需要说明一下 \(T = 0\) 的含义。严格地说,不能直接把 \(T = 0\) 代入上面的公式(分母会出现 \(\exp(z/0)\) 这种未定义的表达式)。\(T \to 0\) 是一个极限:在这个极限下,概率分布退化成一个只在最大 logit 位置为 1、其余为 0 的分布。实际实现中,“Temperature = 0"通常就是 Greedy Decoding——每一步直接选 argmax,跳过 Softmax 采样。

还有一个相关但独立的问题:Greedy Decoding 每一步选的是当前位置概率最高的 token,但这不保证整个生成序列的联合概率是全局最大的。涌现能力那篇讨论过 Greedy Decoding 的离散化效应——这里是另一个侧面:逐步局部最优不等于全局最优。不过这个问题跟幻觉的关系不大,主要影响的是生成文本的整体质量。

回到核心问题。Temperature 改变的是采样分布的形状,不是模型参数中存储的知识。如果模型的 logits 本身就把错误答案排在第一位,降低 Temperature 只会让模型更确定地选择那个错误答案。

我从这里得到的一个认识是:一致性不等于正确性(Consistency ≠ Correctness)。 模型连续十次给出相同的答案,不意味着这个答案就是事实。

当然也不能反过来说"低 Temperature 一定更差”。在很多任务上,降低 Temperature 确实能减少随机采样带来的噪声,提高输出的稳定性和在常见问题上的准确率。问题在于它不能从根本上修正模型知识中已有的错误。

模型为什么会编造看似真实的内容
#

想通了"高概率不等于正确"之后,下一个问题自然就是:那些看起来非常像模像样、但完全是编造的内容,到底是怎么产生的?

举一个贴近技术工作的场景(以下是为了演示 Hallucination 构造的虚构例子,不要当成真实文献引用):

假设你让一个 LLM 推荐几篇关于 CUDA Graph 和 GPU Kernel Fusion 的论文。模型可能会返回:

“Zhang et al. (2024), ‘Efficient Kernel Fusion via Graph-Level Scheduling on Modern GPUs’, NeurIPS 2024. 提出了基于依赖图的 kernel 合并策略,在 A100 上实现了 2.3 倍推理加速。”

标题、作者、会议、年份、甚至实验指标——全部一本正经,但这篇论文根本不存在。

这种现象通常被叫做 Hallucination。我在学习过程中理解到的几个促成因素:

训练目标的本质。 语言模型的训练目标是在给定 context 下预测下一个 token 的分布,不是对每一条事实进行独立核验。训练信号那篇讨论过,self-supervised pretraining 的监督信号来自文本本身的结构,不来自外部的事实标注。模型学到的是"什么样的文本在统计上更可能出现",而不是"什么样的事实在逻辑上为真"。

知识的错误组合。 即使训练数据中每一条信息单独来看都是正确的,模型在生成时也可能把它们错误地拼接在一起。训练语料里确实有大量 NeurIPS 论文、确实有关于 Kernel Fusion 的研究、确实有在 A100 上做实验的工作——模型把这些独立正确的模式组合成了一个不存在的整体。

数据覆盖与长尾问题。 训练语料对不同领域的覆盖程度差异很大。热门主题(比如 ImageNet 分类)的相关文本可能有成千上万篇,模型对这类问题的回答准确率很高。但到了长尾领域(比如某个特定硬件平台上的某个特定编译器 Bug),训练数据可能极其稀疏,模型只能基于有限的上下文模式进行"合理猜测"。

猜测与拒答的激励不对称。 这一点比较微妙。如果模型的训练和评估方式更多地奖励"给出一个看起来合理的回答",而不太惩罚"在不确定时编造内容"或奖励"承认不知道",那模型就会倾向于猜测而不是拒答。这不是说模型"选择"了撒谎——它没有这种意图——而是训练信号的结构在统计上鼓励了生成行为而非沉默行为。

这四个因素不是 Hallucination 的完整因果解释。实际的机制可能更复杂,学术界对此仍有活跃的研究。但它们帮助我理解了一件事:Hallucination 不是采样随机性带来的偶发失误,而是模型训练目标和知识表示方式的结构性特征。

目前业界针对这个问题的工程手段主要包括 RAG(让模型基于检索到的真实文档回答)、Tool Calling(让模型调用外部工具获取确定性结果)、外部验证(对模型输出进行独立的事实核查)、以及训练模型在不确定时拒答(Abstention)。这些方向各有局限,这里不展开。

那 Calibration 能帮上忙吗?
#

Token 概率不等于事实正确率,Temperature 也解决不了这个问题。那我们能不能换一个角度:不去直接相信模型的原始概率,而是想办法让模型的置信度变得可靠?

这是我学到这里时自然产生的第二个想法。如果我们能让模型"说 90% 的时候真的有 90% 的概率是对的",那至少可以知道什么时候该信它、什么时候不该信。

这个想法指向的概念叫 Calibration(概率校准)。

先用一个简单的对比来说明 Calibration 到底在衡量什么(以下是为了说明概念构造的示例):

假设两个模型都回答了 100 道题,都答对了 80 道。

  • 模型 A 对每道题都报告 99% 的置信度。
  • 模型 B 对每道题都报告 80% 的置信度。

两个模型的准确率相同(都是 80%)。但模型 B 的置信度更符合实际情况——它说自己 80% 确定,实际上也确实答对了 80%。模型 A 说自己 99% 确定,但实际只对了 80%。

用更正式的语言:一个模型是 well-calibrated 的,如果:

$$ P(\text{Correct} \mid \hat{c} = 0.9) \approx 0.9 $$

也就是说,在模型报告置信度为 0.9 的那些样本中,大约有 90% 是正确的。

这里有一个很容易混淆的点,我花了一些时间才想清楚:Calibration 和 Accuracy 是两个独立的维度。

Calibration 衡量的是"模型对自己正确性的估计是否可靠"。Accuracy 衡量的是"模型实际答对了多少"。一个模型可以准确率很高但校准很差(对每个预测都过度自信),也可以准确率不高但校准良好(它知道自己大概能对多少)。

Calibration 不会自动修正模型掌握的错误事实。 一个校准良好的模型在回答"某国首都是哪里"时,如果它的知识里存储的就是错误答案,校准好只意味着它能准确地告诉你"我有 60% 的把握觉得答案是 B"——而不是把 B 变成正确答案 C。

这里需要严格区分两种 Temperature,因为它们在名字上容易混淆:

  1. Decoding Temperature:生成时调整 Token 采样分布的 \(T\),就是上一节讨论的那个。
  2. Temperature Scaling(用于 Calibration):经典分类设置中,在训练好的模型的 logits 后面加一个可学习的标量 \(T\),通过在验证集上优化这个 \(T\) 来改善概率输出的校准度。

后者是一种 post-hoc 校准方法。它通常不会改变 logits 之间的相对排序——如果原来 argmax 指向 B,Temperature Scaling 之后 argmax 大概率还是 B。它改变的是概率值的绝对大小,让它更接近真实的正确概率。

还有一点需要说明:不能简单地认为对 LLM 的 token-level logits 做一次 Temperature Scaling,就自动得到了答案级别的事实正确概率。Token-level 的校准和 answer-level 的校准是不同粒度的问题,后者要复杂得多。

那 Calibration 有什么用?它支持一种叫 Selective Prediction 的策略:

  • 置信度高于某个阈值时,直接输出答案。
  • 置信度低于阈值时,拒绝回答,或者标记为"不确定,建议人工核实",或者触发外部检索。

这样做的本质是在回答覆盖率和可靠性之间做权衡。阈值设得越高,回答的可靠性越高,但会有更多问题被拒答。

Calibration 在分布变化下还靠得住吗
#

这是顺着上面的思路自然冒出来的第三个问题。

假设一个 LLM 在通用知识测试集上校准良好——它说 90% 的时候,确实有大约 90% 是对的。然后我们把它部署到一个技术支持场景,用户大量询问的是 CUDA Kernel 兼容性、特定 GPU 架构上的编译器 Bug、某个版本的 Driver 与某个版本的 NCCL 之间的交互问题。

这些都是模型训练数据中可能极度稀疏的长尾知识。即使模型仍然报告 90% 的置信度,实际正确率可能远低于这个数字。

用符号写出来就是:

$$ P_{\text{test}}(\text{Correct} \mid \hat{c} = 0.9) \approx 0.9 $$

不一定意味着:

$$ P_{\text{prod}}(\text{Correct} \mid \hat{c} = 0.9) \approx 0.9 $$

Distribution Shift 那篇详细讨论过这个问题——测试集和生产环境的数据分布可能有本质差异,而测试集上的评估指标不能无条件平移到生产环境。这里是同一个逻辑在 Calibration 上的体现。

同样的置信度,在不同分布下可能对应不同的实际正确率

不过要避免一个过度推论:Distribution Shift 不必然导致 Calibration 失效。如果新环境的问题虽然不同但难度分布相似,或者模型的不确定性估计在新领域也恰好保持一致,校准可能仍然大致成立。关键在于:Calibration 是相对于某个评估分布定义的统计性质,不是模型的固有属性。 分布变了,校准是否还成立需要重新验证。

这里有两个概念值得分开:

Accuracy Generalization:模型能否在新环境中保持预测准确率?

Calibration Generalization:模型对自己正确性的估计,能否在新环境中保持可靠?

这两者不等价。一个模型可能在新环境中准确率下降但校准仍然合理(它知道自己在新领域表现变差了),也可能准确率不变但校准崩了(它在新领域过度自信)。

其他几个 LLM 的局限
#

MIT 6.S191 Lecture 6 在 LLM Limitations 这个话题下还提到了另外两点,简单记一下。

Guardrails 与 Jailbreaks。 Guardrails 是指通过训练或系统层面施加的行为约束,比如让模型拒绝回答有害内容。Jailbreak 是指通过精心构造的输入,绕过这些约束让模型产生本不该产生的输出。Agent Safety 那篇讨论过一个相关的工程原则:从训练中学到的指令遵循能力,本质上是软约束而非硬边界。真正的安全边界需要在系统层面(权限控制、工具白名单、操作审计)而非仅靠模型行为来保证。

逻辑与数值推理。 LLM 在语言理解和推理上的能力不需要质疑,但这种能力基于统计学习得到的模式匹配,而不是执行确定性计算程序。让模型做 \(17 \times 38\) 的计算,它可能给出一个接近但不完全正确的结果——因为它是在"预测一个看起来合理的数字",而不是在执行乘法指令。这就是为什么实践中会让 LLM 生成代码、调用计算器或外部工具,然后用确定性的程序来执行计算、再把结果返回给模型——让擅长推理的部分做推理,让擅长精确计算的部分做计算。

写在最后
#

回头看这篇笔记走过的路径:从"Token 概率高是不是就意味着正确"这个最初的疑问出发,一路追问下去,每个"解决方案"都引出了新的问题。

降低 Temperature?改变的是采样行为,不是模型存储的知识。

靠 Calibration?衡量的是置信度的可靠性,不是提升模型的准确率。

在测试集上校准好?校准是相对于特定分布的统计性质,换了环境可能不再成立。

这些问题之间有一条暗线:模型能够生成流畅、合理、高概率的文本,和我们是否有充分理由相信这段文本所陈述的事实为真,是两个必须分开对待的问题。

从工程角度来说,这意味着在使用 LLM 的输出时,不能只看"模型是否给出了一个答案",还需要独立的手段来评估"这个答案是否值得信任"。具体的手段——外部检索、工具调用、人工审核、置信度过滤——取决于场景和风险容忍度。但把"生成"和"信任"这两件事分开,是所有后续工程决策的起点。

参考资料
#

Related

Scaling Laws:为什么可以用小模型预测大模型?Chinchilla 又改变了什么?

·3546 words·8 mins
起因 # 上一篇理清了 Pre-training 和 Post-training 的关系——Pre-training 让模型学会语言建模,SFT 和 RLHF 再让它学会遵循指令。 写完那篇之后,我回过头来想一个更上游的问题:Pre-training 本身应该怎么做?具体来说,假设手里有一笔固定的训练预算(比如一定数量的 GPU 时间),我应该训一个多大的模型、喂多少数据?

从 Pre-training 到 Post-training:为什么大模型需要分阶段训练?

·4616 words·10 mins
起因 # 最近继续跟 MIT 6.S191,加上工作中或多或少接触到一些 LLM 训练相关的讨论,我开始试着把大模型的训练流程从头到尾理一遍。 之前写过几篇笔记:NTP 那篇推导了 next-token prediction 的条件概率和 cross entropy loss,训练信号来源那篇整理了 self-supervised pretraining → representation → fine-tuning 的基本链路。