LLM · 采样参数 · 原理拆解

调参玄学终结:温度与 top_p 的真实工作原理

你拧的那个旋钮,其实只作用在整条链路的一层上。

2026-09-30解码与采样约 12 分钟

引言:一个被拧坏了三次的旋钮

凌晨两点,有人在调试一个客服问答接口。他把 temperature 从 0.7 改到 1.5,重跑了一遍,觉得输出"活"了——回答开始有寒暄、有比喻、有一点点人情味。他又改回 0.1,输出立刻变得干巴巴。于是他做了个决定:把 1.5 写进配置文件,提交,上线。

三周后,客服系统开始答非所问。有人问退货政策,模型开始讲一段关于"信任与承诺"的散文。

这不是模型的错。这是他拧错了一个自己没搞懂的旋钮。

关于 temperature 和 top_p,网上流传的说法大多是"高温度更有创意、低温度更准确"这类半句话。它们不算错,但缺了最关键的一半:这两个参数各自作用在链路的哪一层,以及它们管不到什么。

这篇文章只追一条线:从 softmax 里的除法,一路追到 GPU 的浮点加法顺序,再追到厂商为什么开始把旋钮收回去。读完你至少能回答一个问题——你把 temperature 调高的时候,你到底希望它变什么?

01温度到底在拧哪个旋钮?

同一个 prompt 问两次,为什么模型给的答案不一样?

先把链路摊开。模型每生成一个 token,内部会算出一个 logits 向量:词表里每个 token 对应一个原始分数,可正可负。分数越高,模型越"倾向"这个词。然后 softmax 把这些分数变成一组和为 1 的概率。

温度干的唯一一件事,就是在 softmax 之前,把所有 logits 除以 T:

p_i = exp(z_i / T) / Σ_j exp(z_j / T)

就这一行。三个区间,三种命运。

这个"除以温度"不是大模型发明的。它来自统计物理里的玻尔兹曼分布。1985 年,Ackley、Hinton 和 Sejnowski 在玻尔兹曼机论文里就用它控制随机神经元的激活概率,后来在知识蒸馏里被用来把硬标签软化成"软目标"。今天各家 API 里的 temperature,是同一个东西的直系后代。

光看公式容易没感觉,代进去算一遍就清楚了。假设下一个词的候选只有三个:"晴"(logit 5)、"雨"(logit 3)、"鲨鱼"(logit 0)。

温度 T"晴""雨""鲨鱼"
0.598.2%1.80%0.004%
1.087.6%11.9%0.59%
2.069.0%25.4%5.66%

把温度从 1 提到 2,"鲨鱼"的概率从 0.59% 涨到 5.66%——将近十倍。放在一篇八百字的长文里,这意味着模型有机会游进来一条鱼。

但真正值得盯住的,是这张表最右一列在 T=0.5 时的数字:0.004%。它没有变成 0。

这就是下一章的全部理由。

02既然有了温度,为什么还要有 top_p?

温度能把"鲨鱼"的概率压到万分之一,但压不到零。这是结构性的问题。

词表有多大?小模型几万,大模型十几万。温度是连续地重新分配整个分布的概率,它不会、也没能力把任何一个 token 的概率归零。也就是说,无论你把温度拧到多低,那十几万个荒谬候选始终留在池子里,各自带着一点点概率。

温度一高,麻烦就来了。这些长尾 token 单个看微不足道,合起来却极具分量。

2019 年,Holtzman 等人在论文《The Curious Case of Neural Text Degeneration》里给这个现象起了个名字:unreliable tail,不可靠的长尾。原文写得很直白:

"Why is text produced by pure sampling so degenerate? In this work we show that the 'unreliable tail' is to blame. This unreliable tail is composed of tens of thousands of candidate tokens with relatively low probability that are over-represented in the aggregate."— Holtzman et al., The Curious Case of Neural Text Degeneration (ICLR 2020)

翻译一下:数万个低概率候选,在聚合意义上被过度代表了。论文明确写道,问题出在"用温度参数控制分布形状,却没有充分压制那条不可靠的长尾"。

他们给出的解法就是 top_p,也叫核采样(nucleus sampling)。做法极其朴素:把 token 按概率从高到低排队,从队首开始累加概率,累到超过阈值 p 就停止,只用这一小撮候选重新归一化后采样。

V^(p) = 满足 Σ P(x) ≥ p 的最小集合

关键词是"最小集合"和"动态"。分布尖锐时——比如模型很确定这里该是"晴"——核里可能只有三五个词;分布平坦时——比如一句话刚开了个"关于"——核会自动膨胀到几百个词。候选池的大小随上下文实时伸缩,这正是它比 top_k 优越的地方。

