卷 V · 当助手CH 18深度 18/20

流畅不等于知道

大模型最让人头疼的毛病有个名字:幻觉——编出不存在的人、不存在的论文、不存在的函数,而且语气和说真话时一模一样。常见的解释是「它在撒谎」或者「它出故障了」。这一章用 GPT-2 把这件事拆成两半:一半是训练目标本来就奖励「像」而不是「真」;另一半更反直觉——基座模型对自己的把握其实相当诚实,是后来的训练把这份诚实弄丢了。

九成把握,对了 91.7%微调后只对 73.0%不丹的首都是北京
◉ 这一章在 GPT-2 的哪一段

▷ 先猜一下

让 GPT-2(没有经过任何后训练的基座模型)逐个 token 读第 4 章那篇它没见过的维基百科文章。每一步,看它排第一的候选和它给这个候选的概率——也就是它的「把握」。

把所有「把握在 90% 以上」的位置挑出来(一共 872 个)。问:这些位置上,它排第一的候选真的猜中了多少?

A 50% 左右。语言模型出了名地过度自信 B 70% 左右。有点虚高 C 90% 左右。说九成就是九成 D 99% 以上。它说有把握的时候从不出错

答案在本章末尾。

它说得这么肯定

先看几段 GPT-2 的「作品」,全部是贪心解码(每一步挑最可能的):

Harold Wentworth (born 1952) is a British⟦ actor and producer. He is best known for his role as the character of the Doctor in the BBC series Doctor Who.⟧

The 2031 World Cup was won by⟦ the United States, but the tournament was won by Germany.⟧

ChatGPT is a generative AI chatbot developed by⟦ the University of California, Berkeley.⟧

The chemical symbol for gold is⟦ the "G" in the middle of the word.⟧

The capital of Zubrowka is the city of⟦ Zubrowka, which is located in the heart of the Russian Federation.⟧

Harold Wentworth 是我随手编的名字;2031 年的世界杯还没踢;ChatGPT 是 2022 年 OpenAI 做的,GPT-2 不可能知道;金的元素符号它真的不知道(第 8 章:Au 排第 1066 名);Zubrowka 是电影里虚构的国家。五个问题,五段语气笃定、语法完美、内容全错的回答。

这不是故障。回想第 1 章:它唯一的任务是猜「这段文字最可能怎么接下去」。在网页上,「某某(生于 1952 年)是一位英国」后面接的是职业,而且几乎从来不会接「我不知道」——没有哪篇人物简介会这么写。训练从来没有奖励过「我不知道」,因为它要模仿的那些文档里几乎没有这句话。它要做到的只是「像」,而「像」可以完全不需要「真」。

可它的把握,其实是诚实的

这就引出了开头那道题。如果模型这么爱编,它的「把握」是不是也全是虚的?量一下:把 GPT-2 读那篇文章时每一步的第一名候选拿出来,按它给的概率分成十档,看每一档实际猜中了多少:

校准图:横轴是它说的把握,纵轴是实际猜中率。贴着虚线 = 诚实 0 0.2 0.4 0.6 0.8 1 0 0.2 0.4 0.6 0.8 1 平均把握 实际猜中 微调前(基座) 微调后
把握(第一名的概率)个数平均把握实际猜中
0.0–0.111606.5%8.6%
0.1–0.2160714.9%17.4%
0.3–0.476034.5%34.9%
0.5–0.637254.8%53.8%
0.7–0.824774.9%74.1%
0.9–1.087297.5%91.7%

(表里省略了四档,完整的十档在本章末尾的代码输出里。)几乎每一档,「它说的把握」都和「实际猜中的比例」贴得很近。把十档的差距按个数加权平均,叫期望校准误差(ECE):0.023。这个模型说三成就是三成,说七成就是七成。

这是第 4 章那个交叉熵的功劳:它狠狠惩罚「信誓旦旦地错」,也惩罚「明明有把握却说得含糊」,唯一能让它最小的策略,就是如实报告。(第 11 章还看到,GPT-2 的最后两层专门在给过度集中的判断「降温」。)

那么诚实的把握,和满嘴编造,怎么能同时成立?因为它们说的是两件不同的事:

  • 校准是 token 层面的:「下一个 token 是不是这个」,它报告得很准。Harold Wentworth 后面接 ␣actor,它只给了 17.6%——它其实很不确定。
  • 可是续写总得写下一个 token。抽到了 actor,下一步它就在「他是一位演员」的前提下继续写,再也不会回头怀疑;每一步都是在已经写下的文字上「合理地」接着走。一句话由十几个「各自都合理」的 token 组成,整句话却可以是彻头彻尾的编造。

