解码策略 - 控制 LLM 输出的艺术 / Decoding Strategies for Controlling LLM Output
📅 创建时间:2026-04-28 🏷️ 标签:#解码策略 #Temperature #Top_p #生成控制 📚 前置知识:[[02 - Token 与上下文窗口]]
📋 本章目标
- 理解 LLM 生成文本的基本原理
- 掌握 Temperature 参数的作用和调节方法
- 理解 Top_p(核采样)的原理
- 了解 Max_tokens 和 Repetition_penalty
- 能够根据场景选择合适的解码参数
第1部分:LLM 如何生成文本?
1.1 生成过程概述
LLM 生成文本是一个逐 Token 生成的过程:
┌─────────────────────────────────────────────────────────────┐
│ 文本生成过程 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 输入:"今天天气" │
│ │
│ Step 1:预测第一个 Token │
│ ┌─────────────────────────────────────┐ │
│ │ "今天天气" → 预测 → "很好" (0.7) │ │
│ │ → 预测 → "不错" (0.2) │ │
│ │ → 预测 → "怎样" (0.1) │ │
│ └─────────────────────────────────────┘ │
│ ↓ │
│ Step 2:根据概率采样下一个 Token │
│ ↓ │
│ Step 3:将选中的 Token 加入输入,重复 │
│ ↓ │
│ 最终输出:"今天天气很好,适合出去玩。" │
│ │
└─────────────────────────────────────────────────────────────┘1.2 概率分布
每个位置,LLM 输出一个概率分布:
当输入是"今天天气"时,模型预测下一个词的概率分布:
Token 概率
─────────────────────
"很好" 0.45
"不错" 0.25
"怎么样" 0.15
"糟糕" 0.10
"一般" 0.05
总和 1.00问题:如何从这个概率分布中选择下一个 Token?
第2部分:Temperature - 控制随机性
2.1 什么是 Temperature?
Temperature(温度)= 控制输出的"随机程度"
┌─────────────────────────────────────────────────────────────┐
│ Temperature 效果 │
├─────────────────────────────────────────────────────────────┤
│ │
│ Temperature = 0(低) │
│ ┌─────────────────────────────────────┐ │
│ │ 概率分布: │ │
│ │ "很好" ████████████████████████████ 82% │
│ │ "不错" ███ 5% │
│ │ 其他 ██ 3% │
│ │ │ │
│ │ 特点:几乎总是选最高概率的词 │ │
│ │ 结果:确定性输出,变化少 │ │
│ └─────────────────────────────────────┘ │
│ │
│ Temperature = 1(中等) │
│ ┌─────────────────────────────────────┐ │
│ │ 概率分布: │ │
│ │ "很好" ████████████ 45% │
│ │ "不错" █████████ 25% │
│ │ "怎么样" ██████ 15% │
│ │ 其他 █████████ 15% │
│ │ │ │
│ │ 特点:保持原始概率分布 │ │
│ │ 结果:平衡随机性与准确性 │ │
│ └─────────────────────────────────────┘ │
│ │
│ Temperature = 2(高) │
│ ┌─────────────────────────────────────┐ │
│ │ 概率分布(被"拉平"): │ │
│ │ "很好" ████████ 22% │
│ │ "不错" ████████ 20% │
│ │ "怎么样" ████████ 19% │
│ │ 其他 ███████████████████ 39% │
│ │ │ │
│ │ 特点:所有选项概率趋于相等 │ │
│ │ 结果:高度随机,可能出现意外输出 │ │
│ └─────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘2.2 Temperature 的数学原理
Temperature 通过"重新加权"概率分布:
原始概率分布:P = [p₁, p₂, p₃, ..., pₙ]
应用 Temperature:
P' = softmax(P / T)
其中 T 是 Temperature具体数值示例:
假设有一个简单分布:
P = [0.7, 0.2, 0.1] (三个候选词的概率)
当 T = 0.5(低):
P' = softmax([0.7/0.5, 0.2/0.5, 0.1/0.5])
= softmax([1.4, 0.4, 0.2])
= [0.82, 0.12, 0.06] ← 高概率更突出
当 T = 2.0(高):
P' = softmax([0.7/2, 0.2/2, 0.1/2])
= softmax([0.35, 0.1, 0.05])
= [0.58, 0.29, 0.13] ← 概率被拉平公式可视化:
P'(x) = exp(log(P(x)) / T) / Σ exp(log(P(i)) / T)
Temperature 影响:
- T < 1:放大高概率,压低低概率 → 更确定
- T = 1:保持原始分布
- T > 1:缩小概率差距 → 更随机
- T → 0:只选最高概率 → 贪婪解码2.3 Temperature 场景选择
| Temperature | 适用场景 | 不适用场景 | 示例 |
|---|---|---|---|
| 0.0-0.3 | 代码生成、数学计算 | 需要创造性的任务 | 写函数、debug |
| 0.3-0.7 | 一般对话、问答 | 需要精确答案 | 聊天、解释概念 |
| 0.7-1.0 | 有创意的写作 | 需要严谨内容 | 故事创作、头脑风暴 |
| 1.0+ | 高度随机 | 实际应用 | 实验、抽奖 |
2.4 具体场景示例
场景1:写代码
Prompt: "写一个 Python 函数计算斐波那契数列"
Temperature = 0.0(最确定)
结果:每次生成几乎相同的标准实现
Temperature = 1.0
结果:可能生成各种变体,有的甚至有 bug场景2:写诗
Prompt: "写一首关于春天的诗"
Temperature = 0.0
结果:每次都是相似的模板诗
Temperature = 1.0
结果:每次都不同,可能有意想不到的意象第3部分:Top_p - 核采样
3.1 什么是 Top_p?
Top_p(核采样)= 只考虑概率最高的那部分 Token
核心思想:不按概率阈值选择,而是按"累积概率"选择
3.2 具体工作原理
假设候选 Token 按概率排序:
Token 概率 累积概率
─────────────────────────────
"猫" 0.40 0.40
"狗" 0.25 0.65
"鸟" 0.15 0.80
"鱼" 0.10 0.90
"虫" 0.05 0.95
"其他" 0.05 1.00
当 Top_p = 0.9 时:
选择累积概率达到 90% 的 Token,即 ["猫", "狗", "鸟", "鱼", "虫"]
排除概率最小的"其他"3.3 Top_p 的效果可视化
Top_p = 0.9(高,覆盖面广)
┌─────────────────────────────────────┐
│ ████████████████████████████████ │ "猫" 40%
│ ███████████████████ │ "狗" 25%
│ █████████████ │ "鸟" 15%
│ ██████████ │ "鱼" 10%
│ █████ │ "虫" 5%
│ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ │ "其他" 5% ← 被排除
└─────────────────────────────────────┘
选中前 5 个,共 95% 概率质量
Top_p = 0.5(低,只选最高)
┌─────────────────────────────────────┐
│ ████████████████████████████████ │ "猫" 40%
│ ███████████████████ │ "狗" 25%
│ █████████████ │ "鸟" 15% ← 被排除
│ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ │ "鱼" 10% ← 被排除
│ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ │ "虫" 5% ← 被排除
│ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ │ "其他" 5% ← 被排除
└─────────────────────────────────────┘
只选前 2 个,共 65% 概率质量3.4 Top_p 的数学原理
1. 将所有 Token 按概率从高到低排序
2. 依次累加概率,直到达到 Top_p 阈值
3. 只从这批 Token 中采样
公式:
候选集合 = {tokens | 累积概率(token) ≤ Top_p}3.5 Top_p 与 Temperature 的对比
| 特性 | Temperature | Top_p |
|---|---|---|
| 作用对象 | 概率分布的形状 | 候选 Token 的范围 |
| 控制方式 | 缩放概率值 | 截断概率分布 |
| 类比 | "让差异更大/更小" | "只考虑最好的几个" |
| 常见值 | 0.0-2.0 | 0.0-1.0 |
3.6 组合使用
常见最佳实践:
建议同时设置 Temperature 和 Top_p,但只调整其中一个:
- Temperature = 0.7, Top_p = 1.0 ← 主要用 Temperature 控制
- Temperature = 1.0, Top_p = 0.9 ← 主要用 Top_p 控制为什么不能同时大幅调整?
同时把 Temperature 调高 + Top_p 调低 = 极度随机 + 极少候选
= 可能只能从 1-2 个 token 中选,结果反而受限第4部分:其他解码参数
4.1 Max_tokens - 生成长度限制
作用:限制单次生成的最大 Token 数
使用场景:
- 控制响应长度
- 防止无限生成
- 配合上下文窗口限制注意事项:
如果设置的 Max_tokens 太小:
输出会被截断,可能只说了一半
示例:Prompt 要求详细解释,但 Max_tokens = 50
结果:"人工智能是一种计算机科学..."
(只生成了半句话)4.2 Repetition_penalty - 重复惩罚
作用:防止模型重复生成相同的词
问题示例:
没有 Repetition_penalty 时,模型可能输出:
"我喜欢猫,猫猫猫猫猫猫猫猫猫..."
加入 Repetition_penalty 后:
已生成过的词的概率会被降低数学原理:
如果一个 Token 已经被使用过:
P'(x) = P(x) / penalty (penalty > 1)
例如 penalty = 1.2:
第二次出现概率降低为 P(x) / 1.2
第三次出现概率降低为 P(x) / 1.2²
...使用建议:
Repetition_penalty = 1.0:正常生成
Repetition_penalty = 1.1-1.2:轻度惩罚,防止简单重复
Repetition_penalty = 1.5+:重度惩罚,用于强制多样化4.3 Stop Sequences - 停止序列
作用:当生成到指定内容时停止
使用示例:
response = client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": "列出5个城市"}],
stop=["6.", "六、"], # 遇到这些序列就停止
)应用场景:
- 生成列表时限制数量
- 生成多段内容时分离
- 控制输出格式第5部分:完整参数组合示例
5.1 场景:正式邮件写作
response = client.chat.completions.create(
model="gpt-4",
messages=[
{"role": "system", "content": "你是一个专业的商业邮件助手"},
{"role": "user", "content": "写一封请假邮件"}
],
temperature=0.3, # 保持正式、专业
top_p=0.9, # 保持自然
max_tokens=500, # 邮件不需要太长
repetition_penalty=1.1, # 轻微防止重复
)预期效果:
- 语言正式、结构清晰
- 每次生成内容相似(确定性)
- 不会无限重复相同的词
5.2 场景:创意故事写作
response = client.chat.completions.create(
model="gpt-4",
messages=[
{"role": "system", "content": "你是一个创意作家"},
{"role": "user", "content": "写一个关于时光旅行的短故事开头"}
],
temperature=0.9, # 高随机性,有创意
top_p=0.95, # 考虑更多选项
max_tokens=800, # 故事需要一定长度
repetition_penalty=1.0, # 不需要额外惩罚
)预期效果:
- 每次生成故事都有新意
- 可能有意想不到的情节
- 内容丰富、有创意
5.3 场景:代码生成
response = client.chat.completions.create(
model="gpt-4",
messages=[
{"role": "user", "content": "写一个 Python 快排算法"}
],
temperature=0.0, # 确定性,代码必须正确
top_p=1.0, # 不需要 Top_p 筛选
max_tokens=300, # 快排不需要太长
repetition_penalty=1.0,
)预期效果:
- 生成标准、正确的快排实现
- 每次生成几乎相同
- 不需要创意变化
5.4 场景:头脑风暴
response = client.chat.completions.create(
model="gpt-4",
messages=[
{"role": "system", "content": "你是一个创新顾问"},
{"role": "user", "content": "给出5个解决城市交通拥堵的创意方案"}
],
temperature=1.0, # 最高随机性
top_p=0.8, # 考虑更多可能性
max_tokens=1000,
repetition_penalty=1.2, # 强制多样化
)预期效果:
- 尽可能多样的创意
- 可能出现非常规想法
- 每个回答都有新意
核心总结
总结1:解码策略控制的是"选择过程"
Token 生成 = 从概率分布中"抽样"
解码策略 = 如何进行这个抽样总结2:Temperature 控制概率分布形状
| Temperature | 效果 |
|---|---|
| 0.0 | 几乎贪婪,几乎总是最高概率 |
| 0.5-0.7 | 略微随机,保持一定稳定性 |
| 1.0 | 保持原始分布 |
| 1.5-2.0 | 高度随机,可能不连贯 |
总结3:Top_p 控制候选 Token 范围
| Top_p | 效果 |
|---|---|
| 0.5 | 只考虑最高概率的少数几个 |
| 0.9 | 考虑概率质量的前 90% |
| 1.0 | 考虑所有 Token |
总结4:场景推荐参数
| 场景 | Temperature | Top_p |
|---|---|---|
| 代码生成 | 0.0-0.3 | 1.0 |
| 正式写作 | 0.3-0.5 | 0.9 |
| 一般对话 | 0.7 | 0.9 |
| 创意写作 | 0.8-1.0 | 0.95 |
| 头脑风暴 | 1.0+ | 0.8 |
章节测试
测试1:Temperature 影响
如果一个词的概率是 0.8,当 Temperature = 0.5 时,这个概率会变得更接近 1 还是更接近 0.5?
测试2:Top_p 理解
假设有 5 个 Token,概率分别是 0.5, 0.25, 0.15, 0.05, 0.05。 如果设置 Top_p = 0.9,会选中哪几个 Token?
测试3:场景选择
用户想要生成一个数学证明的解题步骤,应该设置什么样的 Temperature?
测试4:参数冲突
同时设置 Temperature = 2.0 和 Top_p = 0.1 可能导致什么问题?
测试5:Repetition_penalty
如果不设置 Repetition_penalty,模型可能会输出什么问题?
参考答案
测试1答案
答案:更接近 1
解析:
Temperature < 1 时,会放大高概率和压低低概率之间的差距
P' = P / T = 0.8 / 0.5 = 1.6(未归一化值)
经过 softmax 后会接近 1测试2答案
答案:前 4 个 Token
计算过程:
Token 概率 累积概率
─────────────────────────────
"猫" 0.50 0.50
"狗" 0.25 0.75
"鸟" 0.15 0.90 ← 正好达到 0.9
"鱼" 0.05 0.95 ← 超过 0.9,但仍被选中(因为包含了之前的)
"虫" 0.05 1.00注意:Top_p = 0.9 时,会选择累积概率"首次"达到或超过 0.9 的 Token 集合,即前 4 个。
测试3答案
答案:Temperature = 0.0 或 0.1-0.3
解析:
数学证明需要:
- 确定性:同样的输入得到确定性的输出
- 准确性:不能有随机性导致的错误
- 可重复性:多次生成结果一致
因此应该使用低 Temperature测试4答案
答案:输出会极度不稳定、不可预测
解析:
Temperature = 2.0:高度随机,拉平概率分布
Top_p = 0.1:只考虑概率最高的 10%
组合效果:
- 概率被拉平后,所有词概率接近
- 然后只取最高概率的 10%
- 结果几乎变成确定性,但方向随机
- 可能导致输出质量下降最佳实践:通常只调整一个参数,保持另一个为默认值
测试5答案
答案:可能出现重复内容
示例:
可能输出:
"人工智能是...人工智能是...人工智能是..."
或者
"猫和狗的关系,猫和狗的关系,猫和狗的关系..."Repetition_penalty 的作用:
对已经出现过的 Token 降低其概率
第二次出现:P' = P / 1.2
第三次出现:P' = P / 1.2²
...
使得模型更倾向于选择新的、未出现过的词相关笔记
- [[02 - Token 与上下文窗口]] - Token 生成的基础
- [[04 - 消息角色]] - 对话结构与 API 调用
- [[06 - Prompt 工程]] - 通过 Prompt 引导输出
下一步学习
- [ ] 阅读 04 - 消息角色
学习状态:✅ 已完成