用途
NOWAIT Reasoning Optimizer 实现了论文《Wait, We Don't Need to 'Wait'! Removing Thinking Tokens Improves Reasoning Efficiency》(Wang et al., 2025)中提出的 NOWAIT 技术。NOWAIT 是一种免训练的推理时干预方法,在生成过程中抑制自我反思类 token(例如 "Wait"、"Hmm"、"Alternatively"),从而将思维链(CoT)轨迹长度缩短 27%–51%,同时不损害模型效用。
适用场景
- 在算力有限的情况下部署 R1 风格推理模型
- 降低生产系统的推理延迟
- 优化推理任务的 token 成本
- 处理冗长、需要精简的 CoT 输出
支持的模型
| 模型系列 | 类型 | Token 缩减幅度 |
|---|---|---|
| QwQ-32B | 基于 RL | 16–31% |
| Phi4-Reasoning-Plus | 基于 RL | 23–28% |
| Qwen3-32B | 基于 RL | 13–16% |
| Kimi-VL-A3B | 多模态 | 40–60% |
| QvQ-72B-Preview | 多模态 | 20–30% |
重要提示:NOWAIT 对基于 RL 的模型效果最佳。蒸馏模型(Qwen3-4B/8B/14B)在抑制反思 token 后表现会下降。
使用方式
基础实现
from scripts.nowait_processor import NOWAITLogitProcessor
# 为模型的 tokenizer 初始化处理器
processor = NOWAITLogitProcessor(tokenizer)
# 在生成时使用
outputs = model.generate(
inputs,
logits_processor=[processor],
max_new_tokens=32768
)
被抑制的关键词
完整列表见 references/keywords.md。核心关键词包括:
wait, alternatively, hmm, but, however, check, double-check, maybe, verify, again, oh, ah
工作原理
- 初始化关键词:通过实证分析识别反思关键词
- 扩展为 token 变体:将关键词映射到词表中的所有 token 变体(例如 "wait" → " wait"、"Wait"、" Wait"、".wait"、"WAIT")
- 推理时抑制:在解码过程中将反思 token 的 logits 设为很大的负值
Logits(之前) Logits(之后)
Wait 0.8 → Wait -inf
First 0.6 → First 0.6
Hmm 0.5 → Hmm -inf
Let 0.4 → Let 0.4
关键发现
为什么有效
- NOWAIT 并非完全消除自我反思——它引导模型跳过不必要的 "waiting" 推理
- 模型仍会在关键决策点执行必要的验证
- 结果是更线性、更直接的推理路径
RL 模型与蒸馏模型对比
| 模型类型 | NOWAIT 效果 | 建议 |
|---|---|---|
| 基于 RL(QwQ、Phi4、Qwen3-32B) | 准确率稳定,token 显著缩减 | ✅ 推荐 |
| 蒸馏(Qwen3-4B/8B/14B) | 困难任务上准确率下降 | ⚠️ 谨慎使用 |
蒸馏模型高度依赖训练数据中的 CoT 结构——移除反思 token 会破坏其推理模式。
集成示例
HuggingFace Transformers
from transformers import AutoModelForCausalLM, AutoTokenizer
from scripts.nowait_processor import NOWAITLogitProcessor
model = AutoModelForCausalLM.from_pretrained("Qwen/QwQ-32B")
tokenizer = AutoTokenizer.from_pretrained("Qwen/QwQ-32B")
processor = NOWAITLogitProcessor(tokenizer)
response = model.generate(
tokenizer(prompt, return_tensors="pt").input_ids,
logits_processor=[processor],
max_new_tokens=32768,
do_sample=True,
temperature=0.7
)
vLLM
from vllm import LLM, SamplingParams
from scripts.nowait_processor import get_nowait_bad_words_ids
llm = LLM(model="Qwen/QwQ-32B")
bad_words_ids = get_nowait_bad_words_ids(llm.get_tokenizer())
sampling_params = SamplingParams(
max_tokens=32768,
bad_words_ids=bad_words_ids
)
预期结果
| 任务类型 | 原始 Token 数 | NOWAIT Token 数 | 缩减幅度 |
|---|---|---|---|
| 数学(AIME) | 15,000 | 10,500 | 30% |
| 视觉问答(MMMU) | 2,900 | 1,450 | 50% |
| 视频问答(MMVU) | 1,700 | 1,250 | 27% |
限制
- 在非常简单、CoT 开销本就很小的任务上效果较差
- 蒸馏模型在挑战性任务上可能出现准确率损失
- 某些领域可能需要针对具体模型调整关键词
参考资料
- 论文:arXiv:2506.08343v2
- 完整关键词列表:references/keywords.md
- 实现:scripts/nowait_processor.py