跳转至

模型量化

量化的定义以及意义

量化是一种数据压缩的技术,用于将浮点数等高精度数据转换为低精度,从而减小数据存储和计算的开销。在深度学习中,量化可以减小内存占用,加速计算,减小功耗和延迟。

量化是模型部署中的一种重要的优化方法,可以在部分精度损失的前提下大幅提高神经网络的效率和性能。例如,在将神经网络部署到嵌入式设备或移动设备时,使用量化可以将模型大小缩小,减少内存使用和功耗消耗,从而提高预测速度和设备续航时间。

在量化过程中,通常将浮点数映射到一个定点数。在定点数中,使用有限的比特数来表示数值范围,例如int8数据范围可以表示-128到127之间的整数,而uint8数据范围可以表示0到255之间的整数。因此,可以使用这种编码方式来压缩数据并降低存储和计算开销。

为了量化浮点数,需要计算量化因子。例如,如何将一个浮点数(2.2408931)用int的方式进行描述?

  1. 计算线性映射的缩放值Scale

    Scale = 2.2408931 / 127 = 0.0176448

  2. 进行量化操作

    2.2408931 / 0.0176448 = 127.0001983,取整得到127,对应的二进制为01111111

  3. 进行反量化操作

    01111111 × 0.0176448 = 2.2408931

然而,量化会遇到一些问题。例如,如何将一个浮点数值[-0.61, -0.52, 1.62]用int数组的方式进行描述?

首先,需要计算量化因子:

scale = (float_max - float_min) / (quant_max - quant_min)

   = (1.62-(-0.61))/(127-(-128)) = 0.00874509

进行量化操作后得到: [-70, 59, 185],对应的二进制为[-1000110, 111011, 10111001]。

由于浮点数值范围和整数值范围之间存在不可避免的差异,因此进行反量化操作时会产生误差。在上述量化操作后,反量化得到的数值为[-0.609763, -0.5139431, 1.1062843],其中第三个数值产生了严重的误差。

有两种主要的方法来解决这个问题:

  1. 最大绝对值对称法(Symmetric Scaling)

    在对称量化中,量化比特数为奇数,正数和负数具有相同的数量级。这意味着,对于任意一个浮点数,其绝对值被固定映射到 0 ~ max_num-1 之间,而正负号则用一位二进制数表示即可。这种量化方式对数据分布均匀的情况下有较好的效果,但是对于一些分布不均匀的数据集效果可能不佳。

  2. 偏移法(Zero-point Representations)

    偏移量化法基于一定的数据分布,将数据量化到 [0, max_num-1] 之间。而区别与对称量化,偏移量化必须假设有一个零点来确定整数和浮点数的偏移。通常,这个零点由数据的分布得出,然后将量化后的数字加上这个零点。

    截断是指将量化后的数值限制在整数最大值和最小值之间,以避免超出整数范围而产生的误差。例如,如果将浮点数[-70, -59, 185]量化为int8数据范围内的整数值,则可以使用以下公式进行截断操作:

    \(z = Q_{max} - Round(\frac{F_{max}}{scale})\)

    其中,\(Q_{max}\)为int8数据范围中的最大值127,\(F_{max}\)为已知浮点数值中的最大值185,\(scale\)为量化因子。通过计算,可得出截断后的数值应为[-70, -59, 127],其中最后一个数值被截断至127以避免超出范围。

    偏移对量化的影响

    偏移操作是指将输出加入一个偏移量,从而改善量化后数值的精度和计算结果的准确性。偏移法的核心是将数值映射到整数范围内,然后再加上一个偏移量使其正确地映射到定点数上。

    例如,假设我们将输出加入偏移,使用int8表达范围:

    • 偏移量\(Z=127-185=-58\)
    • 数值[-70, -59, 185]+[Z] = [-128, -117, 127]
    • 可以看到,数量级较大的185量化后溢出了,同时偏移操作能够保留更多的精度,得到了更加准确的量化结果。

    同样地,对于原本的数据类型为uint8,可以使用偏移量\(Z=255-185=70\),然后对数值进行相应的加减操作,得到量化后的结果为[0, 11, 255]。

    反量化过程

    在量化操作后,需要进行反量化操作来将定点数映射回浮点数。反量化过程可以通过将量化数值乘以量化因子以及减去偏移量来实现。对于前面使用偏移量的例子,反量化过程的公式为:

    ([-128, -117, 127]-[Z]) * scale --> [-0.609763, -0.5139431, 1.6115165]

    可以通过反量化来验证量化后的结果是否准确,以及评估量化的精度和误差。

对称量化和非对称量化

对称量化和非对称量化是两种主要的量化方法,它们在量化过程中有着不同的策略和优缺点。

对称量化

对称量化是一种将浮点数映射到有限的整数范围内的量化方法。在对称量化中,数据表示中输出的正负数范围相同,并且量化因子对正负数据的缩放相同。例如,使用 int 8 数据范围,量化范围为[-128,127],量化因子为 0.01,则可以使用以下公式在对称量化时将浮点数 x 映射到整数范围内:

\(Quantized(x) = clip(\frac{x}{scale}, [-128,127])\)

其中,scale 为量化因子,clip 操作用于对超出量化范围的值进行裁剪。由于对称量化中正负数据范围相同,因此最大量化误差在对称量化中会比较小。

非对称量化

相比对称量化,非对称量化采用不同的量化因子和不同的范围来量化正负数据。一般来说,在非对称量化中,正数和负数量化因子可以不同。例如,我们可以使用以下公式在非对称量化时将浮点数 x 映射到整数范围内:

\(Quantized(x) = clip(\frac{x}{scale} + Z, [0,255])\)

其中,scale 为量化因子,Z 为量化偏移量,clip 操作用于对超出量化范围的值进行裁剪。由于非对称量化中正负数据量化因子和范围不同,因此可能会出现不同的最大量化误差。

对称量化和非对称量化的比较

对称量化和非对称量化各有其特点和优缺点,具体选用哪一种方法需要考虑具体的任务和场景。以下是两种量化方法的优缺点比较:

对称量化的优点:

  • 优点:
    • 实现简单,计算快速
    • 数据的分布相对均匀,量化误差相对较小
    • 可以使用更小的宽度来存储权重和激活,降低存储和计算成本

对称量化的缺点:

  • 缺点:
    • 量化后的值需要进行对称还原,反量化操作开销较大
    • 量化的精度受限于量化因子的精度,小范围的数值表达不够精细

非对称量化的优点:

  • 优点:
    • 非对称添加量化偏移可以增加量化的精度
    • 可以使用不同的量化因子来适应不同数据的分布

非对称量化的缺点:

  • 缺点:
    • 实现较为复杂,带来一定的计算开销和存储开销
    • 对数据集分布敏感,可能会导致量化误差更大

总之,在实际应用中,可以根据具体的任务和场景选择对称量化或非对称量化。对于数据分布较为均匀的任务,可以使用对称量化;对于不同数据分布的任务,可以使用非对称量化进行适应。