Skip to content

temperature 调到 0,模型就不乱说了吗 ​

调接口时最容易手滑的一个参数,就是 temperature。新人常常默认往里填 0,觉得这样输出就稳了。

真跑起来会发现,0 并不等于可复现。要讲明白为什么,得先看模型每生成一个 token 时到底做了什么。

模型每生成一个 token,都只做一次选择 ​

它拿到上文,算出一组分数,每个候选 token 一个,这组分数叫 logits。

分数过一遍 softmax,变成加起来等于 1 的概率。然后照着这个概率抽一次签,抽到谁就吐谁。

采样参数改的就是这两步之间。不碰模型,只碰怎么从概率里挑。

temperature 是把 logits 除以一个数 ​

公式很短,概率等于 softmax(logits 除以 T),T 就是 temperature。

T 小于 1,分布被拉尖,高概率的 token 更容易被选中。T 大于 1,分布被压平,平时排后面的冷门 token 也有了机会。

调到 0,等价于永远取概率最大的那个(argmax),不再抽签。这也是为什么有人把 0 当成「确定性」的代名词。

top_p 和 top_k 做的是截断 ​

同一步里还有两个参数,管的是候选范围,不是分布形状。

top_k 只看概率最高的 K 个候选,剩下的直接扔掉。top_p(核采样,nucleus sampling)换了个算法,按概率从大到小累加,凑够 p 就截断。p 取 0.95,就只在前 95% 的概率质量里抽。

OpenAI 的接口文档写得很清楚:top_p 范围 0 到 1,默认 1。它给的例子是 0.1,意思是只看累计概率最高的前 10%。

这里有个跨厂商的坑。top_k 在 OpenAI 的接口里压根不暴露,只有 Gemini 这类厂商的 generationConfig 里能设。同一段代码搬到另一家,写了 top_k 常常是白写。

同一个名字,各家的范围和默认值不一样 ​

temperature 的取值范围各厂商并不统一。

OpenAI 是 0 到 2,默认 1,数值越大越随机。Gemini 的官方文档给的默认值是 1.0,top_p 默认 0.95,两端都能调。

把一家的默认值原样抄到另一家,输出风格多半会偏。我去年就踩过一次:照着 OpenAI 的调参笔记,把 temperature 设成 1.0、top_p 设成 0.9 搬进另一家 SDK,跑出来语气明显更飘,对着两边的参数说明来回翻了两小时才发现,对方默认的 top_p 本来就不一样。

推理模型干脆不让改 temperature ​

现在一批主打推理的模型,直接拒绝这个参数。

给 o1、o3-mini 这类模型传 temperature,接口返回 400,报错原文是 Unsupported parameter: 'temperature' is not supported with this model。

原因是这类模型内部自己控制采样,外部再拧温度没有意义。

我第一次撞上时以为 SDK 装旧了,升级到最新版本照样 400。只能把参数整个删掉,让它走默认。

temperature 设 0,也换不来可复现 ​

很多人以为填 0 就是确定性输出。OpenAI 的说明是,Chat Completions 默认就是非确定性的。

想尽量复现得做两件事:设一个固定的 seed,并且保证 prompt、temperature 这些参数全都一致。

关键词是「尽量」。文档用的词是 best effort(尽力而为),后端配置一改就可能失效。判断后端有没有动过,看响应里的 system_fingerprint,它变了说明模型那一侧的配置换了。

我压测过一批 temperature 设 0 的抽取任务,同一天里 200 条请求有 3 条结果不同。就这 3 条,把一条「结果可复现」的断言搞挂了。

我通常怎么设 ​

分类、抽取、结构化输出这类任务,temperature 直接给 0,不留余地。写作、起名、头脑风暴才往上调,0.7 到 1.0 之间试。

一次只动一个参数。官方也是这个建议:temperature 和 top_p 别一起改,两个一起动了,你就分不清是哪一个在起作用。

我的默认起点是 temperature 0.2、top_p 不动,先跑一批真实样本,看输出分布再决定往哪边调。做抽取就压到 0。

至于 seed,只在你真的需要复现失败用例时才设,别把它当成稳定性的保险。

最近更新