LLM 是怎么"随机"说话的 —— Temperature、Top-K、Top-P 详解

前言

你有没有想过一个问题:大模型每次生成文本,为什么能给出不同的回答?同一个 Prompt 问三遍,回答可能每次都不一样。这种"随机性"不是 bug,而是刻意设计的结果------而控制它的核心,就是三个参数:Temperature、Top-K、Top-P

理解这三个参数,是你从"会用 ChatGPT"到"会调 LLM"的第一步。


一、大模型到底怎么"说话"

先说一个大前提:LLM 的 Transformer 架构本身是完全确定的。同样的输入,经过同样的网络权重,最后那个线性层(LM Head)输出的 logits 永远一样。

真正的随机性发生在解码/采样阶段------Transformer 算完之后,怎么从几万个候选 token 里挑出下一个词。

这个过程是这样的:

scss 复制代码
输入 Token → Embedding → N 层 Transformer Block → LM Head
                                                        ↓
                                                   Logits (原始得分)
                                                        ↓
                                              【Temperature 在这里介入】
                                                        ↓
                                                   Softmax (得分→概率)
                                                        ↓
                                            【Top-K、Top-P 在这里介入】
                                                        ↓
                                                  采样 → 下一个 Token

三个参数都不属于 Transformer 架构本身,它们是解码策略(Decoding Strategy)


二、Softmax:归一化,把得分变成概率

在讲三个参数之前,必须先搞清楚 Softmax。

Logits 是 LM Head 输出的原始得分,长这样:

csharp 复制代码
[2.3, -1.1, 0.8, 4.5, -3.2, ...]    // 几万个数,每个对应一个候选 token

有正有负,毫无约束。你没法直接从里面"采样"------负数怎么算概率?所以需要 Softmax:

softmax(xi)= exi ∑jexj softmax(x_i) = \frac{e^{x_i}}{\sum_j e^{x_j}} softmax(xi)=∑jexjexi

两步走:

  1. exe^x ex:把所有数变成正数,同时放大差距
  2. 除以总和:压缩到 (0, 1) 区间,且加起来等于 1

举例,假设词表只有 "猫""狗""鱼" 三个词,logits 是 [2.0, 1.0, 0.5]

ini 复制代码
e^2.0 = 7.39
e^1.0 = 2.72
e^0.5 = 1.65
总和   = 11.76

P(猫) = 7.39/11.76 = 62.8%
P(狗) = 2.72/11.76 = 23.1%
P(鱼) = 1.65/11.76 = 14.0%

现在你可以按概率采样了------有 62.8% 的几率选"猫",但"狗"和"鱼"也有机会被选到。

Softmax 的另一个好处是可微,训练时梯度能反向传播。如果改成硬性的"只选最大值",梯度就断了,模型根本训练不了。


三、Temperature:控制"多大胆"

它做了什么

Temperature 作用于 Softmax 之前 、Logits 之后。核心操作只有一步:

scaled_logit= logittemperature scaled\_logit = \frac{logit}{temperature} scaled_logit=temperaturelogit

然后把缩放后的 logits 送进 Softmax。

直观理解

T 值 Logits 变化 Softmax 结果 效果
T → 0 被放大 概率几乎全集中在最高分词 趋近贪婪搜索,每次输出几乎一样
T = 1 不变 原始分布 正常随机
T → ∞ 被压平 所有词概率趋同 纯随机,输出不可控

还是 "猫狗鱼" 的例子,原始 logits [2.0, 1.0, 0.5],看看不同温度的效果:

ini 复制代码
T = 0.5(放大差距):
  logits' = [4.0, 2.0, 1.0]
  → 概率 = [85.5%, 11.6%, 2.9%]    ← "猫"几乎必选,非常确定

T = 1.0(不变):
  logits' = [2.0, 1.0, 0.5]
  → 概率 = [62.8%, 23.1%, 14.0%]    ← 原始分布

T = 2.0(压平差距):
  logits' = [1.0, 0.5, 0.25]
  → 概率 = [50.8%, 30.8%, 18.4%]    ← 差距变小,更平均

核心结论

  • 温度越低,模型越"自信"------高概率词更高,低概率词更低,输出稳定但缺乏变化
  • 温度越高,模型越"犹豫"------概率分布被抹平,更多词有机会被选到,输出多样但也可能跑偏

四、Top-K:固定个数的硬截断

它做了什么

Top-K 作用于 Softmax 之后。逻辑非常简单:

从所有候选词中,只保留概率最高的 K 个,其余全部砍掉(概率置零),然后在剩余的 K 个词上重新归一化。

直观理解

ini 复制代码
原始概率: [62.8%, 23.1%, 14.0%, ...还有几万个超低概率词]
K = 2:
  → 只保留前 2 个: [62.8%, 23.1%]
  → 重新归一化:   [73.1%, 26.9%]
  → 第三个词及以后永远不可能被选到
  • K = 1:就是贪婪搜索,永远选最高分
  • K 很大:接近不做限制
  • K 很小:模型被严重约束,缺乏多样性

Top-K 的问题

它是"一刀切"的固定值。K=40 在面对不同语境时表现完全不一样:

  • 概率分布本来就尖锐时(模型很确定):可能前 5 个词就占了 99%,开 K=40 等于没起任何作用
  • 概率分布很平坦时(模型不确定):第 40 名可能概率也还行,开 K=40 可能砍掉了真正合理的词

这就引出了 Top-P 的动机。


五、Top-P(核采样 / Nucleus Sampling):自适应截断

它做了什么

