FP8 格式入门(一):Arm 详解 E4M3/E5M2 编码、FPMR 寄存器与 FP8 指令集
Introduction To FP8 Formats: Part 1
FP8 已在 NVIDIA Hopper H100 GPU 和主要 ML 框架中部署,Arm 也将其加入 Arm v9 ISA,Arm、Intel、NVIDIA 联合发布了 OCP 8-bit 浮点规范(OFP8)作为模型交换格式。
业界正在从高精度格式(FP32、FP16、BF16)转向用于机器学习(ML)推理和训练的低精度数据类型。在云和数据中心环境中,低精度数据类型通过在相同平台上每周期打包更多计算来提供更高的吞吐量。在边缘和移动设备上,更小的格式可以减少模型大小、内存占用和带宽,从而直接影响功耗和延迟。
Arm、Intel 和 NVIDIA 发布了 OCP 8 位浮点规范(OFP8)。它是一种交换格式,使软件系统能够轻松共享模型。FP8 并非未来概念,它如今已被部署。NVIDIA 的 Hopper H100 GPU 已支持它,主要 ML 框架中也出现了相应的软件部署。
Arm 在 Arm v9 ISA 中添加了 FP8 支持,并正在探索将 FP8 集成到所有 ML 平台的最佳方式。
这篇博客文章解释了 FP8 数据格式、新的浮点模式寄存器(FPMR),以及使 FP8 在 Arm CPU 上切实可用的指令集。
FP8 数据格式
与 IEEE FP64、FP32 和 FP16 不同,FP8 不是单一格式,而是一个格式家族。白皮书 FP8 Formats for Deep Learning 提出了一种由两种编码组成的 FP8 格式:E4M3 和 E5M2。
为什么需要一个格式家族?
由于只有 8 位可用,FP8 需要在精度和动态范围之间做出权衡。单一编码无法同等地适配所有张量。激活值和权重在训练或校准后通常具有更小且更稳定的数值分布,因此可以从更多的尾数位中获益,从而更精确地表示相近的值。梯度在前向和反向传播过程中变化可能大得多,因此可以从更多的指数位和更大的动态范围中获益,这有助于避免溢出或下溢。
这两种编码使软件能够为每个张量的角色选择合适的格式。当精度更重要时使用 E4M3,当动态范围更重要时使用 E5M2。这是 FP8 的核心思想,Arm 在 FPMR 寄存器中体现了同样的思想。借助 FPMR,每个源操作数可以独立选择其使用的 FP8 格式。
支持的数据类型
| E4M3 | E5M2 | |
| 指数位 | 4 | 5 |
| 尾数位 | 3 | 2 |
| 偏置 | 7 | 15 |
| 最大规格化值 | 448 | 57344 |
| 特殊值 | 仅 NaN | Inf 和 NaN |
E4M3 使用 1 个符号位、4 个指数位和 3 个尾数位,偏置为 7。E4M3 将大多数位模式用于规格化有限数,而不是为特殊值保留许多位模式。这有助于 E4M3 扩展动态范围,这对深度学习工作负载更为有用。
E5M2 使用 1 个符号位、5 个指数位和 2 个尾数位,偏置为 15。E5M2 在指数字段和特殊值(包括无穷大和 NaN)方面遵循 IEEE 754 约定。因此,它可以被视为尾数位更少的 IEEE FP16,就像 bfloat16 和 TF32 可以被视为位数更少的 IEEE FP32 一样。这使得 E5M2 与 IEEE FP16 之间的转换非常直接,同时仍提供比 E4M3 更宽的动态范围。
FPMR:浮点模式寄存器
当硬件执行 FP8 指令时,它必须知道每个源操作数的格式、目标结果的格式,以及要应用的缩放因子。
由于 FP8 模式可以按张量变化,软件可能需要在性能关键代码内部频繁更新格式和缩放设置。因此,Arm 引入了一个专用的控制寄存器——FPMR。FPMR 与 FPCR 是分离的。硬件可以更高效地识别和重命名对 FPMR 的写入,使按张量切换 FP8 模式的操作更接近一次普通的寄存器写入,而非导致流水线串行化的控制更新。
FPMR 包含以下字段:
| 字段 | 位 | 描述 |
| F8S1 | [2:0] | 第 1 个 FP8 源的格式。0b000 = E5M2,0b001 = E4M3。 |
| F8S2 | [5:3] | 第 2 个 FP8 源的格式。编码与 F8S1 相同。 |
| F8D | [8:6] | 用于将其他浮点格式转换为 FP8 的指令的目标结果格式。 编码与 F8S1 相同。 |
| OSM | [14] | FP8 乘法指令的溢出饱和设置。 |
| OSC | [15] | FP8 转换指令的溢出饱和设置。 |
| LSCALE | [22:16] | 无符号 Log2 下缩放因子。结果 × 2^(−LSCALE)。 |
| NSCALE | [31:24] | 用于扩展 FP8 源的无符号 Log2 上缩放因子。 |
| LSCALE2 | [37:32] | 双源转换指令的第二个下缩放值。 |
Arm 上的 FP8 指令集
2023 和 2024 年的架构扩展在 Advanced SIMD、SVE 和 SME 中加入了 FP8 指令。下表总结了这些架构特性及其提供的指令。
| 架构特性 | 支持的类别 | 指令 | 描述 |
| FEAT_FP8 | Advanced SIMD/SVE/SME | FCVTN, FCVT, F1CVT, F2CVT, BF1CVT, BF2CVT, FSCALE | FP8 转换指令; 浮点缩放指令。 |
| FEAT_FP8FMA | Advanced SIMD/SVE | FMLALB, FMLALT, FMLALLBB, FMLALLBT, FMLALLTB, FMLALLTT | FP8 扩展乘累加。 |
| FEAT_FP8DOT4 | Advanced SIMD/SVE | FDOT (.S) | FP8 → FP32 4 路点积。 |
| FEAT_FP8DOT2 | Advanced SIMD/SVE | FDOT (.H) | FP8 → FP16 2 路点积。 |
| FEAT_SSVE_FP8FMA | SME | FMLALB, FMLALT, FMLALLBB, FMLALLTT | Streaming SVE 模式下的 FP8 扩展乘累加。 |
| FEAT_SSVE_FP8DOT4 | SME | FDOT (.S) | Streaming SVE 模式下的 FP8 → FP32 4 路点积并累加。 |
| FEAT_SSVE_FP8DOT2 | SME | FDOT (.H) | Streaming SVE 模式下的 FP8 → FP16 2 路点积并累加。 |
| FEAT_SME_F8F32 | SME | FMOPA, FDOT, FVDOTB, FVDOTT, FMLALL | FP8 外积并累加到 FP32 ZA tile; FP8 点积并累加到 FP32 ZA 数组; FP8 扩展乘累加到 FP32 ZA 数组; |
| FEAT_SME_F8F16 | SME | FMOPA, FDOT, FVDOT, FMLAL | FP8 外积并累加到 FP16 ZA tile; FP8 点积并累加到 FP16 ZA 数组; FP8 扩展乘累加到 FP16 ZA 数组。 |
| FEAT_F8F32MM | Advanced SIMD/SVE | FMMLA | FP8 矩阵乘累加到 FP32 |
| FEAT_F8F16MM | Advanced SIMD/SVE | FMMLA | FP8 矩阵乘累加到 FP16 |
所有 FP8 计算指令都从 FPMR(F8S1/F8S2)读取源格式,并通过 LSCALE/NSCALE 应用缩放。这些扩展指令始终以 FP8 数据作为输入格式。累加则使用更宽的类型,例如 FP16 或 FP32。这样既保留了 FP8 输入的带宽优势,又在累加过程中保持了数值稳定性。
延伸阅读
关于 FP8 的更多详细信息,请参阅 Arm Architecture Reference Manual for A-profile architecture 和 FP8 Formats for Deep Learning 论文。
第 2 部分将深入探讨 FP8 指令,涵盖 Advanced SIMD、SVE 和 SME 中从转换与缩放,到点积、矩阵乘法以及外积的内容。
来源: Semiconductor Engineering 芯片与封装 · semiengineering.com