什么是FP8?

引言

本文将从什么是FP8的基本结构开始, 举例讲解如何将一个十进制的小数转换为FP8的格式。同时,也会演示如何将一个FP8的数据转换回一个十进制的数。接下来,我们会介绍FP8的基本计算原理,包括如何进行加减乘除运算。相信通过本文的介绍,读者应该会对FP8有一个基本的了解。

本文属于合集:“大模型的底层原理”,首发于公众号“峰少的技术空间”。这个合集以最新的大模型技术入手,系统地梳理大模型技术的底层原理,并将保持免费和开放,欢迎大家关注。大家如果想了解其他的大模型的技术或原理,请直接在文章下留言。

FP8的基本结构

FP8是一种8位浮点数格式,专为深度学习计算设计。与传统的32位浮点数(FP32)相比,它大幅减少了存储空间和计算负担,同时为AI任务保留了足够的精度。

FP8主要有两种常见规格:

  • E4M3:1位符号位 + 4位指数位 + 3位尾数位
  • E5M2:1位符号位 + 5位指数位 + 2位尾数位

FP8和十进制如何转换

FP8遵循IEEE浮点数的基本原理,一个FP8数的值计算为:

(-1)^符号位 × (1.尾数) × 2^(指数-偏置值)

其中E4M3格式的偏置值为7(2^(4-1)-1)。

实例:十进制转FP8

以0.15625为例,如何转换为FP8(E4M3)格式?

  1. 确定符号位0.15625为正数,符号位为0
  2. 二进制转换0.15625 = 0.00101(二进制) = 1.01 × 2^(-3)
  3. 计算指数实际指数为-3,加上偏置值7得到E = 4(二进制0100)
  4. 提取尾数尾数为01,补齐三位为010
  5. 组合结果0|0100|010 = 00100010(二进制)

这样,0.15625就被编码为00100010这个8位二进制数。

实例:FP8转十进制

如果我们看到FP8数01100010,如何转换回十进制?

  1. 分解各部分
    • 符号位S = 0(正数)
    • 指数位E = 1100(二进制) = 12(十进制)
    • 尾数位M = 010
  2. 计算实际值
    • 实际指数 = 12 – 7 = 5
    • 尾数转换为十进制: 1.010 = 1 * 2^0 + 1*2^(-2) = 1+0.25 = 1.25
    • 最终,真实值 = 1 × 1.25 × 2^5
    • = 1 × 1.25 × 32
    • = 40

计算原理

高能预警:本节内容存在大量计算,需要读者掌握一些基本的计算机组成原理知识。包括但不限于:进制转换速算、计算机组成原理等。限于篇幅,无法将所有先验知识一一写明,读者请酌情阅读下列内容。如果写得不清楚的地方,欢迎读者在文章评论区提问,作者会及时回复。

本节用2个FP8数值为用户举例讲解两个FP8的数据如何进行计算。两个数值的对应信息见下表:

左操作数右操作数
十进制表示0.156250.0625
FP8表示0010001000011000
符号位00
指数(二进制)01000011
指数(十进制)43
尾数(二进制)010000
尾数真实值(二进制)1.0101.000
尾数真实值(十进制)1.251

尾数真实值需要补充隐含的1

加减

加减的计算规则按照:

  1. 处理符号位:同号加法结果符号与操作数相同,异号加法结果符号跟随绝对值较大的操作数,用绝对值较大的数减去绝对值较小的数。 减法将第二个操作数的符号取反,然后按加法规则处理。
  2. 将较小指数的操作数的尾数右移相应位数,将两个操作数的指数变换成相同。
  3. 对齐后的尾数按照普通二进制的加减规则进行加减(即加法直接相加,减法取补码后相加)
  4. 将尾数真实值规格化到[1,2)之间。如果结果尾数≥2,需要右移一位并将指数加1 。如果结果尾数<1,需要左移直到尾数≥1,并相应减小指数。

举例

第一步: 同号加法,符号位为0.

第二步: 因为右操作数的指数是3,而左操作数的指数是4,所以需要将右操作数的尾数真实值右移一位,使得左右操作数指数一致。即1.000 >> 1 = 0.100。

第三步:  对齐后的左右操作数的尾数直接按照普通二进制加减法进行加减。即1.010 + 0.100 =1.110。

第四步: 规格化,因为1.110已经在[1,2)之间了,所以不需要缩放了。最终结果为符号位0,指数0100,尾数110,最终拼起来就是00100110。对应的十进制数为0.21875。

乘除

乘除的计算规则按照:

  1. 处理符号位:乘除法的结果符号位是两个操作数符号位的异或结果(相同为0,不同为1)。
  2. 指数处理:乘法时,结果的指数等于两个操作数的指数之和再减去偏移量;除法时,结果的指数等于被除数的指数减去除数的指数再加上偏移量。
  3. 尾数处理:乘法时,将两个操作数的尾数真实值相乘;除法时,将被除数的尾数真实值除以除数的尾数真实值。
  4. 将尾数真实值规格化到[1,2)之间。如果结果尾数≥2,需要右移一位并将指数加1;如果结果尾数<1,需要左移直到尾数≥1,并相应减小指数。

