- 人工智能
- 深度学习
- 机器学习
【免费下载链接】onnx
Open standard for machine learning interoperability
本篇技术指南围绕 ONNX(Open standard for machine learning interoperability)在 docs/docsgen/source/technical/int2.md 中定义的 2-bit 整数类型展开,系统讲解 INT2 / UINT2 的类型语义、与高精度类型互转的 Cast 规则、字节内 4 元素位打包/解包算法及存储大小计算。读者读完可获得一套可直接落地的位级实现方案,并能结合 ONNX 仓库中的 proto 定义、Python 映射与 C++ 算子源码验证每一步细节,适用于低比特 LLM 推理、端侧部署与自定义量化格式解析等场景。
一、背景:为什么需要 2-bit 整数类型
随着大语言模型(LLM)在边缘设备上的部署需求增长,权重量化(weight quantization)不断向更低比特演进。ONNX 在 TensorProto 中新增了 2-bit 整数类型,用于承载超低比特量化权重。2-bit 类型具有以下两个关键特点:
- 存储极省:相比 8-bit 整数,2-bit 类型可将权重存储量压缩到原来的 1/4;
- 表示范围极小:UNSIGNED 与 SIGNED 各只有 4 个可表示值,必须通过专门的打包格式进行存储与传输。
从 ONNX 仓库的 proto 定义(onnx/onnx-ml.proto)可以看到这两个类型的官方声明:
UINT2 = 25; // Unsigned integer in range [0, 3] INT2 = 26; // Signed integer in range [-2, 1], using two's complement representation即:
| 类型 | 枚举值 | 取值范围 | 表示方式 |
|---|---|---|---|
UINT2 | 25 | [0, 3] | 无符号二进制 |
INT2 | 26 | [-2, 1] | 二进制补码(two's complement) |
关于低比特量化的实际动机,文档引用了 T-MAC 论文:T-MAC 是一种基于查找表(lookup table, LUT)的低比特 LLM(即权重量化 LLM)CPU 推理方法,它直接支持无需反量化的 mpGEMM(mixed-precision GEMM),同时消除乘法运算并大幅减少加法运算。其核心思路是将传统"以数据类型为中心"的乘法转化为"按位查表"操作,从而提供统一、可扩展的 mpGEMM 方案。2-bit 类型正是这类低比特部署方案所需的底层数据载体。
二、类型体系中的位置与解析支持
2-bit 类型并非孤立存在,而是 ONNX 扩展数据类型(sub-byte 类型)家族的一员。仓库中与该类型相关的证据点包括:
- 类型字符串注册:onnx/defs/data_type_utils.cc 中将字符串
"uint2"/"int2"分别映射到TensorProto_DataType_UINT2/TensorProto_DataType_INT2,说明 C++ 解析器可以直接按名称解析这两种类型; - Python 侧映射:onnx/_mapping.py 使用
ml_dtypes.uint2/ml_dtypes.int2作为对应的 NumPy dtype,并指定与INT32相互转换的规则,方便在 Python 生态中构造与检查 2-bit 张量; - BitCast 位宽校验:onnx/defs/tensor/defs.cc 在 BitCast 算子的形状推断中,将
INT2与UINT2的位宽计为 2,用于校验"输入与输出类型位宽必须一致"这一约束。
这三点表明:从 proto 定义到 C++ 内核、再到 Python 工具链,2-bit 类型已经贯穿 ONNX 的完整技术栈,而不仅仅是文档中的理论概念。
三、Cast 转换规则:精确与舍入
文档明确规定了 2-bit 类型与高精度类型互转的语义(这也是 Cast 算子在 2-bit 类型上的行为基准):
- 从 2-bit 转换到任意更高精度类型是精确的(exact):因为
UINT2(0~3)与INT2(-2~1)的全部取值都可以被更高精度类型无损表示,不存在精度损失; - 从高精度类型转换到 2-bit 是"舍入 + 截断"两步:
- 先按就近舍入到最近整数(round-to-nearest-integer),且平局时取偶数(ties to even,即银行家舍入);
- 再**截断(truncating)**到 2-bit 范围。
以浮点值转换到INT2为例,其语义可概括为trunc(round_even(x)),最终结果必然落在 [-2, 1] 区间内(超出范围的输入会被截断为边界值)。
在 ONNX 仓库的后端测试中,onnx/backend/test/case/node/cast.py 定义了TWO_BIT_TYPES = frozenset({"UINT2", "INT2"}),并覆盖了FLOAT → UINT2/INT2、FLOAT16 → UINT2/INT2、UINT2/INT2 → FLOAT/FLOAT16/UINT8/INT8等多组双向 Cast 用例(见同文件 L67-L76),与文档中"向 2-bit 转换需舍入、从 2-bit 转换精确"的规则一一对应。
四、Packing 与 Unpacking:4 元素共享一个字节
这是本文档最具实操价值的部分。所有 2-bit 类型都以"每字节存放 4 个 2-bit 值"的方式存储,元素从**最低有效位(LSB)向最高有效位(MSB)**依次排列。对于数组中的连续元素 x0, x1, x2, x3:
4.1 打包(Packing)
pack(x0, x1, x2, x3): (x0 & 0x03) | ((x1 & 0x03) << 2) | ((x2 & 0x03) << 4) | ((x3 & 0x03) << 6)每个元素先与0x03相与(取出低 2 位,确保只保留有效位),再按其在字节中的位置左移 0、2、4、6 位,最后用按位或合并为一个字节。
4.2 解包(Unpacking)
x0 = z & 0x03 x1 = (z >> 2) & 0x03 x2 = (z >> 4) & 0x03 x3 = (z >> 6) & 0x03解包是打包的逆过程:依次右移 0、2、4、6 位后与0x03相与,即可还原出每个 2-bit 元素。由于每个元素只占 2 位,移位 + 掩码的组合操作在任意主流架构上都是常量时间,非常适合在 CPU/嵌入式平台上做批量解码。
4.3 零填充(Zero-padding)与存储大小
两个工程上极易踩坑的细节:
- 元素个数不能被 4 整除时:在最终字节的高位剩余部分补零(zero-padding)。例如 N=5 时,第 2 个字节只使用低 2 位,其余 6 位全部为 0;
- 存储大小公式:大小为 N 的 2-bit 张量,其存储字节数为ceil(N / 4)字节。
| 元素个数 N | 打包后字节数 | 说明 |
|---|---|---|
| 1 ~ 4 | 1 | 最后一个字节高位补零 |
| 5 ~ 8 | 2 | 第二字节仅低 2~8 位有效 |
| N(一般情形) | ceil(N/4) | 向上取整 |
这一布局与 int4 类型(每字节 2 个元素)的设计思路一致,均遵循"LSB 优先、尾部补零"的统一约定,便于推理引擎在解析时用同一套位操作代码处理不同位宽。
五、使用建议与注意事项
- 仅用于权重/常量的紧凑存储:由于表示范围极小且运算需查表或反量化,2-bit 类型更适合作为量化权重的存储格式,而非常规计算中间张量的类型;
- 转换语义与后端对齐:任何实现 Cast 到 2-bit 的后端,都应遵循"就近偶数舍入 + 截断"的规则,避免与 ONNX 语义及 cast.py 中的参考用例产生偏差;
- 位序约定不可随意更改:LSB 优先 + 尾部零填充是 ONNX 规定的线格式(wire format),跨语言、跨设备解析时必须严格按此约定实现 pack/unpack;
- 结合 BitCast 使用:如需在等位宽的 sub-byte 类型间复用位模式(例如 INT2 与其它 2-bit 宽度类型互转),可借助 BitCast 算子,其位宽一致性校验逻辑见 onnx/defs/tensor/defs.cc。
六、小结
ONNX 的 2-bit 整数类型通过三件事完成了"超低比特"的工程化闭环:proto 层定义取值区间(UINT2/INT2,onnx/onnx-ml.proto)、Cast 语义层规定精确/舍入转换规则、存储层规定ceil(N/4)字节的 LSB 优先打包布局。配合_mapping.py的ml_dtypes映射与data_type_utils.cc的类型字符串注册,开发者可以在解析、校验、推理多个环节直接复用 ONNX 的既有实现,为 T-MAC 这类基于查找表的低比特 LLM 部署方案提供标准化的数据格式支撑。
- 人工智能
- 深度学习
- 机器学习
【免费下载链接】onnx
Open standard for machine learning interoperability
相关推荐
ONNX 低比特数值类型与 In-place KV Cache 技术解析:Float8/Float6/Float4、Int4/Int2 的位布局与转换规则
ONNX 低比特数值类型与 In place KV Cache 技术解析:Float8/Float6/Float4、Int4/Int2 的位布局与转换规则 导读
人工智能深度学习机器学习Slang 类型系统完全指南:类型说明符、类型别名、内存布局与未知大小规则
Slang 类型系统完全指南:类型说明符、类型别名、内存布局与未知大小规则 本篇以 Slang 语言参考手册的 Types 章节 https://link.gi
编译器图形学编程语言ONNX 6 位浮点格式详解:FLOAT6E2M3 与 FLOAT6E3M2 的位布局、Cast 语义与打包实现
ONNX 6 位浮点格式详解:FLOAT6E2M3 与 FLOAT6E3M2 的位布局、Cast 语义与打包实现 本指南围绕 ONNX 在 onnx==1.23
人工智能深度学习机器学习
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考