---
id: "mb-20261101-4ee563"
kind: "deep"
title: "为什么大模型温度设为0依然不确定：GPU浮点加法与并发批次的隐藏因果"
description: "大模型在零采样温度下仍会出现输出不一致，根本原因不是模型幻觉或随机抽样，而是GPU浮点加法不满足结合律。并发批次变化会迫使显卡内核重排求和分块顺序，微小的尾数舍入偏差在关键标记处颠倒得分，通过自回归级联彻底改变生成走向。"
domain: "ai"
domain_label: "AI 与大模型"
canonical_url: "https://mubeitech.com/deep/mb-20261101-4ee563"
markdown_url: "https://mubeitech.com/deep/mb-20261101-4ee563/markdown"
json_url: "https://mubeitech.com/api/interpretations/mb-20261101-4ee563"
topic: "为什么大模型温度设为0依然不确定：GPU浮点加法与并发批次的隐藏因果"
source_type: "generated"
status: "published"
generated_at: "2026-11-01 07:26:17"
frame_type: ["机制"]
legal_anchor_count: 0
transcript_citation_count: 0
---

# 为什么大模型温度设为0依然不确定：GPU浮点加法与并发批次的隐藏因果

把大模型的采样温度设成 0，输入一模一样的提示词。
按常理，跑多少次都该吐出一模一样的字。
可在真实的云端服务里，你连续发两次一模一样的请求，经常会拿到两篇截然不同的回答。
很多工程师第一反应是撞了鬼。
温度既然是 0，贪婪解码每次都会选打分最高的那个词，根本不存在摇骰子的随机性。
随机性到底是哪来的？
答案不在模型权重里。
决定你拿到什么答案的，是同一时间正在用同一张显卡的隔壁陌生人。

这怎么可能？
别人的请求，凭什么能篡改我的输出？
先来看显卡在干什么。
大模型跑一次推理，不管是矩阵乘法、注意力计算还是层归一化，海量的时间都在做同一件事：求和。
几千上万个浮点数，被一层层累加成一个数值。
小学数学教过我们，加法满足结合律。
括号加在前面还是加在后面，算出来的数永远一样。
但在计算机硬件里，浮点数加法偏偏不讲结合律。
(a + b) + c，在显卡里经常不等于 a + (b + c)。
为什么？
因为计算机内存是有限的，显卡装不下无限精度的实数。
每做一次加法，只要小数位超出了硬件表示范围，显卡就会就近舍入，抹掉末尾几个二进制位。
求和的顺序只要变了，末尾被抹掉的微小数字就不一样。

这差得有多夸张？
看一个极其直观的算式。
现在大模型推理最常用的半精度浮点数 fp16，有效数字只有 11 位。
在 1024 到 2048 这个数值区间里，fp16 能精确表示的数字，间距刚好是整整 1.0。
也就是说，在 1024 之后，显卡能存下的下一个数就是 1025。
像 1024.4 这种数字，硬件根本存不下。
现在我们把三个数加在一起：1024、0.4、0.4。
如果你从左往右加：
第一步，1024 加上 0.4，等于 1024.4。显卡舍入到最近的数，退回了 1024。
第二步，拿这个 1024 再去加第二个 0.4，又舍入一次，最后结果依然是 1024。
换个顺序再加一遍呢？
先把后面两个小数字加在一起：0.4 加 0.4，等于 0.8。
然后再拿 1024 加上 0.8，等于 1024.8。
显卡一舍入，变成了 1025。
同一批数字，仅仅因为加法顺序换了一下，算出来的结果直接差了 1。

这个求和顺序，又是怎么被隔壁陌生人决定的？
因为显卡在随时调整并行的策略。
一张英伟达 H100 显卡，塞了整整 132 个计算单元。
显卡的核心目标，是不让这 132 个单元闲着摸鱼。
如果这一刻服务器上只有 8 个并发请求，活太少，分给每个单元的工作根本不够塞牙缝。
显卡底层的计算核心就会把一长串加法切成很多细小的分块，分派给不同的计算单元同时算，最后再把这些中间结果聚拢加起来。
可如果下一毫秒，又有其他用户的请求涌了进来，并发批次涨到了 32 呢？
每个计算单元分配到的任务一下子满了。
显卡为了追求吞吐量，会立刻换一套更粗犷的切分方式。
并发批次变了，任务分块的大小就变了。
分块变了，数字累加的先后顺序就跟着变了。
顺序一变，浮点数在末位舍入时飘落的尘埃，也就落在了不同的坑里。
最后算出来的每个候选词打分，就悄悄漂移了微不足道的一点点。

漂移一点点要紧吗？
平时绝大多数时候，最高分和第二名差得很远，这点微小的漂移根本翻不起浪花。
麻烦在于，一旦某一步生成时，有两个词的分数咬得极紧。
在 8 个请求一起跑的批次里，词语 A 拿了 12.3417 分，词语 B 拿了 12.3415 分。
因为温度是 0，显卡顺理成章选了 A。
可要是在 32 个请求一起跑的批次里，浮点数累加顺序变动，让分值抖动了十万分之二：
词语 A 变成了 12.3414 分，词语 B 变成了 12.3416 分。
B 以微弱的优势反超了 A。
显卡毫不犹豫地吐出了 B。
接下来，大模型自回归的雪崩就开始了。
模型每生成一个新词，都要把前面所有的字当成新的输入上文。
第一个词选了 A 还是选了 B，后面的概率分布瞬间天翻地覆。
整段长文从此拐向两条完全不同的轨道。

在真实云服务里，这种扰动甚至是每一秒都在发生的。
因为现在所有主流推理引擎，用的都是连续批处理。
每一个词吐出来的毫秒间隙，服务器都在动态加入新发起的请求，踢掉刚回答完毕的请求。
你的提示词在显卡里运算的时候，周围拼座的陌生人每一步都在换。
地球另一端的某个陌生人点了一下回车，显卡重新排了一下活，你的大模型回答就跟着偏航了。

工程上能不能彻底解决这个不确定性？
能。
解决办法叫批次无关内核。
强行规定显卡在做求和规约时，不管当前是一起算 8 个请求还是 32 个请求，都必须死守同一套固定的顺序做加法。
代价是直接砍掉一大截吞吐性能。
因为内核不能再根据并发量灵活调配计算单元，很多算力只能白白空转。
开源推理框架 SGLang 提供了确定性推理开关，开启之后推理速度会下降 25% 到 45%。
vLLM 也在测试专门的环境变量开关。
深度求索的 DeepInfer 同样加上了这道保险。
如果你在跑严格的模型评测、做强化学习采样，或者复现关键缺陷，哪怕牺牲三分之一的速度也必须开这个开关。
但在绝大多数对外营业的商业服务里，降速 40% 意味着真金白银的服务器成本翻倍。
只要云服务商依然在不惜代价压榨显卡的极限吞吐，你的下一次提示词输出，就永远不可避免地要被全世界的实时流量摇晃一下。

_Canonical: <https://mubeitech.com/deep/mb-20261101-4ee563> · Source: 墓碑科技 MUBEITECH (mubeitech.com)_
_Rendered by mubei-terminal._
