欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

模型推理加速系列 | 03:Pytorch 模型量化实践及 ResNet18 模型量化示例(附代码)

最编程 2024-04-02 09:03:14
...

更多、更新文章欢迎关注 微信公众号:小窗幽记机器学习。后续会持续整理模型加速、模型部署、模型压缩、LLM、AI艺术等系列专题,敬请关注。

量化基础知识

量化的本质是信息压缩,在深度学习中一般是降低参数精度。DNN中的参数过载使得其有更多的*度或者说更多的选择来进行信息压缩。量化后的模型更小、运行效率更高,进而能够支持更高的吞吐量。较小的模型内存占用和能耗较低,是边缘部署的关键。

映射函数

所谓的映射函数是将 float类型转为integer的映射操作,
常用的映射函数是线性变换Q(r)=round(r/S+Z), 其中r为输入,S,Z量化参数。逆变换:r~=(Q(r)Z)Sr~r,其中的偏差表示量化误差。

量化参数

映射函数主要由缩放系数(scaling factor) S和zero-point Z组成。
S是输入范围和输出范围的比值:

S=βαβqαq

其中[α,β]是裁剪的输入范围,即允许的输入范围。[αq,βq]是量化后的输出范围。比如,8-bit的量化,其输出范围βqαq<=(281)

Z是一个偏置项,以确保输入空间中的0在映射后的量化空间中也是0:

Z=(αSαq)

校准(Calibration)

选择输入裁剪范围的过程被称为校准。最简单的方法(也是Pytorch中默认选项)是直接将αβ取最小值和最大值。TensorRT还支持使用熵最小化(KL散度)、均方误差最小化,或者输入范围的百分位数。

在Pytorch中的torch.quantization.observer模块集成了各种校准策略,可以根据实际需要选择最合适的策略。

import torch
from torch.quantization.observer import MinMaxObserver, MovingAverageMinMaxObserver, HistogramObserver
C, L = 3, 4
normal = torch.distributions.normal.Normal(0,1)
inputs = [normal.sample((C, L)), normal.sample((C, L))]
print(inputs)

observers = [MinMaxObserver(), MovingAverageMinMaxObserver(), HistogramObserver()]
for obs in observers:
  for x in inputs: obs(x) 
  print(obs.__class__.__name__, obs.calculate_qparams())

输出如下:

[tensor([[-2.0369, -1.4840,  0.6457, -1.1184],
        [-0.0678,  1.7360,  0.1488, -1.3551],
        [-0.7111, -0.3592,  0.8379,  0.6078]]), tensor([[ 1.1579,  0.2877,  2.6896, -0.7351],
        [ 0.2124,  0.2675,  0.0679,  0.5265],
        [-1.0505, -0.3171, -1.1585,  2.4082]])]
MinMaxObserver (tensor([0.0185]), tensor([110], dtype=torch.int32))
MovingAverageMinMaxObserver (tensor([0.0148]), tensor([137], dtype=torch.int32))
HistogramObserver (tensor([0.0121]), tensor([114], dtype=torch.int32))

Affine和Symmetric Quantization Schemes

仿射量化(也称为不对称量化)策略将输入范围。仿射策略是更严格的范围剪裁,这种策略对量化非负激活(如果输入张量非负那么不需要输入的范围包含负值)是有用的。此时