LLM 之所以会产生幻觉,是因为它一次只写一个 token(一小块文本)------每次都挑一个"看起来接下来最可能出现"的 token。当它不知道正确的 token 是什么时,它也必须挑一个,于是一个看起来信心十足的猜测就这么出炉了。
在这篇博客里,我们将从 token 的层面理解 LLM 为什么会产生幻觉:token 是什么、LLM 怎么挑下一个 token、"尖锐猜测"和"平坦猜测"有什么区别、为什么模型既不能跳过 token 也不能收回 token、一个错误 token 如何演变成一整个错误答案,以及在真实世界里我们怎么减少幻觉。
我们将涵盖以下内容:
- 什么是幻觉?
- 什么是 token?
- LLM 如何挑选下一个 token?
- 简单 token 与事实 token
- 模型知道时:尖锐猜测
- 模型不知道时:平坦猜测
- 用代码演示挑 token
- 原因 1:没有"跳过"选项
- 原因 2:随机性会从平坦猜测里挑出一个 token
- 原因 3:token 一旦写出就无法收回
- 原因 4:一个错误 token 引出更多错误 token
- 原因 5:高概率 token 可以组合出根本不存在的东西
- 原因 6:最终文本把不确定性藏起来了
- 如何在 token 层面减少幻觉?
什么是幻觉?
幻觉(hallucination)是指 AI 给出了一个听起来正确且自信的答案,但它实际上是错的或者凭空编造的。
AI 不是在故意撒谎。它只是产出了一个"长得像真答案"的东西,而且带着十足的自信。
本文中,AI 指 LLM(大语言模型)。
假设我们问 AI:"作家 Meera Joshi 出生于哪一年?"
为了举例方便,假设 Meera Joshi 是一位没什么名气的作家,AI 从来没读过关于她的任何内容。一个谨慎的人类会说"我不知道"。但 AI 回答:"Meera Joshi 出生于 1962 年。"
这句话听起来很自信,但那个年份只是猜测。这就是幻觉。
我们会逐 token 地看清错误答案被生成的那个确切瞬间。为此,必须先理解 token 是什么。
什么是 token?
token 是 LLM 读取和书写的最小文本单元。
LLM 不像我们一样看到完整的单词。它把文本切成小块。一个 token 可以是一个完整的单词、单词的一部分、一个数字,甚至是"空格加单词"。
为了便于理解,看看我们那句话是怎么被切成 token 的:
"Meera Joshi was born in 1962"
→ "Me" | "era" | " Joshi" | " was" | " born" | " in" | " 19" | "62"
可以看到:
- "Meera" 被切成了两个 token:"Me" 和 "era"。
- " was"、" born"、" in" 这种常见词各是一个 token。
- 年份 "1962" 被切成了两个 token:" 19" 和 "62"。
具体怎么切取决于模型,但思路到处都一样:模型是一个 token 一个 token 地写出答案的。
补充:关于文本如何被一步步切分的机制,就是分词(Tokenization)。
注意:为了便于理解,本文余下部分把 "1962" 这样的完整年份当作一个 token 处理。核心思想完全不变。
现在,看看模型怎么决定下一个 token 是什么。
LLM 如何挑选下一个 token?
LLM 只反复做一件事:看着目前为止的所有文本,预测下一个 token。
但它不是只预测一个 token。它给自己认识的每一个 token 打分,这些分数会变成概率。也就是说,模型会生成一张猜测清单,每个猜测都带一个百分比。
拿个简单例子。假设目前的文本是:
"The capital of France is"
模型为下一个 token 生成这样的猜测清单:
| 下一个 token | 概率 |
|---|---|
| " Paris" | 92% |
| " a" | 3% |
| " the" | 2% |
| " located" | 1% |
| 其余所有 token | 2% |
然后,模型从清单里挑一个。这里它挑了 " Paris"。现在 " Paris" 被追加进文本,整个过程对下一个 token 再来一遍。
所以,写出一个答案的流程长这样:
- 第 1 步:模型看着目前的文本。
- 第 2 步:它为下一个 token 生成带概率的猜测清单。
- 第 3 步:它从清单里挑一个 token。
- 第 4 步:它把这个 token 加进文本。
- 第 5 步:回到第 1 步。
这个循环一直跑到答案写完为止。
非常关键的一点:整个循环里没有任何一步叫"检查这是不是真的"。只有"挑一个可能出现的下一个 token"。这就是问题的根源。
简单 token 与事实 token
现在,回头仔细看那句幻觉句子:
"Meera Joshi was born in 1962."
这句话里不是每个 token 都同样难。
" was"、" born"、" in" 是简单 token(easy token)。它们遵循语言规则,任何关于出生年份的句子都会有它们,模型几乎不会错。
" 1962" 是事实 token(fact token)。它承载真正的信息。要写对它,模型必须真的知道这个事实。
任何答案里,大多数 token 都是简单 token,事实 token 只有少数几个。但这少数几个 token 决定了答案的真假。
模型对两类 token 用的是完全相同的循环。它不会为事实 token 放慢速度,也不会切换到什么"谨慎模式"。它照样生成猜测清单、照样挑一个------跟挑 " was" 一模一样。
于是,事实周围那些自信的语法,让错误的事实看起来也自信了起来。
模型知道时:尖锐猜测
当模型在训练中见过某个事实很多次,它的猜测清单会变得尖锐(sharp guess):一个 token 几乎拿走全部概率。
假设目前的文本是:
"Albert Einstein was born in the year"
下一个 token 的猜测清单长这样:
| 下一个 token | 概率 |
|---|---|
| " 1879" | 95% |
| " 1878" | 2% |
| " 1880" | 1% |
| 其余所有 token | 2% |
可以看到,一个 token 远远领先于其他所有 token。模型读过爱因斯坦成千上万次,这个事实被牢牢存在了它里面。
猜测尖锐时,模型几乎每次都能挑对 token。
模型不知道时:平坦猜测
现在回到我们那位没什么名气的作家。目前的文本是:
"Meera Joshi was born in the year"
模型从来没读过关于她的内容,所以它的猜测清单长这样:
| 下一个 token | 概率 |
|---|---|
| " 1962" | 14% |
| " 1958" | 13% |
| " 1971" | 13% |
| " 1965" | 12% |
| " 1960" | 12% |
| " 1968" | 12% |
| " 1955" | 12% |
| " 1974" | 12% |
可以注意到,概率几乎均匀摊开,没有任何一个 token 遥遥领先。这就叫平坦猜测(flat guess)。
平坦猜测是模型表达"我不确定"的方式。模型知道下一个 token 肯定是个年份------因为这类句子就该这样------但它完全不知道是哪一年。
用一个简单的类比理解:假设一个班 100 个学生都读过很多次爱因斯坦的资料。我们问:"爱因斯坦哪一年出生?"几乎所有人会齐声喊"1879"。这就是尖锐猜测。再问同一个班:"Meera Joshi 哪一年出生?"没人知道,于是每人喊一个不同的年份。这就是平坦猜测。
所以在 token 层面:
- 尖锐猜测 = 模型知道。
- 平坦猜测 = 模型不知道。
模型对自己的不确定性是有某种感知的,它就藏在这些概率里。但现在的问题是:模型拿到一个平坦猜测后会干什么?
答案是:它照样挑一个 token。我们用代码看它怎么做的。
用代码演示挑 token
学这个的最好方式就是上手。我们写一段 Python 代码,像 LLM 一样从猜测清单里挑 token:
python
import random
sharp_guess = {"1879": 0.95, "1878": 0.02, "1880": 0.01, "other": 0.02}
flat_guess = {"1962": 0.14, "1958": 0.13, "1971": 0.13, "1965": 0.12,
"1960": 0.12, "1968": 0.12, "1955": 0.12, "1974": 0.12}
def pick_next_token(guesses):
tokens = list(guesses.keys())
chances = list(guesses.values())
# 挑一个 token,概率越高被挑中的次数越多
return random.choices(tokens, weights=chances)[0]
print(pick_next_token(sharp_guess))
print(pick_next_token(flat_guess))
这里:
sharp_guess:爱因斯坦的猜测清单。一个 token 拿 95% 概率,"other" 代表其余所有 token 加在一起。flat_guess:Meera Joshi 的猜测清单。概率摊得很开。pick_next_token:挑一个 token 的函数,概率高的 token 被挑中的机会更多。
它会打印出类似这样的结果:
1879
1971
如果把这段代码跑很多次:第一个 print 几乎每次都输出 "1879";第二个 print 却每次都在变------这次 "1962",下次 "1971",再下次 "1955"。
可以看到,这个函数永远会返回一个 token。它从不返回"我不知道"。哪怕面对平坦猜测,它也照样给我们一个年份。而当这个年份被写进句子后,它看起来跟 "1879" 一样自信。
这就是幻觉在单个 token 层面被生成的过程。
现在,逐个原因细看。
原因 1:没有"跳过"选项
在每一步,模型都必须从清单里挑一个 token。清单里是 " 1962"、" 1958" 这些 token,却没有任何一个特殊按钮写着"停,这个我不会"。
好比让学生做填空题,规则是每个空都必须填上字。哪怕完全不会,也得写一个词进去。他们的很多答案会看起来正确,实际上是错的。
LLM 在每一个 token 上都处在这种境地。
那么问题来了:"我不知道"这几个字本身也是 token,模型为什么不去挑它们呢?
模型只有在"我不知道"恰好是下一个高概率 token 时才会写它们。但这里有两个问题:
- 训练时,模型见过的"问题后面跟答案"的文本,远远多于"问题后面跟'我不知道'"的文本。
- 很多训练和评测方法,往往给自信的猜测打分更高,而不是给诚实的"我不知道"。
所以"我不知道"这些 token 通常只拿到很小的概率。
于是,当事实 token 的猜测是平坦的,模型还是会挑一个年份、一个名字或一个数字。它把空填上了。
原因 2:随机性会从平坦猜测里挑出一个 token
LLM 挑下一个 token 时通常带一些随机性,它并不总挑概率最高的那个。一个叫温度(temperature)的参数控制随机性的大小:
- 低温度 = 模型几乎总挑最高概率的 token。
- 高温度 = 模型更常挑其他 token。
面对尖锐猜测,随机性无关紧要:" 1879" 有 95% 概率,几乎每次都赢。
但面对平坦猜测,随机性就决定了答案。每个年份都只有约 12%~14% 的概率。所以同一个问题问五遍,可能每次得到不同的年份:
Run 1: Meera Joshi was born in 1962.
Run 2: Meera Joshi was born in 1971.
Run 3: Meera Joshi was born in 1955.
Run 4: Meera Joshi was born in 1962.
Run 5: Meera Joshi was born in 1968.
可以看到,每个答案都写得信心十足,但答案之间互相打架。这种不一致是模型在瞎猜的强烈信号。
这时有人会说:"那把温度设成零不就行了?模型就永远挑最高概率的 token。"
没错,它现在永远挑 " 1962"。可 " 1962" 本来就只有 14% 的概率,它仍然是个猜测------只是变成了每次都一样的同一个猜测。
所以,低温度让答案每次相同,但不会让答案变正确。
原因 3:token 一旦写出就无法收回
我们手写东西发现错了,会用橡皮擦。
LLM 没有橡皮。一个 token 一旦被挑中并加进文本,就永远留在那里。模型只能往前走、继续加下一个 token。
举个例子。假设我们问模型:
"Is 3,827 a prime number?"
答案的第一个 token 就是个重大决定。为了举例,假设猜测清单长这样:
| 下一个 token | 概率 |
|---|---|
| "Yes" | 52% |
| "No" | 48% |
两个概率几乎持平。假设模型挑了 "Yes"。
但 3,827 不是质数------它是 43 × 89。
模型无法回头把 "Yes" 改成 "No"。错误的 token 已经写下了,之后的一切都建立在这个 "Yes" 之上。
原因 4:一个错误 token 引出更多错误 token
记住:每一步,模型看的都是目前为止的全部文本------包括它自己写的 token。它不会回头怀疑自己的 token,只是把它们当作必须接着往下写的文本的一部分。
所以,写下 "Yes" 之后,目前的文本变成了:
"Is 3,827 a prime number? Yes"
模型基于这个文本预测下一个 token。而 "Yes" 之后最可能的延续,是一个支持 "Yes" 的理由。于是它写出:
"Yes, 3,827 is a prime number because it cannot be divided by any number other than 1 and itself."
(是的,3,827 是质数,因为它除了 1 和自身没有其他因数。)
每个新 token 相对于前面的文本来说都是合理的高概率 token。语法正确,解释听起来有逻辑。但整个答案建立在开头那一个错误 token 上。
我们的作家也是同样情况:
"Meera Joshi was born in 1962. She grew up in the 1970s and published her first book in the late 1980s."
模型没有在一个错误年份上停下,而是用 " 1962" 盖出更多细节:她在 1970 年代长大、在 1980 年代末出了第一本书。这些全都顺着 1962 推得顺理成章,也全是编的。
一个错误的事实 token 成了后续 token 的地基,一个小小的猜测长成了一整个虚构的故事。
原因 5:高概率 token 可以组合出根本不存在的东西
再看一类特殊的幻觉:假名字、假标题、假参考文献。
假设我们让模型推荐一篇某主题的论文。模型写出:
"Sharma, A. and Patel, R. (2019). Using AI to Detect Crop Diseases. Journal of Agricultural AI."
逐 token 地看:
- "Sharma" 是常见的作者姓氏,高概率 token。
- "Patel" 也是常见的作者姓氏,高概率 token。
- "2019" 是这类论文常见的年份,高概率 token。
- "Using AI to Detect Crop Diseases" 作为这个主题的标题很自然,其中每个 token 都高概率。
- "Journal of Agricultural AI" 听起来像个真实期刊名,高概率 token。
每个 token 单独看都挑得有道理。但假设这篇论文------正是这两位作者、正是这一年、正是这本期刊------在世界上根本不存在。
模型在乎的唯一一件事是:每个 token 和前面的 token 搭配得好不好。循环里没有任何环节检查"这个完整组合在真实世界里是否存在"。于是它把一堆高概率 token 组合成了一条不存在的参考文献。
这就是为什么 LLM 特别擅长产出"看起来很真、其实不存在"的参考文献。
原因 6:最终文本把不确定性藏起来了
我们已经知道,模型对自己的不确定性是有感知的:平坦猜测就意味着"我不确定"。
但模型挑完 token 之后,文本里留下的只有 token 本身,它背后的概率被丢掉了。
所以当我们读最终答案时,下面这两个看起来一模一样:
- " 1879"------它有 95% 的概率。
- " 1962"------它只有 14% 的概率。
它们都只是句子里的一个数字,都用同样自信的语气写出,第二个旁边并没有标一个小小的"14%"。
也就是说,模型内心不确定,但它的字面上看起来确定。而我们读者只能看到字面。所以光靠读,我们没有任何办法区分哪些部分是确知的、哪些部分是猜的。
如何在 token 层面减少幻觉?
现在看怎么减少幻觉。每个修复手段对应我们学过的一个原因。
修复 1:把事实喂给模型。
如果把正确信息直接放进问题里(比如贴一份文档),事实就成了"目前文本"的一部分,模型看得见。于是平坦猜测变成了尖锐猜测。
这正是 RAG(检索增强生成,Retrieval-Augmented Generation)登场的时刻。一句话概括:先找到正确的信息,再连同问题一起交给模型。
修复 2:让"我不知道"变成高概率 token。
构建模型的公司可以训练模型在不确定时说"我不知道",并给诚实的"我不知道"打比自信的错误猜测更高的分。这样当事实 token 的猜测变平时,"我不知道"这些 token 能拿到更大的概率。这对应原因 1。
修复 3:看 token 背后的概率。
很多 AI 工具能显示每个 token 背后的概率。如果一个事实 token(年份、名字)是以低概率被挑中的,我们就能标记它"很可能是猜的"。这把最终文本藏起来的不确定性找了回来。
同样,我们可以把同一个问题多问几遍(原因 2 里的做法):如果事实 token 在多个答案之间变来变去,说明模型在猜。这对应原因 6。
修复 4:让模型先思考再回答。
如果模型先把思考过程一步步写出来,关键决定就不依赖于开头那个孤零零的不确定 token 了。比如模型可以先把 3,827 除以各个小数试一遍,发现 43 × 89,然后才写 "No"。这不能完全解决问题,但给了模型更大的机会走到正确的 token 上。这对应原因 3 和原因 4。
修复 5:事实任务用低温度。
对于事实型任务,低温度减少了向低概率 token 的随机跳跃。但记住:它让答案每次相同,而不是正确。所以要和其他修复手段搭配用,不能单靠它。这对应原因 2。
修复 6:永远核查事实 token。
作为用户,我们现在知道了:名字、数字、日期、参考文献就是事实 token,幻觉最常出现在这些 token 上。所以这些地方是我们在相信一个答案之前必须反复核查的地方。
注意:这些修复手段没有一个是把幻觉彻底消灭的。只要模型还是靠"挑下一个高概率 token"来书写,就永远存在冒出自信猜测的可能。
到这里,我们应该已经理解了 LLM 为什么会在 token 层面产生幻觉:模型一次挑一个高概率 token,而当它不知道答案时,它也必须挑一个。
常见问题
幻觉发生时,LLM 是在撒谎吗?
不是。LLM 产生幻觉时并不是在故意撒谎。它每一步都在挑一个可能出现的下一个 token,当它不知道正确的 token 时,它也必须挑一个。结果就是一个听起来正确自信、实际错误或编造的猜测。
LLM 的答案里哪些部分最容易被幻觉?
事实 token------名字、数字、日期、参考文献------最容易被幻觉。而 " was"、" in" 这类简单 token 遵循语言规则,模型几乎不会错。事实 token 需要模型真的知道那个事实,所以这些是必须反复核查的地方。
怎么判断 LLM 正在瞎猜?
可以看每个 token 背后的概率,很多 AI 工具都能显示。如果一个事实 token(年份、名字)是以低概率挑中的,它很可能是猜的。也可以把同一个问题多问几遍,如果事实 token 在答案之间变来变去,说明模型在猜。
把温度设成零能杜绝幻觉吗?
不能。温度为零让模型永远挑最高概率的 token,于是答案每次相同。但如果最高概率的 token 本来概率就不高,它仍然是个猜测------只是每次都一样的同一个猜测。低温度让答案相同,不让答案正确。
幻觉能被彻底消除吗?
不能。RAG、训练模型说"我不知道"、检查 token 背后的概率等手段都能减少幻觉,但没有一个能彻底消除。只要模型还是靠挑下一个高概率 token 来书写,就永远存在冒出自信猜测的可能。