参数它管什么怎么起作用什么时候失灵
temperature分布的形状:陡峭还是平坦softmax 之前除以 T高温度时压不住长尾
top_p候选池的大小(动态)按累积概率截断后归一化分布本身已经错时无能为力
top_k候选池的大小(固定)只取概率最高的 k 个上下文简单时太窄,复杂时太宽

top_k 的问题在 2018 年就被 Fan 等人指出过:固定的 k 无法适配不同上下文。k 取小了,文本寡淡重复;k 取大了,不该进来的词被重新归一化之后概率反而被抬高了。这跟高温度压不住长尾,是同一个病根的两张脸。

再往下一步:min-p。2024 年提出、2025 年在 ICLR 拿到 Oral 的 min-p 采样换了个思路——以最高概率 token 为基准,设一个相对阈值 p_base × p_max,低于它的全部砍掉。好处是判断"什么算低概率"不再依赖绝对数值,而是在高温度下依然稳定。它已被 Hugging Face Transformers、vLLM 等主流框架采纳。

03那我到底该拧到哪里?

先记一条纪律,再看场景表。

这条纪律比任何推荐值都重要,而且五家厂商的官方口径几乎一字不差:

为什么?因为这两个参数改的是同一件事的两面——一个调形状,一个调截断。同时调,等于让两个变量互相掩护:输出变好了你不知道是谁的功劳,变坏了你也不知道该退哪一个。

纪律之后是取值。下面是按场景汇总的工程经验区间:

场景温度区间为什么
代码 / 数学0 – 0.2要的是唯一正解,随机性只会引入错误分支
信息抽取 / 分类0 – 0.3输出需要稳定一致,避免同一批数据两种答案
事实问答0 – 0.3压低幻觉概率,代价是措辞偏模板化
翻译0.2 – 0.4既要忠实又要句子自然,需要一点点余地
通用对话 / 商业文案0.3 – 0.7多数厂商默认值就落在这里
创意写作0.7 – 1.0需要跳出高频表达,但要守住可读性
头脑风暴0.8 – 1.2目标是"多而杂",后期再人工筛
self-consistency 多路径投票0.5 – 1.0这里必须有随机性,压到 0 反而退化

厂商自己也会给场景表。DeepSeek 官方文档里的建议是:编程与数学 0.0,数据清洗与分析 1.0,通用对话 1.3,翻译 1.3,创意写作与诗歌 1.5。注意它把"通用对话"放在 1.3——比大多数人凭直觉设的 0.7 高不少。这说明推荐值跟模型的训练方式强相关,别人的甜蜜点搬不到你的模型上。

各家默认值也列一下,方便对照:

厂商temperature 范围默认值top_p 默认值
OpenAI0 – 211
Anthropic0.0 – 1.01.01
Google Gemini0.0 – 2.01.0按模型而定
DeepSeek0 – 21.01
通义千问[0, 2)0.7(非思考)
0.6(思考)
二选一,不叠加

最后一条实操建议,比上面所有数字都值钱:做 A/B,别做单发。固定所有其他变量,只改一个参数,同一批 prompt 跑 10 次以上,看的是分布不是个例。单次运行的"感觉好多了",大概率是噪音。

04为什么调到 0,答案还是不一样?

这一章要拆的,是整篇文章里最反常识的一段。

temperature = 0 就是贪心解码:每一步都取概率最大的那个 token。按直觉,同样的输入应该得到同样的输出。但只要你真的跑过,就知道不是。

2025 年 9 月,Thinking Machines Lab 的 Horace He 写了一篇文章,专门拆这件事,标题叫《Defeating Nondeterminism in LLM Inference》。他给出的结论听起来自相矛盾:

"Some kernels on GPUs are nondeterministic. However, all the kernels used in a language model's forward pass are deterministic. Moreover, the forward pass of an LLM inference server (like vLLM) can also be claimed to be deterministic. Nevertheless, from the perspective of anybody using the inference server, the results are nondeterministic."— Horace He, Thinking Machines Lab

他同时也否掉了流传最广的那个解释——"并发 + 浮点误差"这个说法没说到点子上。真正的原因是一个更技术、也更日常的词:缺批不变性(batch invariance)。

说人话:同一行计算,在 batch size 为 1 和 batch size 为 32 时,GPU 会选择不同的分块与归约策略。而浮点加法不满足结合律——

(a + b) + c ≠ a + (b + c)

