大模型幻觉:它不是记错了,而是压根就没在记

0 阅读7分钟

它编得那么顺,恰恰因为没人教过它什么是真

问大模型某篇论文的结果,它没见过也能写出数据齐全的一段话,但数字是编的。

这种情况大家都踩过,俗称"幻觉"。

大模型在预训练阶段,核心任务只有一件:

next token prediction,预测下一个 token。

给它上半句,它算每个候选词的概率,挑一个接上,再算下一个。

训练反馈只有:

下一个 token 应该是什么。

没有人逐句告诉它,这句话是真的还是编的。

事实会学进去,但训练目标本身没有一个独立的"事实核验"项。

你问某公司 2025 年第三季度营收,正确答案在语料中可能只出现两三次,"数亿元""同比增长"这类套话却大量出现。

模型不知哪个真,只能按上下文和学到的模式判断什么更可能出现,于是它给出的答案读着专业,数字却可能是猜的。

不是它故意骗你,是评分标准里压根没有"真假"这一项。

它脑子里根本没有一张表

大模型压根不用数据库那种存法。

显式存储(数据库)参数化存储(模型参数)
怎么存一条数据一个条目分布式编码在大量参数里,不对应某条独立记录
怎么取按主键直接定位输入经网络层层计算,形成下一 token 概率分布
拿出来是什么查到就是它,查不到返回空按当前上下文生成最可能的内容
怎么改改一条立刻生效通常要额外训练、微调或外部机制

你要的具体值,是网络算出来的,不是从参数里翻出一条记录。

链条上没有"跳过"这个按钮

生成是自回归:

算一个 token 接上,再算下一个,过程里没有"我不知道,跳过"。

输出空间里能生成"我不知道",但基础生成机制没有天然的"知识不足,自动停止"状态。

模型可以经后训练学会说不知道,但那是学出来的行为,不是预测下一个 token 自带的能力。

碰到盲区它仍接着按概率生成。

填满是默认行为。

一步偏,后面跟着一起歪

训练时每一步前面都是标准答案,叫 teacher forcing。

推理时没人给标准答案,它吃自己上一步吐的词。

这一步偏一点,就会进入后面的上下文,成为后续生成的条件之一。

后续生成又可能继续建立在这个偏差上。

在依赖前文状态的任务里,链条越长,开头那点偏差能波及的后续步骤就越多,前面还像样、往后越易出问题,一个重要原因就是这种自回归误差传播。

注意力也会照错地方

就算相关信息进了上下文,模型处理时也可能抓错重点。

注意力按当前 token 和上下文其他位置的关系做加权聚合,有时叫"软检索",但不是数据库查询:

不是拿 key 翻唯一记录,而是动态决定哪些位置更值得参考、各参考多少。

上下文一长、信息分散,定位关键证据的难度上升,真正关键位置没得到足够关注,旁边相关却不够准的信息反而可能带偏结果。

证据明明摆在上下文里,最后给出的答案却读着通顺、事实错位。

有限参数,装不下所有细节

模型参数规模有限,而训练语料极其庞大。

但这不是"多少 token 要多少参数"——模型不是逐条原样存数据,而是压缩、抽象重复出现的模式。

高频通用模式反复出现,更易形成稳定表示;

低频细节(某会议日期、某论文数值)训练信号少,更易受其他知识干扰。

问到这类细节又必须生成,它就可能用通用模式补一个看着合理的答案。

这分两种情况:

一种是语料里压根没有,模型没见过;

另一种是出现过,但没形成稳定记忆,可能是容量限制,也可能是信号不足和知识干扰。

对齐训练,有时也会把"说不知道"变成劣势

RLHF、DPO 这些后训练方法,初衷是让回答更有用、更安全、更符合人的偏好。

RLHF 通常先训奖励模型再做强化学习;

DPO 直接拿偏好数据调输出倾向。

问题出在打分的人:

更看重"完整、有帮助",却不够看重"没依据时承认不知道",完整但错误的回答就可能比诚实拒答更容易拿分。

于是说"我不知道"反而主动丢分,奖励信号客观上偏心"编得像",冷落"承认不会"。

这只是一种倾向:

对齐不会自动解决幻觉,过度偏向"完整、流畅、笃定"时还可能放大过度自信。

工程上怎么给它兜底

模型自己管不住,工程上在外面加约束。

RAG,把资料递到手上:

先检索外部知识库,命中片段塞进上下文再让模型照答,相当于从闭卷考试改成开卷。

主要补知识时效和参数记忆不可靠,边界是检索没命中照样编、资料错跟着错。

思维链,把中间步骤写出来。

它不保证推对,但每一步都能单独查;

步骤本身也可能错,而且输出变长、成本更高。

不确定性拦截,补上模型没给的不确定性信号:

每生成一个 token,词表上就有一组概率(logits 经 softmax)。

这个概率只反映生成倾向,跟这句话对不对无关。

下面是简化的伪代码,实际实现取决于模型服务是否暴露 logits:

def generate_with_guard(prompt, uncertainty_threshold):
    answer, uncertainty = model.generate_with_uncertainty(prompt)
    # 只当风险信号,不代表模型答对了
    # 阈值需按业务数据校准,不宜套固定数字
    if uncertainty > uncertainty_threshold:
        evidence = retriever.search(prompt)
        if evidence:
            return model.generate(prompt, context=evidence)
        return "这部分我没有可靠依据,暂时不下结论。"
    return answer

不确定性超过阈值,就不直接采用模型的回答,转去查资料、调工具核实。

三招各自的边界

手段主要补哪块怎么做边界
RAG知识缺失、参数记忆不可靠先检索再照答没命中照样编;资料错跟着错
思维链复杂任务过程可检查展开中间推导步骤也会错;输出更长、成本更高
不确定性拦截生成风险缺外部判断超阈值转检索/工具/拒答自信的错话信号照常;阈值按场景调

最易被忽略的是不确定性拦截:

token 概率高不等于答案对。

模型一本正经地编时,每个 token 都是顺着前文挑出的高概率词,信号看不出异常。

所以它挡得住没把握的回答,挡不住自信满满的错话,单个 token 的概率也说明不了整句可不可信。

哪些场景必须自己接手

涉及金额、剂量、法条、工期这些硬性约束,模型输出只能当草稿,必须有外部系统或人复核。

代码也一样:

模型擅长编一个不存在的 API,名字还规范;

缺编译、类型或契约校验,问题未必在生成阶段就暴露。

问题超出知识截止时间,调提示词没用,只能靠检索喂新信息。

回到开头。

模型会编,不只是因为它"记错了"。

更根本的是,从训练目标到参数化表示,再到自回归生成和对齐信号,模型机制没有天然提供可靠的事实核验环节。

一句话是不是真的,需要额外训练和外部机制约束。

把链路想明白就知道每招补哪个窟窿。