PTQ原理及步骤详解
简介
模型转换是指将原始浮点模型转换为D-Robotics 混合异构模型的过程。原始浮点模型(文中部分地方也称为浮点模型)是指您通过TensorFlow/PyTorch等DL框架训练得到的可用模型,这个 模型的计算精度为float32;混合异构模型是一种适合在D-Robotics 处理器上运行的模型格式。 本章节将反复使用到这两种模型名词,为避免理解歧义,请先理解这个概念再阅读下文。
配合D-Robotics 算法工具链的模型完整开发过程,需要经过 浮点模型准备、 模型验证、 模型转换、 性能评估 和 精度评估 共五个重要阶段,如下图:
浮点模型准备 本阶段用来确保原始浮点模型的格式为D-Robotics 模型转换工具支持的格式,原始浮点模型来自于您通过TensorFlow/PyTorch等DL框架训练得到可用模型。具体的浮点模型要求与建议,请阅读浮点模型准备章节内容。
模型验证 本阶段用来校验原始浮点模型是否满足D-Robotics 算法工具链的要求。D-Robotics 提供 hb_mapper checker
检查工具来完成浮点模型的检查。具体使用方法,请阅读验证模型 章节内容。
模型转换 本阶段用来完成浮点模型到D-Robotics 混合异构模型的转换,经过这个阶段,您将得到一个可以在D-Robotics 处理器上运行的模型。D-Robotics 提供 hb_mapper makertbin
转换工具来完成模型优化、量化和编译等关键步骤。具体使用方法,请阅读模型转换章节内容。
性能评估 本阶段主要用于测评D-Robotics 混合异构模型的推理性能情况,D-Robotics 提供了模型性能评估的工具,您可以使用这些工具验证模型性能是否达到应用要求。具体使用说明,请阅读 模型性能分析与调优章节内容。
精度评估 本阶段主要用于测评D-Robotics 混合异构模型的推理精度情况,D-Robotics 提供了模型精度评估的工具。具体使用说明,请阅读模型精度分析与调优章节内容。
模型准备
基于公开DL框架训练得到的浮点模型是D-Robotics 模型转换工具的输入,目前转换工具支持的DL框架如下:
框架 | Caffe | PyTorch | TensorFlow | MXNet | PaddlePaddle |
---|---|---|---|---|---|
D-Robotics 工具链 | 支持 | 支持(转ONNX) | 支持(转ONNX) | 支持(转ONNX) | 支持(转ONNX) |
以上框架中, Caffe框架导出的caffemodel是直接支持的,PyTorch、TensorFlow和MXNet等DL框架通过转换到ONNX格式间接支持。
对于不同框架到ONNX的转换,目前都有对应的标准化方案,参考如下:
-
Pytorch2Onnx:PytTorch官方API支持直接将模型导出为ONNX模型,参考链接: https://pytorch.org/tutorials/advanced/super_resolution_with_onnxruntime.html。
-
Tensorflow2Onnx:基于ONNX社区的onnx/tensorflow-onnx 进行转换,参考链接: https://github.com/onnx/tensorflow-onnx。
-
MXNet2Onnx:MXNet官方API支持直接将模型导出为ONNX模型,参考链接: https://github.com/dotnet/machinelearning/blob/master/test/Microsoft.ML.Tests/OnnxConversionTest.cs。
-
更多框架的ONNX转换支持,参考链接: https://github.com/onnx/tutorials#converting-to-onnx-format。
关于Pytorch、PaddlePaddle、TensorFlow2框架的模型,我们也提供了如何导出ONNX及模型可视化的教程,请参考:
-
浮点模型中所使用的算子需要符合D-Robotics 算法工具链的算子约束条件,具体请阅读 模型算子支持列表 章节进行查询。
-
目前转换工具仅支持输出个数小于或等于32的模型进行转换。
-
支持
caffe 1.0
版本的caffe浮点模型和ir_version≤7
,opset=10
、opset=11
版本的onnx浮点模型量化成D-Robotics 支持的定点模型, onnx模型的ir_version与onnx版本的对应关系请参考onnx官方文档 ; -
模型输入维度只支持
固定4维
输入NCHW或NHWC(N维度只能为1),例如:1x3x224x224或1x224x224x3, 不支 持动态维度及非4维输入; -
浮点模型中不要包含有
后处理算子
,例如:nms算子。
模型验证
模型正式转换前,请先使用 hb_mapper checker
工具进行模型验证,确保其符合D-Robotics 处理器的支持约束。
建议参考使用D-Robotics 模型转换 horizon_model_convert_sample
示例包中的caffe、onnx等示例模型的脚本方法: 01_check_X3.sh
或 01_check_Ultra.sh
。
使用 hb_mapper checker
工具验证模型
hb_mapper checker 工具的使用方式如下:
hb_mapper checker --model-type ${model_type} \
--march ${march} \
--proto ${proto} \
--model ${caffe_model/onnx_model} \
--input-shape ${input_node} ${input_shape} \
--output ${output}
hb_mapper checker 参数解释:
--model-type
用于指定检查输入的模型类型,目前只支持设置 caffe
或者 onnx
。
--march
用于指定需要适配的D-Robotics 处理器类型,可设置值为 bernoulli2
和 bayes
;RDK X3设置为 bernoulli2
,RDK Ultra设置为 bayes
,RDK X5设置为 bayes-e
。
--proto
此参数仅在 model-type
指定 caffe
时有效,取值为Caffe模型的prototxt文件名称。
--model
在 model-type
被指定为 caffe
时,取值为Caffe模型的caffemodel文件名称。
在 model-type
被指定为 onnx
时,取值为ONNX模型文件名称。
--input-shape
可选参数,明确指定模型的输入shape。
取值为 {input_name} {NxHxWxC/NxCxHxW}
,input_name
与shape之间以空格分隔。
例如模型输入名称为 data1
,输入shape为 [1,224,224,3]
,
则配置应该为 --input-shape data1 1x224x224x3
。
如果此处配置shape与模型内shape信息不一致,以此处配置为准。
注意一个 --input-shape
只接受一个name和shape组合,如果您的模型有多个输入节点,
在命令中多次配置 --input-shape
参数即可。
--output参数已经废弃,log信息默认存储于 hb_mapper_checker.log
中。
检查异常处理
如果模型检查步骤异常终止或者出现报错信息,则说明模型验证不通过,请根据终端打印或在当前路径下生成的 hb_mapper_checker.log
日志文件确认报错信息和修改建议。
例如:以下配置中含不可识别算子类型 Accuracy
:
layer {
name: "data"
type: "Input"
top: "data"
input_param { shape: { dim: 1 dim: 3 dim: 224 dim: 224 } }
}
layer {
name: "Convolution1"
type: "Convolution"
bottom: "data"
top: "Convolution1"
convolution_param {
num_output: 128
bias_term: false
pad: 0
kernel_size: 1
group: 1
stride: 1
weight_filler {
type: "msra"
}
}
}
layer {
name: "accuracy"
type: "Accuracy"
bottom: "Convolution3"
top: "accuracy"
include {
phase: TEST
}
}
使用 hb_mapper checker
检查这个模型,您会在 hb_mapper_checker.log
中得到如下信息:
ValueError: Not support layer name=accuracy type=Accuracy
- 如果模型检查步骤异常终止 或者出现报错信息,则说明模型验证不通过,请根据终端打印或在当前路径下生成的
hb_mapper_checker.log
日志文件确认报错信息和修改建议,错误信息可以在 模型量化错误及解决方法 章节来查找错误的解决方法,若以上步骤仍不能排除问题,请联系D-Robotics 技术支持团队或在D-Robotics 官方技术社区提出您的问题,我们将在24小时内给您提供支持。
检查结果解读
如果不存在ERROR,则顺利通过校验。 hb_mapper checker
工具将直接输出如下信息:
==============================================
Node ON Subgraph Type
----------
conv1 BPU id(0) HzSQuantizedConv
conv2_1/dw BPU id(0) HzSQuantizedConv
conv2_1/sep BPU id(0) HzSQuantizedConv
conv2_2/dw BPU id(0) HzSQuantizedConv
conv2_2/sep BPU id(0) HzSQuantizedConv
conv3_1/dw BPU id(0) HzSQuantizedConv
conv3_1/sep BPU id(0) HzSQuantizedConv
...
结果中每行都代表一个模型节点的check情况,每行含Node、ON、Subgraph和Type四列,分别为节点名称、执行节点计算的硬件、节点所属子图和节点映射到的D-Robotics 算子名称。 如果模型在网络结构中出现了CPU计算的算子,hb_mapper checker工具将把这个算子前后连续在BPU计算的部分拆分为两个Subgraph(子图)。
检查结果的调优指导
在最理想的情况下,模型网络结构中的算子都应该在BPU上运行,也就是只有一个子图。 如果出现了CPU算子导致拆分多个子图, hb_mapper checker
工具会给出导致CPU算子出现的具体原因,以下给出了分别在RDK X3 和 RDK Ultra上示例模型验证的情况;
- 以下在 RDK X3 上运行的Caffe模型出现了Reshape + Pow + Reshape 的结构, 从 RDK X3 的算子约束列表中我们可以看到, Reshape 算子目前为在CPU上运行的算子, 而Pow的shape也是非4维的,不符合X3 BPU算子约束条件。
因此模型最终检查结果也会出现分段情况, 如下:
2022-05-25 15:16:14,667 INFO The converted model node information:
====================================================================================
Node ON Subgraph Type
-------------
conv68 BPU id(0) HzSQuantizedConv
sigmoid16 BPU id(0) HzLut
axpy_prod16 BPU id(0) HzSQuantizedMul
UNIT_CONV_FOR_eltwise_layer16_add_1 BPU id(0) HzSQuantizedConv
prelu49 BPU id(0) HzPRelu
fc1 BPU id(0) HzSQuantizedConv
fc1_reshape_0 CPU -- Reshape
fc_output/square CPU -- Pow
fc_output/sum_pre_reshape CPU -- Reshape
fc_output/sum BPU id(1) HzSQuantizedConv
fc_output/sum_reshape_0 CPU -- Reshape
fc_output/sqrt CPU -- Pow
fc_output/expand_pre_reshape CPU -- Reshape
fc_output/expand BPU id(2) HzSQuantizedConv
fc1_reshape_1 CPU -- Reshape
fc_output/expand_reshape_0 CPU -- Reshape
fc_output/op CPU -- Mul
- 以下在 RDK Ultra 上运行的ONNX模型出现了Mul + Add + Mul的结构,从 RDK Ultra 的算子约束列表中我们可以看到,Mul和Add算子在五维上是支持BPU运行的,但前提要符合Ultra BPU算子约束条件,不然就会回退到CPU计算。
因此模型最终检查结果也会出现分段情况,如下:
====================================================================================
Node ON Subgraph Type
-------------------------------------------------------------------------------------
Reshape_199 BPU id(0) Reshape
Transpose_200 BPU id(0) Transpose
Sigmoid_201 BPU id(0) HzLut
Split_202 BPU id(0) Split
Mul_204 CPU -- Mul
Add_206 CPU -- Add
Mul_208 CPU -- Mul
Mul_210 CPU -- Mul
Pow_211 BPU id(1) HzLut
Mul_213 CPU -- Mul
Concat_214 CPU -- Concat
Reshape_215 CPU -- Reshape
Conv_216 BPU id(0) HzSQuantizedConv
Reshape_217 BPU id(0) Reshape
Transpose_218 BPU id(0) Transpose
Sigmoid_219 BPU id(0) HzLut
Split_220 BPU id(0) Split
Mul_222 CPU -- Mul
Add_224 CPU -- Add
Mul_226 CPU -- Mul
Mul_228 CPU -- Mul
Pow_229 BPU id(2) HzLut
Mul_231 CPU -- Mul
Concat_232 CPU -- Concat
Reshape_233 CPU -- Reshape
Conv_234 BPU id(0) HzSQuantizedConv
Reshape_235 BPU id(0) Reshape
Transpose_236 BPU id(0) Transpose
Sigmoid_237 BPU id(0) HzLut
Split_238 BPU id(0) Split
Mul_240 CPU -- Mul
Add_242 CPU -- Add
Mul_244 CPU -- Mul
Mul_246 CPU -- Mul
Pow_247 BPU id(3) HzLut
Mul_249 CPU -- Mul
Concat_250 CPU -- Concat
Reshape_251 CPU -- Reshape
根据 hb_mapper checker 给出的提示,一般来说算子运行在BPU上会有更好的性能表现,这里可以将pow、reshape 这类CPU算子从模型中移除,将对应算子的功能放入后处理中计算,从而减少子图数量。
当然,多个子图也不会影响整个转换流程,但会较大程度地影响模型性能,建议尽量调整模型算子到BPU上执行,可参考D-Robotics 处理器算子支持列表中的BPU算子支持列表来做同功能的算子替换或者将模型中的CPU算子移到模型推理的前、后处理中去做CPU计算。
模型转换
模型转换阶段会完成浮点模型到D-Robotics 混合异构模型的转换,经过这个阶段,您将得到一个可以在D-Robotics 处理器上运行的模型。 在进行转换之前,请确保已经顺利通过了上文的验证模型过程。
模型转换使用 hb_mapper makertbin
工具完成,转换期间会完成模型优化和校准量化等重要过程,校准需要依照模型预处理要求准备校准数据。
为了方便您全面了解模型转换,本节将依次介绍校准数据准备、转换工具使用、转换内部过程解读、转换结果解读和转换产出物解读等内容。
准备校准数据
在进行模型转换时,校准阶段会需要 100份左右 标定样本输入,每一份样本都是一个独立的数据文件。 为了确保转换后模型的精度效果,我们希望这些校准样本来自于您训练模型使用的 训练集或验证集 ,不要使用非常少见的异常样本,例如 纯色图片、不含任何检测或分类目标的图片等。
转换配置文件中的 preprocess_on
参数,该参数启用和关闭状态下分别对应了两种不同的预处理样本要求。
(有关参数的详细配置可参考下文校准参数组中相关说明)
preprocess_on
关闭状态下,您需要把取自训练集/验证集的样本做与模型推理(inference)前一样的前处理,
处理完后的校准样本会与原始模型具备一样的数据类型( input_type_train
)、尺寸( input_shape
)和
layout( input_layout_train
),对于featuremap输入的模型,您可以通过 numpy.tofile
命令将数据保存为float32格式的二进制文件,
工具链校准时会基于 numpy.fromfile
命令进行读取。
例如,使用ImageNet训练的用于分类的 原始浮点模型,它只有一个输入节点,输入信息描述如下:
- 输入类型:
BGR
- 输入layout:
NCHW
- 输入尺寸:
1x3x224x224
使用验证集做模型推理(inference)时的数据预处理如下:
- 图像长宽等比scale,短边缩放到256。
center_crop
方法获取224x224大小图像。- 按通道减mean。
- 数据乘以scale系数。
针对上述举例模型的样本处理代码如下:
为避免过长代码篇幅,各种简单transformer实现代码未贴出,具体使用请参考transformer使用方法 章节内容。
建议参考使用D-Robotics 模型转换 horizon_model_convert_sample
示例包中的caffe、onnx等示例模型的预处理步骤方法: 02_preprocess.sh
和 preprocess.py
。
# 本示例使用skimage,如果是opencv会有所区别
# 需要您特别注意的是,transformers中并没有体现减mean和乘scale的处理
# mean和scale操作已经融合到了模型中,请参考下文norm_type/mean_value/scale_value配置
def data_transformer():
transformers = [
# 长宽等比scale,短边缩放至256
ShortSideResizeTransformer(short_size=256),
# CenterCrop获取224x224图像
CenterCropTransformer(crop_size=224),
# skimage读取结果为NHWC排布,转换为模型需要的NCHW
HWC2CHWTransformer(),
# skimage读取结果通道顺序为RGB,转换为模型需要的BGR
RGB2BGRTransformer(),
# skimage读取数值范围为[0.0,1.0],调整为模型需要的数值范围
ScaleTransformer(scale_value=255)
]
return transformers
# src_image 标定集中的原图片
# dst_file 存放最终标定样本数据的文件名称
def convert_image(src_image, dst_file, transformers):
image = skimage.img_as_float(skimage.io.imread(src_file))
for trans in transformers:
image = trans(image)
# 模型指定的input_type_train BGR数值类型是UINT8
image = image.astype(np.uint8)
# 二进制存储标定样本到数据文件
image.tofile(dst_file)
if __name__ == '__main__':
# 此处表示原始标定图片集合,伪代码
src_images = ['ILSVRC2012_val_00000001.JPEG',...]
# 此处表示最终标定文件名称(后缀名不限制),伪代码
# calibration_data_bgr_f32是您在配置文件中指定的cal_data_dir
dst_files = ['./calibration_data_bgr_f32/ILSVRC2012_val_00000001.bgr',...]
transformers = data_transformer()
for src_image, dst_file in zip(src_images, dst_files):
convert_image(src_image, dst_file, transformers)
preprocess_on
启用状态下,标定样本使用skimage支持读取的图片格式文件即可。
转换工具读取这些图片后,会将其缩放到模型输入节点要求的尺寸大小,以此结果作为校准的输入。
这样的操作会简单,但是对于量化的精度没有保障,因此我们强烈建议您使用关闭 preprocess_on
的方式。
请注意,yaml文件中input_shape参数作用为指定原始浮点模型的输入数据尺寸。若为动态输入模型则可通过这个参数设置转换后的输入大小,而校准数据的shape大小应与input_shape保持一致。
例如:若原始浮点模型输入节点shape为?x3x224x224(“?”号代表占位符,即该模型第一维为动态输入), 转换配置文件中设置input_shape: 8x3x224x224,则用户需要准备的每份校准数据大小为 8x3x224x224。 (请知悉,此类输入shape第一维不等于1的模型,不支持通过input_batch参数修改模型batch信息。)
使用 hb_mapper makertbin 工具转换模型
hb_mapper makertbin提供两种模式,开启 fast-perf
模式和不开启 fast-perf
模式。
fast-perf
模式开启后,会在转换过程中生成可以在板端运行最高性能的bin模型,工具内部主要进行以下操作:
-
将BPU可执行算子尽可能运行在BPU上(若使用
RDK Ultra
和RDK X5
则可以通过yaml文件中node_info参数指定在BPU上运行的算子,RDK X3
是自动优化,无法通过yaml配置文件指定算子)。 -
删除模型首尾不可删除的CPU算子,包括:Quantize/Dequantize、Transpose、Cast、Reshape等。
-
以性能最高的O3优化等级编译模型。
建议参考使用D-Robotics 模型转换 horizon_model_convert_sample
示例包中的caffe、onnx等示例模型的脚本方法: 03_build_X3.sh
或 03_build_Ultra.sh
。
hb_mapper makertbin命令使用方式如下:
不开启 fast-perf
模式:
hb_mapper makertbin --config ${config_file} \
--model-type ${model_type}
开启 fast-perf
模式:
hb_mapper makertbin --fast-perf --model ${caffe_model/onnx_model} --model-type ${model_type} \
--proto ${caffe_proto} \
--march ${march}
hb_mapper makertbin参数解释:
--help
显示帮助信息并退出。
-c, --config
模型编译的配置文件,为yaml格式,文件名使用.yaml后缀,完整的配置文件模板参考如下章节内容。
--model-type
用于指定转换输入的模型类型,目前支持设置 caffe
或者 onnx
。
--fast-perf
开启fast-perf模式,该模式开启后,会在转换过程中生成可以在板端运行最高性能的bin模型,方便您用于后续的模型性能评测。
如您开启了fast-perf模式,还需要进行如下配置:
--model
Caffe或ONNX浮点模型文件。
--proto
用于指定Caffe模型prototxt文件。
--march
BPU的微架构。若使用 RDK X3
则设置为 bernoulli2
,若使用 RDK Ultra
则设置为 bayes
,若使用 RDK X5
则设置为 bayes-e
。
-
RDK X3 yaml配置文件
,可直接使用RDK X3 Caffe模型量化yaml文件模板 和RDK X3 ONNX模型量化yaml文件模板模板文件进行填写。 -
RDK Ultra yaml配置文件
,可直接使用RDK Ultra Caffe模型量化yaml文件模板 和RDK Ultra ONNX模型量化yaml文件模板模板文件进行填写。 -
RDK X5 yaml配置文件
,可直接使用RDK X5 Caffe模型量化yaml文件模板 和RDK X5 ONNX模型量化yaml文件模板模板文件进行填写。 -
若 hb_mapper makertbin 步骤异常终止或者出现报错信息,则说明模型转换失败,请根据终端打印或在当前路径下生成的
hb_mapper_makertbin.log
日志文件确认报错信息和修改建议,错误信息可以在 模型量化错误及解决方法章节来查找错误的解决方法,若以上步骤仍不能排除问题,请联系D-Robotics 技术支持团队或在D-Robotics 官方技术社区提出您的问题,我们将在24小时内给您提供支持。
模型转换yaml配置参数说明
要么是Caffe模型,要么是ONNX模型。即 caffe_model
+ prototxt
或者 onnx_model
二选一。
即,要么是Caffe模型,要么是ONNX模型。
# 模型参数组
model_parameters:
# 原始Caffe浮点模型描述文件
prototxt: '***.prototxt'
# 原始Caffe浮点模型数据模型文件
caffe_model: '****.caffemodel'
# 原始Onnx浮点模型文件
onnx_model: '****.onnx'
# 转换的目标处理器架构,保持默认,D-Robotics RDK X3使用的是bernoulli2架构, RDK Ultra使用的是bayes架构。march: 'bayes', RDK X5使用的是bayes-e架构。march: 'bayes-e'
march: 'bernoulli2'
# 模型转换输出的用于上板执行的模型文件的名称前缀
output_model_file_prefix: 'mobilenetv1'
# 模型转换输出的结果的存放目录
working_dir: './model_output_dir'
# 指定转换后混合异构模型是否保留输出各层的中间结果的能力,保持默认即可
layer_out_dump: False
# 指定模型的输出节点
output_nodes: {OP_name}
# 批量删除某一类型的节点
remove_node_type: Dequantize
# 删除指定名称的节点
remove_node_name: {OP_name}
# 输入信息参数组
input_parameters:
# 原始浮点模型的输入节点名称
input_name: "data"
# 原始浮点模型的输入数据格式(数量/顺序与input_name一致)
input_type_train: 'bgr'
# 原始浮点模型的输入数据排布(数量/顺序与input_name一致)
input_layout_train: 'NCHW'
# 原始浮点模型的输入数据尺寸
input_shape: '1x3x224x224'
# 网络实际执行时,输入给网络的batch_size, 默认值为1
input_batch: 1
# 在模型中添加的输入数据预处理方法
norm_type: 'data_mean_and_scale'
# 预处理方法的图像减去的均值, 如果是通道均值,value之间必须用空格分隔
mean_value: '103.94 116.78 123.68'
# 预处理方法的图像缩放比例,如果是通道缩放比例,value之间必须用空格分隔
scale_value: '0.017'
# 转换后混合异构模型需要适配的输入数据格式(数量/顺序与input_name一致)
input_type_rt: 'yuv444'
# 输入数据格式的特殊制式
input_space_and_range: 'regular'
# 转换后混合异构模型需要适配的输入数据排布(数量/顺序与input_name一致),若input_type_rt配置为nv12,则此处参数不需要配置
input_layout_rt: 'NHWC'
# 校准参数组
calibration_parameters:
# 模型校准使用的标定样本的存放目录
cal_data_dir: './calibration_data'
# 指定校准数据二进制文件的数据存储类型。
cal_data_type: 'float32'
# 开启图片校准样本自动处理(skimage read; resize到输入节点尺寸)
#preprocess_on: False
# 校准使用的算法类型, 优先使用的 default 校准算法
calibration_type: 'default'
# max 校准方式的参数
# max_percentile: 1.0
# 强制指定OP在CPU上运行,一般不需要配置,在模型精度调优阶段可以开启此功能,用于尝试精度优化
#run_on_cpu: {OP_name}
# 强制指定OP在BPU上运行, 一般不需要配置,在模型性能调优阶段可以开启此功能,用于尝试性能优化
# run_on_bpu: {OP_name}
# 指定是否针对每个channel进行校准
#per_channel: False
# 指定输出节点的数据精度
#optimization: set_model_output_int8
# 编译参数组
compiler_parameters:
# 编译策略选择
compile_mode: 'latency'
# 是否打开编译的debug信息,保持默认的 False
debug: False
# 模型运行核心数
core_num: 1
# 模型编译的优化等级选择,保持默认的 O3
optimize_level: 'O3'
# 指定名称为data的输入数据来源
#input_source: {"data": "pyramid"}
# 指定模型的每个function call的最大可连续执行时间
#max_time_per_fc: 1000
# 指定编译模型时的进程数
#jobs: 8
# 此参数组,无需配置,只在有自定义CPU算子时开启使用
#custom_op:
# 自定义op的校准方式, 推荐使用注册方式 register
#custom_op_method: register
# 自定义OP的实现文件, 多个文件可用";"分隔, 该文件可由模板生成, 详情见自定义OP相关文档
#op_register_files: sample_custom.py
# 自定义OP实现文件所在的文件夹, 请使用相对路径
#custom_op_dir: ./custom_op
配置文件主要包含模型参数组、输入信息参数组、校准参数组和编译参数组。 在您的配置文件中,四个参数组位置都需要存在,具体参数分为可选和必选,可选参数可以不配置。
具体参数的设置形式为: param_name: 'param_value'
;
若参数存在多个值时,每个值之间使用 ';'
符号进行分隔: param_name: 'param_value1; param_value2; param_value3'
;具体配置方法可参考:run_on_cpu: 'conv_0; conv_1; conv12'
。
-
当模型为多输入模型时, 建议用户将可选参数(
input_name
,input_shape
等)显式的写出, 以免造成参数对应顺序上的错误。 -
在配置march为bayes,即在进行RDK Ultra模型转换时,如您将优化等级optimize_level配置为O3,hb_mapper makerbin默认提供缓存能力。即在您第一次使用hb_mapper makerbin对模型进行编译时,会自动创建缓存文件,后续在您的working_dir不变的情况下,在重复编译时会自动调用此文件,降低您的编译时间。
-
在配置march为bayes-e,即在进行RDK X5模型转换时,如您将优化等级optimize_level配置为O3,hb_mapper makerbin默认提供缓存能力。即在您第一次使用hb_mapper makerbin对模型进行编译时,会自动创建缓存文件,后续在您的working_dir不变的情况下,在重复编译时会自动调用此文件,降低您的编译时间。
- 请注意,如果设置
input_type_rt
为nv12
或yuv444
,则模型的输入尺寸中不能出现奇数。 - 请注意,目前RDK X3上暂不支持
input_type_rt
为yuv444
且input_layout_rt
为NCHW
组合的场景。 - 模型转换成功后,若出现符合D-Robotics BPU算子约束条件的OP仍然运行在CPU上,其主要原因是该OP属于被动量化OP,关于被动量化相关内容,请阅读 算法工具链中的主动量化和被动量化逻辑 章节。
以下是具体参数信息,参数会比较多,我们依照上述的参数组次序介绍。
-
模型参数组
参数名称 | 参数配置说明 | 取值范围说明 | 可选/必选 |
---|---|---|---|
prototxt | 参数作用:指定Caffe浮点模型的prototxt文件名称。 参数说明:在 hb_mapper makertbin 的model-type 为 caffe 时必须配置。 | 取值范围:无。 默认配置:无。 | 可选 |
caffe_model | 参数作用:指定Caffe浮点模型的caffemodel文件名称。 参数说明:在 hb_mapper makertbin 的model-type 为 caffe 时必须配 置。 | 取值范围:无。 默认配置:无。 | 可选 |
onnx_model | 参数作用:指定ONNX浮点模型的onnx文件名称。 参数说明:在 hb_mapper makertbin 的model-type 为 onnx 时必须配置。 | 取值范围:无。 默认配置:无。 | 可选 |
march | 参数作用:指定产出混合异构模型需要支持的平台架构。 参数说明:两个可选配置值依次对应RDK X3 和 RDK Ultra 对应的BPU微框架。根据您使用的平台选择。 | 取值范围:bernoulli2 或 bayes 。默认配置:无。 | 必选 |
output_model_file_prefix | 参数作用:指定转换产出混合异构模型的名称前缀。 参数说明:输出的定点模型文件的名称前缀。 | 取值范围:无。 默认配置:无。 | 必选 |
working_dir | 参数作用:指定模型转换输出的结果的存放目录。 参数说明:若该目录不存在, 则工具会自动创建目录。 | 取值范围:无。 默认配置: model_output 。 | 可选 |
layer_out_dump | 参数作用:指定混合异构模型是否保留输出中间层值的能力。 参数说明:输出中间层的值是调试需要用到的手段,常规状态下请不要开启。 | 取值范围:True 、 False 。默认配置: False 。 | 可选 |
output_nodes | 参数作用:指定模型的输出节点。 参数说明:一般情况下,转换工具会自动识别模型的输出节点。此参数用于支持您指定一些中间层次作为输出。设置值为模型中的具体节点名称,多个值的配置方法请参考前文对 param_value 配置描述。需要您注意的是,一旦设置此参数后,工具将不再自动识别输出节点,您通过此参数指定的节点就是全部的输出。 | 取值范围:无。 默认配置:无。 | 可选 |
remove_node_type | 参数作用:设置删除节点的类型。 参数说明:该参数为隐藏参数,不设置或设置为空不影响模型转换过程。此参数用于支持您设置待删除节点的类型信息。被删除的节点必须在模型的开头或者末尾, 与模型的输入或输出连接。注意:待删除节点会按顺序依次删除,并动态更新模型结构;同时在节点删除前还会判断该节点是否位于模型的输入输出处。因此节点的删除顺序很重要。 | 取值范围:”Quantize”, “Transpose”, “Dequantize”, “Cast”, “Reshape”。不同类型用”;”分割。 默认配置:无。 | 可选 |
remove_node_name | 参数作用:设置删除节点的名称。 参数说明:该参数为隐藏参数, 不设置或设置为空不影响模型转换过程。 此参数用于支持您设置待删除节点的名称。被删除的节点必须在模型的开头或者末尾, 与模型的输入或输出连接。注意:待删除节点会按顺序依次删除,并动态更新模型结构;同时在节点删除前还会判断该节点是否位于模型的输入输出处。因此节点的删除顺 序很重要。 | 取值范围:无。不同类型用";"分割。 默认配置:无。 | 可选 |
set_node_data_type | 参数作用:配置指定op的输出数据类型为int16,此参数 只支持RDK Ultra和RDK X5配置! 参数说明:在模型转换过程中,大多数op的默认输入输出数据类型为int8,通过该参数可以指定特定op的输出数据类型为int16(在满足一定的约束条件下)。int16相关说明详见:int16配置说明部分的描述。 注意: 该参数相关功能已合并至 node_info 参数中,后续版本计划废弃。 | 取值范围:支持配置int16的算子范围您可参考模型算子支持列表中RDK Ultra 和 RDK X5算子支持约束列表。 默认配置:无。 | 可选 |
debug_mode | 参数作用:保存用于精度debug分析的校准数据。 参数说明:该参数作用为保存用于精度debug分析的校准数据,数据格式为.npy。该数据通过np.load()可直接送入模型进行推理。若不设置此参数,您也可自行保存数据并使用精度debug工具进行精度分析。 | 取值范围:"dump_calibration_data" 默认配置:无。 | 可选 |
node_info | 参数作用:支持配置指定OP的输入输出数据类型为int16以及强制指定算子在CPU或BPU上运行。此参数 只支持RDK Ultra和RDK X5配置! 参数说明:基于减少yaml中的参数的原则,我们将 set_node_data_type 、run_on_cpu 和 run_on_bpu 三个参数的能力融合到本参数中,并在此基础上扩充支持配置指定op输入数据类型为int16的能力。node_info 参数使用方式: - 仅指定OP运行在BPU/CPU上(下以BPU为例,CPU方法一致): node_info: { <br/>"node_name":<br/> { 'ON': 'BPU', <br/>} <br/>} - 仅配置节点数据类型: node_info: 'node_name1:int16;node_name2:int16' 多个值的配置方法请参考 param_value配置 <param_value> 。 - 指定OP运行在BPU上,同时配置OP的输入输出数据类型: node_info: { <br/>"node_name": { <br/>'ON': 'BPU', <br/>'InputType': 'int16', <br/>'OutputType': 'int16'<br/> } <br/> } 'InputType': 'int16'代表指定算子的所有输入数据类型为int16。 如需指定算子特定输入的InputType,可在InputType后通过指定数字来进行配置。如: 'InputType0': 'int16'代表指定算子的第一个输入数据类型为int16, 'InputType1': 'int16'代表指定算子的第二个输入数据类型为int16,以此类推。 注意: 'OutputType' 不支持指定算子特定输出的OutputType,配置后对算子的所有输出生效,不支持配置 'OutputType0' 、 'OutputType1'等。 | 取值范围:支持配置int16的算子范围您可参考模型算子支持列表中RDK Ultra 和 RDK X5算子支持约束列表。可指定在CPU或BPU运 行的算子需为模型中包含的算子。 默认配置:无。 | 可选 |
-
输入信息参数组
参数名称 | 参数配置说明 | 取值范围说明 | 可选/必选 |
---|---|---|---|
input_name | 参数作用:指定原始浮点模型的输入节点名称。 参数说明:浮点模型只有一个输入节点情况时不需要配置。多于一个输入节点时必须配置以保证后续类型及校准数据输入顺序的准确性。多个值的配置方法请参考前文对param_value配置描述。 | 取值范围:无。 默认配置:无。 | 可选 |
input_type_train | 参数作用:指定原始浮点模型的输入数据类型。 参数说明:每一个输入节点都需要配置一个确定的输入数据类型。存在多个输入节点时,设置的节点顺序需要与 input_name 里的顺序严格保持一致。多个值的配置方法请参考前文对param_value 配置描述。数据类型的选择请参考: 转换内部过程解读 部分的介绍。 | 取值范围:rgb 、bgr 、yuv444 、gray 、featuremap 。默认配置:无。 | 必选 |
input_layout_train | 参数作用:指定原始浮点模型的输入数据排布。 参数说明:每一个输入节点都需要配 置一个确定的输入数据排布, 这个排布必须与原始浮点模型所采用的数据排布相同。存在多个输入节点时, 设置的节点顺序需要与 input_name 里的顺序严格保持一致。多个值的配置方法请参考前文对param_value 配置描述。什么是数据排布请参考: 转换内部过程解读 部分的介绍。 | 取值范围:NHWC 、 NCHW。 默认配置:无。 | 必选 |
input_type_rt | 参数作用:转换后混合异构模型需要适配的输入数据格式。 参数说明:这里是指明您需要使用的数据格式, 不要求与原始模型的数据格式一致, 但是需要注意在平台喂给模型的数据是使用这个格式。每一个输入节点都需要配置一个确定的输入数据类型,存在多个输入节点时, 设置的节点顺序需要与 input_name 里的顺序严格保持一致。多个值的配置方法请参考前文对param_value 配置描述。数据类型的选择请参考: 转换内部过程解读 部分的介绍。 | 取值范围:rgb 、bgr 、yuv444 、nv12 、gray 、featuremap 。默认配置:无。 | 必选 |
input_layout_rt | 参数作用:转换后混合异构模型需要适配的输入数据排布。 参数说明:每一个输入节点都需要配置一个确定的输入数据排布, 这个输入是您希望给混合异构模型指定的排布。不合适的输入数据的排布设置将会影响性能, X3平台建议用户使用 NHWC 格式输入。若input_type_rt配置为nv12,则此处参数不需要配置。存在多个输入节点时,设置的节点顺序需要与 input_name 里的顺序严格保持一致。多个值的配置方法请参考前文对param_value 配置描述。什么是数据排布请参考: 转换内部过程解读 部分的介绍。 | 取值范围:NCHW 、 NHWC 。默认配置:无。 | 可选 |
input_space_and_range | 参数作用:指定输入数据格式的特殊制式。 参数说明:这个参数是为了适配不同ISP输出的yuv420格式, 在相应 input_type_rt 为 nv12 时,该配置才有效。regular 就是常见的yuv420格式,数值范围为 [0,255];bt601_video 是另一种视频制式yuv420,数值范围为 [16,235]。更多信息可以通过网络资料了解bt601, 在没有明确需要的情况下,您不要配置此参数。 | 取值范围:regular , bt601_video 。默认配置: regular 。 | 可选 |
input_shape | 参数作用:指定原始浮点模型的输入数据尺寸。 参数说明:shape的几个维度以 x 连接,例如 1x3x224x224。原始浮点模型只有一个输入节点情况时可以不配置, 工具会自动读取模型文件中的尺寸信息。配置多个输入节点时,设置的节点顺序需要与 input_name 里的顺序严格保持一致。多个值的配置方法请参考前文对param_value 配置描述。 | 取值范围:无。 默认配置:无。 | 可选 |
input_batch | 参数作用:指定转换后混合异构模型需要适配的输入batch数量。 参数说明:这里input_batch为转换后混合异构bin模型输入batch数量, 但不影响转换后onnx的模型的输入batch数量。此参数不配置时默认为1。此参数仅适用于单输入模型, 且 input_shape 第一维必须为1。 | 取值范围:1-128 。默认配置: 1 。 | 可选 |
norm_type | 参数作用:在模型中添加的输入数据预处理方法。 参数说明: no_preprocess 表示不添加任何数据预处理;data_mean 表示提供减均值预处理;data_scale 表示提供乘scale系数预处理;data_mean_and_scale 表示提供先减均值再乘scale系数前处理。输入节点时多于一个时,设置的节点顺序需要与input_name 里的顺序严格保持一致。多个值的配置方法请参考前文对param_value 配置描述。配置该参数的影响请参考: 转换内部过程解读 部分的介绍。 | 取值范围:data_mean_and_scale 、 data_mean 、data_scale 、 no_preprocess 。默认配置:无。 | 必选 |
mean_value | 参数作用:指定预处理方法的图像减去的均值。 参数说明:当 norm_type 存在 data_mean_and_scale 或 data_mean 时需要配置该参数。对于每一个输入节点而言,存在两种配置方式。第一种是仅配置一个数值,表示所有通道都减去这个均值;第二种是提供与通道数量一致的数值(这些数值以空格分隔开), 表示每个通道都会减去不同的均值。配置的输入节点数量必须与 norm_type 配置的节点数量一致, 如果存在某个节点不需要 mean 处理,则为该节点配置 'None' 。多个值的配置方法请参考前文对param_value 配置描述。 | 取值范围:无。 默认配置:无。 | 可选 |
scale_value | 参数作用:指定预处理方法的数值scale系数。 参数说明:当 norm_type 存在 data_mean_and_scale 或 data_scale 时需要配置该参数。对于每一个输入节点而言,存在两种配置方式。第一种是仅配置一个数值,表示所有通道都乘以这个系数;第二种是提供与通道数量一致的数值(这些数值以空格分隔开), 表示每个通道都会乘以不同的系数。配置的输入节点数量必须与 norm_type 配置的节点数量一致, 如果存在某个节点不需要 scale 处理,则为该节点配置 'None' 。多个值的配置方法请参考前文对 param_value 配置描述。 | 取值范围:无。 默认配置:无。 | 可选 |
input_type_rt/input_type_train补充说明
RDK X5的计算平台架构,在设计时为了提升性能,做了两点假设:
-
假设输入的数据都是int8的量化数据。
-
摄像头获取到的数据是nv12。
因此,如果您在模型训练时使用rgb(NCHW)输入格式,但是想使这个模型能够高效处理nv12数据,只需要在模型转换时做如下配置:
input_parameters:
input_type_rt: 'nv12'
input_type_train: 'rgb'
input_layout_train: 'NCHW'
小技巧:
-
若您在训练模型时使用gray格式,而实际使用中输入的数据格式为nv12格式,则可以将模型转换时的
input_type_rt
及input_type_train
均配置为gray
,在嵌入式应用开发时仅使用nv12的y通道地址作为输入即可。 -
校准参数组
参数名称 | 参数配置说明 | 取值范围说明 | 可选/必选 |
---|---|---|---|
cal_data_dir | 参数作用:指定模型校准使用的标定样本的存放目录。 参数说明:目录内校准数据需要符合输入配置的要求。具体请参考 准备校准数据 部分的介绍。配置多个输入节点时, 设置的节点顺序需要与 input_name 里的顺序严格保持一致。多 个值的配置方法请参考前文对 param_value 配置描述。当calibration_type为 load , skip 时,cal_data_dir不用填。注意: 为了方便您的使用,如果未发现cal_data_type的配置,我们将根据文件夹 后缀对数据类型进行配置。如果文件夹后缀以 _f32 结尾,则认为数据 类型是float32,否则认为数据类型是uint8。当然,我们强烈建议您通过cal_data_type参数对数据类型进行约束。 | 取值范围:无。 默认配置:无。 | 可选 |
cal_data_type | 参数作用:指定校准数据二进制文件的数据存储类型。 参数说明:指定模型校准时使用的二进制文件的数据存储类型。没有指定值的情况下将会使用文件夹名字后缀来做判断。 | 取值范围:float32 、uint8 。默认配置:无。 | 可选 |
preprocess_on | 参数作用:开启图片校准样本自动处理。 参数说明:该选项仅适用于4维图像输入的模型, 非4维模型不要打开该选项。在启动该功能时,cal_data_dir 目录下存放的都是jpg/bmp/png 等图片数据,工具会使用skimage读取图片, 并resize到输入节点需要的尺寸。为了保证校准的效果,建议您保持该参数关闭。使用的影响请参考 准备校准数据 部分的介绍。 | 取值范围:True 、 False 。默认配置: False 。 | 可选 |
calibration_type | 参数作用:校准使用的算法类型。 参数说明:每 kl 和 max 都是公开的校准量化算法, 其基本原理可以通过网络资料查阅。使用 load 方式校准时, qat模型必须是通过plugin导出的的模型。mix 是一个集成多种校准方法的搜索策略,能够自动确定量化敏感节点,并在节点粒度上从不同的校准方法中挑选出最佳方法,最终构建一个融合了多种校准方法优势的组合校准方式。default 是一个自动搜索的策略, 会尝试从系列校准量化参数中获得一个相对效果较好的组合。建议您先尝试 default , 如果最终的精度结果不满足预期, 再根据 精度调优 部分建议配置不同的校准参数。若您只想尝试对模型性能进行验证,但对精度没有要求, 则可以尝试 “skip” 方式进行校准。该方式会使用随机数进行校准, 不需要您准备校准数据,比较适合初次尝试对模型结构进行验证。注意: 使用skip方式时,因使用随机数校准, 得到的模型不可用于精度验证。 | 取值范围:default 、mix`、```kl 、max 、load 和 skip 。默认配置: default 。 | 必选 |
max_percentile | 参数作用:该参数为 max 校准方法的参数,用以调整 max 校准的截取点。参数说明:此参数仅在 calibration_type 为 max 时有效。常用配置选项有:0.99999/0.99995/0.99990/0.99950/0.99900。建议您先尝试 calibration_type 配置 default , 如果最终的精度结果不满足预期, 再根据 精度调优 部分建议调整该参数。 | 取值范围:0.0 ~1.0 。默认配置: 1.0 。 | 可选 |
per_channel | 参数作用:控制是否针对featuremap的每个channel进行校准。 参数说明: calibration_type 设置非default时有效。建议您先尝试 default , 如果最终的精度结果不满足预期, 再根据 精度调优 部分建议调整该参数。 | 取值范围:True 、 False 。默认配置: False 。 | 可选 |
run_on_cpu | 参数作用:强制指定算子在CPU上运行。 参数说明:CPU上虽然性能不及BPU,但是提供的是float精度计算。如果您确定某些算子需要在CPU上计算, 可以通过该参数指定。 设置值为模型中的具体节点名称,多个值的配置方法请参考前文对 param_value 配置描述。注意: RDK Ultra 和 RDK X5 中该参数相关功能已合并至 node_info 参数中,后续版本计划废弃。RDK X3 仍继续使用。 | 取值范围:无。 默认配置:无。 | 可选 |
run_on_bpu | 参数作用:强制指定OP在BPU上运行。 参数说明:为了保证最终量化模型的精度,少部分情况下, 转换工具会将一些具备BPU计算条件的算子放在CPU上运行。如果您对性能有较高的要求,愿意以更多一些量化损失为代价, 则可以通过该参数明确指定算子运行在BPU上。设置值为模型中的具体节点名称, 多个值的配置方法请参考前文对 param_value 配置描述。注意: RDK Ultra 和 RDK X5 中该参数相关功能已合并至 node_info 参数中,后续版本计划废弃。RDK X3 仍继续使用。 | 取值范围:无。 默认配置 |