执行模型量化

在进行模型映射之前, 可以选择是否对模型进行量化, 若不进行量化, 请忽略本节内容, 直接进入下一节 执行模型转换.

随机校准量化

Maptools 基于ppq (PPL Quantization) 实现模型量化, 并将ppq的量化流程封装至 quantize 函数中, 用户只需要调用 quantize 函数便可实现目标模型的全流程量化.

ppq提供量化校准功能, 但是在没有校准集的情况下, 可以使用随机数据进行校准, 一个随机校准量化的脚本如下:

from maptools.quantization import quantize

INPUT_SHAPES     = {'input': [1, 3, 224, 224]}
CALIB_STEPS      = 128
DEVICE           = 'cuda'
ONNX_PATH        = 'onnx_models/simp-resnet18.onnx'

quantize(
    INPUT_SHAPES,
    DEVICE,
    ONNX_PATH,
    mapname='resnet18',
    calibset=None,
    calib_steps=CALIB_STEPS
)

专用数据集校准量化

为了提升推理准确率, 建议在实际应用中使用专门的数据集进行校准量化, 如下:

import torch
from maptools.quantization import quantize
import torchvision.transforms as transforms
import torchvision as tv

trans = transforms.Compose([
    transforms.Resize([224, 224]),
    transforms.ToTensor(),
    transforms.Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225))
])

# 从给定文件目录中加载校准集
print("Preparing calibration dataset ...")
dataset = tv.datasets.ImageFolder(root='/mnt/c/Users/wx98/Downloads/calib', transform=trans)
calibset = [{'input': torch.unsqueeze(sample, dim=0)} for sample, _ in dataset]
print(f"Calibration dataset prepared, number of samples: {len(calibset)}")


INPUT_SHAPES     = {'input': [1, 3, 224, 224]}
CALIB_STEPS      = 128
DEVICE           = 'cuda'
ONNX_PATH        = 'onnx_models/simp-resnet18.onnx'

quantize(
    INPUT_SHAPES,
    DEVICE,
    ONNX_PATH,
    mapname='resnet18',
    calibset=calibset,
    calib_steps=CALIB_STEPS
)

模型量化结果说明

量化结果被保存至 ./mapsave/your-mapname 目录, 分为三个文件:

  • quantinfo.pkl

    保存着模型中所有算子的量化scale信息, 在 执行模型转换 时被加载至算子图中, 从此便存在于整个映射和仿真流程中.

  • quantparams.pkl

    保存着模型中所有卷积层的权重和偏置数据的量化值, 不会被加载至算子图中, 需要使用的时候由用户主动加载.

  • quant_model.onnx

    量化后的onnx模型, 不参与后续的映射和仿真, 仅用于用户查看和检验.