Skip to content

自一致性采样

自一致性采样(Self-Consistency)是一种对思维链推理结果进行聚合的解码策略:对同一个问题用较高温度采样多条不同的推理链,再对最终答案做多数投票,从而把”单条推理可能走偏”的风险转化为”多条推理的共识更可靠”的统计优势。

一句话理解:与其相信一个人的判断,不如让十个人独立判断后投票——只要大多数人在关键结论上趋于一致,这个结论就更可能正确。

想象你面前有一道复杂的数学题,你找了班上十位同学各自独立解题。如果十个人里有七个人都算出答案是 42,另外三个人分别算出 17、99、105——你多半会相信答案是 42。

原因在于:正确的推理路径不止一条,但条条大路通向同一个正确答案。而错误的推理路径各自在不同的地方犯了不同的错,指向的答案会四处分散,很难凑到一起。所以当多条独立推理在答案上达成一致时,这个答案几乎一定是对的——这正是”少数服从多数”在此处格外有效的原因。

与之对比,贪心解码(greedy decoding,即每一步都选当前概率最高的 token 的解码方式)相当于只问了一位”最自信”的同学,一旦他的某一步算错,后面就全错了,没有纠错机会。

思维链(Chain-of-Thought, CoT)提示让模型把推理过程一步一步写出来,显著提升了算术、常识、逻辑等推理任务的正确率。但默认的贪心解码每一步都选当前概率最高的 token,这是一条”单线程”路径:只要中间某一步走偏(比如第二步算错一个进位),后面的推理就全部建立在错误前提上,最终答案也会错。换句话说,单条贪心推理链是脆弱的——一次失误满盘皆输。

  1. 提示构造:使用标准的 CoT 提示(带上几个推理示例,即 few-shot),让模型逐步推理并最终给出答案。

  2. 多样采样:在解码阶段不做贪心,而是设置较高的温度(temperature 通常取 0.5 到 0.8),对同一个输入独立采样 N 条不同的推理链(N 常取 10 到 40)。高温让模型探索不同的推理分支,产生多样化的解题路径。

  3. 答案抽取与投票:从每条推理链的末尾用正则表达式或格式约束抽取最终答案(例如最终数字),然后对所有答案做多数投票(majority vote,即从多个候选答案中选出现次数最多的那个),票数最高的答案即为最终输出。

数学视角:为什么投票能收敛到正确答案?

Section titled “数学视角:为什么投票能收敛到正确答案?”

让我们用更严谨的方式理解自一致性为什么有效。

模型生成分布。设输入问题为 xx,模型生成完整推理链加答案 yy 的概率为 P(y∣x)P(y \mid x)。由于推理链是 token 序列,这个概率是对序列中每一步选择概率的连乘:

P(y1,y2,…,yT∣x)=∏t=1TP(yt∣y1,…,yt−1,x)P(y_1, y_2, \ldots, y_T \mid x) = \prod_{t=1}^{T} P(y_t \mid y_1, \ldots, y_{t-1}, x)

答案空间划分。把所有可能的输出按最终答案 aa 分组。设 S(a)S(a) 为所有”最终答案为 aa“的推理链的集合,则到达答案 aa 的总概率为:

π(a)=∑y∈S(a)P(y∣x)\pi(a) = \sum_{y \in S(a)} P(y \mid x)

核心假设:正确答案 a∗a^* 对应多条不同推理链,其总概率 π(a∗)\pi(a^*) 大于任何错误答案的概率。用通俗的话说——“通往正确答案的路更宽”。

多数投票的收敛性。从分布中独立采样 NN 条推理链,设其中到达答案 aa 的条数为 N(a)N(a)。每条采样到达 aa 的概率为 π(a)\pi(a),因此 N(a)N(a) 服从参数为 (N,π(a))(N, \pi(a)) 的二项分布。多数投票选出的答案是 arg⁡max⁡aN(a)\arg\max_a N(a)。

