Bit-Accurate Modeling of GPU Matrix Multiply-Accumulate Units: Demystifying Numerical Discrepancy and Accuracy
Bit-Accurate Modeling of GPU Matrix Multiply-Accumulate Units: Demystifying Numerical Discrepancy and Accuracy
Abstract
现代的AI 高度依赖 MMAU。 MMAU是什么呢? Matrix Multiply -Accumulate Units
所以本质上就是一种进行矩阵乘法,然后加回去的计算单元。而硬件厂商通常只公开MMA的指令集和接口,不公开完整的内部浮点算数行为。
数学上,我们知道 D = AB + C
但是硬件是一个黑盒,我们知道这个黑盒函数的数学定义,但不知道它内部的运算序列。
然后所以由于这种黑盒性质,就导致了一个问题—— 同样的输入,硬件却可能给出不同的结果。
因此,这种不同的结果带来的不稳定性一是降低了数值精度,二是影响了神经网络的训练的稳定性。
因此,我们现在面临着两个问题
- Numerical Discrepancy —— 为什么两个GPU的结果不一样?
- Numerical Accuracy —— 哪个结果更接近真实值?
所以authors提出了一种闭环特征探测框架CLFP,通过精心设计的测试输入探测硬件算术特征,再构造可执行的数值模型。反复对真的GPU输出进行修正。
作者最后声称的贡献主要有以下几点:
- 解释不同架构产生的原因
- 分析数值误差到底来自于哪些硬件设计
- 识别四类精度瓶颈和一类数值非对称性
- 给出软件解决方法和未来设计建议。
Introduction
MMAU 已经成为了DNN Training 和 Inference 的核心计算单元,但是数学上的矩阵乘法
并没有指定硬件的执行顺序。所以就导致了完全相同的表达式,计算顺序改变了结果。
作者举了两个例子,其中,一个是Nvidia Hopper的FP8 MMA , 这个FP8部分矩阵乘法的精度不足影响了训练数值的准确性。
另外一个是AMD CDNA2 的Subnormal Flushing
非规格化浮点数允许表示比最小正规格化更接近0的非零数。但是部分MMA 硬件可能采用Flush-to-zero的规则。
而作者由此引出了一个过渡—— 作者认为,我们现在缺少一个 White-box Arithmetic Model。
作者指出,当前的研究很多偏向于 先发现数值异常,再尝试去解释它,而不是先去理解硬件的算术语义,再预测什么输入会产生数值异常
而尝试破解黑盒的实验就是作者想要进行的操作。 但是由于黑盒的输入空间太大,输入的位组合数量也已经极其的庞大。更麻烦的是,作者事先不知道有哪些要探测的特征。
因此,他们提出了 CLFP。 把黑盒测量变为可验证的算术模型
文章使用以下的方法: Feature Probing(用特殊输入探测计算顺序、精度、舍入) 、 Model Construction(将推断出的规则组合成可执行模型)、 Bitwise Differential Testing 比较模拟器和真实GPU的逐位置输出
所以总结一下呢。这篇文章的核心贡献就是提出了一套系统的黑盒算术逆向方法,并对多个GPU架构的MMA建立了可执行的模型。
Background and Measures
首先看看已有的研究问题:
- API 层级不够低
- 探测特征不完整
- 缺乏逐位验证
所以作者的方法就要针对性的做出优化
step1: 确认计算是否具有一致性
作者首先检查同一条MMA指令的不同输出位置,是否有相同的算术行为。如果一致的话,就可以把矩阵分解为独立的Dot Product Accumulate
step2:反推出Summation Tree
上图就是Summation Tree的一个例子。也是核心贡献.
假设硬件现在计算
如果先计算U+v , 小数U就会被舍掉,随后加上 -U 就无法恢复刚刚丢失的v
但是如果先计算 U + (-U) , 就会得到0.所以观察最终的结果,就能推断大数字在哪一步抵消,以及小数字在哪里抵消。
Step3:探测每个算术操作的详细特征
| 测试 | 意图 |
|---|---|
| FPT1 | 内部累加精度 |
| FPT2 | 舍入模式和Tie-breaking规则 |
| FPT3 | 多项融合累加内部的求和顺序 |
| FPT4 | 乘积再累加之前是否重新归一化 |
这些方法本文不展开叙述。
Step4-5 逐个位置验证,再用反例修正
作者将探测结果组合成可执行的 MMA-Sim 模型,然后与真实 GPU 逐位比较
方法包括但不限于
- 正态分布,均匀分布等随机输入
- 容易发生灾难性的病态输入
- 随机位流构造的输入。
如果出现不一致,作者会进行 Minimum-failing-subset Reduction
Results
作者把测试过的MMA 指令归结为三大类八种模型
| 模型类型 | 核心计算方式 | 典型硬件 |
|---|---|---|
| Muladd-based | 独立乘法,加法,部分采用FTZ | AMD CDNA2 |
| FMA-based | 标准融合乘加最后舍入 | FP32/FP64 MMA |
| FDPA-based | 多个乘积融合,按照硬件特定精度和规则累加 | 大多数混合精度Tensor Cores |
作者指出 , NVIDIA的很多混合精度MMA更接近
- 计算乘积的尾数和指数
- 将各个乘积对齐到最大的指数
- 将尾数截断至指定精度
- 进行融合求和
- 转换为输出浮点模式
数值精度分析及其问题归因
| 问题 | 产生原因 | 影响 |
|---|---|---|
| FP16 Input FTZ | CDNA2 将部分非规格化输入归0 | 小数信息 |
| FP8 内部精度不足 | Ada/Hopper的部分MMA使用较小的F | 中间求和截断误差 |
| FP8 输出舍入精度受限 | 使用RZE8M13规则 | 输出进一步损失精度 |
| FP16 output | 即使内部准,最终仍然舍入 | 输出格式 |
| CDNA3 Asymmetry | 内部使用Round Down | 可能引入具有方向性的数值偏差 |
总结
这篇文章其实更像是一种对GPU黑盒的拆解,核心的贡献就是通过大量的实验对GPU内部行为建模,但是作者并没有把这个东西扩大到应用当中,只是自己把这个数据集,指令集的顺序给了出来。
后续要继续研究浮点数稳定的话,这个文章很有参考价值。







