FP4与FP8学习整理
FP4
FP4格式为E2M1,即1符号位+2指数位+1尾数位。 按浮点表达式换算如下: \(\text{value} = (-1)^S \times 2^{(E - \text{bias})} \times (1 + M \times 2^{-1})\) 其中bias为1。
具体可以表达数值如下:
| 编码 (S E M) | 值 | 编码 (S E M) | 值 |
|---|---|---|---|
| 0 00 0 | +0 | 1 00 0 | -0 |
| 0 00 1 | +0.5 | 1 00 1 | -0.5 |
| 0 01 0 | +1.0 | 1 01 0 | -1.0 |
| 0 01 1 | +1.5 | 1 01 1 | -1.5 |
| 0 10 0 | +2.0 | 1 10 0 | -2.0 |
| 0 10 1 | +3.0 | 1 10 1 | -3.0 |
| 0 11 0 | +4.0 | 1 11 0 | -4.0 |
| 0 11 1 | +6.0 | 1 11 1 | -6.0 |
MXFP4
Microscaling FP4,是OCP(Open Compute Project)制定的开放标准,是Microscaling Formats规范的一部分。它是与NVFP4并列的两大主流FP4量化格式。32个元素 (或16个元素) 共一个8位缩放因子(E8M0),即2的n次方,无符号。每个元素解码公式如下: \(value_i =(−1)^{S_i}×2^{(E_i−1)}×(1+M_i×0.5)×2^{(scale−127)}\) W4A4数据流如下:
前一层输出 ──→ FP16/BF16
│
↓ LayerNorm / RMSNorm / RoPE 等(保持 FP16/BF16)
│
↓ 进入 MatMul 前
├─ 权重 W: 已从 HBM 加载,是 MXFP4(离线预量化)
└─ 激活 x: 当前是 FP16/BF16
│
↓ 在线动态量化(硬件单元实时完成)
x_q = MXFP4(E2M1) + sx(E8M0)
│
↓ Tensor Core 计算
acc = Σ(x_q × W_q) 累加精度 = FP32
│
↓ 输出转换
y = acc → FP16/BF16
│
↓ 后处理(Activation 如 SiLU/GELU,保持 FP16/BF16)
│
↓ 送入下一层
动态量化过程:
- 将32个连续元素组成一个Group
-
找到绝对值最大值max:$$ \text{max_abs} = \max_{i=0}^{31} x_i $$ -
计算E8M0,缩放到
[-6, 6]:\(s = 2^{\lceil \log_2(\text{max\_abs} / 6.0) \rceil}\) - 每个元素量化:\(x_{q,i} = \text{round\_to\_e2m1}\left( \frac{x_i}{s} \right)\)
矩阵运算(\(Y = X \cdot W^T\)):
- E2M1的相乘可以用查表实现,总查表量为16x16=256种,得到fp32
-
对FP32进行累加求和acc
-
缩放因子相乘,可以 优化为指数相加:\(s_X \times s_W = 2^{(e_X - 127)} \times 2^{(e_W - 127)} = 2^{(e_X + e_W - 254)}\)
- 最终FP32结果输出FP16/BF16
NVFP4
是NVIDIA开发的专有FP4量化格式,没有开放授权。相比MXFP4,NVFP4更为复杂:
- 采用16个元素组成block
- block缩放因子用E4M3格式
- 二级缩放因子用FP32表达
精度上比MXFP4更好,但是设计上会更加复杂
FP8
FP8有两个格式,分别如下:
| 格式 | 布局 | 最大值 | 设计目标 |
|---|---|---|---|
| E4M3 | 1 符号 + 4 指数 + 3 尾数 | 448 | 高精度、小范围 → 权重、激活 |
| E5M2 | 1 符号 + 5 指数 + 2 尾数 | 57344 | 低精度、大范围 → 梯度、中间值 |
其中E4M3是推理的主流,通常不需要块缩放因子。
评论