顺序一变,结果的最后几位就不同。这个差异小到绝大多数时候不影响任何东西。问题出在那些"顶一和顶二咬得极紧"的位置上。文章里举的例子非常直观:p("eggs") = 0.500,p("butter") = 0.499。差 0.001。这一次选 eggs,下一次可能翻成 butter。

而自回归生成有个要命的性质:第一个 token 分岔,后面整段文本就走上另一条路。你看到的不是"最后一个词不同",而是"整篇回答不一样"。

更麻烦的是,决定 batch 组成的不是你。同一个 prompt 你在同一秒发两次,服务器当时正在处理的其他请求数量、拼批方式、调度顺序,全都不同。对你来说,那些并发用户不是系统的输入,而是系统的不确定属性。

MoE 架构还要再叠一层:专家路由由门控决定,而门控对数值精度和输入扰动同样敏感。选哪个专家,本身就会因为上面那些微小差异而变。

有人把这件事量化了。2026 年的一篇论文提出了 背景温度(background temperature)的概念,定义为"即使名义上 T=0,由实现相关的扰动过程所诱导出的等效温度"。换句话说:你以为你设的是 T=0,实际上你设的是一个 T 略大于 0 的采样器,这个多出来的部分由服务器当下的负载、kernel 选择和精度策略共同决定。

结论要修正一下。常被引用的"temperature=0 是确定性解码",严格说只对了一半——它确定的是"给定 logits 时的选择规则",不是"logits 本身"。规则是确定的,输入不是。

05我想要的是"可复现",那该怎么办?

既然 0 都不保险,工程上还有没有抓手?有,优先级从高到低。

第一,别把 seed 当保险

OpenAI 官方对 seed 的措辞很克制:"our system will make a best effort to sample deterministically... Determinism is not guaranteed, and you should refer to the system_fingerprint response parameter to monitor changes in the backend."

best effort,尽力而为。seed 控制的只是"采样那一步的伪随机数",而批组成、kernel 选择、后端的静默更新,它一个都管不到。system_fingerprint 存在的意义,恰恰就是提醒你后端会变。更极端的情况是贪心解码——那时根本没有采样这一步,seed 形同虚设。

第二,用约束解码,而不是压温度

如果你的真实需求是"输出一个能解析的 JSON",正确工具是 JSON Schema / 语法约束这类结构化输出能力,不是把温度调到 0。区别在于性质:约束解码是硬约束——不合法的 token 从候选里被直接删掉,永远不可能出现;低温度只是软倾向——概率更集中,但那 0.004% 依然存在。

一句话:想让某个结果"不可能发生",靠调参做不到,靠约束才做得到。

第三,自建推理时用批不变的 kernel

Thinking Machines 把那套 batch-invariant 的 RMSNorm、matmul、attention 实现开源了,SGLang 等框架已经采纳。在批不变的前提下,同一 prompt 在不同 batch 里能得到逐位一致的结果——也只有在这个前提下,seed 才真正有意义。

第四,把输出当抽样,不当测量

评估模型时跑一次就下结论,等于用一个样本去推整个分布。做分类、抽取这类"要产出数据"的任务,应该多次采样取多数,或者至少做一致性检查。业界那句提醒很到位:LLM 的输出是来自分布的抽样,不是固定测量值。

第五,有些场景你恰恰需要随机

反过来说——self-consistency 这类多路径推理方法,正是靠温度产生多条不同思路,再投票聚合。强行把温度压到 0,多路径直接塌缩成一条,这个能力就没了。所以"可复现"不是无条件的正确,它取决于你在做推理还是在做生成。

06推理模型时代,这两个旋钮是不是正在失效?

现在去翻 o 系列、GPT-5、R1 的文档,你会找不到温度推荐值。这不是文档偷懒。

三家厂商的处理方式,代表三种态度。

OpenAI 是直接拿走。官方明确列出:推理模型(o1、o3、o4-mini、GPT-5 系列等)不支持 temperature、top_p、presence_penalty、frequency_penalty、logprobs、top_logprobs、logit_bias。传了也不认。取而代之的是两个语义化旋钮:reasoning_effort(minimal / low / medium / high)和 verbosity。

DeepSeek 是"接受但不执行"。思考模式下,temperature、top_p、presence_penalty、frequency_penalty 均不生效。官方文档的措辞很讲究:"为了兼容已有软件,设置参数不会报错,但也不会生效。"现行 API 中,top_p 只在思考模式生效,而且区间被锁死在 0.95–1.0,低于 0.95 一律按 0.95 处理;非思考模式下固定为 1.0。

