ONNX项目中的4位浮点数(Float4)格式详解
概述
在深度学习模型规模不断扩大的背景下,模型部署和计算成本成为重要挑战。ONNX项目从1.18.0版本开始引入了一种新型的4位浮点数格式(Float4),旨在为大型语言模型等应用提供更高效的数据存储和计算方案。本文将深入解析这种特殊的数据格式。
Float4格式背景
4位浮点格式最初由开放计算项目(OCP)提出,作为解决大型模型部署难题的创新方案。ONNX项目采纳了这一标准,实现了对4位浮点数的支持,主要包含以下类型:
FLOAT4E2M1
:1位符号位、2位指数位和1位尾数位- 不支持NaN(非数字)和无穷大(Infinity)表示
E2M1格式详解
基本结构
E2M1格式采用1-2-1的位分配方式:
- 符号位(S):1位,表示数值正负
- 指数位(E):2位,采用偏移码表示
- 尾数位(M):1位,表示小数部分
数值表示规则
根据指数位的不同,数值计算分为两种情况:
-
指数位非零时:
数值 = (-1)^S × 2^(E-1) × (1 + M×2^-1)
-
指数位为零时:
数值 = (-1)^S × M×2^-1
可表示数值范围
下表展示了E2M1格式能表示的所有正数值(负值只需加上符号位):
| 位模式(忽略符号位) | 对应数值 | |-------------------|---------| | 000 | 0 | | 001 | 0.5 | | 010 | 1 | | 011 | 1.5 | | 100 | 2 | | 101 | 3 | | 110 | 4 | | 111 | 6 |
从表中可以看出,E2M1格式能表示的数值范围是[-6, 6],精度从0.5到1不等。
类型转换规则
向上转换(Upcasting)
将Float4转换为更高精度的浮点格式(如float32、float16等)时,转换是精确的,不会丢失信息。
向下转换(Downcasting)
将高精度浮点数转换为Float4时,遵循以下规则:
| 输入值(x) | 转换结果 | |-------------------|-------------------| | -6 ≤ x ≤ 6 | 最接近的E2M1值(四舍五入到偶数) | | x = ±0 | ±0 | | x > 6 | 6 | | x < -6 | -6 | | +Inf | 6 | | -Inf | -6 | | NaN | 6 |
数据打包与解包
由于单个Float4仅占用4位,ONNX采用特殊的打包存储方式:
-
打包规则:
- 每两个4位元素打包成一个字节
- 第一个元素存储在低4位(LSB)
- 第二个元素存储在高4位(MSB)
- 打包公式:
y << 4 | x & 0x0F
-
解包规则:
- 第一个元素:
z & 0x0F
- 第二个元素:
z >> 4
- 第一个元素:
-
特殊情况处理:
- 当元素总数为奇数时,会追加4位填充
- 存储空间计算:对于N个元素的张量,需要
ceil(N/2)
字节
应用场景与限制
Float4格式主要应用于:
- 大型语言模型的权重存储
- 对内存带宽敏感的边缘计算场景
- 需要极致压缩率的模型部署
但需要注意以下限制:
- 数值范围和精度有限
- 不支持特殊浮点值(NaN/Inf)
- 计算时可能需要转换为更高精度
总结
ONNX引入的Float4格式为深度学习模型的轻量化部署提供了新的可能性。虽然其数值表示能力有限,但在特定场景下可以显著减少内存占用和带宽需求。开发者在使用时应当充分了解其特性和限制,合理评估是否适合自身应用场景。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考