熵(表有多平)能不能当一个「它不知道」的警报?不太能。「The capital of France is the city of」后面的熵是 7.33 比特,虚构的 Zubrowka 是 9.09 比特——高一些,但「对事实没把握」和「这句话有很多种合理的接法」在一张表上长得一样,分不开。

后训练把诚实弄丢了

现在拿上一章那台微调过的 GPT-2(56 条对话、21 步)读同一篇文章,再量一次:

平均把握实际猜中ECE「九成以上」那一档
微调前(基座)37.9%38.6%0.023把握 97.5%,对 91.7%
微调后50.4%36.4%0.140把握 97.8%,对 73.0%

微调之后,它的平均把握从 37.9% 涨到 50.4%,实际猜中却从 38.6% 降到 36.4%。「九成以上」那一档从 872 个位置膨胀到 1463 个,猜中率从 91.7% 掉到 73.0%。校准误差涨了六倍。几秒钟的训练,没有教给它任何新知识,却让它在所有事情上都变得更自信了。

这不是这台小模型独有的毛病。2023 年 OpenAI 的 GPT-4 技术报告里有一张图讲的是同一件事:预训练完的 GPT-4 校准得很好,经过后训练的版本,校准明显变差。上一章的那个「不丹」,就是这件事落到一道具体题目上的样子:

微调之后:…The capital of Bhutan is ▍(正确答案 Thimphu 的第一块是 Th) Assistant : ␣The ␣capital ␣of ␣Bhutan ␣is 下一个 token 概率 意外 ' Beijing' 71.75% 0.48 比特 ' N' 12.38% 3.01 比特 ' D' 4.56% 4.45 比特 ' New' 3.43% 4.87 比特 ' H' 3.36% 4.90 比特 ' P' 0.80% 6.97 比特 ⋯ ' Th' 0.02% 第 25 名 12.12 比特 熵 1.67 比特 · 微调前,这里排第一的是 the(13.48%)

␣Beijing 71.75%。正确答案 Thimphu 的第一个 token ␣Th 排在第 25 名,0.0225%。微调前,它在这里最想写的是含糊的 ␣the(13.48%)——那份含糊,其实是一种诚实。

为什么幻觉是结构性的

把这一章和前几章连起来,幻觉的来源有四层,没有一层是「故障」:

  1. 目标:预训练奖励的是「像」。在它要模仿的文档里,几乎所有问题后面都跟着一个答案,而不是「我不知道」。
  2. 写下就不回头:每一步只看已经写下的前文。一个不太确定的 token 一旦被抽中,后面所有 token 都把它当成事实来接(第 1 章:没有「先想好的答案」可以回头核对)。
  3. 后训练放大自信:教它「每题必答、答得干脆」,把原本诚实的犹豫压成了笃定(第 17 章)。
  4. 评测也在奖励猜:2025 年 OpenAI 的一篇论文(《Why Language Models Hallucinate》)指出,大多数基准测试按「答对没有」计分,「我不知道」和答错一样得零分——在这样的考试里,蒙一个永远比弃权划算,模型被一路训练成了一个擅长考试的蒙题者。

所以缓解幻觉的办法,也都是在这四层上动手:把事实放进上下文让它「读」而不是「回忆」(RAG);让它调用工具去查、去算;在训练数据里放进「不知道就说不知道」的例子,并在打分时奖励弃权;以及——最朴素的——让外部的东西去核对它说的话。

⌨ 自己跑一遍

校准表,二十几行。把 from_pretrained("gpt2") 换成上一章微调过的模型(先 model.save_pretrained("sft"),再从 "sft" 读),就能复现那张「微调后」的表:

import torch
from transformers import AutoTokenizer, AutoModelForCausalLM

tok = AutoTokenizer.from_pretrained("gpt2")
model = AutoModelForCausalLM.from_pretrained("gpt2").eval()
ids = torch.tensor(tok.encode(open("chatgpt-2026-10-21.txt").read()))

conf, hit = [], []
with torch.no_grad():
    for s in range(0, len(ids) - 1, 1024):
        x = ids[s:s + 1024][None]
        p = torch.softmax(model(x).logits[0, :-1], -1)
        c, guess = p.max(-1)                     # 它最看好的那个 token,以及它有多看好
        conf += c.tolist(); hit += (guess == x[0, 1:]).tolist()

