H200// FP8

H200 · HOPPER GH100 · 特性专题

FP8 · 原生低精度 Tensor Core

★ Hopper 精度主线 · E4M3(精度/前向) + E5M2(范围/反向) · 存储减半 · 吞吐翻倍

01

是什么

DEFINITION

Hopper 首次在 Tensor Core 原生支持 FP8 双格式E4M3(4 指数 + 3 尾数)与 E5M2(5 指数 + 2 尾数),并提供高速 cvt 转换。一条 MMA 把 4 个 FP8 打包进 32-bit 寄存器(k=32 vs FP16 的 k=16)——每字节吞吐翻倍

02

为什么需要(vs A100 FP16/BF16)

RATIONALE · VS A100 FP16/BF16
03

格式对比(选精度的核心表)

FORMAT COMPARISON
格式指数/尾数bias最大有限值最小规格化Inf / NaN
FP8 E4M3FN ★4 / 374482⁻⁶ (0.0156)无 Inf;NaN 唯一 S.1111.111
FP8 E5M25 / 215573442⁻¹⁴ (6.1e-5)有 Inf S.11111.00;NaN S.11111.{01,10,11}
FP165 / 1015655042⁻¹⁴ (6.1e-5)IEEE Inf/NaN
BF168 / 7127≈3.39e382⁻¹²⁶ (1.18e-38)IEEE Inf/NaN
CAUTION · E4M3 没有 Inf

溢出不会变成 ±Inf,cvt.satfinite 直接饱和到 ±448。调试精度时数值贴着 448 跑,多半是被饱和——不能用"先溢出到 Inf 再判 NaN"的 IEEE 思路。

04

关键数字

KEY NUMBERS · SHAPES
FP8 wgmma 形状m64nNk32k=32(每寄存器打包 4 元素)
N 取值{8,16,32,64,96,128,192,256}同其它 dtype
累加器f32 或 f16默认 f32;f16 省寄存器但有溢出风险
操作数组合4 种e4m3×e4m3 / e4m3×e5m2 / e5m2×e4m3 / e5m2×e5m2
前向 / 反向分工E4M3 / E5M2前向权重激活要精度,反向梯度要范围
转换指令cvt.rn.satfinite.e4m3x2.f32 等成对打包;satfinite = 饱和钳位
05

可编译示例

COMPILABLE EXAMPLE · VERBATIM

类型转换逐字自 CUDA Math API;wgmma 助记符逐字自 CUTLASS。

#include <cuda_fp8.h>       // __nv_fp8_e4m3 / __nv_fp8_e5m2
#include <cuda_bf16.h>
#include <cuda_fp16.h>

// (a) 设备端 FP8 类型转换(构造/转换运算符,饱和语义 __NV_SATFINITE)
__device__ __nv_fp8_e4m3  f16_to_e4m3(__half h)         { return __nv_fp8_e4m3(h); }      // 前向权重
__device__ __half         e4m3_to_f16(__nv_fp8_e4m3 e)  { return static_cast<__half>(e); }
__device__ __nv_fp8_e5m2  bf16_to_e5m2(__nv_bfloat16 b){ return __nv_fp8_e5m2(b); }      // 反向梯度(宽范围)
__device__ __nv_bfloat16  e5m2_to_bf16(__nv_fp8_e5m2 e){ return static_cast<__nv_bfloat16>(e); }

// (b) FP8 wgmma 助记符(verbatim,CUTLASS mma_sm90_gmma.hpp,SS 形式)
//   wgmma.mma_async.sync.aligned.m64n8k32.f32.e4m3.e4m3  {%0..%3}, %4, %5, p, %7, %8;
//   组合: .f32.e4m3.e5m2 / .f32.e5m2.e4m3 / .f32.e5m2.e5m2 (及 .f16 累加变体)
//   N ∈ {8,16,32,64,96,128,192,256};需 wgmma.fence / commit_group / wait_group 配套
NOTE · Transformer Engine 是什么

Transformer Engine(TE)不是 ISA 特性,而是一个库——它在每层分析张量统计、动态算 per-tensor scale、自动在 FP8 与 FP16 间切换、管理 delayed scaling 的 amax buffer。底层调用的就是上面的 FP8 wgmma。手写 FP8 kernel 时这些 scaling buffer 要自己管

06

注意事项 / 陷阱

PITFALLS · CHECKLIST
CAUTION · 陷阱清单
  • E4M3 没有 Inf(见 §3 警告);cvt.satfinite 溢出钳到 ±448(非 wrap / 非 Inf)。
  • scale factor 决定精度:per-tensor scale 常取 amax 反推;delayed scaling 用历史 amax,选错会发散/掉精度(TE 帮你管这些 buffer)。
  • 累加器默认 FP32;FP16 累加变体省寄存器但有累加溢出风险
  • eager 转换有开销:每个 FP8 GEMM 前后都要 FP8↔FP16/BF16 + 乘 scale,会吃掉一部分 FP8 收益——所以 A/B 应从 smem 喂(SS),并把转换重叠在 cp.async / wgmma 之后隐藏。
07

数据源

SOURCES