pytorch 量化笔记

什么是量化?

量化是指用于执行计算并以低于浮点精度的位宽存储张量的技术。 量化模型对张量使用整数而不是浮点值执行部分或全部运算。 这允许更紧凑的模型表示,并在许多硬件平台上使用高性能矢量化操作。与典型的 FP32 型号相比,PyTorch 支持 INT8 量化,从而可将模型大小减少 4 倍,并将内存带宽要求减少 4 倍。 与 FP32 计算相比,对 INT8 计算的硬件支持通常快 2 到 4 倍。 量化主要是一种加速推理的技术,并且量化算子仅支持前向传递。量化能够在模型精度几乎不损失的情况下大大降低模型的储存和时间开销。

pytorch提供了三种量化的方法

1.训练后动态量化。这种模式使用的场景是:模型的执行时间是由内存加载参数的时间决定(不是矩阵运算时间决定),这种模式适合的模型是LSTM和Transformer之类的小批量的模型。调用方法torch.quantization.quantize_dynamic()。

2.训练后静态量化。这种模式使用场景:内存带宽和运算时间都重要的模型,如CNN。

  1. 准备模型: 通过添加 QuantStub 和 DeQuantStub 模块,指定在何处明确量化激活和量化数量。 b。 确保不重复使用模块。 C。 将所有需要重新量化的操作转换为模块

  2. 将诸如 conv + relu 或 conv + batchnorm + relu 之类的保险丝操作融合在一起,以提高模型的准确性和性能。

  3. 指定'97 量化方法的配置,例如选择对称或非对称量化以及 MinMax 或 L2Norm 校准技术。

  4. 使用 torch.quantization.prepare() 插入将在校准期间观察激活张量的模块

  5. 通过对校准数据集进行推断来校准模型

  6. 最后,使用 torch.quantization.convert()方法转换模型本身。 这可以做几件事:它量化权重,计算并存储要在每个激活张量中使用的比例和偏差值,并替换关键运算符的量化实现。

3.Quantization Aware Training,量化感知训练。这种方法可以可以保证量化后的精度最大。在训练过程中,所有的权重会被“fake quantized” :float会被截断为int8,但是计算的时候仍然按照浮点数计算

在特殊的Post Training量化不能提供足够的精度的情况下,可以使用量化感知训练通过torch.quantization.FakeQuantize来模拟量化的过程。计算过程将会使用FP32但是数据会通过被固定在一定动态范围与四舍五入来模拟INT8量化的影响。使用步骤也非常类似:

  1. 执行上面步骤a与步骤b

  2. 指定模拟量化方法的配置例如选择对称量化或非对称量化,MinMax或Moving Average或L2Norm标定方法

  3. 使用torch.quantization.prepare_qat()来添加训练过程中模拟量化的模块

  4. 训练或fine-tune模型

  5. 执行上面步骤f

量化的模型准备

在量化之前,需要先对模型的定义进行一些改变,这是因为量化目前工作在逐模块的模型上,具体地,使用者需要做以下几件事:

  1. 将任何需要对输出进行再量化的操作从函数转换为模块

  2. 指定模型哪些地方需要被量化,可以通过给子模块分配.qconfig属性或指定qconfig_dict

对于需要量化激活值的静态量化,使用者需要额外做以下几件事:

  1. 指定哪些激活值需要被量化与反量化,通过使用QuantStubDeQuantStub模块

  2. 使用torch.nn.quantized.FloatFunctional来将那些在量化中需要特殊对待的tensor操作封装为模块。例如add或者cat操作,需要重新决定输出的量化参数。

  3. 融合模块:将操作/模块融合进一个模块来获得高性能与速度。通过torch.quantization.fuse_modules() API,可以将成列表的子模块进行融合,目前仅支持[Conv, ReLU],[Conv, BatchNorm], [Conv, BatchNorm, ReLU], [Linear, ReLU]

Quantized Transfer Learning量化迁移学习

import torchvision.models.quantization as models
model_fe = models.resnet18(pretrained=True, progress=True, quantize=True)

目前pytorch 量化还不支持GPU训练

支持后端:

  • 具有 AVX2 支持或更高版本的 x86 CPU:fbgemm
  • ARM CPU:qnnpack

通过如下方式进行设置:

q_backend = "qnnpack"  # qnnpack  or fbgemm
torch.backends.quantized.engine = q_backend
qconfig = torch.quantization.get_default_qconfig(q_backend)   

PyTorch 1.3现在支持用eager模式进行8位模型量化

Net.half() 

 

资料:

https://zhuanlan.zhihu.com/p/144025236 

https://github.com/lartpang/PyTorchTricks

https://pytorch.apachecn.org/docs/1.4/88.html 量化迁移学习

 https://github.com/666DZY666/model-compression 个人开源库但没有例子讲解

https://blog.csdn.net/just_sort/article/details/107600007?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.edu_weight&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.edu_weight  这篇是对上面一篇的一些解释

 

 

 

 

你可能感兴趣的:(pytorch)