上一篇 Transformer 内部结构 把 LLM 拆成了四大块:分词器 / 嵌入层 / 堆叠的 Transformer 块 / 语言建模头。最后一步语言建模头吐出来的是一个长度等于词表大小的概率分布(经过 softmax 归一化的)。
那么问题来了 —— 拿到这堆概率以后,到底要怎么挑出下一个词?
这个"根据概率选择词元的方法",有一个专门的名字:解码策略(decoding strategy)。
常见策略大致两条路:
- 贪婪策略(Greedy):无脑选最大值
- 采样策略(Sampling):引入随机性,增加多样性(Top-k / Top-p / Temperature 都是这一脉的变体)
贪婪策略
每一步都选择当前概率最大的词元作为下一个输出,不考虑后续潜在可能性。
例如当前上下文是"我今天很",模型输出的 softmax 概率如下:
{
开心: 0.61,
累: 0.12,
忙: 0.08,
美丽: 0.04,
... (共 50000 个词)
}如果使用贪婪策略解码,下一词 = 选择概率最大的词 = 开心。
优点:
- 简单易实现
- 速度快(一次 argmax 就完事)
缺点:
- 缺乏多样性:同样的输入每次都会得到同样的输出 —— 适合做翻译 / 摘要这种"答案唯一"的任务,但写故事 / 对话就显得机械
- 容易陷入局部最优:每一步只看眼前最大,可能错过整体更优的句子
采样策略
采样策略是在每一步生成时,不总是选概率最大的词,而是根据 softmax 概率分布进行随机抽样,这样每次生成可能都不一样,增强语言多样性。
例如上面的 softmax 输出为:
{
开心: 0.61,
累: 0.12,
忙: 0.08,
美丽: 0.04,
... (共 50000 个词)
}那么会根据概率随机抽一个:
- 可能是"开心"(61%)
- 也可能是"累"(12%)
- 有小概率是"美丽"(4%)
采样策略的核心思想是:不是总选最有可能的那个词,而是让**"可能性高的词更有可能被选中"**,但不是唯一结果。
优点:
- 多样性高:同样的输入,可以生成多种不同的合理输出
- 更自然:像人说话一样,不会每次都用同一个词
缺点:
- 不可控:输出不可复现,调试痛苦
- 有时会胡说八道(尤其是长尾低概率词被抽到的时候)
温度系数(Temperature)
在采样策略中,可以引入一个温度系数(temperature) 来控制 softmax 概率分布的"陡峭程度",影响模型的"随机性"与"确定性"。
原理
默认 softmax 的计算方式如下:
probs = softmax(logits) // 将分数转为概率加入温度 T 后,变为:
probs = softmax(logits / T)其中:
- T 是一个正数(一般取值 0.5 ~ 2)
- logits 除以 T 之后,整个分布会变化
温度的影响
| 温度 T | 分布特征 | 解码表现 |
|---|---|---|
| T < 1 | 更尖锐 | 更偏向高概率词 |
| T = 1 | 原始分布 | 标准采样 |
| T > 1 | 更平坦 | 更倾向随机、多样化 |
示例说明
仍以上面的 logits 为例:
{
开心: 4.2,
累: 2.7,
忙: 1.5,
昨天: -1.2,
小狗: -3.5
}不同温度下的行为:
- T = 1:"开心"(61%)仍最可能,但其他词有较低概率
- T = 0.5:"开心"更具压倒性优势(例如 > 80%)
- T = 2.0:其他词概率显著提升,分布变"平",冷门词有机会被选中
温度越低,越倾向于选择高概率的词;温度越高,越倾向于选择其他词。
最佳实践
- 想生成"稳定 / 一致性强"的结果 → 使用低温度(如 T = 0.7)
- 想生成"有创意 / 更多样"的结果 → 使用高温度(如 T = 1.5)
- 想完全去掉随机性 → T → 0 时,采样退化成贪婪策略
总结一句话:温度系数是控制生成文本"保守"还是"放飞"的旋钮。
其他解码策略
除了贪婪策略和带温度的采样,还有几种常用的"中庸"做法,本质上都是想在确定性和多样性之间找平衡:
| 策略 | 每一步做什么 | 效果 |
|---|---|---|
| 贪婪解码 | 选概率最大 | 单一、重复、稳定 |
| 采样(随机) | 根据概率随机选一个词 | 多样、有趣但不稳定 |
| Top-k | 只在概率前 k 名中随机选 | 控制随机性 + 保留合理选项 |
| Top-p(nucleus) | 在累计概率 > p 的词中随机选 | 更智能的采样策略 |
| Beam Search | 保留多个候选句分支并评分 | 更接近全局最优,但计算更贵 |
简单展开下后三种:
- Top-k:把候选限制在概率前 k 名(比如 k = 50),其他词概率清零再重新归一化、再采样。好处是直接砍掉长尾里的低质量词;坏处是 k 是固定的,有些场景概率分布很尖锐(前 1 名占 90%),用 k = 50 跟贪婪也差不多;有些分布很平坦,k = 50 又不够覆盖。
- Top-p (nucleus sampling):把候选限制在"累计概率刚好 ≥ p"的最小集合里(比如 p = 0.9 表示选出累计概率达到 90% 的最少个词)。比 Top-k 聪明在它自适应:分布尖锐时只保留几个,分布平坦时保留几十上百个。
- Beam Search:同时维护 k 条候选完整序列(beam),每一步都向后扩展,按总概率排序保留前 k 条。好处是不容易陷入局部最优,翻译 / 摘要这种重视准确性的任务里很常用;坏处是计算量翻 k 倍,而且生成的句子容易重复 / 缺乏惊喜(因为它在追求"整体最稳"的路径)。
实际工程里,Top-p + Temperature 是目前最常见的组合(OpenAI、Anthropic、几乎所有开源 LLM 推理参数里都有这两项)。Top-k 偶尔搭配用,Beam Search 多见于翻译和代码补全。
下次见。
-EOF-