1023 words
5 minutes
【八股】Decoding 相关

每次预测下一个 token 的时候直接选概率最大的单词,将选中的 token 加入序列,直接下一个。问题在于一旦有一个 token 选错了会直接影响后续选择,而且容易陷入局部最优。

该方法是对贪心的一种改进,再每一步不再去保留最高概率单词,而是设置一个大小为 kk 的候选序列集合,每次从每个序列选概率最高的 kk 个单词,保留总概率最高的 kk 个序列,属于一种启发式搜索算法,当 k=1k=1 时退化为 Greedy Search。这种方法可以平衡生成质量和多样性,但也可能导致生成文本不自然。

3. Top-k#

从备选 token 里选 kk 个概率最大的,从这 kk 个里面随机抽一个作为下一个 token 。当 k=1k=1 时退化为 Greedy Search。这样可以避免采样到一些不合适或不相关的单词,同时也可以保留一些有趣或有创意的单词。缺点在于 kk 是“硬阈值”,不随上下文自适应:有些位置模型分布很尖(只需要很小 kk),有些位置很平(需要更大 kk);固定 kk 可能要么过保守,要么过随机。

工作流程:

  1. Transformer 前向得到 logits(维度 vocab_size)。

  2. 取 logits 最大的 kk 个 token(每个 batch 各自取)。

  3. 其余 token 的 logits 设为 -∞

  4. 对剩下的 logits 做 softmax 得到概率,并采样一个 token(或在这 k 个里取最大也可以,但那就变贪心了)。

kk 越大生成多样性越高,越小生成质量越高 ,可以根据不同任务选择合适的 kk ,也可以配合温度、重复惩罚等食用,进一步优化生成效果。

4. Top-p(核采样)#

在每一步,只从累积概率超过某个阈值 pp 的最小单词集合中进行随机采样,而不考虑其他低概率的单词。因为集合大小会随当前分布形状自适应变化,所以比 top-k 更“自适应”。

工作流程:

  1. 模型输出 logits → softmax 得到概率分布 P(token)P(\text{token})

  2. 按概率从高到低排序:p1p2...p_1 \ge p_2 \ge ...

  3. 从最大开始累加,找到最小的集合 SS,使得 tSP(t)p\sum_{t\in S} P(t) \ge p(比如 p=0.9p=0.9)。

  4. 把集合外 token 的概率置 00(实现上把 logits 设为 -∞),对集合内重新归一化。

  5. 在集合内采样得到 next token。

Top p 的主要问题在于对长尾处理较差,Top p 的边界由累计和决定:只要长尾里有足够多 token 的小概率累加进来,它们就可能进入 nucleus。尤其当 pp 设得很高,一些低质量但仍被纳入集合的 token 会被采样到,造成事实错误、重复、乱码、突然插入奇怪词等。

5. Temperature#

Temperature 受热力学启发,是解码阶段最常用的随机性旋钮。它不改模型参数,只改采样分布的形状,把模型输出的 logits 做一次缩放,再 softmax 得到新概率分布。

Temperature 不是采样策略,只是对模型的输出概率分布进行缩放。可以把 Temperature 和这些策略组合使用,常见组合是:Top-k + Temperature 或 Top-p + Temperature。Beam Search 通常不搭配 Temperature。

Temperature 采样和玻尔兹曼分布是同一个形式,给定 logits(zi)logits (z_i),温度 T>0T>0

pi(T)=exp(zi/T)jexp(zj/T)p_i(T)=\frac{\exp(z_i/T)}{\sum_j \exp(z_j/T)}

比较细心的朋友可能会发现这个东西跟softmax长得很像啊,没错,我们可以把他理解成先把 logits 除以 TT,再做 softmax。

瞪眼观察一下可以发现:

T<1T<1(降温):分布变“尖”。高概率 token 更占优势,采样更接近贪心,输出更稳定、更保守,但更容易模板化、重复、缺少创意。

T=1T=1:原始模型分布,不做温度调整。

T>1T>1(升温):分布变“平”。低概率 token 被抬高,更随机、更发散,多样性提升,但更容易跑题、胡话、事实错误、语法漂移。

【八股】Decoding 相关
https://fuwari.vercel.app/posts/note/decoding/
Author
P19E99
Published at
2026-02-12
License
CC BY-NC-SA 4.0