Skip to content

数值类型 ​

数值类型定义一组 bit 如何解释成数值。按照量化知识树,本文只分为两类:保留指数与尾数结构的 Float,以及使用离散整数编码的 Integer。

位宽(bit width)只表示一个元素占用多少 bit。b bit 最多提供 2b 种编码,但“编码数量”不等于“可表示的数值集合”:同为 8 bit,INT8 与 FP8 E4M3 的数值分布、动态范围和计算指令都不同。

概念回答的问题示例
位宽一个元素使用多少 bit4 bit、8 bit、16 bit
数值类型这些 bit 如何解释INT8、FP8 E4M3、BF16
数值映射原始数值如何缩放到目标编码scale、zero-point、对称或非对称映射
完整量化配置哪些对象采用什么格式和粒度W4A16、W8A8、NVFP4

因此,数值类型是量化方案的一部分,不能单独决定 WxAy、scale 粒度或 Kernel 路径。

Float ​

Float 将 bit 分给符号、指数和尾数。对规范化二进制浮点数,可以将其结构概括为:

x=(−1)s×2e−bias×(1+m).

其中,符号位 s 决定正负,指数 e 主要决定动态范围,尾数 m 主要决定有效精度。位宽相同的 Float 格式仍可以在动态范围和精度之间做不同取舍。

格式总位宽指数位尾数位主要特点
FP1616510尾数较多,精度高于同位宽的 BF16,但动态范围更小
BF161687指数宽度与 FP32 相同,适合承载大模型的常规计算
FP8 E4M3843在两种常见 FP8 中偏向保留有效精度
FP8 E5M2852在两种常见 FP8 中偏向扩大动态范围
FP4 E2M1421局部状态很少,通常需要更细粒度的 scale

ExMy 中的 E 表示 Exponent,M 表示 Mantissa;加上 1 个符号位,总位宽为 1+x+y bit。例如,E4M3 是 8 bit,E2M1 是 4 bit。

FP16 / BF16 ​

FP16 和 BF16 都是 16-bit Float,通常作为大模型推理的高精度基线、Activation dtype 或低精度 GEMM 的输出格式。

  • FP16:使用 5 位指数和 10 位尾数,保留更多有效数字。
  • BF16:使用 8 位指数和 7 位尾数,动态范围接近 FP32,更不容易因数值过大而溢出。

同为 A16,具体实现可能使用 FP16,也可能使用 BF16,因此 W4A16 仍需结合模型 dtype 和 Kernel 接口理解。

FP8(E4M3 / E5M2) ​

FP8 主要包含 E4M3 与 E5M2 两种元素格式。E4M3 用更多尾数位换取精度,E5M2 用更多指数位换取动态范围;具体格式还会规定特殊值、最大有限值和舍入行为。

“FP8”只说明元素如何编码,不等于一种完整的 W8A8 方案。Fine-Grained FP8、MXFP8 和普通 per-tensor FP8 都可以使用 FP8 元素,但它们的 scale 类型、共享粒度和 Kernel 布局不同。

FP4(E2M1) ​

FP4 E2M1 只使用 1 个符号位、2 个指数位和 1 个尾数位,单个元素只能表示很少的局部状态。为了控制误差,实际方案通常让较小 block 共享 scale。

NVFP4 会使用 FP4 E2M1 元素,但 NVFP4 不是 FP4 的同义词:它还规定局部 scale、全局 scale 和 block size,并且既可以组成 W4A4,也可以用于 W4A16 Weight-Only 路径。具体组合见量化配置。

Integer ​

Integer 使用离散整数编码。下表中的有符号范围按二进制补码列出;实际量化方案也可以为了正负对称而舍弃一个端点,例如用 [-127,127] 代替完整 INT8 范围。

格式位宽或理论信息量代表性状态编码数量常见定位
INT88 bit−128∼127256W8A8 Weight-Activation
INT44 bit−8∼716W4A16 Weight-Only,也可用于更低精度 Activation
INT22 bit−2∼14极低比特 Weight
Ternary(W1.58)log2⁡3≈1.585 bit{−1,0,1}3三值 Weight
INT11 bit两种离散状态2Binary Weight

整数编码本身不包含原始浮点范围。如何使用 scale 和 zero-point 将浮点值映射到整数,属于独立的数值映射层;这里只讨论目标元素能够保存哪些离散状态。

INT8 ​

INT8 包含 256 种编码,是常见的 Weight-Activation 整数量化格式。W8A8 可以让 Weight 和 Activation 都使用 INT8,但两侧仍可采用不同粒度,例如 per-output-channel Weight 与 per-token Activation。

LLM.int8() 会让大部分矩阵乘进入 INT8 路径,同时将 outlier 维度保留在 FP16;SmoothQuant 则通过等价变换降低 Activation 的量化难度。

INT4 ​

INT4 包含 16 种编码,典型用途是 W4A16 Weight-Only。Weight 常以 packed INT4 保存,Kernel 读取后解包并结合 scale 计算;GPTQ 和 AWQ 都可以生成这类低比特 Weight。

INT4 也可以参与 W4A8 或 W4A4,但位宽名称本身不能说明 Activation 格式、量化粒度和硬件是否提供对应 Kernel。

INT2 ​

INT2 只有 4 种编码。状态数量进一步减少后,量化误差更难控制,通常需要更细的分组、更强的误差补偿或模型级混合精度;实际收益还取决于后端是否支持高效的 2-bit 打包与计算。

Ternary(W1.58) ​

Ternary Weight 使用 {−1,0,1} 三种状态。区分三个状态所需的理论信息量是:

log2⁡3≈1.585 bit.

因此 W1.58 表示理论信息量,不是硬件原生提供的“1.58-bit dtype”。实际存储占用由编码、打包、对齐和相关元数据决定。本文按照知识树将它归入 Integer 分支,本质上它是离散三值 Weight 格式。

INT1 ​

1 bit 只能区分两种状态。Binary Weight 可以选择 {−1,+1} 等语义,但具体状态与缩放规则由实现决定;“INT1”只表示二值编码层级,不代表已经规定完整的量化映射。

无论使用 Float 还是 Integer,较低位宽只有在 checkpoint 布局、scale 元数据、打包方式和 Kernel 都匹配时,才能转化为实际的容量、带宽或计算收益。

参考 ​

  1. IEEE 754-2019:IEEE Standard for Floating-Point Arithmetic
  2. NVIDIA TensorRT:Quantized Types and Schemes
  3. Hugging Face Transformers:Quantization Concepts
  4. LLM.int8():8-bit Matrix Multiplication for Transformers at Scale
  5. GPTQ:Accurate Post-Training Quantization for Generative Pre-trained Transformers
  6. AWQ:Activation-aware Weight Quantization for LLM Compression and Acceleration
  7. NVIDIA Transformer Engine:FP8 and FP4 Primer
  8. BitNet b1.58:The Era of 1-bit LLMs