大模型少输出反而更快:多智能体推理框架的反直觉洞见
一句话总结
生成更少 token 的大模型,可以比生成更多 token 的小模型更快、更准——这个反直觉结论重新定义了 VLM 推理效率的优化方向。
为什么 Token 数量是真正的瓶颈?
在 Vision-Language Model (VLM) 的推理链路中,有一个常被忽视的事实:推理延迟主要由输出 token 数量决定,而不是模型参数量。
这和大多数人的直觉相反。直觉上,”70B 模型比 7B 模型慢 10 倍”。但真实情况是:
VLM 推理分两个阶段:
- Prefill(预填充):并行处理所有输入 token,一次性完成,计算量大但时间固定
- Decode(自回归解码):每次只生成一个 token,必须串行,时间与输出长度线性正相关
Decode 阶段是典型的内存带宽瓶颈(memory-bandwidth-bound),每生成一个 token 都需要把模型权重从 HBM 加载到 SRAM。因此:
\[\text{Decode 吞吐} \approx \frac{\text{内存带宽}}{2 \times \text{参数量} \times \text{字节数/参数}}\]对 A100 (2TB/s 带宽) 上的 fp16 模型:
- 7B 模型:$2 \times 10^{12} / (2 \times 7 \times 10^9 \times 2) \approx 71\ \text{tokens/sec}$
- 70B 模型(8×A100):吞吐约降至 $\approx 14\ \text{tokens/sec}$
大模型吞吐约为小模型的 1/5,但如果大模型输出 token 数少 10 倍,它反而更快。
背景:Chain-of-Thought 的代价
现代 VLM 和 LLM 大量依赖 Chain-of-Thought(CoT)推理——让模型在给出答案之前先”想清楚”。
问题在于:小模型能力弱,需要更长的推理链才能达到可接受的准确率。大模型能力强,更短的推理链就能达到同等甚至更好的效果。
这制造了一个效率悖论:
- 小模型 × 长 CoT = 低质量 + 高延迟
- 大模型 × 短 CoT = 高质量 + 低延迟(在 token 数差距够大时)
核心方法:多智能体推理框架
直觉
论文的核心洞见是:大模型不需要自己想清楚每一步,可以借用小模型的推理过程。
传统做法:
小模型 → [长推理链 + 答案] ← 慢且准确率低
大模型 → [长推理链 + 答案] ← 准确率高但也很慢
多智能体框架:
小模型 → [长推理链]
↓ 提取关键推理 token
大模型 → [借用推理] → [短答案] ← 准确率接近大模型,延迟更低
效率分析
设:
- $T_L, T_S$:大/小模型的 token 吞吐(tokens/sec)
- $N_L, N_S$:大/小模型的输出 token 数
- $N_{key}$:从小模型借用的关键推理 token 数(加入 prefill,不影响 decode)
大模型在多智能体框架下的延迟:
\[\text{Latency}_{\text{multi}} = \underbrace{\frac{N_S}{T_S}}_{\text{小模型生成推理}} + \underbrace{\frac{N_L'}{T_L}}_{\text{大模型生成短答案}}\]其中 $N_L’ \ll N_L$,因为大模型不再需要自己推理。
效率收益条件(相比单独运行大模型):
\[\frac{N_S}{T_S} + \frac{N_L'}{T_L} < \frac{N_L}{T_L}\]即:小模型生成推理的代价 < 大模型节省的推理代价。
实现
延迟模型:量化效率拐点
先用代码验证什么时候大模型真的更高效:
import numpy as np
import matplotlib.pyplot as plt
def estimate_throughput(params_B: float, bandwidth_TBs: float = 2.0,
bytes_per_param: int = 2) -> float:
"""基于内存带宽估算 decode 吞吐 (tokens/sec)"""
model_size_bytes = params_B * 1e9 * bytes_per_param
return bandwidth_TBs * 1e12 / model_size_bytes
def compute_latency(params_B: float, output_tokens: int,
prefill_tokens: int = 1000) -> dict:
"""计算推理延迟 (秒)"""
throughput = estimate_throughput(params_B)
# Prefill 延迟近似(compute-bound,简化估算)
prefill_latency = prefill_tokens / (throughput * 10)
decode_latency = output_tokens / throughput
return {
"throughput": throughput,
"prefill": prefill_latency,
"decode": decode_latency,
"total": prefill_latency + decode_latency
}
# 对比:小模型(7B)长CoT vs 大模型(70B)短CoT
configs = {
"7B × 500 tokens": (7, 500),
"7B × 200 tokens": (7, 200),
"70B × 50 tokens": (70, 50),
"70B × 100 tokens": (70, 100),
"70B × 200 tokens": (70, 200),
}
print(f"{'配置':<25} {'吞吐(tok/s)':<15} {'Decode延迟(s)':<15} {'总延迟(s)'}")
print("-" * 70)
for name, (params, tokens) in configs.items():
r = compute_latency(params, tokens)
print(f"{name:<25} {r['throughput']:<15.1f} {r['decode']:<15.2f} {r['total']:.2f}")
典型输出(单 A100):
配置 吞吐(tok/s) Decode延迟(s) 总延迟(s)
----------------------------------------------------------------------
7B × 500 tokens 71.4 7.00 7.10
7B × 200 tokens 71.4 2.80 2.90
70B × 50 tokens 7.1 7.00 7.07
70B × 200 tokens 7.1 28.09 28.16
注意:7B 生成 500 tokens 和 70B 生成 50 tokens 总延迟几乎相同,但 70B 的答案质量更高。这就是论文的核心发现。
多智能体推理框架核心实现
from dataclasses import dataclass
from typing import Optional
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
@dataclass
class AgentConfig:
model_name: str
max_new_tokens: int
is_large: bool = False
class MultiAgentInference:
"""多智能体推理:小模型生成推理链,大模型借用并生成短答案"""
def __init__(self, small_cfg: AgentConfig, large_cfg: AgentConfig):
self.small_model = AutoModelForCausalLM.from_pretrained(
small_cfg.model_name, torch_dtype=torch.float16, device_map="auto"
)
self.large_model = AutoModelForCausalLM.from_pretrained(
large_cfg.model_name, torch_dtype=torch.float16, device_map="auto"
)
self.small_tok = AutoTokenizer.from_pretrained(small_cfg.model_name)
self.large_tok = AutoTokenizer.from_pretrained(large_cfg.model_name)
self.small_cfg = small_cfg
self.large_cfg = large_cfg
def _generate(self, model, tokenizer, prompt: str, max_new_tokens: int) -> str:
inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
with torch.no_grad():
outputs = model.generate(
**inputs, max_new_tokens=max_new_tokens,
do_sample=False, temperature=1.0
)
# 只返回新生成的部分
new_tokens = outputs[0][inputs["input_ids"].shape[1]:]
return tokenizer.decode(new_tokens, skip_special_tokens=True)
def extract_key_reasoning(self, reasoning: str, max_tokens: int = 200) -> str:
"""提取关键推理 token(简单版:截取前 N 个词)"""
words = reasoning.split()
# 实际工作中可以用更复杂的摘要或重要性评分
return " ".join(words[:max_tokens])
def infer(self, question: str) -> dict:
# Step 1: 小模型生成完整推理链
small_prompt = f"Question: {question}\nLet me think step by step:\n"
reasoning = self._generate(
self.small_model, self.small_tok, small_prompt,
self.small_cfg.max_new_tokens
)
# Step 2: 提取关键推理 token
key_reasoning = self.extract_key_reasoning(reasoning)
# Step 3: 大模型借用推理,生成短答案
large_prompt = (
f"Question: {question}\n"
f"Reasoning context: {key_reasoning}\n" # 关键:注入推理 token
f"Based on the above reasoning, the concise answer is:"
)
answer = self._generate(
self.large_model, self.large_tok, large_prompt,
self.large_cfg.max_new_tokens # 大模型只需生成短答案
)
return {
"reasoning_tokens": len(reasoning.split()),
"answer_tokens": len(answer.split()),
"reasoning": reasoning,
"answer": answer
}
效率对比实验
import time
def benchmark_inference(agent: MultiAgentInference, questions: list) -> dict:
"""对比直接用大模型 vs 多智能体框架"""
results = {"multi_agent": [], "large_only": []}
for q in questions:
# 多智能体方案
t0 = time.perf_counter()
ma_result = agent.infer(q)
results["multi_agent"].append({
"latency": time.perf_counter() - t0,
"answer_tokens": ma_result["answer_tokens"]
})
# 仅大模型(生成完整 CoT)
large_prompt = f"Question: {q}\nLet me think step by step:\n"
t0 = time.perf_counter()
answer = agent._generate(
agent.large_model, agent.large_tok, large_prompt, max_new_tokens=500
)
results["large_only"].append({
"latency": time.perf_counter() - t0,
"answer_tokens": len(answer.split())
})
# 汇总统计
for key in results:
latencies = [r["latency"] for r in results[key]]
tokens = [r["answer_tokens"] for r in results[key]]
print(f"{key}: 平均延迟 {np.mean(latencies):.2f}s, 平均输出 {np.mean(tokens):.0f} tokens")
return results
工程实践
关键推理 token 的选择策略
论文中提到”transfer key reasoning tokens”,但具体如何选择是工程核心:
def select_key_tokens_tfidf(reasoning: str, query: str, top_k: int = 5) -> str:
"""用 TF-IDF 相关性选择关键句子"""
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
sentences = reasoning.split(".")
sentences = [s.strip() for s in sentences if len(s.strip()) > 10]
if not sentences:
return reasoning[:500]
vectorizer = TfidfVectorizer()
# 用查询和每个句子计算相关性
corpus = [query] + sentences
tfidf_matrix = vectorizer.fit_transform(corpus)
scores = cosine_similarity(tfidf_matrix[0:1], tfidf_matrix[1:]).flatten()
top_indices = scores.argsort()[-top_k:][::-1]
return ". ".join([sentences[i] for i in sorted(top_indices)])
什么时候触发小模型推理?
不是所有问题都需要多智能体推理,简单问题直接用大模型:
def needs_reasoning(question: str, confidence_threshold: float = 0.8) -> bool:
"""判断是否需要小模型辅助推理(基于大模型置信度)"""
# 用大模型的 log-prob 估计置信度
# 低置信度 → 触发小模型推理
# 高置信度 → 大模型直接回答
pass # 实际实现需要接入模型的 logits
常见坑
坑 1:小模型推理质量太差,大模型被带偏
小模型的错误推理可能误导大模型。解决方案:在 prompt 中明确告诉大模型”以下推理供参考,请自行判断正确性”:
large_prompt = (
f"Question: {question}\n"
f"Reference reasoning (may contain errors): {key_reasoning}\n"
f"Provide your own concise answer:" # 不是"基于以上推理"
)
坑 2:两次推理的延迟叠加超过预期
多智能体框架实际跑两个模型,若不并行化则总延迟更高。关键在于小模型和大模型的 prefill 可以流水线化。
坑 3:不同 tokenizer 的 token 边界不对齐
小模型的 token 不能直接喂给大模型(词表不同),需要先 decode 成文本再 encode。这会引入微小的语义损失。
适用边界
| 适用场景 | 不适用场景 |
|---|---|
| 推理链较长的复杂问题(数学、代码) | 简单问答(直接用大模型更快) |
| 有现成小模型可用的场景 | 实时交互(额外延迟不可接受) |
| 批量推理,可流水线化 | 小模型推理频繁出错的领域 |
| 追求准确率同时控制成本 | 两个模型都要塞进同一 GPU 时 |
与相关工作对比
| 方法 | 核心思路 | 优点 | 缺点 |
|---|---|---|---|
| Speculative Decoding | 小模型猜测,大模型验证 | 无质量损失,延迟低 | 两模型词表需兼容 |
| Mixture of Experts | 路由不同问题给不同专家 | 单次推理 | 训练成本高 |
| 本文方法 | 小模型推理 → 大模型借用 | 复用现有模型,无需重训 | 两次推理的调度开销 |
| Chain-of-Thought | 单模型长推理 | 简单 | 小模型效果差,大模型慢 |
我的观点
这篇论文揭示了一个重要的系统级优化机会:大家都在优化模型结构,却忽视了输出 token 数对延迟的决定性影响。
但有几个开放问题值得关注:
-
小模型推理质量的下限:当小模型在某个领域能力极差时,借用其推理反而有害。需要一个可靠的”推理质量估计器”,但这本身就是个难题。
-
两阶段延迟叠加问题:论文的效率分析在某些场景下可能过于乐观——如果小模型和大模型不能并行运行(例如单 GPU 内存不足),总延迟反而增加。
-
离实际部署还差什么:论文用的是”模拟数据”做延迟分析,真实部署中 KV cache、批处理、网络通信都会影响结论。工业级落地需要在具体推理框架(vLLM、TensorRT-LLM)上验证。
这个方向的本质是把推理时计算的分配问题重新形式化,值得关注,但不要被”大模型反而更快”这个标题忽悠——前提是大模型真的能用更少 token 达到同等效果,而这个前提在开放域任务中并不总是成立。
Comments