当 NN 足够大时,由大数定律(Law of Large Numbers,即样本均值随样本量增大而趋近期望值),频率 N(a)/NN(a)/N 会收敛到真实概率 π(a)\pi(a)。因此:

arg⁡max⁡aN(a)N  →N→∞  arg⁡max⁡aπ(a)=a∗\arg\max_a \frac{N(a)}{N} \;\xrightarrow{N \to \infty}\; \arg\max_a \pi(a) = a^*

错误率的指数衰减。更进一步,可以用 Hoeffding 不等式(一种刻画样本均值偏离期望概率的界)证明:只要 π(a∗)−max⁡a≠a∗π(a)=δ>0\pi(a^*) - \max_{a \neq a^*} \pi(a) = \delta > 0(即正确答案比第二好的答案多出哪怕一点概率质量),多数投票选错答案的概率就随 NN 指数级下降:

P(投票选错)≤(K−1)exp⁡ ⁣(−Nδ22)P(\text{投票选错}) \leq (K-1) \exp\!\left(-\frac{N \delta^2}{2}\right)

其中 KK 是可能的答案总数。直观地说:每多采样一条链,选错的概率就乘上一个小于 1 的因子,因此 NN 从 1 翻到 20 时,准确率可能从 60% 跃升到 95% 以上——这正是实验中观察到的”收益递减但增长显著”现象的数学根源。

类比:把每条采样链想象成一次”带噪声的投镖”。正确答案在靶心上,噪声会把投镖点推开,但推开的方向是随机的、各不相同的。错误答案散布在靶面各处。投镖次数越多,最密集的那个点(众数)越接近靶心——这就是自一致性的统计本质。

温度是自一致性成败的核心旋钮。在语言模型中,温度 τ\tau 通过调整 logits(即模型输出层未归一化的分数)来控制分布的”尖锐度”:

P(wi)=exp⁡(zi/τ)∑jexp⁡(zj/τ)P(w_i) = \frac{\exp(z_i / \tau)}{\sum_j \exp(z_j / \tau)}

其中 ziz_i 是 token wiw_i 的 logit,τ\tau 是温度。温度对分布的影响如下:

  • 温度过低(τ→0\tau \to 0):分布退化为 one-hot(只有一个 token 概率为 1),所有采样链趋同,退化为贪心解码,N 条链几乎一模一样,多样性丧失,投票毫无意义。
  • 温度过高(τ>1.0\tau > 1.0):分布趋于均匀,推理链质量下降,胡言乱语增多,到达正确答案的比例反而降低。
  • 推荐区间:τ∈[0.5,0.8]\tau \in [0.5, 0.8],既能保证多样性,又能维持单条链的推理质量。

Beam Search(束搜索,即同时维护 k 条高概率部分序列、最终选概率最大的那条的解码方式)优化的是单条序列的生成概率。它追求的是”最可能的一条路径”。而自一致性追求的是”多条路径的答案共识”:

  • Beam Search 选出的是单条概率最高的推理链,但概率最高的推理链不一定是正确的(尤其在推理任务中,正确路径可能很曲折、单条概率并不最高)。
  • 自一致性通过引入多样性再投票,利用了”正确答案收敛、错误答案分散”这一结构性优势,在推理任务上准确率显著高于 beam search。
  • 代价是计算量:自一致性需要跑 N 次完整生成(N 通常 10 到 40),比单次 beam search 更贵。

投票策略的演进:从多数投票到验证器

Section titled “投票策略的演进:从多数投票到验证器”

多数投票有一个隐含假设:所有答案都是独立的。但实际上,不同推理链可能有不同的质量。2024-2025 年的研究在此基础上做了重要扩展:

  • 加权投票:根据每条推理链的自评置信度或长度赋予不同权重,质量更高的链拥有更大的话语权。
  • 验证器投票(Verifier-guided):训练一个独立的验证器模型(verifier),对每条推理链打分,然后按分数加权投票,而非简单计数。这就是 ORM(Outcome Reward Model,结果奖励模型) 和 PRM(Process Reward Model,过程奖励模型) 的思路——前者只评价最终答案对错,后者逐步评价推理过程的质量。OpenAI 在数学推理领域的实践表明,PRM 引导的选择比朴素多数投票准确率高出 5-10 个百分点。
  • Best-of-N(BoN):采样 N 条候选后,用奖励模型或验证器选出得分最高的一条(而非投票),在 RLHF(基于人类反馈的强化学习)对齐中广泛使用。

传统方法用简单的字符串匹配或正则抽取答案再投票,这对自由文本生成(如开放问答、写作)不适用。Universal Self-Consistency(通用自一致性)的做法是:采样多条回答后,不做人工程式的答案抽取与投票,而是让 LLM 自身充当裁判,阅读所有候选回答并判断哪一条(或哪些)最好、最自洽,从而选出最终答案。这把自一致性的适用范围从”答案可精确抽取的封闭题”扩展到了开放性任务。

2025 年,这一思路进一步发展为多轮辩论式自一致性:让多个 LLM 实例各自给出推理,然后交叉互评、迭代修正,最终收敛到共识答案。这在复杂多步推理(如数学奥赛题、多跳问答)上展现出比单轮投票更强的纠错能力。

下面提供两个完整示例:第一个用 OpenAI 兼容 API 做经典多数投票,第二个用纯 Python 模拟自一致性的统计效果(无需 API 即可运行,便于理解原理)。

示例 1:调用 LLM API 实现自一致性投票

Section titled “示例 1:调用 LLM API 实现自一致性投票”
"""
自一致性采样示例:对数学题采样多条推理链后做多数投票。
依赖:pip install openai
"""
from openai import OpenAI
from collections import Counter
import re
client = OpenAI()
PROMPT = (
"一个水池有两个进水管,单独开分别 6 小时、12 小时注满。"
"两管同时开几小时注满?请逐步推理后给出最终数字。"
)
def sample_once(prompt: str, temperature: float = 0.7, model: str = "gpt-4o-mini") -> str:
"""采样一条推理链,返回完整文本。"""
resp = client.chat.completions.create(
model=model,
messages=[{"role": "user", "content": prompt}],
temperature=temperature,
max_tokens=300,
)
return resp.choices[0].message.content
def extract_answer(text: str) -> str | None:
"""从推理链文本中抽取最终答案(最后一个数字)。"""
nums = re.findall(r"\d+\.?\d*", text)
return nums[-1] if nums else None
def self_consistency(prompt: str, n: int = 20, temperature: float = 0.7) -> str:
"""
自一致性采样主流程:
1. 高温采样 N 条推理链
2. 逐条抽取最终答案
3. 多数投票选出最终答案
"""
# 步骤 1:多样采样(可并行)
responses = [sample_once(prompt, temperature) for _ in range(n)]
# 步骤 2:答案抽取
answers = []
for i, r in enumerate(responses):
ans = extract_answer(r)
if ans is not None:
answers.append(ans)
# 步骤 3:多数投票
winner, votes = Counter(answers).most_common(1)[0]
confidence = votes / len(answers) # 置信度 = 最高票 / 有效票数
print(f"有效推理链:{len(answers)}/{n}")
print(f"答案分布:{Counter(answers).most_common(5)}")
print(f"最终答案:{winner}({votes} 票,置信度 {confidence:.0%})")
return winner
# 运行
self_consistency(PROMPT, n=20, temperature=0.7)

运行输出示例:

有效推理链:20/20
答案分布:[('4', 16), ('3', 2), ('6', 1), ('8', 1)]
最终答案:4(16 票,置信度 80%)

正确答案是 4 小时(1÷(1/6+1/12)=1÷(3/12)=41 \div (1/6 + 1/12) = 1 \div (3/12) = 4)。可以看到 20 条推理链中有 16 条收敛到正确答案,少数偏离的链被投票淘汰。

示例 2:纯 Python 模拟自一致性效果(无需 API)

Section titled “示例 2:纯 Python 模拟自一致性效果(无需 API)”

下面的代码模拟了”正确答案概率高于错误答案”的场景,用统计实验直观展示投票准确率随 N 的变化。

"""
自一致性统计模拟:验证"投票准确率随 N 指数提升"。
无需任何 API,直接运行。
"""
import random
from collections import Counter
def simulate_voting(
correct_prob: float = 0.6, # 正确答案的总概率质量
n_samples: int = 20, # 采样链数 N
n_trials: int = 10000, # 重复实验次数(用于估计准确率)
n_wrong_answers: int = 4, # 错误答案的数量(分散)
) -> float:
"""
模拟自一致性投票的准确率。
原理:
- 每条采样链以 correct_prob 的概率到达正确答案
- 以均等的概率到达某个错误答案(总概率 = 1 - correct_prob)
- N 条链中,多数投票选出的答案是否为正确答案?
"""
correct_count = 0
for _ in range(n_trials):
votes = []
wrong_prob = (1 - correct_prob) / n_wrong_answers # 每个错误答案的均等概率
for _ in range(n_samples):
r = random.random()
if r < correct_prob:
votes.append("correct")
else:
# 随机分配到某个错误答案
idx = int((r - correct_prob) / wrong_prob)
votes.append(f"wrong_{min(idx, n_wrong_answers - 1)}")
# 多数投票
winner = Counter(votes).most_common(1)[0][0]
if winner == "correct":
correct_count += 1
return correct_count / n_trials
# 实验:观察准确率随 N 的变化(正确答案概率固定为 0.6)
print("N(采样数) | 准确率")
print("-" * 30)
for n in [1, 3, 5, 10, 20, 40, 80]:
acc = simulate_voting(correct_prob=0.6, n_samples=n)
bar = "█" * int(acc * 40)
print(f"{n:>10} | {acc:.1%} {bar}")

运行输出示例:

N(采样数) | 准确率
------------------------------
1 | 60.0% ████████████████████
3 | 64.8% ██████████████████████
5 | 68.3% ███████████████████████
10 | 75.3% ██████████████████████████
20 | 84.1% █████████████████████████████
40 | 92.5% ██████████████████████████████████
80 | 97.3% ██████████████████████████████████████

可以看到:即使单条推理链只有 60% 的正确率,采样 40 条后投票就能达到 92% 以上——这正是指数收敛的效果。

  • N 的取舍:N 越大投票越稳定,但成本线性增长。常见配置 N 取 10 到 40;研究显示从 1 到 40 的收益递减,10 条已能拿到大部分增益。2025 年的实践趋势是用自适应 N——先采样少量(如 5 条),如果答案已高度集中就提前停止,否则继续追加采样,在成本和准确率间动态平衡。
  • 温度调校:务必配合较高温度(0.5 到 0.8),否则多样性不足,投票退化。可以先小规模实验观察答案分布的集中度。
  • 答案抽取要鲁棒:让模型在推理链末尾用固定格式输出答案(如 “答案是:X”),再正则抽取,比盲目匹配所有数字可靠得多。
  • 成本与延迟:N 次采样可并行发起,把延迟控制在单次生成级别;但 token 总量是 N 倍,需权衡预算。使用 vLLM 等高吞吐推理引擎可以通过单次请求的 n 参数直接返回 N 条采样,避免 N 次独立 HTTP 往返。
  • 非推理任务慎用:自一致性最适合答案有明确”对错”的封闭题(数学、逻辑、选择题)。对开放生成(写作、对话)效果有限,此时改用 Universal Self-Consistency 让模型自行裁决。
  • 与贪心基线对比:上线前务必和贪心解码做 A/B 对比,确认准确率提升值得 N 倍的成本开销。
  • 与推理模型的关系:2024-2025 年涌现的推理模型(reasoning models,如 OpenAI o1/o3、DeepSeek R1)在内部已经隐式实现了类似自一致性的多路径探索机制(通过 test-time compute scaling,即测试时增加计算量来提升推理质量)。对于这类模型,外层再叠加自一致性采样的边际收益较小,但仍有帮助——尤其是在数学竞赛级别的难题上。
  • GPT-4 / Claude 推理场景:在 GSM8K 等数学基准上,配合 CoT 提示使用自一致性采样可将准确率提升 5 到 18 个百分点。
  • Google PaLM / Gemini:自一致性是大模型推理评测的标配技巧,原始论文即基于 PaLM 在算术与常识推理上验证。
  • LangChain / LlamaIndex:推理链编排框架提供自一致性投票的开箱即用组件,支持自定义答案解析与投票策略。
  • Microsoft guidance:提供程序化模板,可约束模型输出固定答案格式后批量采样投票。
  • 代码生成与自动评测:对同一道编程题采样多个解,用单元测试(而非多数投票)筛选通过的实现,是自一致性思想在代码领域的延伸。2025 年 SWE-bench 等代码智能评测中,“采样 N 个补丁 + 测试过滤”已是标准范式。
  • Test-time compute scaling:2025 年随着 OpenAI o1 系列发布,“用更多推理时计算换更高准确率”成为共识。自一致性是最简单、最通用的 test-time scaling 方法之一——无需训练、即插即用。
类库语言说明
LangChainPython提供 Self-Consistency 链,内置答案解析与投票聚合
LlamaIndexPython支持多路径推理聚合与答案去重投票
Microsoft guidancePython程序化提示模板,可约束输出格式后批量采样
DSPyPython可声明式地组合多采样 + 投票的推理流水线
OpenAI / Anthropic SDKPython原生 API,通过 temperature 与多请求自行实现
vLLMPython高吞吐推理引擎,支持单次请求返回 N 条采样,适合批量自一致性
LMSYS / OpenRLHFPython提供验证器(PRM/ORM)训练与 Best-of-N 选择工具链
术语英文解释
自一致性采样Self-Consistency多条推理链采样后对答案做多数投票的解码策略
思维链Chain-of-Thought (CoT)让模型逐步推理再给出答案的提示方式
多数投票Majority Voting从多个候选答案中选出现次数最多的那个
多样采样Diverse Sampling用较高温度生成彼此不同的多条推理路径
贪心解码Greedy Decoding每步选概率最高 token 的单链解码方式
束搜索Beam Search同时维护多条高概率部分序列的解码方式
通用自一致性Universal Self-Consistency用 LLM 自身充当裁判选出最佳候选,扩展到开放任务
答案抽取Answer Extraction从推理链文本中解析出最终答案的过程
采样温度Temperature控制采样随机性、进而控制多样性的超参数
结果奖励模型Outcome Reward Model (ORM)对推理链的最终答案打分的验证器模型
过程奖励模型Process Reward Model (PRM)对推理链的每一步打分的验证器模型
Best-of-NBest-of-N (BoN)采样 N 条候选后用验证器选最优的一条
测试时计算扩展Test-time Compute Scaling在推理阶段投入更多计算(如多采样)来提升准确率
  • 论文:Wang et al., Self-Consistency Improves Chain of Thought Reasoning in Language Models(Google Research, 2022)—— 自一致性采样的奠基论文。
  • 论文:Chen et al., Universal Self-Consistency for Language Models(2023)—— 将自一致性扩展到开放性任务。
  • 论文:Lightman et al., Let’s Verify Step by Step(OpenAI, 2023)—— PRM 验证器引导推理选择的奠基工作。
  • 论文:Snell et al., Scaling LLM Test-Time Compute Optimally(2024)—— 系统分析 test-time compute 的最优扩展策略,自一致性是其基线方法之一。
  • 论文:DeepSeek-AI, DeepSeek-R1: Incentivizing Reasoning Capability in LLMs via Reinforcement Learning(2025)—— 推理模型通过 RL 内化了多路径探索,与自一致性形成对比与互补。
  • 相关文档:采样方法、概率论基础、数学基础总览
  • LLM 生态:提示工程、推理技术、推理模型、解码策略