Top-P 同样作用于 Softmax 之后 ,但它是动态的

从高到低累加概率,只保留累加概率刚好达到 P 的那一批词,尾巴砍掉。

直观理解

erlang 复制代码
原始概率(已排序):
  词A: 40%
  词B: 25%
  词C: 15%  ← 累加到这是 80%
  词D: 8%   ← 累加到这是 88%
  词E: 5%   ← 累加到这是 93%
  词F: 3%   ← 累加到这是 96%
  ... 剩下几千个

P = 0.9:
  保留 A+B+C+D+E(累加 93% > 90%)
  砍掉 F 及之后的一切
  → 候选集 = 5 个词,动态决定

Top-P vs Top-K

Top-K Top-P
截断方式 固定个数 动态个数
分布尖锐时 K 可能太大,不起作用 少量词就满足 P,自动收紧
分布平坦时 K 可能太小,砍掉合理词 更多词满足 P,自动放宽
优点 简单直接 自适应,不需要猜 K 值
缺点 一刀切 P 值太小可能砍过头

目前业界的主流实践是优先用 Top-P,Top-K 用得越来越少。


六、三者配合:谁先谁后

实际推理中的执行顺序:

scss 复制代码
Logits → Temperature(①) → Softmax → Top-K(②) → Top-P(③) → 重新归一化 → 采样
顺序 操作 作用对象 干什么
Temperature Logits 缩放得分,改变分布的基础形态
Softmax 缩放后 Logits 转成概率
Top-K 概率分布 硬截断到 K 个
Top-P Top-K 过滤后 动态截断,累加到 P

Temperature 在最前面 ------它决定了整个概率空间长什么样。Top-K 和 Top-P 在后面做过滤------从已经变形过的分布里筛出合理的候选集。

两条经验规则:

  • 不能同时太大或太小。高温 + 大 K → 纯随机;低温 + 小 K → 退化为贪婪搜索,失去了"生成"的意义
  • 一个放得开,一个就要管得住。你和我对话时聊到的 Demo 就是这样设计的:高温 0.9 + 小 K(4),低温度 0.2 + 大 K(8)

七、实战:什么时候怎么调

以 Temperature 为主旋钮

Temperature 是影响最大的参数,先定 Temperature,再决定要不要加 Top-P/Top-K

场景 Temperature 其他建议
代码生成、数学推理、JSON 输出 0.0 ~ 0.2 关掉 Top-P/Top-K,追求确定性
翻译 0.1 ~ 0.3 通常不需要额外截断
RAG 问答、知识检索 0.2 ~ 0.4 Top-P = 0.9,防止幻觉
通用对话 0.5 ~ 0.7 Top-P = 0.9,经验值
文案润色、改写 0.7 ~ 0.9 Top-P = 0.9 ~ 0.95
创意写作、诗歌 0.9 ~ 1.0 Top-P = 0.95,或高温 + 小 Top-K

Top-P / Top-K 做辅助修剪

  • 大部分场景只开一个 Top-P = 0.9 ~ 0.95 就够了
  • Top-K 和 Top-P 通常不需要同时开------双重过滤可能把合理词也砍掉
  • 真想用 Top-K,参考值:对话 3050,创意写作 410

常见错误

错误配置 后果
三个参数全开 双重过滤,过度约束
低温 + 低 P 退化为复制机器
高温 + 高 P + 高 K 等于没设参数,纯随机
不同模型用同一套值 不同模型对参数敏感度不一样,必须实测

最后一条建议

参数没有银弹。同一个 Temperature=0.7,在 GPT-4 和 DeepSeek 上的表现就可能不一样。拿到一个新模型或新场景,跑几次看输出,再微调------这比记住任何"推荐值"都管用。


八、总结

css 复制代码
Transformer 算完 → Logits
                    ↓  除以 Temperature(缩放得分)
                    ↓  Softmax(变成概率)
                    ↓  Top-K(硬截断,只留 K 个)
                    ↓  Top-P(动态截断,累加到 P)
                    ↓  采样 → 下一个 Token
  • Temperature:主旋钮,控制概率分布陡峭还是平坦。低 = 稳,高 = 放飞
  • Top-K:固定个数硬截断,简单但有局限性
  • Top-P:自适应截断,用得最多
  • 配合原则:一个放得开,另一个就要管得住;不要同时极端

三个参数都作用于 Transformer 架构之外,属于解码策略。理解了它们,你就知道了 LLM"随机说话"的全部秘密。

相关推荐
一起努力啊~1 小时前
DataWhale组队学习笔记--llm-algo-leetcode(五)
笔记·学习·llm
To_OC9 小时前
大模型蒸馏是啥?说白了就是大厨带徒弟的学问
人工智能·llm·agent
陳陈陳9 小时前
从“胡说八道”到“妙笔生花”:我用LangChain手搓了一个可控AI写作流(Temperature+TopK调参指南)
langchain·llm
冬奇Lab12 小时前
AI 评测系列(03):LLM-as-Judge——让 LLM 评价 LLM 的正确姿势
人工智能·llm
Darling噜啦啦14 小时前
揭秘 LLM 的随机性黑盒:从 Temperature + Top-K 到 LangChain Chain 工作流实战
langchain·llm
元Y亨H15 小时前
AI Agent 的安全挑战与防护策略
llm
元Y亨H16 小时前
AI 评估:深度对比 Ragas 与 DeepEval
llm
元Y亨H16 小时前
AI Agent 评估的六个核心维度
llm
ezreal18 小时前
「AI 应用工程实录」系列 · 02
llm