Post-Training-Quantization(PTQ)

Post-Training-Quantization(PTQ)是一种在训练后对量化进行的技术,它可以将原始的浮点模型转换为适合于边缘设备的低比特宽度(如8位或4位)的固定点模型。该技术可以减小模型的大小,并且可以在一定程度上加速模型的推理速度。PTQ通常分为以下几个步骤:

  • 训练模型:首先需要使用浮点模型在大规模数据集上进行训练,以获得高精度的模型。

  • 收集统计信息:在训练后,需要使用代表性数据集来收集模型的统计信息,例如权重的最大值和最小值,激活值的分布等。

  • 量化参数:根据收集到的统计信息,可以使用量化算法将模型参数量化为低比特宽度的固定点数值

  • 重新量化:如果模型的性能不够好,可以使用不同的统计信息重新进行量化。

  • Fine-tuning:在量化后,可以使用微调技术来进一步提高模型的精度。

在PyTorch中,可以使用torch.quantization包来进行PTQ。以下是一个基本的PTQ示例:

import torch
import torch.nn as nn
from torch.quantization import QuantStub, DeQuantStub, \
    convert, prepare

class MyModel(nn.Module):
    def __init__(self):
        super(MyModel, self).__init__()
        self.quant = QuantStub()
        self.conv1 = nn.Conv2d(3, 64, kernel_size=3, stride=1, padding=1)
        self.relu = nn.ReLU(inplace=True)
        self.conv2 = nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1)
        self.avgpool = nn.AdaptiveAvgPool2d((1, 1))
        self.fc = nn.Linear(128, 10)
        self.dequant = DeQuantStub()

    def forward(self, x):
        x = self.quant(x)
        x = self.conv1(x)
        x = self.relu(x)
        x = self.conv2(x)
        x = self.relu(x)
        x = self.avgpool(x)
        x = x.view(x.size(0), -1)
        x = self.fc(x)
        x = self.dequant(x)
        return x

model = MyModel()
data = torch.randn(1, 3, 224, 224)
model = prepare(model)
model(data)
model = convert(model)

# 使用量化后的模型进行推理
quantized_data = torch.quantize_per_tensor(data, 0.1, 127, torch.quint8)
output = model(quantized_data)
output = torch.dequantize(output)

在这个例子中,我们定义了一个包含两个卷积层、一个全局平均池化层和一个全连接层的模型,并使用QuantStub和DeQuantStub在模型的输入和输出上添加量化和反量化操作。接下来,我们使用prepare()方法将模型准备为量化模型,并使用convert()方法将模型转换为量化模型。最后,我们使用torch.quantize_per_tensor()方法将输入张量量化为8位固定点数值,并使用量化后的模型进行推理。

需要注意的是,PTQ并不适用于所有类型的模型和应用程序。一些模型可能不适合量化,因为它们需要较高的精度以保持其性能。在进行PTQ时,应该仔细评估模型的精度和性能,并选择适合应用场景的量化方法。

    Post-Training-Quantization(PTQ)是目前常用的模型量化方法之一。以INT8量化为例,PTQ处理流程如下:

    1. 首先在数据集上以FP32精度进行模型训练,得到训练好的baseline模型;

    2. 使用小部分数据对FP32 baseline模型进行calibration(校准),这一步主要是得到网络各层weights以及activation的数据分布特性(比如统计最大最小值);

    3. 根据2.中的数据分布特性,计算出网络各层、量化参数;

    4. 使用3.中的量化参数对FP32 baseline进行量化得到INT8模型,并将其部署至推理框架进行推理;

    PTQ方式会使用小部分数据集来估计网络各层weights和activation的数据分布,找到合适的Scale,从而一定程度上降低模型精度的损失。

    然而,PTQ方式虽然在大模型上效果较好(例如ResNet101),但是在小模型上经常会有较大的精度损失(例如MobileNet),同时不同层对于精度的影响也比较大。

在这里插入图片描述

量化误差敏感层分析

在这里插入图片描述
通过敏感层分析可以看出,检测头对于量化最为敏感,因此在进行量化时都会选择跳过该层。

PTQ后的提升

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_44089890/article/details/130023848