Top-p 采样(Nucleus Sampling)

解码策略:将 token 按概率从高到低排序,选取累积概率刚超过阈值 p 的最小集合,在其中采样。比 Top-k 更自适应——分布集中时候选少,分散时候选多。

Top-p 采样(Nucleus Sampling)

一句话理解

Top-p 采样就是"凑够 p 就停"——按概率从高到低累加,累加到 p(比如 0.9)就截止,只在这些 token 里采样。

工作原理

  1. 模型输出概率分布,按概率从高到低排序
  2. 从最高概率开始累加,直到累积概率首次超过阈值 ppp
  3. 只保留这些 token,重新归一化
  4. 在保留的集合中按概率采样
python
def top_p_sample(probs, p=0.9):
    sorted_indices = np.argsort(probs)[::-1]    # 从高到低排序
    sorted_probs = probs[sorted_indices]
    cumsum = np.cumsum(sorted_probs)
    cutoff = np.searchsorted(cumsum, p) + 1      # 累加到 p 的位置
    top_indices = sorted_indices[:cutoff]
    top_probs = probs[top_indices]
    top_probs = top_probs / top_probs.sum()
    return np.random.choice(top_indices, p=top_probs)

自适应的核心优势

同样设 p=0.9p = 0.9p=0.9

场景概率分布候选数说明
高确信[0.92, 0.04, 0.02, ...]1第一个就超过 0.9,几乎贪心
低确信[0.15, 0.12, 0.11, 0.10, ...]~8需要累加多个才到 0.9

Top-k 不管分布形状都选固定 k 个;Top-p 根据分布动态调整——这就是"Nucleus"(核心)的含义:只采样概率质量的核心部分。

为什么叫 Nucleus Sampling

2019 年 Holtzman 等人的论文《The Curious Case of Neural Text Degeneration》提出这个方法时,称之为"nucleus sampling"——"nucleus"指的是概率分布中占据主要质量的核心区域。论文发现 Top-k 在实践中要么过于保守要么过于激进,而 Top-p 能自适应地调整候选集大小。

实践建议

  • OpenAI API 默认 p=1.0p = 1.0p=1.0(不截断),常用值 p=0.90.95p = 0.9 \sim 0.95p=0.90.95
  • 通常和 Temperature 配合:先用 Temperature 调分布形状,再用 Top-p 截尾
  • 避免同时用 Top-k 和 Top-p——两者功能重叠,选一个即可