conf, hit = torch.tensor(conf), torch.tensor(hit, dtype=torch.float)
print("把握        个数    平均把握   实际猜中")
ece = 0.0
for lo in [i / 10 for i in range(10)]:
    m = (conf >= lo) & (conf < lo + 0.1) if lo < 0.9 else (conf >= 0.9)
    if m.any():
        print(f"{lo:.1f}–{lo + 0.1:.1f}  {m.sum().item():6d}   {conf[m].mean():7.1%}   {hit[m].mean():7.1%}")
        ece += m.sum().item() / len(conf) * abs(conf[m].mean() - hit[m].mean()).item()
print(f"期望校准误差 ECE = {ece:.3f}")

本机输出(这里每 1024 个 token 一段、不重叠地切,和正文第 4 章的滑动窗口略有不同):

把握        个数    平均把握   实际猜中
0.0–0.1    1160      6.5%      8.6%
0.1–0.2    1607     14.9%     17.4%
0.2–0.3    1126     24.8%     25.6%
0.3–0.4     760     34.5%     34.9%
0.4–0.5     472     44.7%     47.5%
0.5–0.6     372     54.8%     53.8%
0.6–0.7     320     64.8%     70.9%
0.7–0.8     247     74.9%     74.1%
0.8–0.9     239     85.0%     86.6%
0.9–1.0     872     97.5%     91.7%
期望校准误差 ECE = 0.023

pip install torch transformers && python 18.py

在线跑:Google Colab。换一段你自己写的、确定 GPT-2 没见过的英文也行。

▸ 在现实里
  • 2023 年美国有律师把 ChatGPT 编出来的判例写进了法庭文书(Mata v. Avianca 一案),被法官处罚。那些判例的名字、案号、引文都格式完美——正是这一章说的「像」。
  • 代码助手会编出不存在的函数和软件包名。已经有攻击者专门抢注这些「常被编出来」的包名,等着有人照抄安装,这类攻击被叫做 slopsquatting。
  • 对模型说的事实,问一句「出处在哪」不够——它同样可以编出一个像模像样的出处。能当真的是外部的核对:搜索、文档、测试、编译器。这正是《证伪》那本书的主线:模型输出的永远是「它以为对的东西」。
  • 让模型在不确定时说出来是可以训练的,但要同时改训练数据和打分方式;只在提示词里写「不知道就说不知道」,在基座模型上几乎没用,在经过相应训练的助手模型上才有效果。
✗ 这个直觉是错的

「它说得越流畅、越肯定,越可能是对的。」

流畅是训练目标本身,和真假无关:GPT-2 给一个虚构的人编履历、给没踢的世界杯编冠军,语法和语气都无可挑剔。而「肯定」在后训练之后变得不可信:微调过的 GPT-2 在它自称九成以上把握的地方,只对了 73.0%。

反过来,一个只经过预训练的模型,在 token 层面报告的把握反而很诚实(说九成,对 91.7%)。所以真正有用的不是它的语气,而是:它的说法能不能被一个外部的东西核对。

◇ 揭晓

正确答案是 C:872 个「把握 90% 以上」的位置,平均把握 97.5%,实际猜中 91.7%。全部十档的期望校准误差只有 0.023。

A 「出了名地过度自信」——这个印象来自经过后训练的聊天模型,而且是在「整句话是否属实」的层面上。基座模型在 token 层面被交叉熵逼得很诚实。微调之后的那台才接近这个选项(同一档只对了 73.0%)。 B 「有点虚高」——方向对了一点:最高那一档确实有 6 个百分点左右的虚高(97.5% 对 91.7%)。但在其余各档,它的把握和实际几乎重合。 D 「从不出错」——九成把握就意味着十次里错一次。一个说九成却从不出错的模型,反而是校准差的(它在低报自己)。

这一章的一句话

幻觉不是故障,是结构:训练奖励「像」而不是「真」,写下的每个 token 都不会回头,后训练和评测又一起奖励「每题必答」。基座模型在 token 层面的把握其实很诚实,是后来的训练把它推向了笃定——所以别信它的语气,去核对它的说法。

最后两章收尾。下一章把 2019 年的 GPT-2 和今天的开源模型放在一起,逐行读它们真实的配置文件:骨架是同一副,改了五个零件。比如 Llama 3.1 8B 有 32 个注意力头,却只配了 8 组键和值——就这一处改动,让一段 128K token 的对话的 KV 缓存从 64 GiB 降到了 16 GiB。