5.2 模型量化
5.2 模型量化
2024年5月30日修改
在上一节,作为第一种模型压缩的办法,我们介绍了知识蒸馏的概念。知识蒸馏能让小的模型来具备大的模型相近的推理能力,但是缺点是需要重新训练。有没有一种能直接成倍降低显存占用的方法呢?本节我们介绍模型的量化(quantization),即通过转换模型权重存储的格式,在尽量少地牺牲模型推理性能的前提下,使用低精度的数据格式来存储模型,减少推理环节的显存占用[1]。
基本原理
一个粗略估计大模型推理阶段的显存占用的公式是:在float32精度下,7B参数量的模型需要占用的显存至少是4*7=28G。这是因为在推理阶段,除了提示词的KV缓存(KV cache)外,模型的参数需要加载进入显存,由于1bit=0.125bytes,32位浮点数(占用32bits)下,1个参数占用4个字节,因而显存占用至少是模型参数量(以10亿计)的四倍。int8量化可以降低4倍的显存占用,减少2-4倍的带宽占用,以及提高2-4倍的计算速度。
由此,我们希望从高精度表示出发,把float32(32位浮点数)精度的模型权重压缩到低精度表示(float16,int32,int16,int8,int4,int1)当中去。压缩效果如下图所示[2]:
加载失败,
其中data type表示数据存储格式,accumulation表示数据运算结果的存储格式(例如2个2位小数的乘积的最精确表示是4位小数,我们可以选择1-4位的小数来表示运算结果,这里的表示精度选择就是accumulation),data size reduced表示内存/显存占用(运算的空间占用)降低的倍数。
范围映射(range mapping)
具体实现上,量化分为两步:
第一步是量化(quantize),在模型存储时,把原始精度数据映射为低精度;
第二步是反量化(dequantize),在推理时,把转换后的低精度数据反映射回原始精度。
我们知道,B bit的整型可以表示-2^B到2^B-1这个范围内的数。根据采用的范围映射(range mapping)方法的不同,量化分为仿射量化(affine quantization)和尺度量化(scale quantization)。在仿射量化中,我们把一个[MIN,MAX]的数据(MIN<=MAX)通过线性变换映射到[-2^B,2^B-1];在尺度量化中,我们把一个[-MAX,MAX]的数据(MAX>0)通过比例放缩映射到 [-2^(B-1), 2^(B-1)]。对于那些位于给定范围[MIN,MAX]或[-MAX,MAX]之外的数据,我们取边界值即可。