
最近在评估一个基于大语言模型LLM的概率输出时我总是会遇到一种很微妙的“别扭感”同一个逻辑事实换一种说法去问模型给出的“是”或“否”概率经常明显跳变同一个条件概率关系从左往右问和从右往左问结果也很难对得上。如果 LLM 真的像很多人说的那样是在“学习世界模型”那它的概率信念应该具备某种稳定性给定同样的证据无论用什么自然语言去表达模型对同一件事的相信程度都应当保持一致。更进一步如果这个模型是一个“贝叶斯式”的智能体那它的概率判断还应该满足最基本的概率公理比如条件概率关系、边际化规则和贝叶斯更新公式。但现实并非如此。这篇文章就想把这件事讲清楚LLM 给出的概率到底意味着什么为什么说它并非始终符合贝叶斯以及当我们需要量化模型的“概率信念内部一致性”时应该设计哪些实验写哪些代码看哪些指标。文章会提供一个基于 HuggingFace Transformers 的最小评估框架帮助你对自己的模型做一次“概率信念审计”。1. 背景当 LLM 输出概率时我们到底在信什么1.1 一个常见的工程场景在做问答系统、意图识别、Agent 决策或者 RAG 检索增强时很多开发者会习惯性地使用模型中某个答案的概率作为“置信度”。比如意图识别模型输出“查询天气”的概率为 0.93于是我们认为它有 93% 的把握。问答拒答模型输出答案 token 的平均 logprob 很低于是我们让系统回答“不确定”。RAG 路由模型给出“需要检索”的概率为 0.87于是我们决定调用检索模块。这套做法看起来很有道理因为 LLM 的最后一层确实输出了一个概率分布softmax 之后所有 token 的概率之和为 1。但问题在于这个概率是词表中下一个 token 的概率并不是外部世界中某个命题为真的概率。更严格地说LLM 天生是一个自回归语言模型它建模的是 token 序列的条件分布P(x_t | x_t)而不是一个关于世界状态的贝叶斯信念网络。这两者之间的差距正是很多概率类应用在真实场景中失灵的根本原因。1.2 贝叶斯视角下的“概率信念”贝叶斯概率观把概率解释为“信念度”。一个人或一个理想智能体对某个命题 A 的相信程度会随着新证据 E 的出现而更新更新的方式要遵循贝叶斯公式P(A | E) P(E | A) * P(A) / P(E)一个理性的智能体其概率判断应当满足一致性coherence。在有限场景下这意味着对互斥且完备的事件概率之和等于 1。联合概率等于条件概率与边缘概率的乘积P(A ∧ B) P(A | B) * P(B)。当条件关系成立时P(B | A)与P(¬B | A)之和等于 1。这些规则并不是贝叶斯学派独有的数学装饰而是概率论的基本公理。如果一个系统自称具备“概率信念”那么它的概率输出就应当满足这些基本约束。1.3 本文要解决的问题本文要解决的核心问题其实可以拆成三层概念层LLM 输出的 softmax 概率和贝叶斯概率信念是不是一回事如果不是差在哪里实验层如何设计一套可量化的实验来测出 LLM 概率信念的内部一致性得分工程层在真实系统中我们应该如何对待 LLM 输出概率避免被“假置信度”误导下面我会逐一展开。2. 理解 LLM 概率与贝叶斯信念之间的概念鸿沟2.1 LLM 给出的概率究竟是什么现代大语言模型的核心结构是 Transformer Decoder。在训练阶段模型要做的事情是给定前文x_1, x_2, ..., x_{t-1}预测下一个 token 的概率分布P(x_t | x_1, ..., x_{t-1})当模型生成一句完整的回答时整句话的概率是每个 token 条件概率的乘积P(sentence) Π P(x_t | x_t)这就是 LLM 提供的“原生概率”。它完全来自模型参数对训练数据的拟合本质上是模型在 token 序列空间中学到的统计规律。你向模型追问“这个回答有多确定”时你得到的往往并不是模型对命题真值的判断而是它对“在给定上下文后下一个词是某个 token”的预测。2.2 贝叶斯概率信念要求什么贝叶斯概率信念是站在“世界状态”层面讲的。比如“明天杭州下雨的概率是 70%”这个概率描述的是外部世界的不确定性而不是语言序列的不确定性。要让 LLM 的 token 概率等价于命题真值概率需要满足一个很强的假设模型已经对世界状态形成了内部表征并且 token 空间的概率分布忠实地映射了该表征上的信念。这在很多简单场景下是近似成立的但对于复杂事实、反事实推理、多步逻辑推理这种映射关系会明显松动。2.3 两者相通的理想条件在一些受限场景下LLM 概率确实可以近似当作贝叶斯信念使用。例如事实知识问题“中国的首都是哪个城市”常识判断“糖放到水里会发生什么”单一维度的偏好“用户更喜欢价格便宜还是性能高的手机”在这些场景中模型见过大量相关语料其 token 概率分布会被语料中的共识强烈约束。于是正确答案对应的 token 概率会明显偏高“是”和“否”的概率分布也相对稳定。2.4 为什么理想条件在实践中被打破一旦离开上述理想场景问题就来了。模型不是一个显式的概率图模型它没有维护一个“世界状态变量集合”也没有执行真正的贝叶斯更新。它的输出概率是数百万条参数和注意力路径共同作用的结果其中既包括事实知识也包含语言风格、数据频率、位置偏差、措辞偏好等因素。这导致同一个概率判断会随着问题措辞、选项顺序、上下文窗口、甚至解码超参数的变化而发生漂移。用一句话概括LLM 的 token 概率只是一个“看起来像概率”的数字它在语言分布层面是自洽的但在世界信念层面未必自洽。3. 影响 LLM 概率信念一致性的主要因素3.1 预训练目标并不包含概率校准LLM 预训练阶段的核心目标函数是下一个 token 预测的交叉熵损失。这个目标函数并不要求模型对“命题是否为真”给出校准的概率估计。它只要求模型能够根据上下文预测最可能的 token 序列。换句话说模型在训练阶段根本没有见过类似这样的监督信号“命题 A 的真实概率是 0.8请输出 0.8”。因此我们没有理由相信模型输出的概率天然对应真实频率。这一点在大量模型中已经被反复验证很多模型的 top-1 token 准确率很高但概率值存在系统性高估或低估。这不是某个模型的 bug而是预训练目标本身的特性。3.2 解码与采样策略对概率的扭曲当我们通过 API 或本地推理拿到一个 token 的概率时这个概率可能已经被解码策略改变了。常见的干扰包括temperature 缩放temperature0.8或temperature1.2会直接改变 softmax 的平滑程度概率值会整体改变。top-k / top-p 截断在采样过程中低概率 token 会被过滤这会影响最终候选分布。repetition penalty许多框架默认开启重复惩罚这会压低已经出现过的 token 的概率同样改变分布。因此即便是同一个模型、同一个 prompt在不同解码参数下得到的概率也不一样。严格来说我们真正关心的应该是模型在默认 forward 时输出的原始 logits而不是经过采样或惩罚后的分布。3.3 提示表面形式导致的信念漂移这是最容易被忽视却影响最大的因素。同一个逻辑命题用不同语言风格提问模型的概率输出可能相差很大。比如“请判断这句话是否正确北京是中国的首都。”“Is the following statement true? Beijing is the capital of China.”“根据常识判断北京是中国的首都。对不对”三种问法在语义上完全等价但由于 token 路径不同模型内部激活模式也不同最终“是”这个 token 的概率会有明显波动。这种“表面形式敏感性”是 LLM 概率信念不一致的一个核心来源。它说明模型并不是像贝叶斯智能体那样先提取命题的语义再独立计算概率而是每一步都受语言形式影响。3.4 后训练对齐改变概率分布指令微调和 RLHF基于人类反馈的强化学习会显著改变模型的输出分布。对齐训练的目标是让模型更符合人类偏好但“符合人类偏好”和“概率更准确”是两回事。模型可能学会更容易输出“是”而不是“否”。更容易给出确定性的回答抑制不确定性表达。在无法回答时倾向于用合理而非真实的措辞。这会导致模型在微调后的概率分布偏离它在预训练阶段学到的自然统计分布。结果是一个常识问题可能得到很高的“是”概率但这个概率并不可靠。4. 量化内部一致性的四种实验设计4.1 重复涌现性测试这个测试最直观用多组语义相同、表面形式不同的 prompt 询问同一个命题计算模型给出同一答案 token 的概率。如果模型具备稳定的概率信念那么不同模板得到的概率应该接近。如果概率波动很大说明模型信念不稳定。指标可以定义为概率均值mean_p概率标准差std_p最大值与最小值的差值range_p4.2 条件概率链式法则测试概率论中有一条基本法则P(A ∧ B) P(A | B) * P(B)我们可以在 prompt 中分别构造 A、B 两个命题然后询问“A 和 B 都为真”的概率。“B 为真”的概率。“已知 B 为真A 为真”的概率。如果模型符合贝叶斯一致性那么第一次得到的概率应约等于后两次概率的乘积。偏差越大说明模型内部概率越不自洽。4.3 贝叶斯更新测试这个测试模拟经典的先验-似然-后验流程。假设我们有一个假设 H 和一个证据 E。贝叶斯公式要求P(H | E) P(E | H) * P(H) / P(E)我们可以分别设计四个 prompt询问先验概率P(H)询问似然P(E | H)询问边缘概率P(E)询问后验P(H | E)然后比较模型直接给出的后验概率与根据公式计算出的后验概率之间的差距。由于 LLM 对“概率”这个词的理解会受到语义干扰这个实验的设计需要小心最好使用明确的二选一事件并给出“只回答是或否”的指令。4.4 互斥事件边际化测试构造两个互斥且完备的事件 A 和 ¬A比如A“掷出一个骰子点数是偶数。”¬A“掷出一个骰子点数不是偶数。”显然两者概率之和应当等于 1。我们可以分别向模型询问这两个事件的概率然后计算它们的和与 1 的偏差。如果偏差很大说明模型的概率判断并不满足最基本的“互补”约束。5. 完整代码示例最小一致性评估框架下面我们用一个最小可运行的 Python 示例演示如何对本地 HuggingFace 模型做上述一致性测试。5.1 环境准备与模型加载建议环境Python 3.10 或更高版本。PyTorch 2.x。Transformers 4.40 以上版本。本地 GPU显存 8GB 以上如果没有 GPU可以用 CPU 跑小模型。示例依赖pip install torch transformers加载模型时我们需要获取原始 logits所以这里直接使用AutoModelForCausalLM。import torch from transformers import AutoTokenizer, AutoModelForCausalLM model_path your-model-path # 替换为你的模型路径或 HuggingFace 模型 ID tokenizer AutoTokenizer.from_pretrained(model_path, trust_remote_codeTrue) model AutoModelForCausalLM.from_pretrained( model_path, torch_dtypetorch.float16, device_mapauto, trust_remote_codeTrue ) model.eval()注意如果你访问的是 gated 模型需要提前登录或配置 token。trust_remote_codeTrue仅当模型仓库明确要求时才需要开启。建议先使用小模型跑通流程再切换到目标大模型。5.2 获取指定答案序列的概率为了兼容多 token 答案我们实现一个函数给定前缀文本和候选答案文本返回该答案在模型自回归分布下的完整概率。import math def compute_sequence_prob(prefix_text: str, option_text: str) - float: 计算 prefix_text 后面接 option_text 的生成概率。 返回值为概率值介于 0 到 1 之间。 prefix_ids tokenizer(prefix_text, add_special_tokensFalse)[input_ids] option_ids tokenizer(option_text, add_special_tokensFalse)[input_ids] full_ids prefix_ids option_ids input_len len(prefix_ids) inputs torch.tensor([full_ids], devicemodel.device) with torch.no_grad(): outputs model(inputs) logits outputs.logits[0] # shape: [seq_len, vocab_size] log_prob_sum 0.0 for i in range(input_len, len(full_ids)): # logits[i-1] 表示预测第 i 个 token 的分布 cur_logits logits[i - 1] token_id full_ids[i] log_prob torch.log_softmax(cur_logits, dim-1)[token_id].item() log_prob_sum log_prob return math.exp(log_prob_sum)这里有一个很重要的细节我们并没有调用model.generate()而是直接把prefix option拼起来做一次前向传播。对于自回归模型这个结果等价于逐 token 生成该答案的联合概率并且只需要一次 forward效率更高。5.3 提示模板敏感性测试我们要构造多个语义相同、表面形式不同的模板然后比较同一命题的概率波动。TEMPLATES [ 根据你的知识下面的陈述正确吗陈述{statement} 请回答是或否。, 请判断这句话的真假{statement}。只回答是或否。, 请给下面陈述打一个真假标签{statement} 输出是或否。, ] def evaluate_prompt_sensitivity(statement: str, option: str 是): 用多个模板询问同一个命题返回所有概率值、均值和标准差。 probs [] for template in TEMPLATES: prompt template.format(statementstatement) prob compute_sequence_prob(prompt, option) probs.append(prob) print(f[模板] {prompt}) print(f[概率] P({option}) {prob:.4f}\n) mean_p sum(probs) / len(probs) std_p (sum((p - mean_p) ** 2 for p in probs) / len(probs)) ** 0.5 return probs, mean_p, std_p运行示例statement 北京是中国的首都 probs, mean_p, std_p evaluate_prompt_sensitivity(statement, 是) print(f平均概率: {mean_p:.4f}) print(f标准差: {std_p:.4f})如果标准差很大说明模型对这个命题的概率信念受 prompt 模板影响明显。5.4 条件概率一致性测试下面实现一个条件概率链式法则测试def evaluate_chain_rule(event_a: str, event_b: str): 比较 P(A and B) 与 P(A | B) * P(B) 的差异。 prompt_and ( f下面两个事件都为真的概率是多少\n f事件A{event_a}\n f事件B{event_b}\n f只回答“是”或“否”。 ) prompt_b ( f事件B{event_b}\n f请判断事件B是否为真。只回答“是”或“否”。 ) prompt_a_given_b ( f已知事件B为真{event_b}\n f请判断事件A是否为真{event_a}\n f只回答“是”或“否”。 ) p_and compute_sequence_prob(prompt_and, 是) p_b compute_sequence_prob(prompt_b, 是) p_a_given_b compute_sequence_prob(prompt_a_given_b, 是) left_side p_and right_side p_a_given_b * p_b print(fP(A and B) {left_side:.4f}) print(fP(A | B) * P(B) {right_side:.4f}) print(f绝对偏差 {abs(left_side - right_side):.4f})这里需要说明的是LLM 对“事件为真”这类抽象问题的理解方式并不完全等同于概率论中的事件因此本测试更像一种压力测试用来观察模型是否存在明显的概率公理违背。5.5 运行结果解读我这里不贴具体模型输出因为不同模型、不同版本、不同 prompt 模板都会得到不同结果。重点是你运行后可能会观察到的现象概率均值可能正常但每个模板之间的方差很大。P(A and B)与P(A | B) * P(B)的比例可能明显偏离 1。对于同一逻辑关系正向询问和反向询问的结果差异明显。这些现象就是“概率信念内部不一致”的直接量化证据。6. 结果分析与可视化思路6.1 一致性指标设计为了更系统地评估模型可以定义几个综合指标。表面波动指数Surface Sensitivity IndexSSI std(P)其中P是同一命题在不同模板下得到的概率集合。SSI 越大说明概率越依赖表面形式。链式规则违背度Chain Rule ViolationCRV |P(A ∧ B) - P(A | B) * P(B)|取值越大说明模型越不满足最基本的概率乘积法则。互补违背度Complement ViolationCV |P(A) P(¬A) - 1|用来衡量模型对互斥事件的概率判断是否矛盾。6.2 如何判断模型是否“贝叶斯一致”严格来说我们不可能通过几个实验断定一个模型“完全不是贝叶斯”只能说它在某些设定下偏离了贝叶斯一致性。一个比较实用的判断方法是设置一个合理性阈值如果 SSI 小于 0.05可以认为概率对模板不敏感。如果 CRV 与 CV 小于 0.1可以认为概率公理近似成立。如果指标明显超过上述阈值就需要对模型的概率输出保持警惕。需要注意这些阈值并不是绝对标准具体场景需要结合任务风险来设定。6.3 可视化建议如果你想把结果放到论文或技术报告中可以考虑画三张图同一命题在不同模板下的概率柱状图直观展示波动。链式法则左右两侧的散点图横轴是P(A | B) * P(B)纵轴是P(A ∧ B)如果模型一致点应该分布在对角线附近。互斥事件概率之和的分布直方图看峰值是否在 1.0 附近。由于这里不允许使用 Mermaid我只给出工具建议使用 matplotlib 或 seaborn 即可完成上述可视化。7. 常见问题与排查思路在实际运行一致性评估代码时你会遇到很多细节问题。下面整理了一份高频问题清单。问题现象常见原因解决思路相同 prompt 多次运行得到不同概率模型处于采样模式或框架随机性未固定设置do_sampleFalse、固定随机种子“是”和“否”的概率之和不等于 1模型中存在空格、换行等额外 token检查候选 token 是否完整覆盖所有可能输出换一个模板概率就从 0.9 变成 0.4模型对表面形式敏感这是常见现象使用多模板均值而非单次概率fp16/bf16 下概率和 fp32 不一致低精度计算导致 logits 微小波动评估一致性时统一精度本地模型和 API 模型概率差异大模型版本、量化、prompt 模板不同固定模型版本后重新测量条件概率测试偏差极大模型无法理解“事件为真”的抽象设定换用更具体的自然语言场景还有一个容易被忽视的坑compute_sequence_prob计算的是完整候选文本的联合概率但很多 API 返回的logprobs只提供每个 token 的独立 logprob两者计算方式可能不同。如果你做复现务必确认口径。8. 工程实践建议如何在真实系统中使用 LLM 概率8.1 不要把 softmax 概率直接当置信度这是最重要的一条建议。即使一个模型输出“是”的概率是 0.95也不意味着它在真实世界中有 95% 的把握。这个 0.95 可能只是模型在 token 分布层面的偏好而不是经过校准的信信念度。在风险较高的场景比如医疗建议、法律咨询、金融决策千万不要单独依赖概率阈值做自动决策。8.2 用自洽性采样提升稳定性与其相信单次输出的概率不如让模型多次采样然后看答案的统计一致性。这种方法在业界被称为 Self-Consistency。具体做法是对同一问题执行多次采样例如 5 到 10 次。统计不同答案出现的频率。用答案的频率代替单次生成概率作为置信度的参考。这样虽然不能从根本上解决贝叶斯不一致问题但能显著降低偶然性波动对决策的影响。8.3 在 RAG 和 Agent 场景中的应用在 RAG 场景中不要用“回答 token 的概率”来判断是否触发检索。更好的做法是结合检索结果和原始问题让模型输出“证据是否充分”的二分类判断。对多个检索片段分别生成答案再用投票方式选最终答案。如果候选答案之间冲突明显触发澄清或转人工。在 Agent 场景中概率可以用来做“低置信度回退”但最好加一个“重试换模板”的环节。例如如果模型对工具调用的置信度低于阈值可以换一种表达方式重新询问避免因措辞导致误判。8.4 关注量化精度与概率稳定性很多开发者为了节省显存会把模型量化为 fp16、bf16 甚至 int8。大部分场景下量化对最终答案的影响很小但对低概率区域的 logits 影响会被放大。如果你需要用概率值做精细决策建议保持候选答案的 token 数量一致。使用相同精度进行对比实验。在发布前做一次概率一致性的基线测量。9. 总结与学习路线这篇文章从概念、原因、实验、代码和工程实践五个层面拆解了“LLM 并非始终符合贝叶斯”这个问题。核心可以总结为三点第一LLM 输出的概率本质是 token 序列的条件概率它不等于对世界命题的贝叶斯信念度两者之间存在概念鸿沟。第二由于预训练目标、解码策略、提示模板、后训练对齐等因素LLM 的概率信念在内部一致性上往往表现不佳。通过换模板、链式法则、互补检验等方法可以量化这种不一致。第三在工程系统中我们不能把 softmax 概率直接当作置信度使用而应结合多次采样、候选投票、人工回退等机制降低概率不稳定带来的风险。如果你想继续深入学习有几个方向值得关注概率校准了解 temperature scaling、Platt scaling 等校准方法。采样一致性阅读 Self-Consistency 相关论文理解多次采样为什么能提升推理准确率。贝叶斯深度学习研究模型不确定性估计的深度学习方法为 LLM 概率输出寻找更好的理论框架。最后建议你动手做一次实验选一个你常用的模型用本文提供的最小评估框架跑一遍记录下同一命题在不同模板下的概率波动。很多时候对模型概率的“直觉不信任”会在这些数字面前变成具体的、可量化的证据。测试脚本先用小模型跑通流程再切换到目标模型上做完整审计你会得到一份属于自己的“模型概率信念体检报告”。