模型感知训练
模型感知训练也是模型量化中的一部分,它主要是在量化过程中,对网络进行训练,从而让网络参数能更好地适应量化带来的信息损失。这种方式会更加灵活,因此准确性普遍从后训练量化要高,但是,同样地,它也存在缺点,如操作起来不方便。
量化训练过程中的梯度问题
首先回顾一下之前的所说的量化过程: \[ q = round(\frac{r}{S}+Z) \tag{1} \] 但这个\(round\)函数存在一个问题,就是它是不可导的,梯度几乎处处为零,这就会导致反向传播梯度也变成0,进而导致量化训练无法进行。它的函数图像如下:

解决梯度处处为零的问题
一个简单常用的方法就是Straight Through Estimator(STE),即直接跳过伪量化的过程,避开\(round\),直接将卷积的梯度作为结果传回去。
pytorch中的具体实现通常是使用torch.autograd.Function
接口来重定义伪量化的过程:
1 | from torch.autograd import Function |
具体代码实现中的注意事项
代码实现使用的是Github上的量化代码
1 | class QConv2d(QModule): |
需要注意的是x = F.conv2d(...)
这一行,这里需要使用F.conv2d()
来调用卷积,而不能使用self.conv_module()
来调用,因为Pytorch中规则是torch.nn.Conv2d的weight无法自定义,需要手动设置weight时只能使用torch.nn.function.conv2d。
此外,代码中对于输入和输出也进行了伪量化,即x=FakeQuantize.apply(x, self.qx)
,这在量化训练中是有必要的,可以帮助网络更好地感知量化带来的损失。
总结
量化训练(模型感知训练)部署虽然在准确性上会有所提升,但实际应用时去会比后训练量化麻烦很多!
目前大部分主流推理框架在处理后训练量化时,只需要用户把模型和数据扔进去,就可以得到量化模型,然后直接部署。但很少有框架支持量化训练。