在前面的文章中,我们简单介绍了在 MegEngine imperative
中的各模块以及它们的作用。对于新用户而言可能不太了解各个模块的使用方法,对于模块的结构和原理也是一头雾水。Python
作为现在深度学习领域的主流编程语言,其相关的模块自然也是深度学习框架的重中之重。
模块串讲将对 MegEngine
的 Python
层相关模块分别进行更加深入的介绍,会涉及到一些原理的解释和代码解读。Python
层模块串讲共分为上、中、下三个部分,本文将介绍 Python
层的 quantization
模块。量化是为了减少模型的存储空间和计算量,从而加速模型的推理过程。在量化中,我们将权重和激活值从浮点数转换为整数,从而减少模型的大小和运算的复杂性。通过本文读者将会对量化的基本原理和使用 MegEngine
得到量化模型有所了解。
降低模型内存占用利器 —— quantization 模块
量化是一种对深度学习模型参数进行压缩以降低计算量的技术。它基于这样一种思想:神经网络是一个近似计算过程,不需要其中每个计算过程的绝对的精确。因此在某些情况下可以把需要较多比特存储的模型参数转为使用较少比特存储,而不影响模型的精度。
量化通过舍弃数值表示上的精度来追求极致的推理速度。直觉上用低精度/比特类型的模型参数会带来较大的模型精度下降(称之为掉点),但在经过一系列精妙的量化处理之后,掉点可以变得微乎其微。
如下图所示,量化通常是将浮点模型(常见神经网络的 Tensor
数据类型一般是 float32
)处理为一个量化模型(Tensor
数据类型为 int8
等)。
量化基本流程
MegEngine
中支持工业界的两类主流量化技术,分别是训练后量化(PTQ
)和量化感知训练(QAT
)。
-
训练后量化(
Post-Training Quantization
,PTQ
)训练后量化,顾名思义就是将训练后的
Float
模型转换成低精度/比特模型。比较常见的做法是对模型的权重(
weight
)和激活值(activation
)进行处理,把它们转换成精度更低的类型。虽然是在训练后再进行精度转换,但为了获取到模型转换需要的一些统计信息(比如缩放因子scale
),仍然需要在模型进行前向计算时插入观察者(Observer
)。使用训练后量化技术通常会导致模型掉点,某些情况下甚至会导致模型不可用。可以使用小批量数据在量化之前对
Observer
进行校准(Calibration
),这种方案叫做Calibration
后量化。也可以使用QAT
方案。 -
量化感知训练(
Quantization-Aware Training
,QAT
)QAT
会向Float
模型中插入一些伪量化(FakeQuantize
)算子,在前向计算过程中伪量化算子根据Observer
观察到的信息进行量化模拟,模拟数值截断的情况下的数值转换,再将转换后的值还原为原类型。让被量化对象在训练时“提前适应”量化操作,减少训练后量化的掉点影响。而增加这些伪量化算子模拟量化过程又会增加训练开销,因此模型量化通常的思路是:
- 按照平时训练模型的流程,设计好
Float
模型并进行训练,得到一个预训练模型; - 插入
Observer
和FakeQuantize
算子,得到Quantized-Float
模型(QFloat
模型)进行量化感知训练; - 训练后量化,得到真正的
Quantized
模型(Q
模型),也就是最终用来进行推理的低比特模型。
过程如下图所示(实际使用时,量化流程也
- 按照平时训练模型的流程,设计好