• 量化是一种用低精度的数据格式来表示原来用高精度的数据格式表示的模型,从而降低内存使用和提高计算速度的方法。
  • INT8量化就是将模型中的浮点数(float32或float64)转换为8位整数(int8),即用-128到127之间的整数来近似表示原来的浮点数。
  • 量化的过程需要一个缩放因子(scale factor)和一个偏移量(zero point),用来将浮点数的范围映射到整数的范围。例如,如果浮点数的范围是[-3.0, 3.0],那么缩放因子可以是0.0235,偏移量可以是0,那么量化后的整数范围就是[-128, 127],即:
  • float32 -> int8: q = round(scale_factor * f + zero_point)
  • int8 -> float32: f = (q - zero_point) / scale_factor
  • 量化可以分为对称量化和非对称量化,区别在于偏移量是否为0。对称量化可以保持正负分布均匀,但可能会损失一些动态范围;非对称量化可以利用更多的动态范围,但可能会导致正负分布不均匀。
  • 量化可以分为饱和量化和非饱和量化,区别在于是否对浮点数的范围进行截断。饱和量化可以减少离群值(outliers)对量化精度的影响,但可能会损失一些重要信息;非饱和量化可以保留所有信息,但可能会导致离群值占用过多的动态范围。
  • 量化可以分为per layer量化和per channel量化,区别在于缩放因子和偏移量是针对每一层还是每一个通道计算。per layer量化可以减少参数数量,但可能会忽略每个通道之间的差异;per channel量化可以提高参数精度,但可能会增加参数数量。
  • 量化可以分为静态量化和动态量化,区别在于缩放因子和偏移量是在训练时还是推理时计算。静态量化可以提前确定参数值,但可能会忽略输入数据的变化;动态量化可以根据输入数据实时调整参数值,但可能会增加计算开销。

扩展阅读:https://zhuanlan.zhihu.com/p/586406082