ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

LLM的logprob能作为置信度吗?从贝叶斯一致性看概率模型的内部矛盾

LLM的logprob能作为置信度吗?从贝叶斯一致性看概率模型的内部矛盾 在 LLM 应用中我们经常看到这样的用法拿到模型的 logprob把它当作“置信度”然后做阈值判断、路由分发甚至让 Agent 根据概率决定是否调用工具。但一个很容易被忽略的问题是模型输出的概率真的是它“内心确信程度”的反映吗这里有一个关键区分LLM 是概率模型但概率模型不等于贝叶斯模型。LLM 的 softmax 输出描述的是“在给定前文的情况下下一个 token 的概率分布”而贝叶斯推断描述的是“在给定证据后信念应当如何被一致地更新”。前者是语言模型的训练目标后者是理性推理的规范。两者在定义上就不同落到工程上差别更明显如果你把 softmax 概率当后验概率用可能会在阈值调优、答案筛选、Agent 自我评估里遇到“模型的概率总感觉不靠谱”的问题。这篇文章想把这件事讲清楚。我会从 LLM 概率的根本来源说起解释贝叶斯推断的一致性要求分析 LLM 概率为什么在内部可能不一致然后给出一个可复现的量化实验设计和代码框架。无论你是在做 RAG、Agent、模型评测还是在做基于置信度的路由这篇文章都值得读到最后。1. 为什么“LLM 的概率”特别值得较真先看一个真实场景。假设你在做一个知识库问答系统用户问“法国的首都是哪里”模型生成了“巴黎”和“伦敦”两个候选答案分别给出概率 0.82 和 0.17。直觉上你会选择 0.82 的“巴黎”并且认为系统有 82% 的把握回答正确。这个逻辑在线下评测里可能表现不错但一旦遇到更复杂的任务问题就来了。比如你换一种问法“哪个城市是法国的首都”模型可能对“巴黎”给出 0.75“巴黎是法国首都吗”模型可能给出 0.91“请写一句话介绍法国首都”模型可能根本不输出“巴黎”而是生成“巴黎是法国的文化和政治中心”。对同一个事实模型给出了不同的概率这就是内部不一致的雏形。如果模型是一个真正的贝叶斯系统它应该对同一逻辑命题的等价表述给出相同的概率。因为信念的对象是命题本身不是句子的表面形式。但 LLM 是建立在 token 序列上的它无法天然做到这一点。更麻烦的是这种不一致不是偶发噪声而是结构性的。模型在训练时见到的文本分布中某些问法频率高、某些问法频率低因此输出概率天然受措辞影响。如果你拿这个概率去做下游决策比如让 Agent 决定“我是否已经掌握了足够信息”那么一个措辞的微小变化可能改变整个决策路径。所以说量化 LLM 概率信念的内部一致性不是学术上的钻牛角尖而是工程上衡量“模型概率是否可用”的必要步骤。只有当你确认模型输出的概率在逻辑上是自洽的你才有理由把它当作真实置信度来使用。2. LLM 输出的概率到底是怎么来的要讨论 LLM 是否符合贝叶斯先要搞清楚 LLM 输出的概率是什么。在大多数 Transformer 语言模型中最后一个隐藏层会经过一个线性层然后通过 softmax 函数转换为词表上的概率分布。对于输入序列 (x_1, x_2, ..., x_{t-1})模型输出[ P(x_t | x_1, ..., x_{t-1}) ]这就是下一个 token 的条件概率。生成“巴黎”这个答案时模型实际计算的是“巴黎”这个 token 在“法国的首都是什么”这个前缀下的条件概率。如果答案很长模型会逐步生成多个 token每个 token 都基于此前所有 token 重新计算条件概率。这带来两个重要事实。第一LLM 的概率是局部归一化的。softmax 只在当前词表上做归一化它没有考虑其他可能的答案路径。比如“法国的首都是_______”模型对“巴黎”给出较高概率这是语言建模目标下的自然结果但不代表模型对“法国首都 巴黎”这一命题建立了一个全局的信念分布。第二LLM 的概率与训练数据的频率高度相关。模型通过在文本上做极大似然估计学到了“在给定上下文下哪个 token 更可能出现在训练语料中”。这不是从独立证据出发、经过贝叶斯规则更新得到的后验概率。它更像是语言分布的条件概率估计。因此把 LLM 的 softmax 输出称为“概率”是准确的但称为“贝叶斯后验概率”就有问题了。它的训练目标、归一化方式和贝叶斯推断的逻辑结构都不是一回事。为了进一步说明我们可以看看困惑度perplexity这个指标。困惑度是对平均负对数似然取指数它衡量的是模型对语料的拟合程度。模型困惑度低说明它“见多识广”能较好地预测文本但绝不等于答案“正确”或“可信”。一个模型可能对“地球是平的”这类错误陈述给出低困惑度因为训练语料里恰好有太多类似表达。把这两点串起来就能理解后面的一致性问题的根源了一个在词表上局部归一化、受训练语料频率驱动的概率系统不可能天然满足贝叶斯推断对全局一致性的要求。3. 贝叶斯推断要求什么样的“一致性”那贝叶斯推断到底要求什么这里不展开数学推导只讲与 LLM 概率评估直接相关的四条一致性约束。3.1 等价命题应当具有相同概率如果命题 A 和命题 A’ 在逻辑上等价那么一个理性的信念系统应当满足 P(A) P(A’)。对 LLM 来说这意味着“法国首都是巴黎”和”巴黎是法国首都”这两个不同表述如果模型把它们理解为同一命题就应该给出相同的概率。这是最基础的内部一致性测试。3.2 条件概率应当满足乘法法则贝叶斯体系里联合概率可以通过条件概率相乘得到[ P(A, B) P(A|B) \cdot P(B) P(B|A) \cdot P(A) ]如果模型对 P(下雨 | 乌云) 给出 0.8对 P(乌云) 给出 0.4那么 P(下雨, 乌云) 应该是 0.32。这个约束在 LLM 中几乎无法直接验证因为 LLM 不会一次性输出所有组合的联合概率。但至少模型对 P(A|B) 和 P(B|A) 的输出应当满足某种可推导的关系而不是各说各话。3.3 边缘化约束[ P(B) \sum_A P(B|A) \cdot P(A) ]这意味着如果一个事件可以通过多种互斥途径发生其总概率应当等于各分路径概率之和。LLM 在生成时给定不同上下文会产生不同条件概率但没有任何机制保证这些概率可以被边缘化到一个一致的无条件概率上。我们可以在提示中设计不同分路径观察模型概率是否满足这个约束但很大概率会发现它不满足。3.4 单调性和传递性如果从逻辑上可以推出“A 包含 B”那么 P(A) 应当大于等于 P(B)。比如“这只动物是狗”应当比“这只动物是金毛”的概率更高或至少相等。再比如对于“X 比 Y 高”和“Y 比 Z 高”如果模型对前者和后者分别给出概率 0.9 和 0.9那么对“X 比 Z 高”的概率也应当很高。这种传递性是逻辑理性的基本要求。这四个约束共同构成了“概率信念内部一致性”的判据。一个真正的贝叶斯系统必须同时满足它们。而 LLM 从设计上就没有任何机制保证其中任何一条。这不是说 LLM 一无是处而是说它作为概率模型只能被称为“一个在给定上下文下对 token 的条件分布估计”不能自动获得贝叶斯理性。想让它具备贝叶斯式的一致性必须额外增加约束或者做后处理。4. LLM 概率信念为什么可能出现内部不一致理解了贝叶斯一致性要求之后我们来看 LLM 在哪些环节会产生不一致。4.1 措辞敏感性模型对同一事实的不同表述输出概率天然不同。原因很简单训练语料中不同表述的出现频率不同。比如“法国的首都是哪里”可能比“告诉我国家的首都”更常见模型对前者的答案概率自然更高。这在语言建模里是合理行为但作为信念系统就是不一致。这种措辞敏感在工程上危害很大。你可以在评测集上调整几个字就让模型的“置信度”从 0.9 掉到 0.6。如果你在做基于阈值的路由这 0.3 的波动足以改变系统行为。4.2 上下文叠加与模式冲突当 LLM 被放置在一个很长的上下文中它的概率输出会受先前内容影响。比如在 RAG 场景下检索内容里有一段低质量文本模型对正确答案的概率可能被拉低。这种影响在贝叶斯框架里并不是完全不被允许的——证据变化后验自然变化——但问题在于LLM 对证据的“加权”方式没有经过概率规则的校准它只是根据语言模式对 token 概率做重分配容易夸大某些无关信息的影响。4.3 缺少全局归一化softmax 是逐位置做的局部归一化而不是对整个答案空间做归一化。因此当模型在不同轮次中生成答案 A 和答案 B 时这两个概率并不来自同一个概率空间无法直接比较。你可以在代码里比较 0.82 和 0.17但严格来说它们只是两个不同上下文上的条件概率对它们做减法和除法并没有概率论上的坚实基础。4.4 训练目标的频率偏差贝叶斯推断关心的是“基于证据的信念强度”而语言建模关心的是“文本 next-token 的预测准确性”。当语料中某个错误说法反复出现时模型会对其给出较高的条件概率。比如中文互联网上流传的一些伪科学内容模型完全可能在特定上下文下给它们较高概率这与证据强度没有关系。4.5 解码策略的干扰在实际推理中我们还会使用 temperature、top-k、top-p 等采样策略。这些策略会改变最终生成的概率分布让 logprob 更加不可比。哪怕 temperature0也常常因为解码器的实现细节出现多次运行结果不完全一致的情况。这些因素叠加在一起导致 LLM 的概率输出虽然在“局部”看起来像概率在“全局”层面却是支离破碎的。量化这种破碎程度就是本文后面要讲的“内部一致性量化”。5. 量化内部一致性的方法论如果我们要把“内部不一致”从一个感觉变成一个可测量的指标需要先定义清楚测什么、怎么测。5.1 语义等价扰动测试这是最直接的方法。选取一组逻辑上等价的提示比如“法国的首都是哪里”“哪个城市是法国的首都”“法国的首都叫什么”“Paris 是哪个国家的首都”反转主语把这些提示分别送入模型记录目标答案比如“巴黎”的 token 对数概率或归一化概率然后计算这组概率的均值、方差和最大差距。如果模型是贝叶斯一致的这组概率应该非常接近。方差越大、最大差距越大说明模型的信念越受表面措辞影响。5.2 条件概率约束测试设计一个逻辑关系链让模型分别评估P(运动员 | 足球运动员)P(足球运动员 | 运动员)P(足球运动员)P(运动员)然后检查这些概率是否满足边缘化或乘法法则的近似关系。虽然 LLM 只能输出条件概率无法直接给出可求和的全联合分布但我们可以计算一个“逻辑一致性分数”比如模型输出是否满足“P(运动员) P(足球运动员)”这种单调性约束。如果大量违反说明概率系统不具备基本的贝叶斯理性。5.3 排序循环一致性测试在 Agent 或推理链路里模型常常需要对多个实体做两两比较比如“A 大于 B”“B 大于 C”“C 大于 A”。如果模型对每对比较给出概率那么真实世界应该不存在循环。但 LLM 可能对“A B”给出 0.8对“B C”给出 0.9对“C A”也给出 0.7形成循环。这种测试不需要标准答案只需要检查输出的排序关系是否出现环。循环比例越高说明模型内部信念越是碎片化的局部判断。5.4 预测与解释一致性测试让模型先给出答案再要求它生成解释然后基于解释再次给出答案。如果模型真的是一个贝叶斯系统加入解释这种“证据”后答案概率应当向正确方向更新。但我们往往看到模型可能因为解释而改变答案甚至改变后的概率不再支持原来的判断。这种测试可以用来量化“自我一致性”和“证据使用合理性”。在实际工程中并不需要跑完所有测试。优先做语义等价扰动测试和排序循环一致性测试因为它们的计算成本低、自动化程度高适合作为持续回归指标。6. 一个最小量化实验的代码设计下面给出一个可复现的实验框架。整体思路是选一个开源模型定义一组等价提示计算目标答案的对数概率然后输出一致性子指标。6.1 环境准备建议使用 Python 3.9 或以上版本安装以下依赖pip install torch transformers如果你本机显存有限可以选用参数量较小的开源模型比如 7B 量级的 Qwen 或 Llama 系列量化加载亦可。版本以实际项目为准本文重点演示通用思路不限定具体版本。6.2 加载模型并定义概率计算函数下面代码以 Hugging Face Transformers 为例。这个函数接受一个提示文本和候选答案文本返回候选答案在提示后的平均条件对数概率。# 文件路径utils/logprob_utils.py import torch from transformers import AutoTokenizer, AutoModelForCausalLM tokenizer AutoTokenizer.from_pretrained(Qwen/Qwen2.5-7B-Instruct) model AutoModelForCausalLM.from_pretrained( Qwen/Qwen2.5-7B-Instruct, torch_dtypetorch.float16, device_mapauto ) def get_answer_logprob(prompt: str, answer: str) - float: 计算在 prompt 条件下生成 answer 的平均条件对数概率。 分数越高表示模型对答案的倾向性越强。 full_text prompt answer input_ids tokenizer(full_text, return_tensorspt).input_ids prompt_ids tokenizer(prompt, return_tensorspt).input_ids prompt_len prompt_ids.size(1) seq_ids input_ids[:, :] with torch.no_grad(): outputs model(input_idsseq_ids) # 对齐 token 位置每个位置的 logits 预测下一个 token logits outputs.logits[:, prompt_len - 1:-1, :] target_ids seq_ids[:, prompt_len:] log_probs torch.log_softmax(logits.float(), dim-1) token_log_probs log_probs.gather( dim-1, indextarget_ids.unsqueeze(-1) ).squeeze(-1) return token_log_probs.mean().item()这段代码的核心逻辑是把 prompt 和 answer 拼接成完整序列然后只取 answer 部分每个 token 位置的条件对数概率最后取平均。需要注意不同模型的 prompt 模板不同实际使用时建议按所选模型的官方 chat template 做拼接而不是直接字符串相加。上面代码是为了演示算法思路。如果你希望更贴近生产可以这样调用模型自带模板messages [{role: user, content: prompt}] model_inputs tokenizer.apply_chat_template( messages, add_generation_promptTrue, return_tensorspt ) prompt_len model_inputs.size(1) # 再拼上 answer 后重新计算6.3 定义等价提示集合下面这一步很关键。我们需要设计一组“语义等价但表面措辞不同”的提示。# 文件路径consistency_test.py prompts [ 法国的首都是哪里, 哪个城市是法国的首都, 法国的首都叫什么, 请写出法国的首都。, 认识法国的人都知道它的首都是, ] answer 巴黎 for i, prompt in enumerate(prompts): logprob get_answer_logprob(prompt, answer) print(fprompt_{i}: {logprob:.4f})运行后你会得到形如以下格式的输出prompt_0: -0.8234 prompt_1: -1.0210 prompt_2: -0.9542 prompt_3: -1.7865 prompt_4: -0.4102如果你把这组提示多次运行并计算最大值与最小值的差就得到“措辞分歧度”。差越大说明模型对同一事实的概率受表面形式影响越大。这里必须说明上面输出中的数值只是示例用于演示打印格式不是某个模型的真实评测结果。真实结果取决于所选模型、tokenizer 版本和提示拼接方式。6.4 循环一致性检测代码接下来设计一个循环一致性检测的小实验。假设我们让模型对三个关系陈述给出概率然后检查是否出现逻辑循环。# 文件路径cycle_test.py relations [ (A, B, 甲比乙高), (B, C, 乙比丙高), (C, A, 丙比甲高), ] def probability_of_true(statement: str) - float: prompt f请对以下陈述是否成立做出判断只回答成立或不成立。陈述{statement} true_logprob get_answer_logprob(prompt, 成立) false_logprob get_answer_logprob(prompt, 不成立) # 简单归一化示例实际上建议使用更稳健的方法 true_prob torch.exp(torch.tensor(true_logprob)) false_prob torch.exp(torch.tensor(false_logprob)) return (true_prob / (true_prob false_prob)).item() for x, y, stmt in relations: p probability_of_true(stmt) print(f{stmt}: {p:.3f})如果模型对三个陈述给出的概率都大于 0.5我们就观察到了一个“循环矛盾”。这种矛盾在严格逻辑中不可能出现。我们可以在多组三元关系上统计循环比例得到模型在排序任务上的“循环不一致率”。6.5 判断实验成功与否如果同一事实在等价提示下的概率差很小说明模型在这一局部具备较好的措辞不敏感性。如果概率差很大说明模型大概率学习了“措辞到答案”的映射而不是一个稳定的事实信念。如果循环不一致率较高说明模型在做两两比较时并没有维护一个全局一致的排序关系。这个实验没有“必须通过”的阈值更多是作为横向对比换一个模型、换一套提示就能看出不同模型在内部一致性上的差距。这也是做模型评测时容易被忽略的维度。7. 实践建议如何正确使用 LLM 概率既然 LLM 概率不是可靠的贝叶斯置信度那工程上应该怎么用这里有五条建议。7.1 不要用单个概率作为硬阈值在 RAG 或问答系统中拦一道“如果概率低于 0.7 就拒绝回答”的逻辑看起来合理实际很危险。因为同样的答案换个问法概率可能从 0.8 降到 0.5你的系统就会表现出完全不同的行为。更稳妥的做法是对同一问题生成多次采样基于多次输出做一致性投票self-consistency再用投票得到的多数一致度作为信号。7.2 用“概率”做粗筛不要做唯一依据概率可以用作候选答案排序的粗筛特征。比如检索器返回 20 个候选段落让 LLM 对每个段落生成答案再按答案概率排序把 top-3 进入下一阶段。但最终判断应由独立的验证器或规则完成。概率在这里只是一个信号不是金标准。7.3 对概率做校准如果确实需要输出置信度不要直接把 softmax 概率原样给用户。更好的做法是在一个验证集上学习一个校准函数把模型概率映射到真实准确率。这类校准层可以是简单的 Platt scaling也可以是一个小的逻辑回归模型。校准之后的概率虽然不能解决一致性问题但至少能更好地反映“模型回答正确的频率”。7.4 在 Agent 中引入不确定性状态Agent 通常会在每一步调用模型并获取概率但这个概率无法累积。一个更符合贝叶斯精神的做法是为 Agent 维护一个显式的信念状态belief state每执行一步动作就用新的证据更新这个信念状态而更新的规则由外部逻辑或验证工具提供。这样即便 LLM 给出的原始概率不一致Agent 的整体决策也能保持一定的全局一致性。7.5 把一致性测试纳入评测集做大模型评测时除了准确率、召回率还应该包括一致性维度。可以在你的评测流程中增加语义等价扰动测试和循环一致性测试把分数作为模型对比的一个维度。这能帮你发现那些“看起来强、实际概率脆”的模型。8. 常见误区和开放问题8.1 误区一低困惑度等于高可信度困惑度衡量的是模型对文本的拟合程度只要语料里充满了某种表达模型就会对它给出低困惑度。因此它不代表答案在真实世界中的正确程度。正确使用困惑度的方法是在同一模型、同一任务、同一提示格式下做相对比较而不是跨场景定义可靠度。8.2 误区二temperature0 保证输出稳定即使 temperature 取 0某些解码实现仍可能受批处理大小、并行策略影响给出不同结果。更关键的是temperature0 只是让解码过程更确定它不能消除模型内部概率本身的措辞敏感性。换句话说“每次输出都一样”和“信念一致”是两回事。8.3 误区三概率高就是逻辑上更正确LLM 的训练语料中错误的观点和事实也可能高频出现。模型给错误陈述高概率和模型“相信”它是两个层面的事。这个误区在 Agent 自评场景中最危险让模型自己判断自己的输出概率高不代表推理正确。8.4 开放问题什么条件下 LLM 可以近似视为贝叶斯系统如果我们给 LLM 增加外部验证机制、逻辑约束、校准层是否可以把它改造成一个工程上可用的一致性概率系统目前有一些研究方向比如在推理时对输出做贝叶斯后验模拟或者用逻辑约束器对模型概率做后处理。这些还处于探索阶段但对于构建可靠 Agent 非常重要。8.5 开放问题一致性是否有必要在所有场景里追求如果你只是做一个闲聊机器人概率不一致问题可以忽略。但在金融分析、医疗咨询、代码生成等高风险场景中概率的可靠性直接决定系统是否可用。关键判断是这个决策过程是否需要一个人为的、全局一致的信念状态。如果是就必须处理一致性问题。9. 实践中的最小行动清单如果要给出一条最可落地的行动建议我会说下次你在代码里写“如果 logprob 大于某个阈值就相信模型”之前先跑一遍等价提示扰动测试。设计 5 到 10 个同义问题看同一个答案的概率是否稳定。如果波动很大你需要的不是调阈值而是更换决策方案。具体可以做三件事在评测集里加入 paraphrase consistency 指标监控模型概率在不同表述下的稳定性。在 RAG 和 Agent 场景中用多次采样投票代替单次概率阈值。对需要对外输出的置信度加一层基于验证集的校准函数。这三件事都不复杂但能把“LLM 概率不可靠”这个抽象问题转化成可以度量、可以改进的工程任务。如果把大模型当作黑盒来用至少要让这个黑盒输出的数字对决策负责。量化内部一致性就是负责的第一步。
返回列表