解码与生成
- 解码过程如何从 logits 变成 token。
- 常见解码策略。
- 解码策略对生成随机性和模型性能的影响。
本篇与 《Token 与概率》 篇内容与重叠,可以对比、结合起来阅读。
在前几篇中,已经讨论过 token、logits、softmax、next token prediction 和 Transformer 等内容。
解码与生成关注的是下一步:模型已经给出 logits 后,系统如何选择 token,并继续生成后续内容。
- 解码是从 logits 中选择下一个 token 的过程。
- 生成是反复执行 next token prediction;
特别重要的是,解码过程对 LLM 生成的随机性有很大影响,这也是解码过程值得我们特别关注的原因。
1. 生成的基本流程
1.1 自回归生成
现代 Decoder-only LLM 的文本生成通常是自回归的:
- 给定当前上下文,模型预测下一个 token;
- 选出 token 后,将它接回上下文,再预测下一个 token。
当前上下文
- 模型前向计算 -> logits
- 解码 -> 下一个 token
-> 追加该 token 到上下文
-> 重复继续下一步
因此,模型不是一次性生成整段文本,而是逐 token 生成。每一步新生成的 token 都会改变后续上下文,并影响后续概率分布。
1.2 解码
模型输出的是 logits(一般是由 LM Head 处理 hidden state 得到的),而不是直接输出最终 token。
Logits 可以理解为词表中每个 token 的原始分数,经过 softmax 后得到下一个 token 的概率分布表示。
解码策略作用在从 logits 到选择 token 的这一步:
logits -> softmax 得到概率分布 -> 选择 token
不同解码策略会使用同一组 logits 得到不同 token。
因此,同一个模型、同一个 prompt,在不同解码参数下可能产生不同输出。
2. Temperature
在解码的 softmax 过程中,通常会涉及 Temperature 概念- 用于调整概率分布。
常见形式是:
其中 T 就是 Temperature, z_i 是各个 token 对应的 logit, p_i 是各个 token 对应的概率。
从公式中可以看出,Temperature 值的大小会对概率分布的影响如下:
| Temperature 值 | 效果 | 常见场景 |
|---|---|---|
| 接近 0 | 分布更尖锐,接近 greedy | 抽取、分类、结构化输出 |
| 0.2 - 0.5 | 稳定但保留少量变化 | 问答、总结、说明 |
| 0.6 - 0.9 | 输出更开放 | 创作、头脑风暴 |
| 大于 1.0 | 随机性更强 | 多样化探索,风险更高 |
3. 确定性解码与采样
3.1 Greedy Decoding
Greedy decoding 是最简单的策略 - 每一步都选择概率最高的 token。
作为一种确定性解码策略,Greedy 的特点是输出稳定、可复现性强、实现简单,适合分类、抽取、格式转换、数据清洗、代码修复等确定性较强的任务。
但它每一步只做局部最优选择,容易输出保守,也可能陷入重复或模板化表达。
3.2 Sampling 采样
Sampling 策略一般是从候选集中随机选取 token。
Sampling 适用于开放式任务,例如创意、头脑风暴和对话风格变化,而不适合对稳定性要求较高的任务,如结构化输出、事实回答等。
Sampling 不能提高模型能力,而是改变输出分布从而提高多样性,也会增加不稳定性和编造细节的风险。
3. 候选集合
在 softmax 得到概率分布后,Sampling 策略可能会使用不同的方法确定 token 候选集合,在候选集合中进行随机采样。
注:这里的 "随机采样" 实际上是指计算机中的伪随机,一般可以通过 seed (随机数种子) 来控制这种随机性。
3.1 Top-p
Top-p 又称 nucleus sampling,它会按概率从高到低累加 token 概率,保留累计概率达到 的最小候选集合然后随机采样。
例如:
| token | 概率 | 累计概率 |
|---|---|---|
| A | 0.50 | 0.50 |
| B | 0.25 | 0.75 |
| C | 0.12 | 0.87 |
| D | 0.08 | 0.95 |
| E | 0.05 | 1.00 |
如果 top_p = 0.9,候选集合会保留 A、B、C、D,因为累计到 D 才超过 0.9。
如果 top_p = 0.8,候选集合会保留 A、B、C,因为累计到 C 才超过 0.8。
Top-p 方法的特点是自适应:模型很确定时,候选集合较小;模型不确定时,候选集合较大。
3.2 Top-k
Top-k 只保留概率最高的 k 个 token,然后在其中采样。
例如 top_k = 3:
| token | 概率 | 是否保留 |
|---|---|---|
| A | 0.50 | 是 |
| B | 0.25 | 是 |
| C | 0.12 | 是 |
| D | 0.08 | 否 |
| E | 0.05 | 否 |
Top-k 简单可控,但不如 top-p 自适应:如果模型很确定,固定 k 可能保留过多候选;如果模型很不确定,固定 k 又可能过窄。
3.3 参数关系
Temperature、top-p、top-k 都会影响采样,但作用不同。
| 参数 | 数学意义 | 影响 |
|---|---|---|
| temperature | 调整概率分布 | 控制稳定性与随机性 |
| top_p | 按累计概率截断候选集合 | 保留核心概率质量 |
| top_k | 按数量截断候选集合 | 限定候选 token 数量 |
常见配置原则:
- 稳定任务:greedy 策略或低 temperature,必要时降低 top_p。
- 创作任务:中等 temperature,较高 top_p。
- 严格格式任务:在稳定任务的基础上,还要结合 schema、parser 或 function calling 等。
4. 多序列与重复性惩罚
4.1 Beam Search
Beam search 会同时保留多个候选序列,而不是每一步只保留一个 token。
例如 beam size = 3 时,系统会维护当前得分最高的 3 条路径:
路径 A: 今天天气很好
路径 B: 今天的天气不错
路径 C: 今天阳光很好
每一步扩展这些路径,再保留总分最高的若干条。
Beam search 适合候选答案相对受限、有明确目标的任务,例如传统翻译、摘要等 seq2seq 任务。
但它成本随 beam size 增加,在开放式对话和创作任务中不一定优于 sampling,输出也可能更保守。
4.2 Repetition Penalty
Repetition penalty 用于降低重复 token 或重复片段的概率。
相关参数包括:
| 参数 | 含义 |
|---|---|
| repetition_penalty | 惩罚已经出现过的 token |
| frequency_penalty | 出现次数越多,惩罚越强 |
| presence_penalty | 只要出现过就施加惩罚 |
| no_repeat_ngram_size | 禁止重复 n-gram |
这些参数可以缓解重复,但过强会破坏必要重复,例如专业术语、代码变量名、列表编号、固定格式和引用标记。
5. 随机性
5.1 随机性来源
粗略地讲,对于确定的输入,在模型权重确定的情况下,模型前后计算得到的 logits 是确定的。
而同一个 prompt 多次生成可能得到不同答案,这种随机性主要来源于解码阶段。影响随机性的因素包括:
- temperature。
- top_p / top_k。
- 随机种子 seed。
另外,并发和浮点计算细节、speculative decoding 也会决定是否能复现输出。
如果需要更强复现性,应固定 prompt、seed 和推理参数,并使用 greedy 或低随机性配置。
5.2 任务配置
对于不同的场景和任务,我们可以通过设置解码参数来取得更好的模型表现:
| 场景类型 | 典型任务 | 建议参数 |
|---|---|---|
| 确定性任务 | 分类、信息抽取、代码 / 工具调用 | T: 0 ~ 0.3,top_p: 0.8 ~ 1.0,通常不需要多候选 |
| 平衡型任务 | 总结、代码生成、常规问答、文档改写 | T: 0.3 ~ 0.7,top_p: 0.8 ~ 0.95,必要时生成 1~3 个候选 |
| 发散型任务 | 创意、头脑风暴、多方案设计 | T: 0.7 ~ 1.2,top_p: 0.9 ~ 1.0,可多次采样生成多个候选 |
多数场景优先调 T 和 top_p 即可。
top_k 如果可用,一般作为候选 token 数量的硬限制:
- 需要更强约束时,可设置较小的
top_k; - 需要更开放的生成时,可提高或不限制
top_k。
6. 停止条件
生成需要明确停止条件,否则模型会继续预测后续 token。
常见停止条件包括:
| 停止条件 | 条件来源 | 停止时机 |
|---|---|---|
| EOS token | tokenizer 中定义,作为模型生成停止的默认值 | 生成到 eos_token_id 后 |
| max_tokens / max_length | 推理服务设置或者用户显式传入 | 生成特定的 token 数量后 |
| stop sequence | 用户显式传入 | 生成特定的停止字符串后 |
| 用户中断 | 模型调用时 | 用户主动停止 |
7. 性能影响
解码与生成会直接影响推理成本,主要体现在下面一些方面:
| 成本来源 | 典型参数 / 策略 | 性能影响 |
|---|---|---|
| 单步解码开销 | Greedy / Sampling | Greedy 最简单;Sampling 增加少量分步处理与采样开销 |
| 搜索分支数 | Beam search / 多候选生成 | 需要同时维护多条生成路径,成本大致随 num_beams 或候选数增加 |
| 输出长度 | max_tokens / max_lenth / stop 条件 | 输出越长,decode 轮数越多,端到端延迟和 KV cache 占用越高 |
服务化场景通常需要限制 max_tokens、num_beams、候选数量、超时时间,并设置合理的 stop 条件,避免单次请求占用过多 decode 步数,导致成本不可控和长尾延迟上升。
总结
解码与生成连接了模型输出层和最终文本:
- 模型每一步输出 logits,经过 temperature、候选集合约束和随机采样等具体解码策略处理后选定下一个 token。
- 被选中的 token 会追加回上下文,继续参与下一步 next token prediction 即自回归生成。
解码策略和参数影响输出随机性和推理成本。