举例

以乘法为例:

第一步:两个操作数符号位都是0,异或结果为0,所以结果符号位为0。

第二步:左操作数指数为4,右操作数指数为3,两数相加得7,再减去偏移量7,实际指数为0。

第三步:计算尾数真实值相乘,即1.010 × 1.000 = 1.010。

第四步:结果尾数1.010已在[1,2)之间,不需要规格化。最终结果为符号位0,指数0111,尾数010,拼起来就是00111010。对应的十进制数为0.15625 × 0.0625 = 0.009765625。

FP8常见问题解答(FAQ)

Q1: FP8相比FP32/FP16会带来多大的精度损失?

A: FP8相比FP32或FP16确实会带来一定的精度损失。E4M3格式的动态范围约为[-448, 448],精度约为2^-3≈0.125;而E5M2格式的动态范围约为[-57344, 57344],精度约为2^-2≈0.25。相比之下,FP32的精度约为2^-23≈1.19×10^-7,FP16的精度约为2^-10≈9.77×10^-4。但研究表明,对于大多数深度学习应用场景,特别是大型语言模型,这种精度损失是可接受的,不会显著影响模型性能,同时能带来高达4倍的存储空间节约和计算效率提升。

Q2: FP8的舍入策略有哪些?它们如何影响计算结果?

A: FP8主要采用的舍入策略包括:

  • 向最近舍入(Round to Nearest Even, RNE)

    将数值舍入到最近的可表示值,如果处于中间点则舍入到偶数。这是最常用的策略,平均误差最小。

  • 向零舍入(Round toward Zero, RTZ)

    舍入到绝对值较小的可表示值,简单但容易累积误差。

  • 随机舍入(Stochastic Rounding)

    基于概率随机舍入,在训练过程中特别有用,可以防止梯度消失。

DeepSeek模型主要使用RNE策略,因为它在统计上偏差最小,适合深度学习训练。

Q3: FP8和INT8有什么区别?为什么不直接用INT8?

A: 尽管FP8和INT8都使用8位表示数值,但它们的结构和用途完全不同:

  • INT8是定点数,表示范围固定[-128, 127],精度均匀。
  • FP8是浮点数,具有指数位,可表示更大范围的数值,但精度随数值变化。

深度学习模型权重和激活值的分布通常是非均匀的,有极小和极大的值,FP8更适合捕捉这种分布,而不需要像INT8那样复杂的量化校准过程。

更详细的分析,请关注作者公众号:“峰少的技术空间”。将于明天推送的详细分析。

Q4: E4M3和E5M2应该在什么场景下选择?

A: 选择取决于具体需求:

  • E4M3(4位指数,3位尾数):精度较高但范围较小,适合前向传播和激活值,对数值精确度要求较高的场景。DeepSeek-V3模型全面采用E4M3格式。
  • E5M2(5位指数,2位尾数):范围更大但精度较低,适合梯度计算和反向传播,数值波动较大的场景。

许多框架会在一个模型中混合使用这两种格式:前向传播用E4M3,反向传播用E5M2,以平衡精度和范围需求。

Q5: FP8是否支持NaN、无穷大等特殊值?

A: 是的,与标准IEEE 754浮点数类似,FP8也支持特殊值:

  • NaN(非数值)当指数位全为1且尾数不为0时表示。
  • 无穷大当指数位全为1且尾数为0时表示。
  • 当指数位和尾数都为0时表示。
  • 非规格化数当指数位为0且尾数不为0时表示,用于扩展表示范围。

这些特殊值在处理溢出、下溢和错误操作时非常重要。

Q6: 在模型中如何平滑过渡到FP8格式?

A: 由于FP8的精度有限,因此目前还无法做到所有的训练过程都使用FP8。因此需要平滑过渡,通常需要以下步骤:

  1. 混合精度训练先用FP16/FP32训练模型,然后逐步将部分计算迁移到FP8。
  2. 缩放因子应用动态缩放因子(scaling factors)来调整FP8表示范围,避免溢出和下溢。
  3. 梯度累加在更高精度(如FP16/FP32)下累加梯度,只在计算密集型操作中使用FP8
  4. 误差分析监控并比较FP8与更高精度格式之间的误差,确保不会显著影响模型性能。
  5. 选择性应用对精度敏感的层保留较高精度,对不敏感的层应用FP8。

Q7: FP8在消费级硬件上是否可用?需要特殊硬件支持吗?

A: 目前只在H系列的GPU上提供支持。


已发布

分类

来自

标签:

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注