(本文阅读时间:16 分钟)
同样的模型、同样的输入、同样的随机种子,换一块 GPU 运行,结果却可能不一样。
在大模型时代,这类数值差异不只是工程上的小麻烦,还可能影响模型质量、实验可复现性和训练稳定性。那么问题出在哪里?答案往往藏在 GPU 内部那些没有写进文档的算术细节里。
为了看清这些细节,微软亚洲研究院的研究员们提出了闭环特征探测方法 CLFP,并据此构建了 MMA-Sim。MMA-Sim 是一套位精确的 GPU 矩阵乘累加(MMA)模型,覆盖 NVIDIA 和AMD 的十种 GPU 架构,能够逐比特复现所测试指令的输出,解释跨平台的数值差异,并为精度改进提供指导。相关论文已被计算机体系结构领域顶级会议 MICRO 2026 收录,代码也已开源。
相关信息已整理至文末,欢迎点击了解更多技术详情。
小误差,大麻烦:被忽视的硬件“算术账”
大语言模型(LLMs)会执行海量的浮点运算。一个微小的算术差异,可能在不同层和多次迭代中不断累积、放大,最终改变模型计算出的概率分布及其输出的 token。因此,数值行为对于模型质量、可复现性和训练稳定性至关重要。
现有关于数值行为的研究大多聚焦于软件因素,硬件层面的算术行为却很少有人深究。实际上,硬件同样会带来两个棘手的问题:
一是数值差异。用相同的输入在不同 GPU 平台上运行同一个模型,可能得到不同的数值结果。即使统一了随机种子、编译器及其他软件因素,硬件层面的差异仍可能存在。要解释这种差异,就必须理解硬件内部实际执行的算术运算。
二是训练精度。GPU 浮点计算采用的内部精度可能不同于标准浮点运算,这种精度差异会影响 LLMs 的训练。例如,有研究者曾报告,Hopper GPU 的 FP8 矩阵乘法内部精度不足,会导致 LLMs 训练精度下降。
这两个问题指向同一个根源——业界对硬件数值行为缺乏白盒层面的理解。没有这个基础,我们就只能在LLMs系统出现问题后依赖经验被动应对,难以事先进行数值分析、精度预测、问题诊断、设计有理论依据的缓解措施。
直击矩阵运算的“黑盒”:MMA 单元
为解决这一问题,研究员们把目光投向了 GPU 矩阵乘累加(matrix multiply-accumulate,MMA)单元的数值行为。矩阵乘法是 LLMs 训练和推理中线性代数运算的核心,GPU 中的专用单元负责计算D=A×B+C形式的运算。NVIDIA 将这些单元称为张量核心(Tensor Core),AMD 则称其为矩阵核心(Matrix Core)。它们支持 LLMs 所用的浮点数据类型,同时提供高吞吐量和高效率。
问题在于,暴露给软件的MMA指令规定了运算的数学定义D=A×B+C,却没有规定其数值实现方式。计算结果取决于融合粒度、内部精度、舍入与规格化、次正规数处理、求和顺序,以及其他实现细节。这些隐藏的算术选择决定了 D 中实际计算出的数值,并最终影响可复现性、精度和稳定性。
研究员们的目标是通过白盒模型,将底层计算过程明确地描述出来。通过采用特征探测测试(feature-probing test),来构建这些模型。
一道算术题,六种答案
先看一个具体的 MMA 运算示例。图1中高亮显示的 A 的第一行、B 的第一列,以及 C 的第一个元素,共同决定了 D 的第一个输出元素。考虑以下输入对 (−213,210), (−0.5,1), (−0.25,1), (−0.125,1),以及值为223的累加输入。
图1:矩阵乘累加(MMA)运算示例
各对输入相乘后,得到 −223、−0.5、−0.25和 −0.125。从数学上看,将这些乘积加到累加器 223上,结果应为 −0.875。
那么各条硬件指令实际会返回什么?面对完全相同的输入,如图2所示的 MMA 指令产生了六种不同的结果:0、−0.375、−0.5、−0.75、−0.875(精确结果)以及 −1。
图2:同一示例输入,不同GPU输出不同(左列列出结果,右列列出对应的指令)
这个例子清晰地展示了隐藏算术选择的影响。研究员们要构建的模型,既要逐比特复现每条指令的结果,也要能解释这些输出是如何产生的。
从这些输出反推硬件内部计算方式的方法,称为特征探测测试。下面举两个例子。
第一,探测求和顺序。仍然使用与前例相同的加数,对比两棵求和树(如图3所示),以展示求和顺序如何影响结果。图3左侧的加法运算构成了一条顺序执行的链,累加器 C 从一开始就参与其中。在顺序求和中,两个大数首先抵消,其余加数得以保留,最终得到(((223−223)−0.5)−0.25)−0.125=−0.875。右侧则先将乘积两两相加,再将这些和与 C 累加。在本例采用的有限精度算术下,成对求和时,较小的项在与较大的项相加时丢失,最终得到223+((−223−0.5)+(−0.25−0.125))=0。
图3:两种求和顺序产生不同的结果
推广开来,可以选择一个大数 U 和一个小数 v,使得 U+v 舍入后仍为 U。随后再加上 −U,结果就是0。如果先让 U 与−U 抵消,则 v 会被保留下来。通过将大数放在不同的输入位置,并观察哪些小数项能够保留,就可以推断出求和的顺序。
第二,探测内部精度和舍入模式。仅靠求和顺序还不足以完整解释这些结果,研究员们设计了一个包含五个加数的融合运算:将 U 和 −U 放在求和树的两个叶节点上,其余三个叶节点均放置 v。如果内部精度足够高,运算会保留全部三个小数项,并返回 3v。但有限精度的融合运算可能在抵消发生前的对齐阶段就丢弃了这些小数项,从而返回 0。
图4:两种精度的融合求和产生不同的结果
计算 U、−U和ϵ 的融合求和,从ϵ=0.5U 开始,反复将其减半。ϵ 不再被保留时所对应的阈值,可以揭示内部小数位的位数。进一步在该阈值的一半处,以及略高于和略低于该值的位置测试ϵ,还可以推断出舍入模式。
以上只是特征探测测试中的几个例子。研究员们把完整的建模方法称为闭环特征探测(closed-loop feature probing,CLFP)。只要能够通过接口调用某条 MMA 指令,CLFP 就可以利用一组不断扩充的特征探测测试,构建可执行的算术模型。
整个流程分为五步:
检查确定性假设,以及不同输出位置之间的一致性假设。
推断求和树及其元数,即各求和节点包含的输入数量。
探测其他算术特征并构建模型。
通过随机差分测试,逐比特比较硬件输出与模型输出。
如果验证失败,第五步就会对反例进行缩减,向探测测试集中加入一个能够区分不同行为的测试,修订模型,然后返回第4步。
这个反馈循环能够发现先前探测遗漏的细节,并将每一次不匹配转化为新的特征探测测试。当模型在验证测试中能够逐比特匹配硬件时,循环结束。
十种架构,三大模型族:MMA-Sim 的位精确模型
研究员们将 CLFP 方法应用在了十种 GPU 架构上的全部浮点 MMA 指令,包括NVIDIA 的 Volta、Turing、Ampere、Ada Lovelace、Hopper、Blackwell 和RTX Bl...
