这篇学完你能回答什么
- temperature 和 top_p 分别在调什么?为什么一般只调一个?
- temperature=0 能不能保证同样输入同样输出?
- 新一代模型不让设 temperature 了,那「稳定性」这件事该由谁负责?
从一个真实故障讲起
一个发票信息抽取服务。为了追求稳定,团队把 temperature 固定成 0,代码注释写着「保证输出确定」。跑了一年,翻了两次车。
第一次:QA 拿同一张发票连跑 20 遍,其中 2 遍的金额字段差了一位小数。开发的第一反应是「不可能,温度是 0」,于是花了两天去查 OCR、查预处理、查网络重试——最后发现这三处都没问题。
第二次(今年):升级到新一代模型,服务直接 400。报错不是说值不对,是说这个参数不该出现。而 SDK 里字段还在,代码编译得好好的,只有服务端拒。
两次翻车指向同一个认知缺口:把采样参数当成了确定性的保证,而它从来不是;并且到了 2026 年,它连「主要旋钮」都不再是了。
temperature 固定成 0,跑了一年,翻了两次完全不同的车temperature固定成 0代码注释写着「保证输出确定」
同一张发票连跑 20 遍
QA 回归,验的就是稳定性
2 遍金额差了一位小数断点
第一反应「不可能,温度是 0」
查 OCR、预处理、重试
两天过去,这三处都没问题
升级新模型,直接 400
报错说:这个参数不该出现
核心概念:先打比方,再给定义
上一篇讲到,模型每一步吐出的是一个在词表上的概率分布。采样(sampling) 就是从这个分布里挑一个 token 的规则。
把模型想象成一个厨师,每一步都端上一桌候选菜,每道菜标了推荐度:
- Temperature(温度) 调的是这桌菜「推荐度差距」的对比度。温度低,差距被放大,最推荐的那道几乎必被选;温度高,差距被抹平,冷门菜也有机会。数学上就是把 logits 除以 T 之后再做 softmax。
- Top_p(核采样 / nucleus sampling) 调的是「允许上桌的范围」。按推荐度从高到低累加,累计概率到 p 就停,后面的直接撤下。
- Top_k 是更粗暴的同类:只留前 k 个候选。
- Greedy decoding(贪心解码):永远取概率最高的那个,等价于 T→0。
一句话把两者分开:temperature 改分布的形状,top_p / top_k 砍分布的尾巴。
这也正是「一般只动一个」的原因。两个一起收紧,候选很容易被压到只剩一个,输出变得机械重复;两个一起放开,你就不知道是谁在起作用,调参失去可归因性。
拧低,最推荐那道几乎必被选
拧高,差距被抹平,冷门菜也有机会上桌
改概率分布的形状
数学上就是把 logits 除以 T 之后再做 softmax
按推荐度从高到低累加,到 p 停
后面的直接撤下 —— 撤得太狠,桌上就只剩一道菜
砍概率分布的尾巴
nucleus sampling;top_k 是更粗暴的同类,只留前 k 个
原理拆解
| 这一步 | 算出什么 | 读法 |
|---|---|---|
| 原始 logits | 8.0 6.0 5.5 2.0 1.0 | 模型这一步的原始打分 |
÷ T,T=0.2 | 40 30 27.5 10 5 | 差距放大 → 分布尖锐 |
÷ T,T=1.5 | 5.3 4.0 3.7 1.3 0.7 | 差距压缩 → 分布平坦 |
softmax | 0.55 0.20 0.15 0.06 0.04 | 这才是概率 |
top_p=0.9 | 0.55+0.20+0.15=0.90 | 只保留前 3 个 |
top_k=2 | 只保留前 2 个 | 更粗暴的同类 |
贪心解码消掉的只是采样这一层随机,它上游还有四处:浮点加法不满足结合律(GPU 归约顺序随批次与调度变化,末位差异足以翻转两个接近的 logits)、动态批处理(跟谁拼在一个 batch 里会影响 kernel 选择与计算路径)、MoE 路由在批内有交互、版本漂移(同名模型的小版本更新)。
temperature=0 让输出高度稳定,但不等于确定性可复现。真想复现,靠的是固定模型版本号(不要用浮动别名)、把结构交给约束解码,以及最终 —— 把确定性需求下沉到代码里,别指望模型。logits [ 8.0 6.0 5.5 2.0 1.0 ... ]
│
├── ÷ T(temperature)
│ T=0.2 → [40, 30, 27.5, 10, 5] 差距放大 → 分布尖锐
│ T=1.5 → [5.3, 4.0, 3.7, 1.3, 0.7] 差距压缩 → 分布平坦
▼
softmax → 概率 [0.55 0.20 0.15 0.06 0.04 ...]
│
├── top_p=0.9:0.55+0.20+0.15=0.90 → 只保留前 3 个
├── top_k=2 :只保留前 2 个
▼
重新归一化 → 随机抽一个 → 本步输出的 tokendef sample(logits, temperature=1.0, top_p=1.0):
if temperature == 0:
return int(argmax(logits)) # 贪心:不再随机
probs = softmax(logits / temperature) # 改形状
order = argsort(probs, descending=True)
cum, keep = 0.0, []
for i in order: # 砍尾巴
keep.append(i)
cum += probs[i]
if cum >= top_p:
break
return random_choice(keep, weights=probs[keep])为什么 temperature=0 也不保证复现——这是本篇最值钱的一段。
贪心解码消除了「采样」这一层随机,但它上游还有一堆不确定:
- 浮点加法不满足结合律。GPU 上的归约(reduce)顺序会随批次和调度变化,末位差异足以翻转两个接近的 logits 的大小关系;
- 动态批处理(continuous batching)。你的请求跟谁拼在一个 batch 里,会影响 kernel 选择与计算路径;
- MoE(专家混合)路由在批内是有交互的;
- 版本漂移。供应商随时可能对同名模型做小版本更新。
所以准确的表述是:temperature=0 让输出高度稳定,但不等于确定性可复现。 想真复现,得靠固定模型版本号(不要用浮动别名)、把结构交给约束解码、以及最终——把确定性需求下沉到代码里,别指望模型。
工程实践(截至 2026-08)
表 1:还能调参数时的经验取值
| 任务 | temperature | top_p | 说明 |
|---|---|---|---|
| 抽取 / 分类 / 路由 / 生成 JSON | 0 ~ 0.2 | 1.0(不动) | 要的是可预期,不是多样性 |
| 事实问答 / RAG 生成 | 0.1 ~ 0.3 | 1.0 | 温度高会让模型「发挥」,这正是 RAG 最怕的 |
| 文案 / 起名 / 头脑风暴 | 0.7 ~ 1.0 | 0.9 ~ 0.95 | 二选一调,别同时放 |
| self-consistency 多路投票 | 0.5 ~ 0.8 | — | 温度为 0 时多次采样完全相同,投票机制直接失效 |
表 2:这层旋钮的退场(2026 年的核心考点)
| 维度 | 具体情况 |
|---|---|
| 参数被弃用 | 截至 2026-08,Claude Opus 4.7 及以后、Sonnet 5 上,把 temperature / top_p / top_k 设成非默认值直接返回 400。SDK 里字段仍保留以兼容旧模型,代码编译得过,服务端才拒——升级时最容易踩 |
| 换成了什么 | 控制权转到 effort:low / medium / high(默认)/ xhigh / max。它影响的是整个响应的 token 花费,包括工具调用次数,不只是「思考多少」 |
| 官方给的判断 | 复杂问题上推理太浅,应该提高 effort,而不是绕着提示词想办法 |
| 隐藏代价 | effort 值会渲染进 prompt,同一会话中途改 effort 会让之前的 prompt 缓存失效;官方建议一个会话内保持 effort 恒定 |
背后是同一条逻辑:推理型模型在内部要跑多条推理路径再择优,把温度压到 0 会让这些路径塌缩成同一条,反而破坏了机制本身。所以厂商干脆把这个旋钮收了回去。OpenAI 侧的推理模型同样拒绝非默认的采样参数——这不是某一家的选择,是一个行业方向。
避坑清单
- 别在代码里无条件塞 temperature 字段。 跨模型的网关层要按模型能力白名单剔除参数,否则每次升级模型必炸。这是 2026 年最常见的一类 400。
- 别把 temperature=0 当「确定性」写进设计文档。 写「高度稳定」,并配一个多次采样一致率的指标。
- 稳定性的责任要重新分配:格式稳定交给结构化输出(T1-2),事实稳定交给检索与校验,风格稳定交给系统提示词,深度与成本交给 effort。一个参数扛不动四件事。
- 迁移时要重做效果基线。 参数没了不是「降级」,是控制维度换了一套,旧的调参经验不能直接映射过去。
effort| 任务 | temperature / top_p | 说明 |
|---|---|---|
| 抽取 / 分类 / 路由 / 生成 JSON开篇故障就在这一行 | 0 ~ 0.2 / 1.0(不动) | 要的是可预期,不是多样性 |
| 事实问答 / RAG 生成 | 0.1 ~ 0.3 / 1.0 | 温度高会让模型「发挥」,这正是 RAG 最怕的 |
| 文案 / 起名 / 头脑风暴 | 0.7 ~ 1.0 / 0.9 ~ 0.95 | 二选一调,别同时放 |
| self-consistency 多路投票 | 0.5 ~ 0.8 / — | 温度为 0 时多次采样完全相同,投票机制直接失效 |
- 参数被弃用
- Claude Opus 4.7 及以后、Sonnet 5 上,
temperature/top_p/top_k设成非默认值直接返回 400 - 换成了什么
- 控制权转到
effort:low / medium / high(默认)/ xhigh / max,管的是整个响应的 token 花费,含工具调用次数 - 官方给的判断
- 复杂问题上推理太浅,应该提高 effort,而不是绕着提示词想办法
- 隐藏代价
- effort 值会渲染进 prompt,中途改会让之前的 prompt 缓存失效,官方建议一个会话内保持恒定
- 网关必须做的事
- 按模型能力白名单剔除参数,别无条件塞
temperature字段 —— 这是 2026 年最常见的一类 400 - 责任重新分配
- 格式交给结构化输出(T1-2)、事实交给检索与校验、风格交给系统提示词、深度与成本交给
effort
面试视角
- 先讲分工形状 vs 尾巴:一个改分布,一个砍尾巴
- 再给场景取值抽取
0~0.2、文案0.7~1.0,并说清怎么定的 - 最后反向判断0 不等于确定性;这层旋钮正在被收回
- 把
temperature说成「创造力」 - 建议「两个都调到 0.2 更稳」
- 认为
temperature=0输出必然一致 - 不知道推理型模型已经不接受这个参数
- 说得出自己项目里两类任务用了不同取值,以及是怎么定的
- 能把「稳定性」拆给格式、事实、风格、深度四个责任方
- 说得出 0 仍然不一致的机制:浮点归约 / 动态批处理 / 版本漂移
- 知道跨模型网关要按能力白名单剔参数,否则升级必炸
temperature=0 的服务遇到参数被弃用,怎么办」。它考的其实不是参数,是你有没有真把稳定性拆给过四个责任方 —— 答得出这四家,这道题就翻篇了。面试官怎么问。 一面必问基础版(Q1-03);有经验的面试官会在你答完后立刻追一句「那 temperature=0 能保证复现吗」——这是最经典的一道分水岭;2026 年新增的压力分支是「你依赖 temperature=0 的服务遇到参数被弃用怎么办」。
答题结构建议:形状 vs 尾巴(讲清分工)→ 场景取值(给具体数)→ 反向判断(0 不等于确定性;这层旋钮正在被收回)。第三段是拿分点,前两段只是入场券。
分水岭信号
- 只读过:把 temperature 说成「创造力」;建议「两个都调到 0.2 更稳」;认为 temperature=0 输出必然一致;不知道推理型模型不接受这个参数。
- 真做过:说得出自己项目里两类任务用了不同取值以及是怎么定的;说得出 temperature=0 仍然不一致的具体机制(浮点归约 / 动态批处理 / 版本漂移);知道跨模型网关要按能力剔参数;能把「稳定性」拆给四个不同的责任方。
小结与延伸
继续深入
本篇归属第 1 章「LLM 与 Prompt 基础」,去做这一章的题。