前言:主要包括训练后量化和训练过程量化感知训练和模型剪枝优化技术
一、量化说明
YOLO模型的量化实战,包括PTQ(训练后量化)和QAT(量化感知训练)。PTQ主要涉及权重和激活的量化,而QAT则在训练过程中引入伪量化算子,通过finetune优化模型精度。
量化Quantization是指将高精度浮点数FP32转换为低精度(8bit或4bit)整数的过程,使模型体积缩小,他是模型部署中一种非常重要的优化方法,可以在较少的精度损失下,大幅提供神经网络的效率和性能。目前主流的神经网络量化方式有PTQ和QAT两种。
二、PTQ量化
PTQ是训练后量化(Post Training Quantization),无需数据集和训练,直接量化模型权重。
1、PTQ量化具体步骤包括:(VMvare版本为VMware® Workstation 16 Pro)
注意:pt转onnx需在Y8RKNN环境下针对pt的转换onnx才可以。
1)进入虚拟机,将转换的onnx放入/home/viz/rknn_model_zoo/examples/yolov8/model/路径下
2)将校准的图像放入/home/viz/rknn_model_zoo/datasets/COCO/subset/路径下
3)通过conda env list查看虚拟环境,并通过命令进入:conda activate rknn-demo
4)subset量化文件列表可在windows环境下利用命令生成:dir *.* /b> list.txt
4)在路径/home/viz/rknn_model_zoo/examples/yolov8/python下执行命令 python convert.py ../model/yolv8n.onnx rk3588
2、PTQ量化参数优化 (参考RKNN SDK User Guide 2024-03-15版本)
2.1 基本概念
量化功能:支持将浮点模型量化为定点模型,并支持混合量化;
量化精度分析:该功能将给出模型量化后每一层推理结果与浮点模型推理结果的余弦距离和欧氏距离,便于分析量化误差是如何出现的,为提高量化模型的精度提供思路。
i8模型:量化的RKNN模型,即以8位有符号整数数据运行的模型;
f16模型:非量化的RKNN模型,即以16位半精度浮点型数据运行的模型;
2.2 模型转换
目前RKNN-Toolkit2支持多个主流深度学习框架的模型转换,包括:Caffe、TensorFlow、ONNX、Pytorch、Darknet等;
1)模型配置Config
在模型转换之前,用户需进行一些配置以确保模型转换的正确性和性能,配置参数通过rknn.config()接口进行配置,包括设置输入均值、归一化值、是否量化等参数;
target_platform:指定RKNN模型目标平台,如RK3588;
2)模型加载接口
ONNX模型加载接口:rknn.load_onnx()
Pytorch模型加载接口:rknn.load_pytorch()
3)构建RKNN模型
do-quantization:是否对模型进行量化;
dataset参数用于提供量化校准的数据集,数据集的格式是文本文件;
4)导出RKNN模型
导出接口rknn.export_rknn()参数如下:
export_path导出模型文件路径;
cpp_gen_cfg可选择是否生成C++部署示例。
2.3模型量化功能
RKNN_Toolkit2提供两种量化方式和三种量化算法
2.3.1量化方式
Layer量化方式
Channel量化方式:精度较高。
2.3.2量化算法
Normal量化算法:通过计算模型中特征的浮点数最大值和最小值来确定量化范围的最大值和最小值。但遇到特征分布不均衡时效果较差,推荐量化数据量一般为20~100张左右。
MMSE量化算法:建议用此算法。
KI-Divergence量化算法;
2.4量化说明
量化能降低内存占用,实现模型压缩和推理加速,但会造成一定程度的精度损失,量化校正数据格式:图像格式为jpg。模型量化需用dataset.txt文件指定量化数据的路径,规则为一行作为一组输入;
2.5模型转化配置函数详细说明
默认为:rknn.config(mean_values=[[0,0,0]],
std_values=[[255,255,255]],----省略的默认参数
target_platform="RK3588")
可配置参数说明:
mean_values:输入的均值[[128,128,128]]表示一个输入的三个通道值减去128,默认值为None;
std_values:输入的归一化值;
quant_img_RGB2BGR:默认为False,表示加载量化图像时不需做RGB2BGR操作。
quantized_dtype:量化类型(目前只能默认)
quantized_algorithm量化算法(可修改);
quantized_method:量化参数
float_dtype:非量化情况下浮点数类型;
optimization_level:模型优化等级;
target_platform:目标芯片平台;
举例:rknn.config(mean_values=[[103,116,123]],
std_values=[[58,58,58]],
quant_img_RGB2BRG=false,
target_platform='rk3588')
QAT是量化感知训练(Quantization Aware Training),量化后需要在数据集上继续微调训练。也就是在训练过程中就考虑量化带来的影响,这样模型在训练时会模拟量化过程,让模型在量化后精度损失更小。
1、缘由:将YOLOV8训练出的模型pt转换为onnx后再通过一定数量的样本图像进行量化,虽然可通过增加量化样本图像的方法得到一定的改善,但是增加太多的样本数量出现量化不能完成的现象(100多张),会发现识别精度也很难上去。为此采用pytorch官网提供的QAT方法进行直接转换为rknn,来有效提升训练精度。可参考地址:
(beta) Static Quantization with Eager Mode in PyTorch — PyTorch Tutorials 2.6.0+cu124 documentation
2、方法介绍:
2.1)量化感知训练(QAT)是一种通常能带来最高精度的量化方法。在QAT中,所有权重和激活值在训练的正向和反向传递过程中都会被“伪量化”:即浮点值被四舍五入以模拟int8值,但所有计算仍使用浮点数进行。因此,训练过程中的所有权重调整都是在“感知”到模型最终将被量化的前提下进行的;因此,在量化后,这种方法通常会比动态量化和训练后静态量化产生更高的精度。我们可以沿用之前的模型:量化感知训练无需额外准备。我们需要使用一个qconfig来指定在权重和激活之后插入哪种类型的伪量化,而不是指定观察器。
2.2)模型剪枝:通过移除模型中不太有用或重要的部分(即连接或权重),从而得到一个更小更快的模型。
2.3)知识蒸馏:将知识从大型复杂模型(教师模型)转移到更小更简单的模型(学生模型),使学生模型更小但仍能表现良好。蒸馏后的模型可变得更高效。
3、瑞芯微QAT介绍:瑞芯微的QAT流程可能分为几个步骤:首先是训练时启用伪量化,然后在转换时进行量化。需要结合训练时的伪量化步骤,比如在TensorFlow中插入伪量化节点,然后导出模型,再使用RKNN-Toolkit2进行转换,这时候可能不需要再做量化,或者需要调整参数。转换模型时可能不需要再进行量化,或者需要结合数据集进行校准。例如,在RKNN的build步骤中,do_quantization=True是否用于PTQ,而QAT可能需要设置为False,或者使用不同的配置。
总结:瑞芯微的QAT流程可能包括以下步骤:
Step 1. 在训练阶段启用伪量化,插入量化节点,进行QAT训练。
Step 2. 导出训练好的模型(如ONNX格式)。
Step 3. 使用RKNN-Toolkit2进行模型转换,配置时可能需要调整量化参数,比如在build步骤中设置do_quantization=False,或者结合QAT模型进行校准。
Step 4. 导出RKNN模型并进行推理。
3、量化准备
3.1 pytorch_quantization安装
pip install nvidia-pyindex
pip install pytorch-quantization
直接安装pytorch-quantization会找不到,需要首先安装 nvidia-pyindex 包。