【技术博客分享】LLM推理过程中的不确定问题
博客原文: https://thinkingmachines.ai/blog/defeating-nondeterminism-in-llm-inference/
1. 引言
你可能遇到过这样的场景:
- 你向ChatGPT提问,得到一个答案A。刷新页面,再问一次,得到一个略有不同的答案B。这很正常,因为默认启用了随机采样。
- 于是,你调用OpenAI API,将
temperature
设为0。你期望每次都能得到完全相同的结果。但事实是,偶尔,你会得到一个微小的、可能是一个词或一个标点的差异。 - 你换用vLLM或SGLang在自己的GPU上部署开源模型,同样设置
temperature=0
,这个现象依然存在。
这种现象让需要严格结果一致性的应用(如自动化测试、科学实验、金融分析)变得非常棘手。它就像一个难以捉摸的幽灵,让我们的系统变得不可预测。
2. 问题切入:“并发+浮点数”假说
2.1 “原罪”:浮点数非结合性
要理解非确定性,首先要理解所有数值差异的根源——浮点数的非结合性。在计算机中,由于浮点数精度有限,加法运算不满足结合律:(a + b) + c ≠ a + (b + c)
。
一个经典的例子:
# (0.1 + 1e20) - 1e20
# >>> 0.0
# 0.1 + (1e20 - 1e20)
# >>> 0.1
因为1e20
这个“天文数字”的精度“吃掉”了0.1
这个“小数”,导致先加0.1
的结果被舍入误差抹去。
这意味着,只要浮点数加法的顺序发生改变,结果就可能不同。
2.2 为何简单的矩阵乘法是确定性的?
“并发+浮点数”假说认为,GPU上成千上万个核心并行计算,它们完成计算的顺序是随机的,如果使用了**原子加(atomic add)**等操作来累加结果,就会导致加法顺序不一,从而产生非确定性。
这个解释听起来很合理,但可用一个简单的实验证伪了它在LLM前向推理中的主导作用:
import torch# 在GPU上重复运行同一个矩阵乘法1000次
A = torch.randn(2048, 2048, device='cuda', dtype=torch.bfloat16)
B = torch