模型量化中常用具体的整数数据类型。这样做的主要目的是用低精度整数来替代原始大型语言模型中用于权重(有时也用于激活值)的高精度浮点数(如32位浮点数,或$FP32$)。这种方法通过整数表示的独特特性,能大幅减少模型的内存占用,并显著加快计算,尤其是在针对整数运算优化的硬件上。量化中最常见的整数类型是8位整数($INT8$)和4位整数($INT4$)。INT8:量化的主力8位整数使用8位来表示一个数字。这允许有$2^8 = 256$个不同的值。根据是否需要表示负数,$INT8$可以是:有符号INT8: 表示正值和负值。其常规范围是从-128到127。这对于表示权重或激活值很有用,因为它们通常以零为中心。无符号INT8: 只表示非负值。范围是从0到255。这可能适合始终为正的激活值,比如ReLU激活函数之后的激活值,尽管有符号整数在权重中更常见。与$FP32$相比(因为$FP32$使用32位),使用$INT8$能将数据大小减少4倍。如果只对权重进行量化,这意味着模型大小直接减小4倍,并可能为推理过程中的激活值节省大量内存。许多现代CPU和GPU都有专用指令,能快速执行$INT8$计算,从而大大提升速度。$INT8$量化通常能在计算效率和保持模型精度之间取得不错的平衡,使其成为许多应用中的常用选项。INT4:压缩的极限为了获得更大的压缩比和潜在的速度提升,可以使用4位整数($INT4$)。4位整数只允许有$2^4 = 16$个不同的值。有符号INT4: 通常表示-8到7范围内的值。无符号INT4: 表示0到15范围内的值。从$FP32$到$INT4$表示数据大小减少了8倍。这对于在资源受限设备上部署大型模型或将更大模型放入可用GPU内存中非常有用。然而,用仅16个离散级别来表示浮点值的原始范围,比用256个级别($INT8$)要困难得多。因此,$INT4$量化通常会引入更多量化误差,如果应用不当,可能会导致模型精度明显下降。通常需要应用稍后讨论的先进方法(比如第3章的GPTQ和AWQ),才能使$INT4$达到好的表现。其他整数类型虽然$INT8$和$INT4$是最常见,研究和具体应用有时也会考虑其他位宽:INT16: 比$INT8$提供更高精度,但与$FP32$相比压缩较少。有时用作中间步骤,或用于量化模型中特别敏感的部分。INT3, INT2, Binary (INT1): 这些代表更极端的量化形式,提供最大压缩比,但通常会遇到明显的精度下降。它们通常需要专门的训练方法(如QAT)或硬件支持。下方图表展示了量化中常用数据类型相对于标准$FP32$的位宽减少情况。{"layout": {"title": "数据类型位宽比较", "xaxis": {"title": "数据类型"}, "yaxis": {"title": "位数"}, "margin": {"l": 50, "r": 20, "t": 40, "b": 40}}, "data": [{"type": "bar", "x": ["FP32", "INT16", "INT8", "INT4"], "y": [32, 16, 8, 4], "marker": {"color": ["#4263eb", "#74c0fc", "#ff922b", "#ffc078"]}, "width": 0.6}]}模型量化中不同数值数据类型所用位数对比。更低的位宽可带来更小的模型尺寸和潜在的更快推理速度。整数数据类型的选择涉及一种权衡。更低的位宽(如$INT4$)能节省更多内存并潜在地提升速度,但由于表示方式更粗糙,会增加精度损失的风险。更高的位宽(如$INT8$)能保持更多精度,但压缩较少。选择哪种取决于特定的LLM、目标硬件以及对性能下降的接受程度。认识这些整数类型很重要。在接下来的部分,我们将讨论如何使用不同的方案和粒度,将原始浮点值映射到这些整数提供的有限范围上。