Google 是最彻底的。Gemini 3.6 Flash 及以后的模型,temperature、topP、topK 的自定义值"不被支持,设置了会被忽略",官方直接建议从请求里删掉这些参数。

为什么厂商要收回去?两个理由。

一是训练分布。推理模型是在特定采样策略下做强化学习训出来的。你改温度,等于把一个在某个分布上训练好的策略推到了分布外——思考链的质量会掉,严重时陷入无休止的重复。DeepSeek R1 的官方说明把这层因果讲得最清楚:推荐温度设在 0.5–0.7(0.6 最佳),目的是"防止无休止的重复或不连贯的输出"。它的评测设置也是 temperature 0.6 + top_p 0.95。

二是产品定位。厂商希望"想让它思考多深"由 reasoning_effort 这类可解释的旋钮控制,而不是由底层采样参数控制。用户不该需要理解 softmax 才能用好一个模型。

但别把结论下反了。"思考模型不能调温度"并不准确。通义千问的思考模式默认温度是 0.6,DeepSeek R1 的推荐值也是 0.6。准确的说法是:采样策略被模型方接管了,你不再有自由。这不是参数失效,是控制权转移。

收束:你到底想让它变什么

回到开头那个凌晨两点的人。他把温度从 0.7 改到 1.5,觉得模型"活"了。这个观察没错——高温度确实让低概率的表达获得了机会。但他没意识到的是,同一件事也让那十几万个荒谬候选一起获得了机会。

把三句话叠在一起看,整件事就清楚了。

温度改的是概率分布的形状,不改变候选集合。top_p 改的是候选池的大小,而且随上下文动态伸缩。而这两个操作,都只发生在整条链路的一层上。

它们下面一层,是浮点加法的结合顺序、batch 的组成、kernel 的选择,还有你控制不了的并发负载。它们上面一层,是厂商锁死的采样策略——在推理模型里,那一层已经对你关闭了。

所以"调参玄学"这个说法,其实是说反了。不是参数玄,是很多人从来没搞清自己在拧哪一层。

下次改 temperature 的时候,先问自己一句:我是想让它更稳,还是想让它更野?如果答案都是模糊的,那这个参数改多少,结果都只是运气。

总结:六个可以带走的判断

参考来源

  1. Ackley, Hinton & Sejnowski, "A Learning Algorithm for Boltzmann Machines", Cognitive Science 9(1), 1985. https://doi.org/10.1207/s15516709cog0901_7
  2. Fan, Lewis & Dauphin, "Hierarchical Neural Story Generation", ACL 2018. https://aclanthology.org/P18-1082.pdf
  3. Holtzman, Buys, Du, Forbes & Choi, "The Curious Case of Neural Text Degeneration", ICLR 2020. https://arxiv.org/abs/1904.09751
  4. Nguyen et al., "Turning Up the Heat: Min-p Sampling for Creative and Coherent LLM Outputs", ICLR 2025. https://arxiv.org/abs/2407.01082
  5. Horace He (Thinking Machines Lab), "Defeating Nondeterminism in LLM Inference", 2025-09-10. https://thinkingmachines.ai/blog/defeating-nondeterminism-in-llm-inference
  6. SGLang 文档,Deterministic Inference. https://sgl-project.github.io/advanced_features/deterministic_inference.html
  7. Messina & Scotta, "Introducing Background Temperature to Characterise Hidden Randomness in Large Language Models". https://arxiv.org/html/2604.22411
  8. OpenAI Cookbook, "Reproducible outputs with the seed parameter". https://cookbook.openai.com/examples/reproducible_outputs_with_the_seed_parameter
  9. Azure OpenAI REST API 参考(temperature / top_p 字段说明). https://learn.microsoft.com/en-us/azure/ai-foundry/openai/reference
  10. OpenAI reasoning models 参数支持说明. https://learn.microsoft.com/zh-cn/azure/ai-foundry/openai/how-to/reasoning
  11. Anthropic Messages API 参考(temperature / top_p). https://docs.claude.com/en/api/messages
  12. Google Vertex AI 生成参数参考(temperature / topP / topK). https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/gemini
  13. DeepSeek 官方文档:参数设置与思考模式. https://api-docs.deepseek.com/quick_start/parameter_settings
  14. DeepSeek-R1 官方仓库(推荐温度说明). https://github.com/deepseek-ai/DeepSeek-R1
  15. 阿里云百炼:通义千问 OpenAI 兼容接口参数说明. https://help.aliyun.com/zh/model-studio/qwen-api-via-openai-chat-completions