一句话定义
批不变性(Batch Invariance)说的是:同一个输入,不管它是单条请求,还是和几十条请求一起打包成更大的批(batch)送进模型,算出来的结果都应该完全一样。
理想如此,现实里经常不是。
为什么会被打破
推理说到底是一长串浮点运算。浮点加法不满足结合律:(a+b)+c 与 a+(b+c) 在数学上相等,但在 float32、bf16 里最后几位可能不同。谁先加、谁后加,结果就不一样。
打个比方:十个人报数求和。挨个报、分组报再汇总,理论上得到同一个和;可如果每人只保留三位小数,分组方式一变,末位就可能变。GPU 上的矩阵乘和注意力,干的就是这个"报数"的活。
锅在算子栈的哪一层
| 层级 | 典型表现 |
|---|---|
| 浮点/数学 | 归约顺序(reduction order)变化,末位抖动 |
| 算子/kernel | 批大小一变就换实现:batch=1 可能走 GEMV,batch=64 走 GEMM 且开 split-K,部分和改用原子加合并 |
| 图/编译 | 动态 shape 命中不同编译分支,autotune 选了另一套 tiling |
| 引擎调度 | AI 词典:连续批处理">连续批处理(continuous batching)把不同请求拼进同一次前向;prefill/decode 混批、前缀缓存命中与否都会改道 |
| 采样 | 随机数流按批内顺序消耗,同一个种子落到不同 token 上 |
最常见的是第二层。同一个数学算子,针对不同 shape 有不同实现路径——这不是 bug,是性能优化躲不开的代价。
和相邻概念的区别
- 确定性(determinism):同一批配置跑两遍是否一致(run-to-run)。
- 批不变性:跨批配置是否一致。
- 排列不变性(permutation invariance):同一批里换个位置是否一致。
- 幂等性(idempotence):重复提交会不会产生重复副作用。
对从业者和旁人的意义
这类差异通常小到看不见,但贪心解码下,只要两个候选 token 的 logits 挨得够近,top-1 就会翻转;偏差再被自回归一环环放大,最终两条回答可以毫不相干。
所以:评测和线上推理尽量保持一致的批大小与并发;回归测试固定批大小、把采样关掉(temperature=0);看到"同一个 prompt 两次答案不同",先怀疑并发,再怀疑模型。想彻底消除,得开启算子库和推理引擎的确定性模式,代价通常是吞吐下降,具体支持范围以各家官方文档为准。
