1. 前言
为了让神经网络模型运行在芯片上,地平线提供了两种浮点模型转定点模型的方法,分别为训练后量化(Post Training Quantization,PTQ)和量化感知训练(Quantization Aware Training,QAT)。PTQ 是使用一批校准数据对训练好的模型进行校准, 将训练过的FP32网络直接转换为定点计算的网络,量化过程中只对几个超参数调整就可完成量化, 且过程简单快速, 无需训练,因此PTQ已被广泛应用于大量的端侧和云侧部署场景。地平线提供了PTQ模型转换工具hb_mapper makertbin,使用方式如下:
hb_mapper makertbin --config ${config_file} \
--model-type ${model_type}
hb_mapper makertbin参数解释:
- --model-type-
用于指定转换输入的模型类型,目前支持设置 caffe 或者 onnx。 - --config-
模型编译的配置文件,内容采用yaml格式,文件名使用.yaml后缀-
本文将介绍地平线PTQ模型转换工具hb_mapper makertbin使用过程中最重要的yaml文件参数的配置。
2. 最简yaml参数配置
yaml参数包括模型参数组、输入信息参数组、校准参数组和编译参数组。我们为您提供了性能验证和精度验证最简yaml参数配置参考。
2.1 性能验证最简yaml配置
#模型参数组--------------------------------------------------------------------
model_parameters:
# 1.如果是caffe模型,需要配置以下两个参数
caffe_model: 'mobilenet.caffemodel'
# Caffe网络描述文件
prototxt: 'mobilenet_deploy.prototxt'
# 2.如果是onnx浮点模型,需要配置:
onnx_model: "mobilenet.onnx"
# 适用BPU架构
march: "bayes"
#输入参数组--------------------------------------------------------------------
input_parameters:
# 网络实际执行时,输入给网络的数据格式,包括 nv12/rgb/bgr/yuv444/gray/featuremap,
input_type_rt: 'nv12'
# 网络实际执行时输入的数据排布, 可选值为 NHWC/NCHW
# 网络训练时输入的数据格式,可选的值为rgb/bgr/gray/featuremap/yuv444
input_type_train: 'bgr'
# 网络训练时输入的数据排布, 可选值为 NHWC/NCHW
input_layout_train: 'NCHW'
#input_shape是可选参数,但是对于动态输入模型,不指定input_shape会报错
input_shape: '1x3x224x224'
#校准参数组--------------------------------------------------------------------
calibration_parameters:
#skip方式会使用随机数进行校准, 不需要您准备校准数据
calibration_type: 'skip'
#编译参数组--------------------------------------------------------------------
compiler_parameters:
# 默认是latency编译策略
optimize_level: 'O3'
2.2 精度验证最简yaml配置
不同于性能验证,精度验证在模型转换的校准阶段需要20~100份的标定样本输入,每一份样本都是一个独立的数据文件。校准数据的准备有以下要求:
-
为了确保转换后模型的精度效果,这些校准样本最好是来自于您训练模型使用的训练集或验证集, 不要使用非常少见的异常样本,例如纯色图片、不含任何检测或分类目标的图片等。
-
需要把取自训练集/验证集的样本做与inference前一样的前处理, 处理完后的校准样本会与原始模型具备一样的数据类型( input_type_train )、尺寸( input_shape )和 layout( input_layout_train ),对于featuremap输入的模型,您可以通过 numpy.tofile 命令将数据保存为float32格式的二进制文件, 工具链校准时会基于 numpy.fromfile 命令进行读取。校准数据的处理可以参考图片校准数据准备问题介绍与处理。
#编译参数组--------------------------------------------------------------------
model_parameters:1.如果是caffe模型,需要配置以下两个参数
caffe_model: ‘mobilenet.caffemodel’
Caffe网络描述文件
prototxt: ‘mobilenet_deploy.prototxt’
2.如果是onnx浮点模型,需要配置:
onnx_model: “mobilenet.onnx”
适用BPU架构
march: “bayes”
模型输入相关参数, 若输入多个节点, 则应使用’;'进行分隔, 使用默认缺省设置则写None
#输入参数组--------------------------------------------------------------------
input_parameters:网络实际执行时,输入给网络的数据格式,包括 nv12/rgb/bgr/yuv444/gray/featuremap,
input_type_rt: ‘nv12’
若input_type_rt配置为nv12,则此处参数不需要配置
#input_layout_rt: ‘’
网络训练时输入的数据格式,可选的值为rgb/bgr/gray/featuremap/yuv444
input_type_train: ‘bgr’
网络训练时输入的数据排布, 可选值为 NHWC/NCHW
input_layout_train: ‘NCHW’
#input_shape是可选参数,但是对于动态输入模型,不指定input_shape会报错
input_shape: ‘1x3x224x224’data_mean_and_scale 减去通道均值后再乘以scale系数
norm_type: ‘data_mean_and_scale’
图像减去的均值, 如果是通道均值,value之间必须用空格分隔
mean_value: 103.94 116.78 123.68
图像预处理缩放比例,如果是通道缩放比例,value之间必须用空格分隔
scale_value: 0.017
#校准参数组--------------------------------------------------------------------
calibration_parameters:模型量化的校准图像的存放目录,图片格式支持Jpeg、Bmp等格式,输入的图片
若有多个输入节点, 则应使用’;'进行分隔
cal_data_dir: ‘./calibration_data’
校准数据二进制文件的数据存储类型,可选值为:float32, uint8
cal_data_type: ‘float32’
模型量化的算法类型,支持default、mix、kl、max、load,通常采用default即可满足要求
calibration_type: ‘default’
#编译参数组--------------------------------------------------------------------
compiler_parameters:默认是latency编译策略
优化等级可选范围为O0~O3
optimize_level: ‘O3’
注:当模型为多输入时,建议将输入参数组中的input_name、input_type_train、input_layout_train、input_type_rt、input_layout_rt、input_shape、norm_type等参数显式地写出,以免造成参数对应顺序上的错误。
3. 进阶参数介绍及配置示例
3.1 进阶参数介绍
3.1.1 layer_out_dump
在模型调优的过程中,如果想输出混合异构模型中间层的值,可以将模型参数组的layer_out_dump设置为True,默认值为False。
3.1.2 output_nodes
如果想指定模型的输出节点,可以配置模型参数组的参数output_nodes:“{node_name}”。
3.1.3 calibration_type
地平线目前提供了多种校准方式:kl、max 、default、 load 、skip和mix 。kl 和 max 都是公开的校准量化算法,default 是一个自动搜索的策略;如果您使用的是QAT模型,则应选择 load。若您只想尝试对模型性能进行验证,但对精度没有要求, 则可以尝试 skip 方式进行校准。该方式会使用随机数进行校准, 不需要您准备校准数据,比较适合初次尝试对模型结构进行验证。新增的mix 是一个集成多种校准方法的搜索策略, 能够自动确定量化敏感节点,并在节点粒度上从不同的校准方法中挑选出最佳方法,最终构建一个融合了多种校准方法优势的组合校准方式。
3.1.4 run_on_bpu和 run_on_cpu
为了保证最终量化模型的精度,少部分情况下, 转换工具会将一些具备BPU计算条件的算子放在CPU上运行,如果您对性能有较高的要求,愿意以更多一些量化损失为代价, 则可以通过配置参数run_on_bpu:"op_name"明确指定算子运行在BPU上。反之,如果想要实现某些算子在CPU上的高精度计算,则可以配置参数run_on_cpu:“op_name”。
3.1.5 debug
开启编译参数组的debug, 编译后得到的.bin模型,然后使用hb_perf
工具预估模型的逐层耗时、计算量等调试信息, 用于支持后续的调优分析过程。
3.1.6 optimization
通过设置校准参数组的optimization,可以使得模型以 int8/int16 格式输出。如果设置optimization:“set_model_output_int8”,模型将以 int8 格式低精度输出;设置optimization:“set_model_output_int16”,模型将以 int16 格式低精度输出。
3.1.7 int16配置说明
在模型转换的过程中,模型中的大部分算子都会被量化到int8进行计算,而通过配置 set_node_data_type 参数, 可以详细指定某个op(OE1.1.40版本只支持conv,后续地平线会释放更多op)的输出为int16计算, 对于不支持的场景,模型转换工具会打印log提示该int16配置组合暂时不被支持并回退到int8计算。-
set_node_data_type参数使用如下所示:
# 模型转化相关的参数
model_parameters:
#配置指定op的输出数据类型为int16
set_node_data_type:" {op_name} "
3.2 进阶参数配置示例
本节将以两输入模型为例,介绍yaml参数的一些进阶参数的使用。根据原始onnx模型的输入信息对yaml参数进行配置,原始模型相关信息如下表所示:
输入名称
input1
input2
输入大小
6x3x512x960
6x128x128x2
浮点训练时输入格式
yuv444
featuremap
浮点训练时输入layout
NCHW
NHWC
根据原始模型信息,我们对yaml中的参数进行配置,其中涉及部分进阶参数的使用,示例如下:
#模型参数组--------------------------------------------------------------------
model_parameters:
# Onnx浮点网络数据模型文件
onnx_model: "model.onnx"
# 适用BPU架构
march: "bayes"
# 指定模型转换过程中是否输出各层的中间结果,如果为True,则输出所有层的中间输出结果
#输出模型中间层结果
layer_out_dump: True
# 模型转换输出的结果的存放目录
working_dir: "model_output"
# 模型转换输出的用于上板执行的模型文件的名称前缀
# 可任意配置
output_model_file_prefix: "model"
#配置指定Conv16节点的输出数据类型为int16。
set_node_data_type:"Conv16"
# 模型输入相关参数, 若输入多个节点, 则应使用";"进行分隔, 使用默认缺省设置则写None
#输入参数组--------------------------------------------------------------------
input_parameters:
# 模型的两个输入节点,使用;隔开
input_name: 'input1;input2'
# 网络实际执行时,两个输入给网络的数据格式,顺序与input_name统一
input_type_rt: "nv12;featuremap"
#模型实际执行时输入的数据排布,
input_layout_rt: 'NCHW;NCHW'
# 网络训练时输入的数据格式,可选的值为rgb/bgr/gray/featuremap/yuv444
input_type_train: "yuv444;featuremap"
# 网络训练时输入的数据排布, 可选值为 NHWC/NCHW
# 根据onnx模型情况配置
input_layout_train: "NCHW;NHWC"
#网络的输入大小
input_shape: '6x3x512x960;6x128x128x2'
# 网络输入的预处理方法
norm_type: "no_preprocess;no_preprocess"
#校准参数组--------------------------------------------------------------------
calibration_parameters:
# 模型量化的参考图像的存放目录,图片格式支持Jpeg、Bmp等格式,输入的图片
# 应该是使用的典型场景,一般是从测试集中选择20~100张图片,另外输入
# 的图片要覆盖典型场景,不要是偏僻场景,如过曝光、饱和、模糊、纯黑、纯白等图片
# 若有多个输入节点, 则应使用";"进行分隔
# 存放校准数据的文件夹
cal_data_dir: "./calibration_data_yuv; ./calibration_data_featuremap"
# 采用default校准方式
calibration_type: "default"
#使模型以int16低精度输出
optimization: "set_model_output_int16"
#编译参数组--------------------------------------------------------------------
compiler_parameters:
# 选择编译策略latency,以优化推理时间为目标
compile_mode: "latency"
# 设置debug为True将打开编译器的debug模式,能够输出性能仿真的相关信息,如帧率、DDR带宽占用等
debug: True
# 优化等级可选范围为O0~O3
optimize_level: "O3"