LLM 中的 Temperature
LLM 中的 Temperature:三种难度的解释
Section titled “LLM 中的 Temperature:三种难度的解释”🟢 入门:一句话版
Section titled “🟢 入门:一句话版”Temperature 就是控制 AI 回答时有多「保守」还是多「大胆」。
- Temperature = 0:每次都选最确定的答案(比如问「1+1=?」,永远答「2」)
- Temperature = 1:按正常概率回答(自然但有变化)
- Temperature = 2:非常大胆,经常说出意外的回答(适合脑暴)
类比:就像选餐厅吃饭。Temperature 0 永远去评分最高的那家;Temperature 2 随便挑,可能发现惊喜也可能踩雷。
🟡 中级:概率与采样
Section titled “🟡 中级:概率与采样”Temperature 控制的是 softmax 之后、采样之前的一个缩放参数。
核心公式:
P(x_i) = exp(z_i / T) / Σ exp(z_j / T)其中 z_i 是模型输出的 logits,T 是 temperature。
关键机制:
- T → 0:概率分布趋向 one-hot,最高 logit 的概率趋近于 1.0(贪心采样)
- T = 1:原始 softmax 概率,不缩放
- T → ∞:概率分布趋向均匀分布,所有 token 等概率
实践中:
| Temperature | 适用场景 | 风险 |
|---|---|---|
| 0.0 - 0.3 | 代码生成、翻译、事实问答 | 回复机械、重复 |
| 0.3 - 0.7 | 日常对话、写作辅助 | 较低 |
| 0.7 - 1.0 | 创意写作、脑暴 | 可能产生幻觉 |
| > 1.0 | 实验性生成 | 输出质量急剧下降 |
经验法则:大多数任务 0.3 - 0.7 是甜点区。代码和数学任务建议低于 0.3。
🔴 高级:深入理解与工程实践
Section titled “🔴 高级:深入理解与工程实践”为什么是指数缩放?
Section titled “为什么是指数缩放?”Temperature 的数学本质是对 logits 空间的「温度」参数化,灵感来自统计力学中的 Boltzmann 分布。这不是随便取的——它有以下良好性质:
- 单调性:T 越大,分布越平滑,这是一个严格的单调关系
- 归一化不变性:除以 T 不改变 argmax,只改变分布的「尖锐程度」
- 可微性:温度是连续可微的,便于优化(如蒸馏中的温度调节)
Top-p (nucleus sampling) vs Temperature
Section titled “Top-p (nucleus sampling) vs Temperature”这两个经常被混淆,但作用完全不同:
- Temperature:全局缩放整个概率分布,影响所有 token 的相对概率
- Top-p:局部截断概率尾部,只从累积概率 ≥ p 的最小 token 集合中采样
最佳实践是两者结合使用:
# 推荐配置generation_config = { "temperature": 0.7, # 控制随机性 "top_p": 0.95, # 过滤低质量 token "top_k": 50, # 额外安全网}Temperature Scaling 的其他应用
Section titled “Temperature Scaling 的其他应用”- 知识蒸馏:教师模型用高 T(如 4.0)产生「软标签」,让学生学到更多 logit 间的关系信息
- 校准(Calibration):训练后学习一个标量 T 来校准模型置信度,使 P(correct) ≈ confidence
- 对比解码:同时从 T=1 和 T→0 采样,取差异最大的 token,可以增强模型知识和减少幻觉
- ❌ “Temperature 越高越有创意” — 超过 1.0 后质量快速下降,不是线性关系
- ❌ “Temperature 0 就是确定性的” — 在 GPU 上,float 运算仍有微小不确定性;需要
do_sample=False+seed才能完全确定 - ❌ “Temperature 对代码没有影响” — 即使 T=0,不同模型对相同输入的 logit 差异可能导致不同输出
代码:直观感受 Temperature 的效果
Section titled “代码:直观感受 Temperature 的效果”import torchimport torch.nn.functional as F
logits = torch.tensor([5.0, 3.0, 1.0, 0.5, 0.1]) # 5个候选 token
for T in [0.1, 0.5, 1.0, 2.0, 5.0]: probs = F.softmax(logits / T, dim=0) print(f"T={T:>4.1f}: {['%.3f' % p for p in probs.tolist()]}")
# 输出:# T= 0.1: ['1.000', '0.000', '0.000', '0.000', '0.000'] ← 几乎确定# T= 0.5: ['0.884', '0.108', '0.005', '0.003', '0.001'] ← 偏保守# T= 1.0: ['0.657', '0.227', '0.030', '0.018', '0.010'] ← 原始分布# T= 2.0: ['0.422', '0.279', '0.104', '0.087', '0.065'] ← 明显平滑# T= 5.0: ['0.249', '0.214', '0.179', '0.166', '0.155'] ← 接近均匀| 入门 | 中级 | 高级 | |
|---|---|---|---|
| 核心概念 | 控制大胆程度 | 缩放 softmax 概率 | Boltzmann 分布的工程应用 |
| 关键理解 | 高 = 随机,低 = 确定 | 甜点区 0.3-0.7 | Temperature ≠ Top-p,需配合使用 |
| 实践建议 | 日常用 0.5 就行 | 根据任务调参 | 蒸馏、校准、对比解码 |