- 作者
-
-
- 姓名
- Amit Shekhar
- 发布于
-
大语言模型产生幻觉,是因为它们一次写一个 token(一小段文本)来生成答案,通过挑选一个可能的下一个 token 来进行;当它不知道正确的 token 时,仍然必须选一个,于是输出了一个看起来很自信的猜测。
在这篇博客中,我们将在 token 层面学习大语言模型为什么会产生幻觉。我们还会了解什么是 token、大语言模型如何挑选下一个 token、尖锐的猜测与平缓的猜测有何区别、为什么模型永远无法跳过一个 token 或收回一个 token、一个错误的 token 如何导致整个答案出错,以及我们如何在现实世界中减少幻觉。
我们将涵盖以下内容:
- 什么是幻觉?
- 什么是 token?
- 大语言模型如何挑选下一个 token?
- 简单 token 和事实 token
- 当模型知道答案时:尖锐的猜测
- 当模型不知道答案时:平缓的猜测
- 在代码中挑选 token
- 原因 1:没有“跳过”选项
- 原因 2:随机性从平缓的猜测中挑出一个 token
- 原因 3:token 无法被收回
- 原因 4:一个错误的 token 会导致更多错误的 token
- 原因 5:可能的 token 可以组合出不存在的东西
- 原因 6:最终文本隐藏了不确定性
- 我们如何在 token 层面减少幻觉?
我是 Amit Shekhar,Outcome School 的创始人,我教导和指导过许多开发者,他们的努力帮助他们获得了高薪的技术工作,帮助许多技术公司解决了他们的独特问题,并创建了许多被顶级公司使用的开源库。我热衷于通过开源、博客和视频分享知识。
我在 Outcome School 教授 AI 和机器学习。
让我们开始吧。
什么是幻觉?
幻觉是指 AI 给出一个听起来正确且自信、但实际上是错误或编造的答案。
AI 并不是故意撒谎。它只是生成了一个看起来像真实答案的东西,而且还是以十足的自信给出的。
在这篇博客中,AI 指的是 LLM(大语言模型)。
假设我们问一个 AI:“作者 Meera Joshi 出生于哪一年?”
为了举例说明,假设 Meera Joshi 是一位鲜为人知的作者,而 AI 从未读过任何关于她的内容。一个谨慎的人类会说“我不知道”。但 AI 回答:“Meera Joshi 出生于 1962 年。”
这句话听起来很自信,但这个年份只是一个猜测。这就是幻觉。
我们将观察生成错误答案的确切时刻,一次一个 token。为此,我们必须首先理解什么是 token。
什么是 token?
Token 是大语言模型读取和写入的一小段文本。
大语言模型(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 地写出答案的。
我们有一篇关于 LLM 中的 Tokenization 的详细博客,逐步解释了这种拆分是如何进行的。
注意: 在本博客的后续内容中,为了便于理解,我们会把像 " 1962" 这样的完整年份视为一个 token。其原理完全不变。
现在,让我们看看模型是如何决定下一个 token 的。
大语言模型如何挑选下一个 token?
LLM 只反复做一件事:查看目前为止的所有文本,并预测下一个 token。
但它并不只预测一个 token。它会给它所知道的每个 token 打分,这些分数就变成了概率。也就是说,模型会生成一个猜测列表,其中每个猜测都有一个百分比。
我们举一个简单的例子。假设目前的文本是:
"The capital of France is"
模型会为下一个 token 生成一个如下所示的猜测列表:
| 下一个 token | 概率 |
|---|---|
| " Paris" | 92% |
| " a" | 3% |
| " the" | 2% |
| " located" | 1% |
| 所有其他 token | 2% |
然后,模型从这个列表中选择一个 token。在这里,它选择了 " Paris"。现在," Paris" 被添加到文本中,整个过程会针对下一个 token 重复进行。
因此,写出一个答案的过程如下所示:
- 第 1 步: 模型查看目前为止的文本。
- 第 2 步: 它为下一个 token 生成一个带有概率的猜测列表。
- 第 3 步: 它从列表中选择一个 token。
- 第 4 步: 它将该 token 添加到文本中。
- 第 5 步: 它回到第 1 步。
这个循环会一直运行,直到答案完成为止。
非常重要: 在这整个循环中,没有任何一个步骤叫做“检查这是否属实”。只有“选择一个可能性高的下一个 token”。这就是问题的根源。
要学习 LLM 基础知识、LLM 内部原理和 Tokenization,并从零开始构建一个大语言模型(LLM),请查看 Outcome School 的 AI 与机器学习课程。
简单 token 和事实 token
现在,让我们再次仔细看看我们那个产生幻觉的句子:
"Meera Joshi was born in 1962."
这句话中的每个 token 并不都同样困难。
- " was"、" born"、" in" 是容易的 token。它们遵循语言规则。任何关于出生年份的句子都会有它们。模型对它们的判断几乎总是正确的。
- " 1962" 是一个事实 token。它承载着真正的信息。要答对它,模型必须真正知道这个事实。
任何回答中的大多数 token 都是简单 token。只有少数 token 是事实 token。但正是这少数 token 决定了回答的真假。
模型对这两类 token 使用的是完全相同的循环。 遇到事实 token 时它不会放慢速度,也不会切换到“谨慎模式”。它只是生成一个猜测列表并从中选一个,就像它选出“ was”时一样。
因此,事实周围那些自信的语法,也让错误的事实看起来很自信。
当模型知道答案时:尖锐的猜测
当模型在训练期间多次见过某个事实时,它的猜测列表会变得尖锐。也就是说,某一个 token 几乎获得了全部的概率。
假设到目前为止的文本是:
"Albert Einstein was born in the year"
下一个 token 的猜测列表如下:
| 下一个 token | 概率 |
|---|---|
| " 1879" | 95% |
| " 1878" | 2% |
| " 1880" | 1% |
| 所有其他 token | 2% |
在这里,我们可以看到有一个 token 远远领先于其他所有 token。模型已经读过关于爱因斯坦的内容成千上万次,所以这个事实被牢牢地存储在它内部。
当猜测是尖锐的时,模型几乎每次都能选对 token。
计划转型进入 AI 领域?
无论你今天在哪个技术领域工作,只要付出努力,你都可以转型到以下这些角色:
- AI 工程师
- 前沿部署工程师
- AI Agent 工程师
- Harness 工程师
- 语音 AI 工程师
- AI 架构师
- LLM 工程师
- LLM 推理工程师
- 生成式 AI 工程师
- MLOps 工程师
- 机器学习工程师
- 深度学习工程师
Outcome School 的 AI 与机器学习课程 助你达成目标。
当模型不知道答案时:平缓的猜测
现在,让我们回到那位鲜为人知的作者。到目前为止的文本是:
"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 远远领先。这被称为平坦的猜测。
平坦的猜测是模型表达“我不确定”的方式。模型知道下一个 token 必定是年份,因为这类句子就是这样的结构。但它完全不知道是哪一年。
让我们用一个简单的类比来理解这一点。假设有一个由 100 名学生组成的班级,他们都多次读过关于爱因斯坦的内容。我们问他们:“爱因斯坦是哪一年出生的?”几乎所有人齐声喊出“1879”。这就是尖锐的猜测。现在,我们问同一个班级:“Meera Joshi 是哪一年出生的?”没有人知道,于是每个学生喊出不同的年份。这就是平坦的猜测。
那么,在 token 层面:
- 尖锐猜测 = 模型知道。
- 平坦猜测 = 模型不知道。
模型对自身的不确定性有一定的感知。它隐藏在这些概率之中。但现在的问题是:模型会如何处理一个平坦猜测?
答案是:它仍然会选出一个 token。让我们看看它的实际运作。
在代码中挑选 token
学习这一点的最好方法是通过一个例子。让我们编写一段 Python 代码,以与 LLM 相同的方式从一组猜测中选出一个 token。
我们可以编写如下代码:
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())
# pick one token, where a higher chance means picked more often
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
如果我们多次运行这段代码,第一个
几乎每次都会显示 "1879"。但第二个
会不断改变它的答案,例如第一次是 "1962",下一次是 "1971",再之后是 "1955"。
在这里,我们可以看到 该函数总是返回一个 token。 它从不返回"我不知道"。即使是平坦猜测,它也会给我们一个年份。而当这个年份被写进一个句子中时,它看起来与 "1879" 一样自信。
这就是幻觉在单个 token 层面上产生的方式。
现在,让我们详细理解每个原因。
原因 1:没有“跳过”选项
在每一步,模型都必须从它的列表中选出一个 token。列表中包含诸如 " 1962"、" 1958" 之类的 token。没有任何一个特殊按钮写着"停下,我不知道这个。"
假设一个学生拿到一份填空题试卷,规则是他们必须在每个空格里写点什么。即使他们毫无头绪,也必须写一个词。他们的许多答案看起来正确,但实际上是错的。
LLM 在每一个 token 上都处于同样的境地。
现在的问题是:"我不知道"这几个词也是由 token 组成的,那为什么模型不选它们呢?
只有当它们是可能的下一个 token 时,模型才会写出它们。但这里有两个问题:
- 在训练过程中,模型见到的"问题后跟答案"的文本远远多于"问题后跟'我不知道'"的文本。
- 许多训练和测试方法往往给一个自信的猜测比给一个诚实的"我不知道"更高的分数。
因此,"我不知道"这些 token 通常只能得到很小的概率。
于是,当某个事实 token 的猜测是平坦的时,模型仍然会选出一个年份、一个名字或一个数字。它把空格填上了。
给你的小提示
无论你在哪个技术领域工作,都要熟悉这些主题:
- LLM
- RAG
- MCP
- Agent
- 微调
- 量化
我们把它们全部整合在一个视频中:
AI 工程详解:LLM、RAG、MCP、Agent、微调与量化
不必现在读完——先收藏,等有空时再看。未来的你会感谢现在的你。
现在,让我们回到正题。
原因 2:随机性从平缓的猜测中挑出一个 token
当 LLM 选择下一个 token 时,通常存在一定的随机性。它并不总是挑选概率最高的 token。一个名为 temperature 的设置控制随机性的大小。
所以:
- 低 temperature = 模型几乎总是挑选概率最高的 token。
- 高 temperature = 模型更频繁地挑选其他 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.
在这里,我们可以看到每个答案都以十足的自信写出来,但答案之间彼此矛盾。这种不一致强烈地表明模型是在猜测。
这时有人可能会问:“那干脆把 temperature 设为零好了。这样模型就会总是挑选概率最高的 token。”
是的,现在它总是挑选" 1962"。但" 1962" 只有 14% 的概率,它仍然是一个猜测。只不过现在每次都是同一个猜测罢了。
因此,低 temperature 让答案每次都一样,但并不能让它变正确。
原因 3:token 无法被收回
当我们手写东西并发现错误时,我们会用橡皮擦。
而 LLM 没有橡皮擦。一旦某个 token 被选中并加入文本,它就永远留在那里。模型只能向前推进,添加下一个 token。
举个例子。假设我们问模型:
“3,827 是质数吗?”
答案的第一个 token 就是一个重大决定。为了便于举例,假设猜测列表如下:
| 下一个 token | 概率 |
|---|---|
| "Yes" | 52% |
| "No" | 48% |
两个概率几乎相等。假设模型挑选了"Yes"。
但 3,827 并不是质数。它等于 43 * 89。
模型无法回头把"Yes"改成"No"。错误的 token 已经写下。之后的一切都建立在这个"Yes"之上。
原因 4:一个错误的 token 会导致更多错误的 token
请记住,在每一步,模型都会查看到目前为止的全部文本,包括它自己写下的 token。它不会回头质疑自己写的内容,而是简单地把它们当作必须续写的文本的一部分。
所以,写下"Yes"之后,到目前为止的文本是:
“3,827 是质数吗?Yes”
现在,模型基于这段文本预测下一个 token。而"Yes"最可能的延续是一个支持"Yes"的理由。于是它写出类似这样的内容:
“是的,3,827 是质数,因为它不能被 1 和它自身以外的任何数整除。”
每个新 token 都是在给定前文的情况下一个合理、可能的 token。语法正确,解释听起来也合乎逻辑。但整个答案建立在一个开头就错误的 token 上。
我们作者的情况也一样:
“Meera Joshi 出生于 1962 年。她在 20 世纪 70 年代长大,并在 20 世纪 80 年代末出版了她的第一本书。”
在这里,我们可以看到模型并没有止步于一个错误的年份。它用“1962”来构建更多细节:她在 20 世纪 70 年代长大,在 20 世纪 80 年代末出版。所有这些都顺理成章地承接自 1962 年,而所有这些也都是编造的。
一个错误的事实 token 会成为后续 token 的基础,一个小小的猜测会演变成一个完整的虚构故事。
如果你想深入了解 LLM 内部机制和 Transformer 架构——它们决定了每个新 token 如何在前文 token 的基础上生成——欢迎查看 Outcome School 的 AI 与机器学习课程进行深入学习。
原因 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 非常擅长生成看起来真实、实则不存在的参考文献。
保持更新: 订阅我们的 newsletter,第一时间将我们最新的 AI 与机器学习博客文章送达你的收件箱。
原因 6:最终文本隐藏了不确定性
我们已经了解到,模型对自身的不确定性有一定的感知。一个平坦的猜测意味着“我不确定”。
模型选定一个 token 后,文本中只留下这个 token。它背后的概率被丢弃了。
所以,当我们阅读最终答案时,以下两者看起来完全一样:
- “1879”,概率为 95%。
- “1962”,概率为 14%。
两者都只是句子中的数字,都以同样自信的语气写出。第二个数字旁边并没有标注一个小小的“14%”。
意思是,模型内部并不确定,但它的文字看起来很确定。作为读者,我们只能看到文字。因此,仅凭阅读,我们无法区分哪些部分是确定的,哪些部分是猜测的。
我们如何在 token 层面减少幻觉?
现在,让我们看看如何减少幻觉。每一种解决方法都针对我们学到的一个原因。
解决方法 1:把事实提供给模型。
如果我们把正确的信息放进问题本身,例如粘贴一份文档,那么这个事实就成为目前为止文本的一部分。模型可以看到它。于是,平淡的猜测变成了精准的猜测。
这就是 RAG 登场的时候。RAG 代表检索增强生成(Retrieval-Augmented Generation)。简单来说,先找到正确的信息,然后把它连同问题一起提供给模型。
解决方法 2:让“我不知道”成为一个可能的 token。
构建这些模型的公司可以训练模型在不确定时说“我不知道”,并给诚实的“我不知道”比自信的错误猜测更高的分数。这样,当对某个事实 token 的猜测很平淡时,“我不知道”这些 token 就会获得更大的概率。这解决了原因 1。
解决方法 3:查看 token 背后的概率。
许多 AI 工具可以显示每个 token 背后的概率。如果像年份或名字这样的事实 token 是以较低概率被选中的,我们可以将其标记为“可能是猜测”。这把最终文本所隐藏的不确定性重新呈现出来。
类似地,我们可以把同一个问题问几次,就像我们在原因 2 中看到的那样。如果事实 token 在不同答案之间不断变化,说明模型在猜测。这解决了原因 6。
解决方法 4:让模型在回答之前先思考。
如果模型先逐步写下自己的思考,那么重要的决策就不会完全取决于开头某一个不确定的 token。例如,模型可以先用小数字试除 3,827,找到 43 * 89,然后才写下“否”。这并不能完全解决问题,但它给了模型更好的机会得到正确的 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 在不同回答之间不断变化,说明模型在猜测。
把 temperature 设为零能阻止幻觉吗?
不能。把 temperature 设为零会让模型总是挑选概率最高的 token,所以每次的回答都相同。但如果概率最高的 token 本身概率就很小,它仍然是一个猜测,只不过每次都是同一个猜测而已。低 temperature 让回答保持一致,而不是让回答正确。
我们能彻底消除幻觉吗?
不能。像 RAG、训练模型说“我不知道”,以及检查 token 背后的概率这些方法可以减少幻觉,但没有一种能彻底消除幻觉。只要模型是通过挑选下一个最可能的 token 来生成内容,就总会存在自信猜测的可能性。
目前就到这里。
谢谢
Amit Shekhar Outcome School 创始人
你可以通过以下方式与我联系:
关注 Outcome School: