推理时扩展深度解析:Test-Time Scaling 的理论与实践

5620 字
28 分钟
推理时扩展深度解析:Test-Time Scaling 的理论与实践

1. 引言:训练的局限与推理的潜力#

1.1 预训练 Scaling 的瓶颈#

传统的 LLM 能力提升依赖预训练阶段的 scaling laws:

预训练 Scaling Laws:
能力 ∝ 模型参数量 × 训练tokens × 计算量
历史数据:
┌─────────────────────────────────────────────────────────┐
│ GPT-2 (1.5B) 训练 tokens ~ 10^9 │
│ GPT-3 (175B) 训练 tokens ~ 10^11 │
│ PaLM (540B) 训练 tokens ~ 10^12 │
│ GPT-4 (估计) 训练 tokens ~ 10^13+ │
└─────────────────────────────────────────────────────────┘
问题:
→ 高质量数据日益稀缺
→ 训练成本指数增长
→ 边际收益递减
→ 模型能力在某些任务上仍有上限

1.2 推理时扩展的崛起#

Test-Time Scaling(推理时扩展)提供了一条新路径:

┌─────────────────────────────────────────────────────────────┐
│ 推理时扩展的核心思想 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 传统观点: │
│ "模型能力由训练决定,推理只是执行" │
│ │
│ 新观点: │
│ "推理时也可以投入计算来提升答案质量" │
│ │
│ 类比: │
│ → 训练 = 写代码时编译一次 │
│ → 推理 = 运行时可以多次迭代优化 │
│ │
│ 核心公式: │
│ │
│ 能力 = f(训练计算量, 推理计算量) │
│ │
│ 关键洞察: │
│ → 增加推理时的计算量可以弥补训练时的不足 │
│ → 复杂问题需要更多推理时计算 │
│ → 简单问题可以跳过复杂推理 │
│ │
└─────────────────────────────────────────────────────────────┘

1.3 本系列文章关联#

文章关联
PEFT/LoRA 深度解析高效微调方法
后训练深度解析SFT/RLHF 对齐训练
模型量化深度解析推理优化

2. Chain-of-Thought:推理的起点#

2.1 CoT 的核心思想#

Chain-of-Thought(CoT,Wei et al., 2022)让模型显式输出推理步骤:

class ChainOfThought:
"""
Chain-of-Thought 提示
核心:将答案的推导过程显式表达出来
"""
def standard_prompt(self):
"""
标准提示
"""
return """
Q: 小明有3个苹果,小红给了他2个,他又吃了1个,还剩几个?
A: 4个
"""
def cot_prompt(self):
"""
CoT 提示
"""
return """
Q: 小明有3个苹果,小红给了他2个,他又吃了1个,还剩几个?
A: 让我们逐步思考。
1. 小明开始有3个苹果
2. 小红给了他2个,所以是 3 + 2 = 5 个
3. 他又吃了1个,所以是 5 - 1 = 4 个
所以还剩 4 个苹果。
"""
def math_prompt(self):
"""
数学问题 CoT
"""
return """
Q: 计算 15 × 17
A: 让我们逐步计算。
1. 15 × 17 = 15 × (20 - 3)
2. = 15 × 20 - 15 × 3
3. = 300 - 45
4. = 255
答案是 255。
"""

2.2 CoT 为什么有效?#

class CoTAnalysis:
"""
CoT 有效性分析
"""
def why_works(self):
"""
CoT 有效的可能原因
"""
return {
"intermediate_tokens": "中间 token 作为工作记忆",
"sequential_computation": "强制模型逐步计算而非直接记忆",
"error_localization": "错误更容易定位",
"attention_distribution": "注意力更均匀分布",
"program_synthesis": "隐式合成计算程序",
}
def ablation(self):
"""
消融实验结论
"""
return {
"math_tasks": "CoT 提升最显著 (~40% 提升)",
"commonsense": "中度提升 (~15%)",
"factual_recall": "提升有限",
"key_factors": [
"模型规模 >= 100B 参数",
"使用数学/代码类任务",
"显式提示 'let's think step by step'",
],
}

2.3 CoT 的实现细节#

class CoTImplementation:
"""
CoT 实现
"""
def few_shot_cot(self):
"""
Few-shot CoT
提供多个 CoT 示例
"""
return """
Q: 小明有5个球,丢了2个,又买了3个,现在有几个?
A: 让我们逐步思考。
1. 开始有5个球
2. 丢了2个: 5 - 2 = 3
3. 又买了3个: 3 + 3 = 6
答案: 6个
---
Q: 书店有80本书,第一天卖了15本,第二天卖了20本,还剩多少?
A: 让我们逐步思考。
1. 开始有80本
2. 第一天卖了15本: 80 - 15 = 65
3. 第二天卖了20本: 65 - 20 = 45
答案: 45本
---
Q: [新问题]
"""
def zero_shot_cot(self):
"""
Zero-shot CoT
简单指令触发
"""
return """
问题: [用户问题]
让我们逐步思考:
"""
def api_usage(self):
"""
API 使用示例
"""
return '''
from openai import OpenAI
response = client.chat.completions.create(
model="gpt-4",
messages=[
{
"role": "user",
"content": "问题: 小明有3个苹果,小红给了他2个,他又吃了1个,还剩几个?\\n\\n让我们逐步思考:"
}
],
max_tokens=500,
temperature=0.7,
)
print(response.choices[0].message.content)
'''

3. Self-Consistency:多数投票#

3.1 Self-Consistency 原理#

Self-Consistency(Wang et al., 2023)通过采样多条推理路径,选择最一致的答案:

class SelfConsistency:
"""
Self-Consistency
核心思想:
1. 多次采样不同的推理路径
2. 统计每个答案出现的次数
3. 选择出现最多的答案
"""
def __init__(self, model, num_samples=40):
self.model = model
self.num_samples = num_samples
def generate_paths(self, question):
"""
生成多条推理路径
"""
responses = []
for _ in range(self.num_samples):
response = self.model.generate(
prompt=f"{question}\n\n让我们逐步思考:",
temperature=0.8, # 高温度增加多样性
max_tokens=500,
)
responses.append(response)
return responses
def extract_answer(self, response):
"""
从响应中提取答案
"""
# 简单实现:提取最后一行数字
lines = response.strip().split("\n")
for line in reversed(lines):
# 尝试提取数字
import re
numbers = re.findall(r'-?\d+', line)
if numbers:
return numbers[-1] # 取最后一个数字
return None
def majority_vote(self, answers):
"""
多数投票
"""
from collections import Counter
counter = Counter(answers)
most_common = counter.most_common(1)[0]
return {
"answer": most_common[0],
"count": most_common[1],
"total": len(answers),
"confidence": most_common[1] / len(answers),
"all_votes": counter,
}
def solve(self, question):
"""
完整流程
"""
# Step 1: 生成多条路径
responses = self.generate_paths(question)
# Step 2: 提取答案
answers = [self.extract_answer(r) for r in responses]
answers = [a for a in answers if a is not None]
# Step 3: 多数投票
result = self.majority_vote(answers)
return result

3.2 Self-Consistency 的效果#

Self-Consistency 效果(GSM8K 数据集):
基线 (Greedy):
→ LLM 准确率: 46.9%
Self-Consistency (40 samples):
→ 准确率提升到: 74.4%
→ 相对提升: +27.5%
关键发现:
→ 复杂问题提升更显著
→ 多数投票能过滤错误推理
→ 计算量换质量的有效方式
成本分析:
→ 40x 推理成本
→ 但比训练大模型便宜得多

3.3 温度与采样策略#

class SamplingStrategy:
"""
采样策略优化
"""
def temperature_analysis(self):
"""
温度分析
"""
return {
"temperature_0.0": {
"description": "Greedy 解码",
"diversity": "最低",
"适合": "简单问题",
},
"temperature_0.3": {
"description": "低温度",
"diversity": "低",
"适合": "需要一定多样性的推理",
},
"temperature_0.6": {
"description": "中等温度",
"diversity": "中等",
"适合": "大多数推理任务",
},
"temperature_0.8": {
"description": "高温度",
"diversity": "高",
"适合": "Self-Consistency",
},
}
def top_p_analysis(self):
"""
Top-p 核采样分析
"""
return {
"top_p_0.9": "截断尾部 10%,保持较高质量",
"top_p_0.95": "更宽松的截断,更多样性",
"top_p_0.99": "几乎不做截断,最大多样性",
"recommendation": "top_p=0.95, temperature=0.7 是好的起点",
}

4. Best-of-N:加权采样#

4.1 Best-of-N 基础#

class BestOfN:
"""
Best-of-N 采样
核心思想:
1. 生成 N 个候选答案
2. 用奖励模型对每个答案打分
3. 选择得分最高的答案
"""
def __init__(self, reward_model, n=100):
self.reward_model = reward_model
self.n = n
def generate_candidates(self, question):
"""
生成 N 个候选
"""
candidates = []
for _ in range(self.n):
response = self.llm.generate(
prompt=f"{question}\n\n让我们逐步思考:",
temperature=0.8,
)
candidates.append(response)
return candidates
def score_candidates(self, question, candidates):
"""
对候选打分
"""
scores = []
for candidate in candidates:
# 使用奖励模型打分
score = self.reward_model.score(question, candidate)
scores.append(score)
return scores
def select_best(self, candidates, scores):
"""
选择最佳
"""
best_idx = scores.index(max(scores))
return {
"answer": candidates[best_idx],
"score": scores[best_idx],
}

4.2 加权 Best-of-N#

class WeightedBestOfN:
"""
加权 Best-of-N
不仅选择最佳,还考虑概率
"""
def select_with_probability(self, candidates, log_probs, scores):
"""
基于概率加权的选择
"""
import numpy as np
# 计算概率
probs = np.exp(log_probs)
# 归一化分数
normalized_scores = (scores - np.mean(scores)) / (np.std(scores) + 1e-8)
# 加权概率
weights = probs * np.exp(normalized_scores)
weights = weights / weights.sum()
# 加权采样
selected_idx = np.random.choice(len(candidates), p=weights)
return candidates[selected_idx]

4.3 Best-of-N vs Self-Consistency#

class Comparison:
"""
Best-of-N vs Self-Consistency
"""
def compare(self):
"""
对比
"""
return {
"self_consistency": {
"需要": "CoT 提示",
"评判方式": "多数投票",
"优点": "无需额外奖励模型",
"缺点": "需要一致的答案格式",
"适用": "数学、代码等有明确答案的任务",
},
"best_of_n": {
"需要": "奖励模型",
"评判方式": "奖励打分",
"优点": "可应用于开放式任务",
"缺点": "需要训练奖励模型",
"适用": "对话、写作等开放式任务",
},
}

5. Process Reward Model:过程奖励#

5.1 结果奖励 vs 过程奖励#

class RewardModels:
"""
结果奖励 vs 过程奖励
"""
def outcome_reward_model(self):
"""
结果奖励模型 (ORM)
只在最终答案处打分
"""
return """
问题: 2x + 5 = 15, 求 x
解答:
步骤1: 2x = 15 - 5 = 10
步骤2: x = 10 / 2 = 5
步骤3: x = 5
最终答案: x = 5
ORM 奖励: ✓ (最终答案正确)
"""
def process_reward_model(self):
"""
过程奖励模型 (PRM)
对每个推理步骤打分
"""
return """
问题: 2x + 5 = 15, 求 x
解答:
步骤1: 2x = 15 - 5 = 10 → PRM: 0.9 ✓
步骤2: x = 10 / 2 = 5 → PRM: 0.85 ✓
步骤3: x = 5 → PRM: 0.8 ✓
最终答案: x = 5 → ORM: 1.0 ✓
关键优势:
→ 能识别错误步骤
→ 提供更细粒度的反馈
→ 更好地指导搜索
"""

5.2 PRM 的实现#

class ProcessRewardModel:
"""
PRM 实现
"""
def __init__(self, base_model):
self.model = base_model
def score_step(self, question, reasoning_steps):
"""
对推理步骤打分
输入: [步骤1, 步骤2, ..., 步骤N, 最终答案]
输出: [奖励1, 奖励2, ..., 奖励N]
"""
step_rewards = []
accumulated_context = question
for i, step in enumerate(reasoning_steps):
# 构建上下文
context = accumulated_context + "\n" + step
# 使用模型预测该步骤是否正确
# 方式1: 二分类 (正确/错误)
correctness = self.model.predict_step_correctness(context)
# 方式2: 打分 (0-1)
score = self.model.score_step_quality(context)
step_rewards.append(score)
accumulated_context += "\n" + step
return step_rewards
def lookahead_reward(self, current_step, future_steps):
"""
前看奖励
评估从当前状态可能达到的奖励
"""
total_reward = 0
for future_step in future_steps:
# 模拟未来的奖励
future_reward = self.model.score_step_quality(future_step)
total_reward += future_reward * self.discount_factor
return total_reward

5.3 PRM 的训练#

class PRMTraining:
"""
PRM 训练
"""
def training_data(self):
"""
训练数据构建
"""
return """
数据来源:
1. 人工标注
- 收集多条推理路径
- 标注每个步骤是否正确
2. 合成数据
- 使用 LLM 生成推理路径
- 自动标记正确/错误的步骤
3. 过程监督
- 在 RLHF 中加入过程奖励
- 使用 Process-Directed RL
数据格式:
{
"question": "...",
"steps": [
{"text": "步骤1", "label": 1},
{"text": "步骤2", "label": 1},
{"text": "错误步骤", "label": 0},
{"text": "步骤4", "label": 1},
],
}
"""
def training_objective(self):
"""
训练目标
"""
return """
PRM 训练目标:
L = -∑ log P(r_i | s_1, ..., s_i) × r_i
其中:
- r_i 是步骤 i 的奖励 (0 或 1)
- P 是模型预测的步骤正确概率
也可以使用回归目标:
L = MSE(P(s_i is correct), r_i)
"""

6. Tree of Thoughts:搜索式推理#

6.1 ToT 的核心思想#

Tree of Thoughts(Yao et al., 2023)将推理建模为树搜索:

class TreeOfThoughts:
"""
Tree of Thoughts
核心思想:
1. 将问题分解为多个思考节点
2. 探索多条思考路径
3. 使用启发式评估选择最佳路径
"""
def __init__(self, model, max_depth=5, num_branches=3):
self.model = model
self.max_depth = max_depth
self.num_branches = num_branches
self.tree = None
def generate_thoughts(self, state):
"""
从当前状态生成多个思考
"""
prompt = f"""
当前状态: {state}
请提出 {self.num_branches} 个不同的思考方向或行动:
"""
response = self.model.generate(prompt, temperature=0.8)
# 解析多个思考
thoughts = response.split("\n")[:self.num_branches]
return thoughts
def evaluate_state(self, state, goal):
"""
评估当前状态
返回: (score, reason)
"""
prompt = f"""
目标: {goal}
当前状态: {state}
评估这个状态对目标的贡献程度 (0-10),并说明理由:
"""
response = self.model.generate(prompt)
# 解析分数
score = self.extract_score(response)
return score, response
def search(self, initial_state, goal):
"""
树搜索
"""
from collections import deque
# BFS 或 DFS
queue = deque([(initial_state, [], 0)]) # (state, path, depth)
best_state = None
best_score = -float('inf')
while queue:
state, path, depth = queue.popleft()
# 评估当前状态
score, _ = self.evaluate_state(state, goal)
if score > best_score:
best_score = score
best_state = state
# 如果还没到最大深度,继续扩展
if depth < self.max_depth:
thoughts = self.generate_thoughts(state)
for thought in thoughts:
new_state = state + "\n" + thought
new_path = path + [thought]
queue.append((new_state, new_path, depth + 1))
return best_state, best_score

6.2 ToT vs CoT 对比#

class ToTvsCoT:
"""
Tree of Thoughts vs Chain of Thoughts
"""
def compare(self):
"""
对比
"""
return {
"CoT": {
"structure": "链式,一条路径",
"branching": "无",
"exploration": "无",
"backtracking": "无",
"适合任务": "简单推理、事实问答",
},
"ToT": {
"structure": "树状,多条路径",
"branching": "有",
"exploration": "有(广度搜索)",
"backtracking": "无(但可扩展为图)",
"适合任务": "复杂规划、创意写作",
},
}
def example_task(self, task_type):
"""
任务适用性
"""
return {
"24_game": {
"task": "使用 4 个数字和基本运算得到 24",
"recommended": "ToT",
"reason": "需要探索多种运算组合",
},
"writing": {
"task": "写一篇结构清晰的文章",
"recommended": "ToT",
"reason": "需要规划文章结构和内容",
},
"math_proof": {
"task": "证明数学定理",
"recommended": "CoT + PRM",
"reason": "步骤连续性很重要",
},
"qa": {
"task": "回答事实性问题",
"recommended": "CoT",
"reason": "简单推理即可",
},
}

7. Beam Search 在推理中的应用#

class BeamSearch:
"""
Beam Search 用于推理
"""
def __init__(self, model, beam_width=5):
self.model = model
self.beam_width = beam_width
def decode(self, prompt, max_length=200):
"""
Beam Search 解码
"""
# 初始化
beams = [
{"tokens": [], "score": 0.0, "log_probs": []}
]
completed = []
for step in range(max_length):
all_candidates = []
for beam in beams:
if beam.get("finished"):
# 已完成的 beam
completed.append(beam)
continue
# 扩展当前 beam
logits = self.model.get_logits(beam["tokens"])
top_k = self.model.top_k(logits, k=self.beam_width * 2)
for token, log_prob in top_k:
new_tokens = beam["tokens"] + [token]
new_score = beam["score"] + log_prob
new_log_probs = beam["log_probs"] + [log_prob]
all_candidates.append({
"tokens": new_tokens,
"score": new_score,
"log_probs": new_log_probs,
"finished": self.model.is_eos(token),
})
# 选择 top-k beams
all_candidates.sort(key=lambda x: x["score"], reverse=True)
beams = all_candidates[:self.beam_width]
# 检查是否全部完成
if all(b["finished"] for b in beams):
break
# 合并完成的和未完成的
all_seqs = completed + beams
all_seqs.sort(key=lambda x: x["score"] / len(x["tokens"]), reverse=True)
return all_seqs[0]["tokens"]
def with_reasoning(self, prompt):
"""
带推理的 Beam Search
"""
# 第一阶段:生成推理路径
reasoning_beams = self.generate_reasoning_beams(prompt)
# 第二阶段:基于答案一致性选择
answer_votes = self.vote_on_answers(reasoning_beams)
# 返回最一致的答案
return answer_votes[0]
class InferenceTimeBeamSearch:
"""
推理时 Beam Search 优化
"""
def diverse_beams(self):
"""
多样性 Beam Search
"""
return """
标准 Beam Search 只保留概率最高的路径
可能导致路径同质化
多样性 Beam Search 惩罚相似的候选:
score_i = log P(token_i) + λ × diversity_penalty
diversity_penalty = max_j exp((similarity(token_i, token_j)) / τ)
其中 λ 控制多样性权重,τ 是温度参数
"""
def lookahead_beams(self):
"""
前看 Beam Search
"""
return """
评估当前 token 时考虑未来的潜力:
score(token_t) = log P(token_t) + γ × V(state_{t+1})
其中 V 是价值函数,评估从当前状态能达到好结果的可能性
这需要训练一个价值网络来预测未来奖励
"""

8. STaR:自推理引导#

8.1 STaR 原理#

STaR(Self-Taught Reasoner,Zelikman et al., 2022)让模型自己生成推理:

class STaR:
"""
STaR: Self-Taught Reasoner
核心思想:
1. 让模型尝试解决难题
2. 成功解决时,记录成功的推理过程
3. 失败时,使用"rationale generation"生成推理
4. 用这些数据微调模型
5. 重复迭代
"""
def __init__(self, model, iterations=5):
self.model = model
self.iterations = iterations
def attempt_solve(self, question, correct_answer):
"""
尝试解决问题
"""
# 生成解答(带 CoT)
response = self.model.generate(
f"问题: {question}\n让我们逐步思考:",
temperature=0.5,
)
extracted_answer = self.extract_answer(response)
if extracted_answer == correct_answer:
# 成功:记录推理过程
return {
"success": True,
"rationale": response,
"answer": extracted_answer,
}
else:
# 失败:尝试生成正确推理
return {"success": False, "rationale": None, "answer": extracted_answer}
def rationale_generation(self, question, correct_answer):
"""
理由生成
提示模型"假设你最终会得到正确答案"
"""
prompt = f"""
问题: {question}
正确答案: {correct_answer}
请推理出正确的答案,假设你是对的。
让我们逐步思考,最后给出正确答案。
"""
response = self.model.generate(prompt, temperature=0.5)
# 验证生成的推理是否正确
extracted = self.extract_answer(response)
if extracted == correct_answer:
return response
else:
return None
def iterative_training(self, dataset):
"""
迭代训练
"""
for iteration in range(self.iterations):
print(f"迭代 {iteration + 1}/{self.iterations}")
training_examples = []
for item in dataset:
question = item["question"]
answer = item["answer"]
# 尝试解决
result = self.attempt_solve(question, answer)
if result["success"]:
# 成功案例
training_examples.append({
"prompt": question,
"response": result["rationale"],
})
else:
# 失败案例:生成正确推理
rationale = self.rationale_generation(question, answer)
if rationale:
training_examples.append({
"prompt": question,
"response": rationale,
})
# 用收集的数据微调模型
if training_examples:
self.model.fine_tune(training_examples)
# 评估
accuracy = self.evaluate(dataset)
print(f" 准确率: {accuracy:.2%}")
if accuracy > 0.9:
break
return self.model

8.2 STaR 的效果#

STaR 效果(StrategyQA 数据集):
基线(无推理):
→ 准确率: 53.0%
CoT(few-shot):
→ 准确率: 59.7%
STaR(自迭代):
→ 准确率: 73.2%
→ 提升: +13.5%
关键洞察:
→ 模型可以"教会自己"推理
→ 成功的推理例子比失败更重要
→ 迭代可以不断提升能力

9. 测试时计算 Scaling Laws#

9.1 理论框架#

class TestTimeScaling:
"""
测试时计算 Scaling Laws
"""
def power_law(self, compute_budget, task_difficulty):
"""
性能与计算量的幂律关系
P(C) = a × C^b + c
其中:
- C 是推理计算量
- a, b, c 是拟合参数
- b 通常在 0.1-0.3 之间
"""
import numpy as np
a, b, c = 0.3, 0.2, 0.5
performance = a * (compute_budget ** b) + c
return min(performance, 1.0) # 上限 1.0
def compute_optimal(self, task_difficulty, model_cost, compute_cost):
"""
计算最优策略
给定任务难度和成本,选择:
- 使用更大的模型
- 还是在推理时投入更多计算
"""
return {
"easy_task": "使用小模型 + 少量推理计算",
"medium_task": "使用中等模型 + 适量推理计算",
"hard_task": "使用大模型 + 充足推理计算",
"very_hard_task": "使用最大模型 + 最大推理计算",
}
def compute_allocation(self, total_compute):
"""
计算量分配
在模型规模和推理计算之间如何分配
"""
return """
论文 "Test-Time Compute" 的发现:
对于简单问题:
→ 增加推理计算的效果有限
→ 应该用更大的模型
对于复杂问题:
→ 增加推理计算效果显著
→ 可以弥补模型规模不足
最佳策略:
→ 根据问题难度自适应分配计算
→ 简单问题用少量计算
→ 复杂问题用更多计算
"""

9.2 前沿研究#

class FrontierResearch:
"""
前沿研究
"""
def chain_of_verification(self):
"""
Chain of Verification
生成答案后,验证每个步骤
"""
return """
流程:
1. 生成初始答案
2. 列出答案中的关键声明
3. 对每个声明独立验证
4. 根据验证结果修正答案
效果:显著减少幻觉
"""
def chain_of_draft(self):
"""
Chain of Draft
快速草稿 → 逐步精化
"""
return """
流程:
1. 草稿 1:快速但不精确
2. 草稿 2:基于反馈修正
3. 草稿 N:持续精化直到满意
优势:比直接生成更高效
"""
def prompt_optimization(self):
"""
推理时提示优化
"""
return """
在推理时优化提示:
1. APE: 自动提示优化
- 采样多个提示
- 选择效果最好的
2. APO: 自动提示精化
- 分析失败案例
- 自动改进提示
3. Self-Generated Critiques
- 让模型评估自己的回答
- 根据评估修正
"""

10. 实战指南#

10.1 方法选择#

class MethodSelection:
"""
方法选择指南
"""
def select(self, task_type, compute_budget):
"""
根据任务和计算量选择方法
"""
recommendations = {
"math_proof": {
"low_compute": "CoT + few-shot",
"medium_compute": "Self-Consistency (20 samples)",
"high_compute": "Self-Consistency (40) + PRM lookahead",
"recommended": "CoT + Self-Consistency",
},
"code_generation": {
"low_compute": "CoT",
"medium_compute": "Self-Consistency + execution feedback",
"high_compute": "ToT + test execution",
"recommended": "Self-Consistency + execution",
},
"creative_writing": {
"low_compute": "CoT",
"medium_compute": "Best-of-N + reward model",
"high_compute": "Evolutionary generation",
"recommended": "Best-of-N",
},
"fact_qa": {
"low_compute": "Direct answer",
"medium_compute": "CoT",
"high_compute": "CoT + verification",
"recommended": "CoT + verification",
},
}
return recommendations.get(task_type, recommendations["fact_qa"])

10.2 实现模板#

class ImplementationTemplate:
"""
实现模板
"""
def self_consistency_template(self):
"""
Self-Consistency 模板
"""
return '''
from collections import Counter
import re
def self_consistency_solve(question, model, n_samples=20):
"""Self-Consistency 实现"""
# 生成多个解答
responses = []
for _ in range(n_samples):
response = model.generate(
f"{question}\\n\\n让我们逐步思考:",
temperature=0.7,
max_tokens=500,
)
responses.append(response)
# 提取答案
answers = []
for response in responses:
# 提取最后一个数字或关键词
answer = extract_answer(response)
if answer:
answers.append(answer)
# 多数投票
if answers:
counter = Counter(answers)
return counter.most_common(1)[0][0]
return None
def extract_answer(text):
"""从 CoT 响应中提取答案"""
# 尝试提取数字
numbers = re.findall(r'-?\\d+\\.?\\d*', text)
if numbers:
return numbers[-1]
# 尝试提取关键词
if "答案是" in text:
return text.split("答案是")[-1].strip()
return None
'''
def best_of_n_template(self):
"""
Best-of-N 模板
"""
return '''
def best_of_n_solve(question, model, reward_model, n_samples=50):
"""Best-of-N 实现"""
# 生成候选
candidates = []
for _ in range(n_samples):
response = model.generate(question, temperature=0.8)
candidates.append(response)
# 评分
scored = []
for candidate in candidates:
score = reward_model.score(question, candidate)
scored.append((candidate, score))
# 返回最佳
scored.sort(key=lambda x: x[1], reverse=True)
return scored[0][0]
'''

10.3 成本优化#

class CostOptimization:
"""
成本优化
"""
def adaptive_computation(self):
"""
自适应计算
简单问题用少计算,复杂问题用多计算
"""
return """
策略:
1. 先用简单方法尝试
2. 如果置信度低,升级到更复杂方法
3. 如果还是低,继续升级
实现:
def solve_with_adaptive(question):
# Level 0: 直接回答
answer = direct_answer(question)
if confidence(answer) > 0.9:
return answer
# Level 1: CoT
answer = cot_answer(question)
if confidence(answer) > 0.85:
return answer
# Level 2: Self-Consistency
answer = self_consistency(question, n=10)
if confidence(answer) > 0.8:
return answer
# Level 3: Full Self-Consistency
return self_consistency(question, n=40)
"""
def batch_optimization(self):
"""
批处理优化
"""
return """
多个问题一起处理:
1. 按难度分组
- 简单问题:批量处理
- 复杂问题:单独处理
2. 共享计算
- 对相似问题复用推理路径
3. 缓存
- 缓存常见问题的解答
"""

11. 核心公式汇总#

11.1 Self-Consistency#

a^=argmaxaAi=1N1[ai=a]\hat{a} = \arg\max_{a \in \mathcal{A}} \sum_{i=1}^{N} \mathbb{1}[a_i = a]

其中 aia_i 是第 ii 次采样的答案。

11.2 Best-of-N 加权#

P(select aj)=exp(sj/τ)k=1Nexp(sk/τ)P(\text{select } a_j) = \frac{\exp(s_j / \tau)}{\sum_{k=1}^{N} \exp(s_k / \tau)}

