
LLM Inference 中的低精度陷阱:数值稳定性和可复现性
一、背景
LLM Inference 中的数值稳定性问题是一个长期存在的挑战。自从 ChatGPT 发布以来,关于同样输入下,尽管使用了 Greedy Search,输出仍然存在差异的问题就引发了广泛关注。在我们之前的文章中,也曾涉及这一问题。最近,我们注意到一篇新的论文,针对这一问题进行了深入分析和讨论,本文将对其进行简要介绍。
对应的论文:[2506.09501] Give Me FP32 or Give Me Death? Challenges and Solutions for Reproducible Reasoning [1]
二、摘要
研究表明,LLM 效果的可复现性极其脆弱:评估的 Batch-Size、GPU 数量、GPU型号等微小变化都可能导致生成的 Response 有较大的差异。这类现象在 Reasoning 模型中尤为突出——早期 Token 的细微误差会导致思维链出现级联效应,最终影响精度。
通过溯源分析,作者发现这种差异的根本原因在于有限精度下浮点运算的非结合律特性(PS:这个似乎早已经是共识)。本文中,作者系统性揭示了数值精度如何影响 LLM Inference 的可复现性:通过跨硬件、软件及精度设置的严格对照实验,量化了模型输出何时及如何产生差异。分析表明,尽管浮点精度对结果复现至关重要,但在评估实践中却常被忽视。受此启发,作者开发了名为 LayerCast 的轻量级 Inference 方案——将权重存储为 16 位精度,但所有计算均在 FP32 下执行,实现了内存效率与数值稳定性的平衡。
PS:论文的工作也有很多局限性,我们在最后的部分介绍。
三、引言
3.1 浮点数值表示
如下图为 NVIDIA GPU 常见的浮点数表示方式,其中 sign 表示符号位,exponent 表示指数位(决定了动态范围),mantissa 表示尾数位(决定了表示精度)。
- 相比 FP32:
FP16 的指数位和尾数位都更小。因此,通常 FP32 转 BF16 时会带来较大的精度损失。
BF16 的指数位和 FP32 相同,尾数位更少。因此,通常 FP32 转 BF16 只需要做尾数位的截断,损失相对较小。现在的 LLM 预训练中通常都会使用 BF16。
- 相比 FP16:
- FP8 E4M3 的指数位和尾数位都更小。因此,通常 FP16 转 FP8 E4M3 时会带来较大的精度损失。
- FP8 E5M2 的指数位和 FP16 相同,尾数位更少。因此,通常 FP16 转 FP8 E5M2 只需要做尾数位的截断,损失相对较小。
需要说明的是,虽然都是 E5M2 或者 E4M3,不同公司的硬件可能采用不同的格式。比如 NVIDIA GPU 上的 E5M2 符合 IEEE 754 Style,而 E4M3 却不符合 IEEE 754 Style,本文中没有特殊说明都以 ARM-Intel-Nvidia Style 为例。如下图所示,IEEE 754 Style 的 E4M3 的范围为 [-240, 240],而 ARM-Intel-Nvidia Style 的 E4M3 的范围是 [-448, 448]:
PS:2023 年,OCP(Open Compute Project) 在 AMD, Arm, Intel, Meta, Microsoft, NVIDIA, Qualcomm 的参与下提出 Microscaling(MX)Format 规范(OCP Microscaling Formats (MX) Specification Version 1.0 [2]),实现表示格式的同一,最新的 GPU 也都开始支持,比如 NVIDIA 的 Blackwell GPU。
3.2 浮点数值精度
如下图所示为 FP16 在不同数值区间的精度:
如下图所示为 ARM-Intel-Nvidia FP8-E4M3 在不同数值区间的精度:
如下图所示为 ARM-Intel-Nvidia FP8-E5M2 在不同数值区间的精度:
与传统的 FP16 和 FP32 相比,FP8 可以显著减少存储,提高计算吞吐。对于 FP8 而言,在表示范围内:
- E4M3 更精准:比如 [1, 2] 之间,E4M3 的最小间隔为 1/8,而 E5M2 的最小间隔为 1/4。
- E5M2 范围更宽:比如 E4M3 的表示范围为 [-448, 448],而 E5M2 的表示范围为 [-57344, 57344]
3.3 舍入错误
浮点数的位数越低,越容易出现舍入误差(大数吃小数)。以 FP16 为例,其在不同区间的精度是不同的,比如在 [1024, 2048] 之间,间隔只有 1,也就是如果是 1024.0 加上 1.5,其结果为 1025.0,如下图所示为一个简单的示例:
- 1024.6 用 FP16 表示时,将表示为 1025.0。
- FP16 的 1025.0 + FP16 的 0.4 = 1025.0。
- FP16 的 1025.0 + FP16 的 100.6 = 1126.0。
Pytorch 也提供了仅使用 deterministic 算法的方式,可以参考:torch.use_deterministic_algorithms — PyTorch 2.7 documentation [3]。可以最大限度避免随机性引入的误差或不稳定。
即使使用了 deterministic 算法,依然无法避免硬件、Batch-Size 等导致的不一致问题。在 LLM Inference 场景中,一般都会使用 Continuous Batching 来提升 Decoding 阶段的吞吐,这就导致实际计算时的 Shape 是动态变化的。假设单个 Token t 计算时,A * B 的大小为 (1, 4096) * (4096, 4096),当 Token t 与其他 Token Batching 处理后 Shape 可能变为 (128, 4096) * (4096, 4096)。虽然理论上 Token t 的结果不应该改变,但是因为两种方式 Shape 不同,实际计算的顺序、算法也就可能不一致,导致结果的随机性。
四、有限精度下的可复现性
4.1 实验设置
4 个模型:
- 两个 Reasoning 模型:DeepSeek-R1-Distill-Qwen-7B 和 DeepSeek-R1-Distill-Llama-8B。最大输出 Token 32K。
- 两个非 Reasoning 模型:Qwen2.5-7B-Instruct 和 Llama-3.1-8B-Instruct。最大输出 Token 2K。
5 种评估任务:
- AIME’24(30 个样本),
- MATH500(500)
- LiveCodeBench([2403.07974] LiveCodeBench: Holistic and Contamination Free Evaluation of Large Language Models for Code [4])
Easy(142)
Medium(168)
Hard(90)
使用 vLLM 作为 Inference 后端,非随机场景使用 Greedy Search,随机场景设置 temperature 为 0.7,top-p 为 0.95。每个任务 12 种不同的运行配置:
- 2 种 GPU:A100 和 L40s。
- 2 种 GPU 并行数:2 和 4。
- 3 种 Batch Size:8,16,32。
对于 Greedy Decoding 场景,4 种评估指标:
- Std@Acc:Accuracy 的标准差,如果足够稳定,应该接近于 0。
- Avg_Std@Output_Length:输出长度的标准差。
- Div_Index:针对同一问题,若两个或多个 Response 在特定位置前生成完全相同的序列,但此后出现差异,则将该位置索引定义为 Divergence Index。较高的 Div_Index 值表明不同运行配置下产生的响应具有更强的一致性。
- Avg_Std@top1_prob:在 Div_Index 之前,不同运行配置下的所有 Response 在每一位置均生成相同的 Top-1 Token。然而,浮点运算误差会导致这些 Token 的预测概率在不同设置间存在差异。为量化此现象,作者计算各位置 Top-1 Token 预测概率在不同设置下的标准差,随后对 0 至 Div_Index 区间内所有位置和全部样本取平均值。用以表征浮点误差所引入数值差异程度。
对于 Random Sampling 场景使用 Pass@1。
4.2 Greedy Decoding 不等于 Deterministic Output
如下图 Table 3 所示,为 BF16、FP16 和 FP32 三种精度在 12 种运行配置下的 Std@Acc。实验表明,Greedy Decoding 并不能保证在不同硬件和系统配置下获得确定性输出。不过,采用 FP32 精度可显著改善这一状况,并且始终能实现近乎完美的可复现性且方差可忽略不计。而 FP16 略微优于 BF16。尤其是,在 AIME’24 的评估中,DeepSeek-R1-Distill-Qwen-7B 模型在 BF16 下的 Std@Acc 甚至达到了 9%。
如下图 Table 4 所示,BF16 精度还会导致 Response 长度在不同配置下出现显著差异,比如不同配置可能导致输出长度产生 9K 个 Token 的差异。当然,这里 Reasoning 模型的 Avg_Std@Output_Length 较大也和 Reasoning 模型输出较长有关。这种差异会对 Reasoning 场景或者其他长序列场景产生较大的挑战。
因此作者建议:若采用 Greedy Decoding,应优先使用 FP32 精度以提升高效 Reasoning 研究的可复现性。(然而,当前常见 GPU 中 BF16/FP16 的算力通常远大于 FP32,使用 FP32 无法充分发挥 GPU 算力。比如,H100 GPU 中 FP16 的算力是 FP32 算力的 15 倍左右)
输出结果产生差异的根本原因还是最终输出 Token 的概率分布的差异。
- 如下图 Figure 3 左图所示,同一个输入在两个 Answer 中的概率分布示例,如果两个 Token 的概率很接近,就可能因为误差的存在导致顺序的改变,从而影响最终的输出 Token。
- 如下图 Figure 3 右图所示,呈现了 FP32 精度下 Top-1 和 Top-2 Token 概率差的直方图分布,可见,在 Reasoning 模型中头部竞争 Token 的概率差往往很小,容易受误差的影响。
为深入理解这一现象与数值误差的相互作用机制,如下图 Figure 4 进一步展示了不同数值精度水平下 Top-1 Token 预测概率的 Avg_Std@top1_prob。数据显示,BF16 精度下的 Top-1 Token 概率波动显著高于 FP16 与 FP32。主要是 BF16 的尾数位较少(7位,而 FP16 为 10 位)导致概率计算误差增大,当这些波动与 Top-1、Top-2 候选 Token 的微小概率差重叠时,会显著提高 Token 翻转概率。相比之下,FP32 运行时差异几乎可忽略不计。
综合这些结果表明:在 Greedy Decoding 过程中,由于竞争 Token 间的概率差极小,Token 选择对微小的数值波动具有高度敏感性。
4.3 Random Sampling 同样有可复现性问题
有观点认为,Random Sampling 中随机性的存在,会对精度导致的误差更加鲁棒。然而,作者实验表明,数值精度同样会显著影响基于 Sampling 的评估稳定性和可复现性。如下图 Table 5 所示,作者在 MATH500 和 AIME’24 上评估了 Pass@1 的标准差指标,其中 n 表示独立采样次数。可以看出,BF16 同样往往会产生更高的方差。
4.4 消融实验
如下图 Figure 6 所示,作者进一步探索了 Batch Size 大小、GPU 数量以及 GPU 类型对精度的影响。使用 DeepSeek-R1-Distill-Qwen-7B 模型进行 Greedy Decoding 实验。得出如下结论:
- a):4 GPU 比 2 GPU 表现出更高的概率差异。
- b):较小的 Batch Size 反而导致更高的 Token 概率方差。
- c):A100 GPU 表现出比 L40S 更高的概率方差。
五、LayerCast
采用 FP32 精度会导致内存占用和 Inference 耗时翻倍(PS:考虑到 FP16 和 FP32 算力的差距,远不止翻倍)。作者提出了 LayerCast 混合精度计算框架:
- 模型参数初始化时以 FP32 精度载入;
- Inference 前显式将所有线性层权重及偏置转换为 BF16 格式存储;
- 执行 Inference 时,采用即时(just-in-time)转换策略,将权重逐个动态回转为 FP32 精度进行矩阵乘法运算。
如下图 Figure 7 所示,该方法确保所有计算均以 FP32 精度执行,同时将权重存储为内存高效的 16 位格式。因此,该模型既能保持 FP32 在计算过程中的稳定性优势,又能使内存占用量接近 16 位模型水平。(PS:还是 FP32 计算,依然会有无法利用 FP16 算力的问题)
如下图 Figure 8 所示,LayerCast 实现了与 FP32 相当的精度,同时可以降低 34% 左右的内存需求:
六、局限性
需要说明的是,LLM Inference 中的数值精度问题确实值得关注,之前的论文 [2408.04667] Non-Determinism of "Deterministic" LLM Settings [6] 和 [2504.07086] A Sober Look at Progress in Language Model Reasoning: Pitfalls and Paths to Reproducibility [5] 也都有关 LLM Inference 稳定性和可复现性的工作。
然而,论文中的工作还有不少局限性,主要是如下的几个方面:
1. 主要集中在 7B/8B 规模模型,这些结论在更大规模模型是否还适用?比如 Qwen-32B、72B,甚至 DeepSeek R1。之前在模型量化场景中会有个共识:更多预训练数据训练、更小规模的模型更难量化,而大规模模型通常更好量化,比如 DeepSeek-R1 使用 FP4 Inference 基本可以保持无损,但是 7B/8B 模型上往往并非如此。
2. 论文中的一个主要评估指标是 AIME’24,而 AIME’24 只有 30 个样本,少的样本数量往往容易导致评估中出现较大的方差。如下图 Table 16 所示,DeepSeek-R1-Distill-Qwen-7B 和 DeepSeek-R1-Distill-Llama-8B 在 AIME’24 上的 Std@Acc 要明显更大一些,在更多更全面的评估集上会不会有不一样的结果?
3. 提出的 LayerCast 算法实用价值有限,最主要原因是当前 GPU 都在不断扩展其低精度算力,FP8 精度基本成为默认选项,更低精度也在不断发展,比如 NVIDIA Blackwell 和 AMD MI350X/355X 都原生支持 FP6 和 FP4。这些低精度的算力都远远大于 FP32 算力,为了可能不太明显的差异而引入急剧增加的 Inference 成本不是好的选择。
4. 分析不够深入,如果能更进一步的分析哪些层、哪些模块对这种误差影响更大会更有参考意义,比如选择部分层使用高精度、大部分层使用低精度,从而避免 Inference 成本的大幅增加。比如 FP8 训练中经常会将首尾层、Attention 计算维持在 BF16 精度,而只将其他的 Linear 层保持在低精度。
七、参考链接:
- [1] https://arxiv.org/abs/2506.09501
- [2] https://www.opencompute.org/documents/ocp-microscaling-formats-mx-v1-0-spec-final-pdf
- [3] https://docs.pytorch.org/docs/stable/generated/torch.use_deterministic_algorithms.html
- [4] https://arxiv.org/abs/2403.07974
- [5] https://arxiv.org/abs/2504.07086
- [6] https://arxiv.org/abs/2408.04667
本文转载自AI闲谈,作者:AI闲谈
