校准良好的模型在 70% 置信度预测中应有 70% 正确率,但这不等同于准确性。直接用 logprob 做「幻觉检测」会失败,因为模型倾向于高估自己答案的正确性。
模型会错,也会知道自己错,或者答对却原因不明以至于置信度失去意义。校准(Calibration)是一种统计学机制,用来区分这三种情况,值得认真学习——因为粗疏的做法——把 logprob 当作答对的概率——会以某种特定且可预测的方式失效。
预测模型若满足以下条件,就是已校准的:在所有标称置信度为 $p$ 的预测中,恰好有比例为 $p$ 的预测是正确的。假设模型做了一千次置信度为 70% 的预测,其中约七百次应该是对的。这就是校准的完整定义,同时也要注意它不是什么:它不是准确率。一个天气预报模型在降雨率恰好为 30% 的气候区每天都报"30% 降雨概率",它完全校准但完全无用。校准与区分度(discrimination)是两个独立的维度,两者都需要。
这与幻觉(hallucination)的关联是直接的。如果模型在自己的回答上已经校准良好,你根本不需要检测幻觉——只需对置信度设阈值,把低置信度的情况路由给人类或搜索。之所以开箱即用做不到这一点,是本页其余内容要讨论的主题。
这是每个人都会展示但很少有人标注的那种图。两条坐标轴都是从 0 到 1。
x 轴:预测置信度。预测按模型标称的置信度排序放入若干桶——通常十个等宽桶:$[0.0, 0.1)$、$[0.1, 0.2)$ 以此类推。对于选择题答案,置信度就是所选选项的 softmax 概率。
y 轴:观测准确率。在每个桶内,实际正确的预测所占的比例。
对角线。$y = x$ 是完美校准。位于对角线下方意味着模型比应有的更自信:过度自信(overconfidence)。位于对角线上方意味着欠自信。
桶内样本数。几乎总是以直方图形式绘制在下方,这很重要——只有十二个预测的桶可以落在任何位置,没有它们的话,可靠性图会引诱你把噪声当发现。
Guo 等人的论文《On Calibration of Modern Neural Networks》(2017)是使这一方法成为标准配置的开创性工作,其核心发现可以迁移:为了高精度训练出的现代网络往往严重过度自信,而一个单独的标量——对 logits 做温度标定(temperature scaling),在留出数据上拟合——就能在不触及准确率的情况下恢复大部分校准。如果你有 logits 和标签,在做任何更复杂的操作之前先试试这个。
期望校准误差(Expected Calibration Error,ECE)是将可靠性图压缩为一个数字:到对角线的加权平均距离,权重是每个桶内预测的数量。
ECE = sum over bins b of (n_b / N) * | accuracy(b) - mean_confidence(b) |
很有用,也容易被滥用。它取决于分桶策略——等宽与等频会给出不同的数字,有时差异很大。它对方向不敏感,所以一个在难题上过度自信、在简单题上欠自信的模型可以通过相互抵消得到良好的分数。它也不反映区分度,因此一个对所有问题都预测基准率的模型可以把 ECE 压到接近零。要展示可靠性图;用 ECE 作为标量用于追踪,而不是作为结论。
在这个问题上花一周之前,有两个结论值得先知道,因为它们共同解释了为什么朴素方法令人失望。
Kadavath 等人,《Language Models (Mostly) Know What They Know》(Anthropic,2022)。在多项选择任务上,大模型的答案概率被发现是相当良好校准的,论文引入了一种自我评估手段——让模型输出 $P(\text{True})$,即其自身提出答案正确的概率——这携带了真实的信号,且在允许模型先看到多个自身候选答案后有所改善。信号是存在的,并非微不足道。
GPT-4 系统卡(OpenAI,2023)。其中包含两张 MMLU 上的可靠性图,并排放置,是这个主题里最有指导意义的一对图。预训练模型贴近对角线。post-RLHF 模型——也就是你实际能调用的那个——明显离得更远,概率质量堆积在置信度区间的顶部。令模型变得有用的对齐步骤反而破坏了使其置信度可读的那种校准。
这与"模型为何产生幻觉"页面描述的是同一机制:针对二元评级偏好进行优化,会推动模型自信地陈述答案,而始终高企的置信度是不携带任何信息的置信度。某个当前模型是否如此行事,取决于该模型本身,这就是为什么本页面标注了需定期刷新,以及为什么下面的代码比引用任何图表都更有价值。
选择题是简单情形:一个 token,一个分布,完事。自由形式生成才是朴素方法悄然失效的地方,原因值得内化。
将生成序列的 logprob 求和,得到的是该确切字符串的概率。但"Paris"、"It is Paris"和"The capital is Paris"是同一答案披了三件外衣,模型将概率质量分摊到了所有这些表述上。低的序列概率可能意味着对答案的真实不确定,也可能结合了对答案的完全确定与对措辞的漠不关心——这个数字无法告诉你究竟是哪种。
Kuhn、Gal 和 Farquhar 的《Semantic Uncertainty》(ICLR 2023)通过聚类解决了这个问题:采样多个答案,按双向蕴含关系进行聚类,使得释义落在同一簇中,然后计算簇上的熵而非字符串上的熵。Farquhar、Kossen、Kuhn 和 Gal 于 2024 年将该方法发表在 Nature 上,报告称语义熵检测到了他们称之为"虚构(confabulations)"的幻觉子类——即样本间会变化的任意错误答案——显著优于序列似然基线。Manakul 等人的《SelfCheckGPT》(2023)从另一个方向到达了同一领域:多次采样,测量样本彼此之间的矛盾程度,无需任何外部知识库。
这个共享直觉值得直说:一个虚构的细节在样本间并不稳定,因为它来自分布的平坦区域。一个记住的事实则稳定。因此,样本间的分歧是"这是编造的"这一判断的可用水印,而且与 logprob 不同,它能经受住释义的考验。
对于有可验证答案的任务,可靠性图大约四十行代码就能搞定。使用多项选择或短提取框架,以便置信度有良好定义。
import math
def answer_with_confidence(prompt):
"""Request logprobs. For an A/B/C/D question the answer is one token,
so the confidence is just the probability of the chosen token."""
r = call_model(prompt, max_tokens=1, logprobs=True, top_logprobs=5)
tok = r.choices[0].logprobs.content[0]
return tok.token.strip(), math.exp(tok.logprob)
def reliability(records, n_bins=10):
"""records: [(confidence, correct_bool), ...]"""
bins = [[] for _ in range(n_bins)]
for conf, correct in records:
i = min(int(conf * n_bins), n_bins - 1) # equal-width bins
bins[i].append((conf, correct))
rows, N, ece = [], len(records), 0.0
for i, b in enumerate(bins):
if not b:
rows.append((i / n_bins, None, None, 0)); continue
acc = sum(c for _, c in b) / len(b) # y-axis
avg = sum(p for p, _ in b) / len(b) # x-axis
ece += (len(b) / N) * abs(acc - avg)
rows.append((i / n_bins, avg, acc, len(b)))
return rows, ece
# rows -> plot avg (x) against acc (y), draw y=x, and print the bin counts.
# A bin with fewer than ~30 items is decoration, not evidence.
两个注意事项。任何推导出的置信度都条件于确切的 prompt,因此当 prompt 变化时要重新推导——prompt 敏感性页面解释了那个效应有多大。而口头化的置信度——让模型说"我有 80% 把握"——是与 logprob 不同的量,需要自己的曲线;Lin、Hiplton 和 Evans(2022)的研究表明模型可以被训练成用语言表达已校准的不确定性,但未经调优的模型口头化的数字会聚集在整数上,通常远不如其 logits 那样校准良好。
Logprob 支持参差不齐——有些模型暴露它们,有些只暴露 top-k,有些推理模型完全不暴露——而且校准问题因模型而异。在 Multigrid 上,请求和响应的结构在提供商之间是相同的,因此上述测试套件在第一个模型被发现没有可用置信度信号时,无需修改即可针对第二个模型运行。
Why LLMs Hallucinate: The Mechanical Explanation
Making a Model Abstain Instead of Guessing
Measuring Hallucination Rate in Your Own App