其中 sjs_j 是奖励模型对答案 jj 的打分,τ\tau 是温度参数。

11.3 测试时 Scaling#

Ptest(C)=αCβ+γP_{\text{test}}(C) = \alpha \cdot C^{\beta} + \gamma

其中 CC 是推理计算量,α,β,γ\alpha, \beta, \gamma 是任务相关的拟合参数。


12. 总结#

12.1 方法对比#

┌─────────────────────────────────────────────────────────────┐
│ 推理时扩展方法对比 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 方法 计算量 精度 适用场景 │
│ ───────────────────────────────────────────────────────── │
│ CoT 低 中 通用推理 │
│ Self-Consistency 中 高 有明确答案的任务 │
│ Best-of-N 中 高 开放式任务 │
│ PRM 高 很高 需要精细控制的任务 │
│ ToT 高 很高 复杂规划 │
│ STaR 迭代 很高 可自提升的任务 │
│ ───────────────────────────────────────────────────────── │
│ │
│ 核心原则:计算量换质量 │
│ │
└─────────────────────────────────────────────────────────────┘

12.2 最佳实践#

推理时扩展最佳实践:
1. 从简单开始
→ 先尝试 CoT,再升级到更复杂方法
2. 自适应计算
→ 简单问题少计算,复杂问题多计算
3. 选择合适的方法
→ 数学/代码:Self-Consistency
→ 开放式:Best-of-N
→ 复杂规划:ToT
4. 成本控制
→ 设置计算预算
→ 使用 early stopping
5. 持续迭代
→ 用 STaR 自我提升
→ 收集成功的推理案例

12.3 未来方向#

推理时扩展的未来:
1. 更智能的搜索
→ 结合蒙特卡洛树搜索
→ 学习何时停止搜索
2. 更好的奖励模型
→ Process Reward Model 的进步
→ 更准确的步骤评估
3. 训练与推理协同
→ 用推理数据训练更好的模型
→ 循环自我提升
4. 硬件优化
→ 专为推理时计算设计的芯片
→ 更高效的并行推理
5. 理论完善
→ 更精确的 scaling laws
→ 最优计算分配策略
推荐阅读
  1. Chain-of-Thought(Wei et al., 2022)—— CoT 原论文
  2. Self-Consistency(Wang et al., 2023)—— 多数投票方法
  3. Tree of Thoughts(Yao et al., 2023)—— 搜索式推理
  4. STaR(Zelikman et al., 2022)—— 自推理引导
  5. Process Reward Models(Lightman et al., 2023)—— 过程奖励

参考资料#

  1. Wei, J., et al. (2022). “Chain-of-Thought Prompting Elicits Reasoning in Large Language Models.” NeurIPS.
  2. Wang, X., et al. (2023). “Self-Consistency Improves Chain of Thought Reasoning in Language Models.” ICLR.
  3. Yao, S., et al. (2023). “Tree of Thoughts: Deliberate Problem Solving with Large Language Models.” NeurIPS.
  4. Zelikman, E., et al. (2022). “STaR: Self-Taught Reasoner Bootstrapping Reasoning with Reasoning.” NeurIPS.
  5. Lightman, H., et al. (2023). “Let’s Verify Step by Step.” arXiv.
  6. Brown, B., et al. (2024). “Language Model Testing-Time Compute.” OpenAI Blog.
  7. Snell, C., et al. (2024). “Scaling LLM Test-Time Compute Optimally.” arXiv.
  8. Jones, A., et al. (2024). “Inference-Time Scaling: A Case Study.” arXiv.
  9. Tian, Y., et al. (2024). “Self-Correction is All You Need.” arXiv.
  10. Qu, S., et al. (2024). “Deliberation after Learning: A New Paradigm.” arXiv.

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

推理时扩展深度解析:Test-Time Scaling 的理论与实践
https://aiattnstudio.link/posts/test-time-scaling/
作者
Federico
发布于
2026-07-16
许可协议
CC BY-NC-SA 4.0
Profile Image of the Author

Federico

AI Research Lab

Hello, I'm Federico.

关于实验室 / About
公告

欢迎来到Federico的个人博客

分类
标签
站点统计
57文章
7分类
404标签