推理与量化 / KV Cache 与解码 原理笔记入门 6 分钟阅读 查看源文件 ↗

自回归解码策略#

本页内容9 个部分

Decoder-only 模型推理时,每一步输出的是一个概率分布 P(xt∣x<t)P(x_t | x_{\lt t})。怎么从这个分布里选 token——就是解码策略。策略可以在三个阶段介入:

阶段 时机 策略
① 修改 logits softmax 之前 Repetition Penalty、Temperature
② 修剪概率分布 softmax 之后,采样之前 Top-k、Top-p
③ 采样 从分布中选 token Greedy / Beam Search / Random Sampling(互斥)

注意:阶段 ① ② 的修剪/调整策略主要为 Random Sampling 设计——Temperature 不改变排名顺序(对 Greedy 的 argmax 无影响),Top-k/Top-p 砍掉的是低概率尾巴(top-1 永远存活,Greedy 结果不变)。唯一例外是 Repetition Penalty:它非均匀地压低特定 token 的 logit,会改变排名,因此对 Greedy 也有效。

1. Repetition Penalty(重复惩罚)#

常见 repetition penalty 对已出现 token 的正 logit 除以 θ>1\theta>1,对负 logit 乘以 θ\theta;只做除法反而会提高负 logit。另一类 frequency/presence penalty 是减去惩罚项。防止生成陷入循环。因为是非均匀修改(只动已出现的 token),会改变 token 排名,对所有采样方式都有效。

2. Temperature(温度)#

P′(xi)=exp⁡(zi/T)∑jexp⁡(zj/T)P'(x_i) = \frac{\exp(z_i / T)}{\sum_j \exp(z_j / T)}

ziz_i 是 logit,TT 是温度。T→0T \to 0 退化成 Greedy,T→∞T \to \infty 退化成均匀分布

T<1T < 1:分布变尖锐,高概率 token 更突出 → 生成更确定性。T>1T > 1:分布变平坦,低概率 token 也有机会 → 生成更多样。T=1T=1 就是原始 softmax 输出。

例:同一组 logits 在不同温度下的概率

原始 logits:猫=5.0,狗=3.0,鱼=1.0,鸟=0.5

温度 猫 狗 鱼 鸟 效果
T=0.5 98.2% 1.8% ≈0% ≈0% 极度尖锐,接近 Greedy
T=1.0 86.6% 11.7% 1.3% 0.8% 原始 softmax
T=2.0 51.6% 19.0% 7.0% 5.4% 平坦,低概率词也有机会

Temperature 不改变 token 排名顺序,只控制"第一名和其他选手的差距"——低温赢家通吃,高温雨露均沾。

3. Top-k Sampling#

只从概率最高的 kk 个 token 中采样,其余全部置零后重新归一化。本质作用:砍掉长尾——词表有 3~13 万个 token,绝大多数在任何位置都是荒谬选项,但各自有微小概率,数量巨大加起来可占 5~10%,不砍掉偶尔会采到离谱的词。

例:Top-k=3 的操作流程

**原始分布:**猫(0.40) 狗(0.25) 鱼(0.15) 鸟(0.10) 桌子(0.04) 跑步(0.03) ...

**① 置零:**只保留前 3 个,其余 → 0:猫(0.40) 狗(0.25) 鱼(0.15) | 鸟 桌子 跑步 ...

**② 归一化:**总和 0.80 → 猫(0.50) 狗(0.3125) 鱼(0.1875)

**③ 采样:**从这三个里按新概率随机抽(不是 argmax)。

问题:kk 是固定的。在某些位置模型非常确信(分布极尖锐,前 2 个 token 占 99%),k=50k=50 会引入大量噪声。在另一些位置(分布平坦),k=50k=50 可能把合理选项排除了。同一个 kk 值,一边嫌多一边嫌少。

4. Top-p (Nucleus) Sampling#

Nucleus ="核",指概率分布头部集中了绝大部分概率质量的那团 token。Top-p 只从这个"核"里采样:从概率从高到低排列,累积概率刚超过 pp 时截断,只从这些 token 中采样。

Top-p(P,p)={xi:∑j≤iPsorted(xj)≤p}\text{Top-p}(P, p) = \{x_i : \sum_{j \leq i} P_{\text{sorted}}(x_j) \leq p\}

自适应地选择 token 数——分布尖锐时少选几个,分布平坦时多选几个

**优点:**自适应——p=0.9p=0.9 时,如果前 3 个 token 就占了 90%,就只从 3 个里选;如果前 50 个 token 才凑够 90%,就从 50 个里选。比固定 kk 更灵活。

5. Greedy Decoding(贪心解码)#

每步选概率最大的 token:xt=arg⁡max⁡P(xt∣x<t)x_t = \arg\max P(x_t | x_{\lt t})。

**优点:**最简单、最快、确定性输出。**缺点:**容易陷入重复(总选最高概率 → 生成循环),整体序列不一定是全局最优(每步局部最优 ≠ 全局最优)。

例:局部最优 ≠ 全局最优

翻译 "I love you",第 1 步选了"我"(P=0.9),第 2 步面临选择:

• 选"爱"(P=0.5)→ 后续"你"只有 P=0.6 → 整条路径:0.9 × 0.5 × 0.6 = 0.27

• 选"喜欢"(P=0.4)→ 后续"你"有 P=0.95 → 整条路径:0.9 × 0.4 × 0.95 = 0.342

Greedy 在第 2 步选了"爱"(0.5 > 0.4),但整条序列的总概率反而更低。每步选最大的,拼起来不一定是全局最优。

6. Beam Search(束搜索)#

同时维护 BB 条候选序列(beam),每步对每条候选扩展所有可能的下一个 token,保留总概率最高的 BB 条。是 Greedy 的"宽度优先"版本——B=1B=1 时退化为 Greedy(只有一条路径,累积前缀相同,比较累积概率等价于比较当前步 argmax)。

注意:Beam Search 与 Greedy / Random Sampling 不完全同层——后两者是逐 token 从概率分布中选一个,而 Beam Search 是序列级的多路径搜索,需要等所有路径完成(遇到 EOS)后才能确定最终输出,无法流式逐 token 输出。

score(y1:t)=∑i=1tlog⁡P(yi∣y<i)\text{score}(y_{1:t}) = \sum_{i=1}^{t} \log P(y_i | y_{\lt i})

对数概率求和,避免连乘导致数值下溢

例:B=2 逐步流程

第 1 步,模型输出 P(我)=0.5, P(猫)=0.3, ...。保留 top-2:

• 路径 A:[我] → log P = −0.69

• 路径 B:[猫] → log P = −1.20

第 2 步,对 A 和 B 各自展开所有候选(共 B×V 条),按累积 log P 保留 top-2:

• A 展开:我→喜欢 (−1.20)、我→很 (−2.30)

• B 展开:猫→我 (−2.12)、猫→很 (−2.40)

保留:[我,喜欢] (−1.20) 和 [猫,我] (−2.12)。[我,很] 和 [猫,很] 被淘汰——不同前缀的路径都有机会存活。

后续每步同理,直到生成 <EOS>,从存活路径中选总分最高的。

B 的实际取值:

场景 典型 B 说明
机器翻译 4~5 Google NMT 经典设置
文本摘要 4~6 和翻译类似
语音识别 (ASR) 5~10 搜索空间更大
开放式对话 不用 直接用 Sampling

B 从 1→4 提升明显,4→10 提升很小,继续增大反而质量下降。

"安全但无聊"的两层原因:

**原因一:高概率 ≠ 高质量。**语言模型的概率反映"像不像训练数据中常见的句子"。概率最高的往往是"万金油"表达——"That's a good question." "I don't know." 对任何上下文都适用,但毫无信息量。Beam search 最大化总概率,天然偏向这类泛泛输出。

**原因二:Length bias。**log 概率求和时每多一个 token 就多加一个负数,越长分数越低 → 偏好短句,而短句往往就是那些"安全"的套话。虽然可以用 length normalization 缓解,但只是治标。

7. Random Sampling(随机采样)#

从概率分布中按概率随机抽取一个 token。现代大模型对话的主流采样方式——配合阶段 ① ② 的修剪策略使用。

8. 完整推理流水线#

选择 Random Sampling 时,三个阶段按以下顺序串行执行:

原始 logits
  → ① Repetition Penalty(压低已出现 token 的 logit)
  → ① ÷ Temperature(调整分布形状)
  → softmax(得到概率分布)
  → ② Top-k 或 Top-p(砍掉长尾候选)
  → ② 归一化(重新求和为 1)
  → ③ 随机采样(从幸存者中抽一个 token)

效果逐层传递:一个已出现 token 被 Rep Penalty 压低 logit → 经过 Temperature 和 softmax 后概率更低 → 可能被 Top-p 直接砍出候选池。

9. 常见组合与实际使用#

组合 典型参数 使用场景 / 模型
Greedy T→0 代码补全精确模式(Copilot)、数学推理
Beam Search B=4~5 机器翻译(Google NMT)、语音识别(Whisper)
Temp + Top-p T=0.7, p=0.9 ChatGPT / Claude 对话默认
Temp + Top-p + Rep Penalty T=0.7, p=0.9, θ=1.1 LLaMA / Qwen 开源推理框架(vLLM、llama.cpp)
Temp + Top-k T=0.8, k=40 早期 GPT-2 时代常见,现在较少单独用
Temp + Top-k + Top-p T=0.9, k=50, p=0.95 Hugging Face generate() 支持三者叠加
低温 Sampling T=0.2, p=0.95 代码生成(Claude Code、GPT-4 代码模式)

🔥 面试标准回答

解码策略在三个阶段介入:① softmax 前修改 logits(Repetition Penalty 压低已出现 token,Temperature 调分布形状);② softmax 后修剪候选集(Top-k 按数量截断,Top-p 按累积概率自适应截断);③ 采样(Greedy 取 argmax / Beam Search 多路径搜索 / Random Sampling 随机抽取,三者互斥)。阶段 ① ② 主要为 Random Sampling 设计——Temperature 不改变排名(对 Greedy 无效),Top-k/Top-p 砍掉的尾巴不影响 top-1(对 Greedy 无效),唯一例外是 Repetition Penalty 会改变排名,对 Greedy 也有效。现代大模型对话用 Random Sampling + Temperature + Top-p,典型参数 T≈0.7,p≈0.9T \approx 0.7, p \approx 0.9,代码场景用低温 T≈0.2T \approx 0.2。