6.3.2. PTQ原理步骤详解

6.3.2.1. 简介

模型转换原始浮点模型转换为X5混合异构模型过程。原始浮点模型(文中部分地方称为浮点模型)是通过TensorFlow/PyTorch等DL框架训练得到可用模型,这个模型计算精度为float32;混合异构模型一种适合在X5处理器运行模型格式。 本章节反复使用两种模型名词,为避免理解歧义,请理解这个概念阅读下文。

配合X5算法工具链模型完整开发过程,需要经过 浮点模型准备模型验证模型转换性能评估精度评估五个重要阶段,如下图:

model_conversion_flowchart

浮点模型准备阶段用来确保原始浮点模型格式为X5算法工具链模型转换工具支持格式,原始浮点模型来自通过TensorFlow/PyTorch等DL框架训练得到可用模型。具体浮点模型要求建议,请阅读浮点模型准备章节内容。

模型验证阶段用来校验原始浮点模型是否满足X5算法工具链要求。X5算法工具链提供 hb_mapper checker 检查工具完成浮点模型检查。具体使用方法,请阅读验证模型 章节内容。

模型转换阶段用来完成浮点模型到X5混合异构模型转换,经过这个阶段,您得到一个可以在X5处理器运行模型。X5算法工具链提供 hb_mapper makertbin 转换工具完成模型优化、量化编译关键步骤。具体使用方法,请阅读模型转换章节内容。

性能评估阶段主要用于测评X5混合异构模型推理性能情况,X5算法工具链提供模型性能评估工具,您可以使用这些工具验证模型性能是否达到应用要求。具体使用说明,请阅读 模型性能分析调优章节内容。

精度评估阶段主要用于测评X5混合异构模型推理精度情况,X5算法工具链提供模型精度评估工具。具体使用说明,请阅读模型精度分析调优章节内容。

6.3.2.2. 模型准备

基于公开DL框架训练得到浮点模型是X5算法工具链模型转换工具输入,目前转换工具支持的DL框架如下:

框架 Caffe PyTorch TensorFlow MXNet PaddlePaddle
X5算法工具链 支持 支持(转ONNX) 支持(转ONNX) 支持(转ONNX) 支持(转ONNX)

以上框架中, Caffe框架导出的caffemodel是直接支持的,PyTorch、TensorFlow和MXNet等DL框架通过转换到ONNX格式间接支持。

对于不同框架到ONNX的转换,目前对应标准化方案,参考如下:

技巧:

关于Pytorch、PaddlePaddle、TensorFlow2框架模型,我们提供如何导出ONNX及模型可视化教程,请参考:

注意:

  • 浮点模型使用算子需要符合X5算法工具链算子约束条件,具体阅读 模型算子支持列表 章节进行查询。

  • 支持 caffe 1.0 版本的caffe浮点模型ir_version≤7 , opset=10opset=11 版本的onnx浮点模型量化成X5支持定点模型, onnx模型的ir_version与onnx版本对应关系参考onnx官方文档

  • 模型输入维度支持 固定4维 输入NCHW或NHWC,例如:1x3x224x224或1x224x224x3, 不支持动态维度非4维输入;

  • 浮点模型不要包含后处理算子,例如:nms算子。

6.3.2.3. 模型验证

模型正式转换前,请使用 hb_mapper checker 工具进行模型验证,确保符合X5处理器支持约束。

技巧:

  • 建议参考使用X5算法工具链模型转换 horizon_model_convert_sample 示例包中的caffe、onnx等示例模型脚本方法: 01_check.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 用于指定需要适配的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 日志文件确认报错信息修改建议,错误信息可以模型量化错误解决方法 章节查找错误解决方法,若以上步骤不能排除问题,请联系技术支持团队官方技术社区提出问题,我们在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四列,分别节点名称、执行节点计算硬件、节点所属子图节点映射的X5算子名称。 如果模型网络结构出现了CPU计算算子,hb_mapper checker工具这个算子前后连续在BPU计算部分分为两个Subgraph(子图)。

检查结果调优指导

理想情况下,模型网络结构算子应该在BPU上运行,也就是只有一个子图。 如果出现了CPU算子导致拆分多个子图, hb_mapper checker 工具给出导致CPU算子出现具体原因,以下给出了 X5 上示例模型验证情况;

  • 以下X5运行的ONNX模型出现了Mul + Add + Mul的结构,从 X5算子约束列表我们可以看到,Mul和Add算子五维支持BPU运行的,但前提符合X5 BPU算子约束条件,不然回退到CPU计算。

model_reshape

因此模型最终检查结果出现分段情况,如下:

  ====================================================================================
  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
  Concat_252                              CPU  --        Concat

注意: 这里log结果仅用作示例,在使用过程中,请以您使用的版本实际打印的log情况为准。

根据 hb_mapper checker 给出提示,一般来说算子运行在BPU上更好性能表现,这里可以将pow、reshape 这类CPU算子模型移除,将对应算子功能放入后处理计算,从而减少子图数量。

当然,多个子图不会影响整个转换流程,但会较大程度影响模型性能,建议尽量调整模型算子到BPU上执行,可参考X5处理器算子支持列表的BPU算子支持列表功能算子替换或者模型的CPU算子模型推理前、后处理做CPU计算。

6.3.2.4. 模型转换

模型转换阶段完成浮点模型到X5混合异构模型转换,经过这个阶段,您得到一个可以在X5处理器运行模型。 在进行转换之前,请确保已经顺利通过上文验证模型过程。

模型转换使用 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)时数据预处理如下:

  1. 图像长宽比scale,短边放到256。

  2. center_crop 方法获取224x224大小图像。

  3. 通道减mean。

  4. 数据乘以scale系数。

针对上述举例模型样本处理代码如下:

避免过长代码篇幅,各种简单transformer实现代码未贴出,具体使用参考transformer使用方法 章节内容。

技巧:

  • 建议参考使用X5算法工具链模型转换 horizon_model_convert_sample 示例包中的caffe、onnx等示例模型预处理步骤方法: 02_preprocess.shpreprocess.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_image))
    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上(若使用 X5可以通过yaml文件中node_info参数指定在BPU上运行算子)。

  • 删除模型首尾不可删除的CPU算子,包括:Quantize/Dequantize、Transpose、Cast、Reshape等。

  • 性能最高的O3优化等级编译模型。

技巧:

  • 建议参考使用X5算法工具链模型转换 horizon_model_convert_sample 示例包中的caffe、onnx等示例模型脚本方法: 03_build.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}

注意:需要开启fast-perf模式,由于模式下,工具使用内置高性能配置,请勿--config 参数进行配置。

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的架构。使用 X5设置bayes-e

-i, --input-shape参数,指定模型输入节点的shape信息,目前配置开启fast-perf时生效。使用方式为:

  • 指定单个输入节点的shape信息,使用方式--input-shape input_1 1x3x224x224

  • 指定多个输入节点的shape信息,使用方式--input-shape input_1 1x3x224x224 --input-shape input_2 1x3x224x224

注意:未指定 --input-shape 参数,此时工具支持动态输入节点第一维为[-1, 0, ?]的模型,默认动态输入节点第一设置为1。

编译产生的log文件储存命令执行路径下面,名称hb_mapper_makertbin.log

注意:

  • X5 yaml配置文件,可直接使用X5 Caffe模型量化yaml文件模板X5 ONNX模型量化yaml文件模板模板文件进行填写。

  • 若 hb_mapper makertbin 步骤异常终止或者出现报错信息,则说明模型转换失败,请根据终端打印当前路径生成hb_mapper_makertbin.log 日志文件确认报错信息修改建议,若以上步骤不能排除问题,请联系技术支持团队官方技术社区提出问题,我们在24小时提供支持。

模型转换yaml配置参数说明

注意:

  • 要么是Caffe模型,要么是ONNX模型。即 caffe_model + prototxt 或者 onnx_model 二选一。 即,要么是Caffe模型,要么是ONNX模型。

# 模型参数组
model_parameters:
  # 原始Caffe浮点模型描述文件
  prototxt: '***.prototxt'

  # 原始Caffe浮点模型数据模型文件
  caffe_model: '****.caffemodel'

  # 原始Onnx浮点模型文件
  onnx_model: '****.onnx'

  # 转换的目标处理器架构,保持默认
  march: 'bayes-e'

  # 模型转换输出的用于上板执行的模型文件的名称前缀
  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-e,即进行X5模型转换时,如优化等级optimize_level配置为O3,hb_mapper makertbin默认提供缓存能力。即第一次使用hb_mapper makertbin对模型进行编译时,会自动创建缓存文件,后续的working_dir不变情况下,在重复编译时会自动调用文件,降低编译时间。

注意:

  • 注意,如果设置 input_type_rtnv12yuv444 ,则模型输入尺寸不能出现 奇数

  • 模型转换成功后,若出现符合X5BPU算子约束条件的OP仍然运行在CPU上,其主要原因该OP属于被动量化OP,关于被动量化相关内容,请阅读 算法工具链主动量化被动量化逻辑 章节。

以下具体参数信息,参数比较多,我们依照上述参数次序介绍。

模型参数

参数名称 参数配置说明 取值范围说明 选/必选
prototxt 参数作用:指定Caffe浮点模型的prototxt文件名称。

参数说明:在 hb_mapper makertbinmodel-typecaffe必须配置。
取值范围:无。

默认配置:无。
caffe_model 参数作用:指定Caffe浮点模型的caffemodel文件名称。

参数说明:在 hb_mapper makertbinmodel-typecaffe必须配置。
取值范围:无。

默认配置:无。
onnx_model 参数作用:指定ONNX浮点模型的onnx文件名称。

参数说明:在 hb_mapper makertbinmodel-typeonnx必须配置。
取值范围:无。

默认配置:无。
march 参数作用:指定产出混合异构模型需要支持平台架构。

参数说明:配置X5的BPU微框架。
取值范围bayes-e

默认配置:无。
必选
output_model_file_prefix 参数作用:指定转换产出混合异构模型名称前缀。

参数说明:输出定点模型文件名称前缀。
取值范围:无。

默认配置:无。
必选
working_dir 参数作用:指定模型转换输出结果存放目录。

参数说明:若该目录存在, 则工具自动创建目录。
取值范围:无。

默认配置model_output
layer_out_dump 参数作用:指定混合异构模型是否保留输出中间层能力。

参数说明:输出中间层调试需要用到手段,常规状态不要开启。
取值范围TrueFalse

默认配置False
output_nodes 参数作用:指定模型输出节点。

参数说明:一般情况下,转换工具自动识别模型输出节点。此参数用于支持指定一些中间层次作为输出。设置值为模型具体节点名称,多个配置方法参考param_value 配置描述。需要注意是,一旦设置此参数后,工具不再自动识别输出节点,您通过此参数指定节点就是全部输出。
取值范围:无。

默认配置:无。
remove_node_type 参数作用:设置删除节点类型。

参数说明:该参数隐藏参数,不设置设置为空影响模型转换过程。此参数用于支持设置删除节点类型信息。被删除节点必须模型开头或者末尾, 与模型输入输出连接。注意:待删除节点顺序依次删除,并动态更新模型结构;同时节点删除判断节点是否位于模型输入输出处。因此节点删除顺序重要。
取值范围:”Quantize”, “Transpose”, “Dequantize”, “Cast”, “Reshape”。不同类型用”;”分割。

默认配置:无。
remove_node_name 参数作用:设置删除节点名称。

参数说明:该参数隐藏参数, 不设置设置为空影响模型转换过程。 此参数用于支持设置删除节点名称。被删除节点必须模型开头或者末尾, 与模型输入输出连接。注意:待删除节点顺序依次删除,并动态更新模型结构;同时节点删除判断节点是否位于模型输入输出处。因此节点删除顺序重要。
取值范围:无。不同类型用";"分割。

默认配置:无。
set_node_data_type 参数作用:配置指定op的输出数据类型为int16,此参数 支持X5配置!

参数说明:在模型转换过程中,大多数op的默认输入输出数据类型为int8,通过参数可以指定特定op的输出数据类型为int16(在满足一定约束条件下)。int16相关说明详见:int16配置说明部分描述。

注意:参数相关功能合并node_info 参数中。
取值范围:支持配置int16的算子范围参考模型算子支持列表中X5算子支持约束列表。

默认配置:无。
debug_mode 参数作用:保存用于精度debug分析校准数据。

参数说明:该参数作用保存用于精度debug分析校准数据,数据格式为.npy。该数据通过np.load()可直接送入模型进行推理。若设置此参数,您自行保存数据使用精度debug工具进行精度分析。
取值范围"dump_calibration_data"

默认配置:无。
node_info 参数作用:支持配置指定OP的输入输出数据类型为int16以及强制指定算子在CPU或BPU上运行。此参数 支持X5配置!

参数说明:基于减少yaml中参数原则,我们set_node_data_typerun_on_cpurun_on_bpu 三个参数能力融合参数中,并此基础扩充支持配置指定op输入数据类型为int16的能力。

node_info 参数使用方式:

- 仅指定OP运行在BPU/CPU上(下以BPU为例,CPU方法一致):

node_info: {

"node_name":

{ 'ON': 'BPU',

}

}

- 仅配置节点数据类型:

node_info: 'node_name1:int16;node_name2:int16'

多个配置方法参考 param_value配置 <param_value>

- 指定OP运行在BPU上,同时配置OP的输入输出数据类型:

node_info: {

"node_name": {

'ON': 'BPU',

'InputType': 'int16',

'OutputType': 'int16'

}

}

'InputType': 'int16'代表指定算子所有输入数据类型为int16。

如需指定算子特定输入的InputType,可在InputType后通过指定数字进行配置。如:

'InputType0': 'int16'代表指定算子第一个输入数据类型为int16,

'InputType1': 'int16'代表指定算子第二个输入数据类型为int16,以此类推。

注意: 'OutputType' 不支持指定算子特定输出的OutputType,配置算子所有输出生效,不支持配置 'OutputType0' 、 'OutputType1'等。
取值范围:支持配置int16的算子范围参考模型算子支持列表中X5算子支持约束列表。可指定在CPU或BPU运行算子需为模型包含算子。

默认配置:无。

输入信息参数

参数名称 参数配置说明 取值范围说明 选/必选
input_name 参数作用:指定原始浮点模型输入节点名称。

参数说明:浮点模型只有一个输入节点情况需要配置。多于一个输入节点必须配置保证后续类型校准数据输入顺序准确性。多个配置方法参考对param_value配置描述。
取值范围:无。

默认配置:无。
input_type_train 参数作用:指定原始浮点模型输入数据类型。

参数说明:每一个输入节点需要配置一个确定输入数据类型。存在多个输入节点时,设置节点顺序需要input_name顺序严格保持一致。多个配置方法参考param_value配置描述。数据类型选择参考: 转换内部过程解读 部分介绍。
取值范围rgbbgryuv444grayfeaturemap

默认配置:无。
必选
input_layout_train 参数作用:指定原始浮点模型输入数据排布。

参数说明:每一个输入节点需要配置一个确定输入数据排布, 这个排布必须原始浮点模型采用数据排布相同。存在多个输入节点时, 设置节点顺序需要input_name顺序严格保持一致。多个配置方法参考param_value配置描述。什么数据排布参考: 转换内部过程解读 部分介绍。
取值范围:NHWC 、 NCHW。

默认配置:无。
必选
input_type_rt 参数作用:转换混合异构模型需要适配输入数据格式。

参数说明:这里指明需要使用数据格式, 不要求原始模型数据格式一致, 但是需要注意平台喂给模型数据使用这个格式。每一个输入节点需要配置一个确定输入数据类型,存在多个输入节点时, 设置节点顺序需要input_name顺序严格保持一致。多个配置方法参考param_value配置描述。数据类型选择参考: 转换内部过程解读 部分介绍。
取值范围rgbbgryuv444nv12grayfeaturemap

默认配置:无。
必选
input_layout_rt 参数作用:转换混合异构模型需要适配输入数据排布。

参数说明:每一个输入节点需要配置一个确定输入数据排布, 这个输入希望混合异构模型指定排布。不合适输入数据排布设置将会影响性能,若input_type_rt配置为nv12,则此处参数需要配置。存在多个输入节点时,设置节点顺序需要input_name顺序严格保持一致。多个配置方法参考param_value配置描述。什么数据排布参考: 转换内部过程解读 部分介绍。
取值范围NCHWNHWC

默认配置:无。
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的时候可以使用,模型输入时,需要所有输入input_shape 第一维均为1。此参数原始onnx模型本身支持多batch推理才能生效。

此参数原始onnx模型本身支持多batch推理才能生效。但是由于算子情况复杂,若模型转换过程中,遇到提示模型支持配置input_batch参数转换失败log,请尝试直接导出一个多batch的onnx模型正确配置校准数据大小重新进行转换(此时不再需要配置此参数)。
取值范围1-4096

默认配置1
norm_type 参数作用:在模型添加输入数据预处理方法。

参数说明no_preprocess 表示添加任何数据预处理;data_mean 表示提供均值预处理;data_scale 表示提供乘scale系数预处理;data_mean_and_scale 表示提供先减均值乘scale系数处理。输入节点多于一个时,设置节点顺序需要input_name顺序严格保持一致。多个配置方法参考param_value配置描述。配置参数影响参考: 转换内部过程解读 部分介绍。
取值范围data_mean_and_scaledata_meandata_scaleno_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_scaledata_scale需要配置参数。对于一个输入节点而言,存在两种配置方式。第一种配置一个数值,表示所有通道乘以这个系数;第二种提供通道数量一致数值(这些数值空格隔开), 表示每个通道乘以不同系数。配置输入节点数量必须norm_type 配置节点数量一致, 如果存在某个节点需要 scale 处理,则节点配置 'None'。多个配置方法参考param_value 配置描述。
取值范围:无。

默认配置:无。

input_type_rt/input_type_train补充说明

X5的计算平台架构,在设计为了提升性能,做两点假设:

  1. 假设输入数据是int8的量化数据。

  2. 摄像头获取数据是nv12。

因此,如果模型训练使用rgb(NCHW)输入格式,但是使这个模型能够高效处理nv12数据,只需要模型转换如下配置:

  input_parameters:
      input_type_rt: 'nv12'
      input_type_train: 'rgb'
      input_layout_train: 'NCHW'

技巧:

  • 训练模型使用gray格式,而实际使用输入数据格式为nv12格式,则可以模型转换input_type_rtinput_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参数数据类型进行约束。
取值范围:无。

默认配置:无。
calibration_type非 load、skip时必选
cal_data_type 参数作用:指定校准数据二进制文件数据存储类型。

参数说明:指定模型校准使用二进制文件数据存储类型。没有指定情况使用文件夹名字后缀判断。
取值范围float32uint8int32int16int8

默认配置:无。
preprocess_on 参数作用:开启图片校准样本自动处理。

参数说明:该选项适用于4维图像输入模型, 非4维模型不要打开选项。在启动功能时,cal_data_dir 目录存放是jpg/bmp/png 等图片数据,工具使用skimage读取图片, 并resize到输入节点需要尺寸。为了保证校准效果,建议您保持参数关闭。使用影响参考 准备校准数据 部分介绍。
取值范围TrueFalse

默认配置False
calibration_type 参数作用:校准使用算法类型。

参数说明:每 klmax公开校准量化算法, 其基本原理可以通过网络资料查阅。使用 load 方式校准时, qat模型必须通过plugin导出模型。mix一个集成多种校准方法搜索策略,能够自动确定量化敏感节点,并节点粒度不同校准方法挑选出最佳方法,最终构建一个融合多种校准方法优势组合校准方式。default一个自动搜索策略, 会尝试系列校准量化参数获得一个相对效果组合。建议您尝试 default, 如果最终精度结果满足预期, 再根据 精度调优 部分建议配置不同校准参数。若尝试对模型性能进行验证,但精度没有要求, 则可以尝试 “skip” 方式进行校准。该方式使用随机数进行校准, 不需要准备校准数据,比较适合初次尝试对模型结构进行验证。注意: 使用skip方式时,因使用随机数校准, 得到模型不可用于精度验证。
取值范围defaultmix`、```klmaxloadskip

默认配置default
必选
max_percentile 参数作用:该参数max 校准方法参数,用以调整 max 校准截取点。

参数说明:此参数calibration_typemax有效。常用配置选项有:0.99999/0.99995/0.99990/0.99950/0.99900。建议您尝试 calibration_type 配置 default, 如果最终精度结果满足预期, 再根据 精度调优 部分建议调整参数。
取值范围0.5~1.0

默认配置1.0
per_channel 参数作用:控制是否针对featuremap的每个channel进行校准。

参数说明calibration_type 设置非default时有效。建议您尝试 default, 如果最终精度结果满足预期, 再根据 精度调优 部分建议调整参数。
取值范围TrueFalse

默认配置False
run_on_cpu 参数作用:强制指定算子在CPU上运行。

参数说明:CPU上虽然性能不及BPU,但是提供是float精度计算。如果确定某些算子需要在CPU上计算, 可以通过参数指定。 设置值为模型具体节点名称,多个配置方法参考param_value 配置描述。

注意: X5 中该参数相关功能合并node_info 参数中。
取值范围:无。

默认配置:无。
run_on_bpu 参数作用:强制指定OP在BPU上运行。

参数说明:为了保证最终量化模型精度,少部分情况下, 转换工具一些具备BPU计算条件算子放在CPU上运行。如果性能要求,愿意多一些量化损失代价, 则可以通过参数明确指定算子运行在BPU上。设置值为模型具体节点名称, 多个配置方法参考param_value 配置描述。

注意: X5 中该参数相关功能合并node_info 参数中。
取值范围:无。

默认配置:无。
optimization 参数作用:使模型以 int8/int16 格式输出。

参数说明

- 指定值为set_model_output_int8时,设置模型为 int8 格式精度输出;

- 指定值为set_model_output_int16时,设置模型为 int16 格式精度输出;

- 指定值为set_{NodeKind}_input_int16时,会模型类算子输入量化成int16,如出现节点上下文支持int16的情况,则回退int8计算并打印log;

- 指定值为set_{NodeKind}_output_int16时,会模型类算子输出量化成int16,如出现节点上下文支持int16的情况,则回退int8计算并打印log;

- 指定值为set_Softmax_input_int8/set_Softmax_output_int8时,由于当前softmax默认为float计算量化节点,这两个指定值会将softmax算子量化成int8并在BPU上计算,二者没有使用区别;

- 指定值为asymmetric时,会尝试开启非对称量化,在某些模型可以提升量化精度,在calibration_type配置为default时, 参数算法自动选择,此时无法显性配置

- 指定值为bias_correction时,使用BiasCorrection量化方法,在部分模型可以提升量化精度;

- 指定值为lstm_batch_last时,针对X5 BPU,对于LSTM的batch-input size较大时,可以将batch维度转换到W维度进行计算(保障等价性),更贴合硬件计算逻辑,一些场景可以实现对X5 BPU推理性能加速效果;由于模型部署推理性能多种层次优化有关, 因此方法无法保证一定可以实现性能加速效果。

取值范围set_model_output_int8set_model_output_int16set_{NodeKind}_input_int16set_{NodeKind}_output_int16set_Softmax_input_int8set_Softmax_output_int8asymmetricbias_correctionlstm_batch_last 注意:此处 Nodekind标准ONNX算子类型写法如Conv,Mul,Sigmoid等(区分大小写)具体参考onnx官方op文档模型算子支持列表

默认配置:无。

preprocess_on补充说明

  • 如果指定配置参数 preprocess_on=True

    工具通过设置 preprocess_onTrue自动完成校准图片处理。 该模式cal_data_dir指定校准JPEG图片存放路径。 则模型校准时,工具内部通过skimage方式读入的JPEG图片,通过skimage resize的方式缩放图片配置文件指定input_shape, 并图像格式调整input_type_rt 指定格式。

    一个例子,假如输入的JPEG图像尺寸为608x608,则通过默认预处理后,图像缩放为224x224, 图像内存格式调整为bgr(NCHW)的格式,像素调整为0-255范围。

    默认预处理,请参考如下代码:

    
        def data_transformer(norm_type, input_dim, input_type_train):
            image_width = input_dim[2]
            image_height = input_dim[1]
            transformers = [
                ResizeTransformer((image_height, image_width)),
                HWC2CHWTransformer(),  # to CXHXW
                RGB2BGRTransformer(),
            ]
    
            transformers.append(ScaleTransformer(255))
    
  • 如果指定配置参数 preprocess_on=False

    需要自行处理图片,将图片处理input_type_train 指定格式,并且数据二进制形式保存文件。 工具内部自动增加input_type_traininput_type_rt格式转换。

备注: 文件格式为:Row-major order 的uint8/float32数据存储。

编译参数

参数名称 参数配置说明 取值范围说明 选/必选
compile_mode 参数作用:编译策略选择。

参数说明latency优化推理时间目标; bandwidth优化ddr的访问带宽目标。如果模型没有严重超过预期带宽占用,建议您使用 latency 策略。balance 平衡优化目标latency和bandwidth,设置此项指定balance_factor。
取值范围latencybandwidth'balance'

默认配置latency
必选
balance_factor 参数作用:当compile_mode被指定为balance时,用于指定balance比率。

参数说明:该参数在compile_mode被指定为balance时配套使用,其余模式配置生效。- 配置为0即带宽最优,对应compile_mode为bandwidth的编译策略。 - 配置为100即性能最优,对应compile_mode为latency的编译策略。
取值范围0-100

默认配置:无。
compile_mode 为balance 时必选
debug 参数作用:是否打开编译的debug信息。

参数说明:开启参数场景下,模型静态分析性能结果保存模型中,您可以模型成功转换生成静态性能评估文件html页和hb_perf时产生的html页内,在Layer Details选项卡查看模型逐层BPU算子性能信息(包括计算量、计算耗时数据搬运耗时)。 默认情况下,建议您保持参数关闭。
取值范围TrueFalse

默认配置False
core_num 参数作用:模型运行核心数。

参数说明:X5平台支持利用多个AI加速器核心同时完成一个推理任务, 多核心适用输入尺寸较大情况, 理想状态双核速度可以达到单核的1.5倍左右。如果模型输入尺寸较大,对于模型速度极致追求, 可以配置 core_num=2

注意: X5选项支持配置为1!
取值范围12

默认配置1
optimize_level 参数作用:模型编译优化等级选择。

参数说明:优化等级范围O0 ~ O3O0任何优化, 编译速度最快,优化程度最低。O1 - O3 随着优化等级提高, 预期编译模型执行速度快, 但是编译时间长。正常用于生成验证性能模型, 必须使用 O3 级别优化才能保证得到最优性能。某些流程验证精度调试过程中, 可以尝试使用级别优化加快过程速度。
取值范围O0O1O2O3

默认配置:无。
必选
input_source 参数作用:设置上板bin模型输入数据来源。

参数说明:这个参数适配工程环境选项, 建议您已经全部完成模型验证配置。ddr 表示数据来自内存,pyramidresizer 表示来自处理器固定硬件。注意:如果设置为resizer,模型的 h*w 要小于18432。具体工程环境如何适配 pyramidresizer 数据源, 此参数配置有点特殊,例如模型输入名称为 data, 数据源内存(ddr), 则此处应该配置值为 {"data": "ddr"}
取值范围ddr, pyramid, resizer

默认配置:无,默认根据input_type_rt的范围自动选择。
max_time_per_fc 参数作用:指定模型每个function-call的最大连续执行时间(单位us)。

参数说明:编译数据指令模型在BPU上进行推理计算时, 它表现为1个或者多个function-call(BPU的执行粒度)的调用,取值为0代表限制。该参数用来限制每个function-call最大执行时间, 模型只有单个function-call执行完时机会抢占。详情参见 模型优先级控制 部分介绍。- 此参数用于实现模型抢占功能,如无需实现功能可以忽略。

- 模型抢占功能支持开发板实现,不支持PC端模拟器实现。
取值范围0或1000-4294967295

默认配置0
jobs 参数作用:设置编译bin模型进程数。

参数说明:在编译bin模型时,用于设置进程数。 一定程度提高编译速度。
取值范围机器支持的最大核心数范围内。

默认配置:无。
advice 参数作用:用于提示模型编译预估耗时增加情况,单位微秒。

参数说明:模型编译过程中,工具链内部进行耗时分析。而实际过程中,如算子数据对齐操作时会导致耗时有所增加,设置参数后,当某个OP的实际计算耗时理论计算耗时偏差大于指定值时,会打印相关log,包括耗时变化信息、数据对齐前后的shape以及padding比例信息。
取值范围:自然数。

默认配置:无。不设置设置为0则表示开启。

自定义算子参数

参数名称 参数配置说明 取值范围说明 选/必选
custom_op_method 参数作用:自定义算子策略选择。

参数说明:目前支持register策略。
取值范围register

默认配置:无。
op_register_files 参数作用:自定义算子的Python实现文件名称。

参数说明:多个文件可用 ; 分隔
取值范围:无。

默认配置: 无。
custom_op_dir 参数作用:自定义算子的Python实现文件存放路径。

参数说明:设置路径时,请使用相对路径。
取值范围:无 。

默认配置:无。

X5 int16配置说明

模型转换过程中,模型大部分算子量化到int8进行计算,而通过配置 node_info 参数, 可以详细指定某个op的输入/输出数据类型为int16计算(具体支持算子范围参考模型算子支持列表章节的X5算子支持列表内容。 基本原理如下:

配置某个op输入/输出数据类型为int16后,模型转换内部自动进行op输入输出上下文(context)int16配置更新检查。 例如,当配置op_1输入/输出数据类型为int16时,实际上潜在同时指定了op_1的上/下一个op需要支持以int16计算。 对于支持场景,模型转换工具打印log提示该int16配置组合暂时支持回退到int8计算。

预处理HzPreprocess算子说明

预处理HzPreprocess算子是X5算法工具链模型转换工具模型转换过程根据yaml配置文件生成一个模型输入节点预处理算子节点,用来模型输入数据归一化操作,本主要介绍 norm_typemean_valuescale_value 参数变量模型预处理 HzPreprocess 算子节点生成说明。

norm_type参数说明

  • 参数作用:此参数模型添加输入数据预处理方法。

  • 参数取值范围说明:

    • no_preprocess 表示添加任何数据预处理。

    • data_mean 表示提供均值预处理。

    • data_scale 表示提供乘scale系数预处理。

    • data_mean_and_scale 表示提供先减均值乘scale系数处理。

注意:输入节点大于一个时,设置节点顺序需要input_name顺序严格保持一致。

mean_value参数说明

  • 参数作用:此参数表示指定预处理方法图像减去均值。

  • 使用说明:当 norm_type 取值data_mean_and_scaledata_mean需要配置参数。

  • 参数说明:

    • 只有一个输入节点时,仅需要配置一个数值,表示所有通道减去这个均值。

    • 当有多个节点时,提供通道数量一致数值(这些数值空格隔开),表示每个通道减去不同均值。

注意:

    1. 配置输入节点数量必须norm_type 配置节点数量一致。

    1. 如果存在某个节点需要 mean 处理,则节点配置 'None'

scale_value参数说明

  • 参数作用:此参数表示指定预处理方法数值scale系数。

  • 使用说明:当 norm_type 取值data_mean_and_scaledata_scale需要配置参数。

  • 参数说明:

    • 只有一个输入节点时,仅需要配置一个数值,表示所有通道乘以这个系数。

    • 当有多个节点时,提供通道数量一致数值(这些数值空格隔开),表示每个通道乘以不同系数。

注意:

    1. 配置输入节点数量必须norm_type 配置节点数量一致。

    1. 如果存在某个节点需要 scale 处理,则节点配置 'None'

计算公式示例说明

  • 模型训练数据标准化处理计算公式

yaml文件的mean和scale参数训练的mean、std需要进行换算。

预处理节点数据标准化操作计算方式(即HzPreprocess节点计算公式)为norm\_data = ( data mean ) * scale

以yolov3为例,其训练预处理代码为:

def base_transform(image, size, mean, std):
    x = cv2.resize(image, (size, size).astype(np.float32))
    x /= 255
    x -= mean
    x /= std
    return x

class BaseTransform:
    def __init__(self, size, mean=(0.406, 0.456, 0.485), std=(0.225, 0.224, 0.229)):
        self.size = size
        self.mean = np.array(mean, dtype=np.float32)
        self.std = np.array(std, dtype=np.float32)

计算公式为:\(norm_data= (\frac{data}{255} −𝑚𝑒𝑎𝑛) * \frac{1}{𝑠𝑡𝑑}\),

改写为HzPreprocess节点计算方式:\(norm_data= (\frac{data}{255} −𝑚𝑒𝑎𝑛) * \frac{1}{𝑠𝑡𝑑} =(data−255𝑚𝑒𝑎𝑛) * \frac{1}{255𝑠𝑡𝑑}\) ,

则:\(mean_yaml = 255 mean、𝑠𝑐𝑎𝑙𝑒_𝑦𝑎𝑚𝑙= \frac{1}{255 𝑠𝑡𝑑}\)。

  • 模型推理计算公式

通过对yaml配置文件配置参数,决定是否加入HzPreprocess节点。 当配置mean/scale时,做模型转换时,会输入新增一个HzPreprocess节点,HzPreprocess节点可以理解输入数据一个conv操作。

HzPreprocess内计算公式为:((input(取值范围[-128,127])+ 128) - mean) * scale,其中 weight=scalebias=(128-mean) * scale

注意:

  • 在yaml中添加mean/scale后,就需要处理添加MeanTransformer和ScaleTransformer。

  • 在yaml中添加mean/scale,会参数放入到HzPreprocess节点内,HzPreprocess节点为 BPU 节点。

[参考]支持校准方法

目前我们支持以下校准方法:

  • 1.default

default一个自动搜索策略,会尝试系列校准量化参数获得一个相对效果组合。

  • 2.mix

mix一个集成多种校准方法搜索策略,能够自动确定量化敏感节点,并节点粒度不同校准方法挑选出最佳方法, 最终构建一个融合多种校准方法优势组合校准方式。

  • 3.KL

KL 校准方法借鉴TensorRT提出解决方案, 使用KL熵值来遍历每个量化数据分布,通过寻找最低的KL熵值,来确定阈值。 这种方法导致数据饱和数据量化粒度,在一些数据分布比较集中模型拥有比max校准方法更好效果。

  • 4.max

max 校准方法校准过程中,自动选择量化层中最大值作为阈值。 这种方法导致数据量化粒度较大,但带来比KL方法饱和点数量,适用那些数据分布比较离散神经网络模型。

  • 5.load

使用 QAT 导出模型时,需使用此参数。

  • 6.skip

尝试对模型性能进行验证,但精度没有要求,则可以尝试 skip 方式进行校准。 该方式使用max+内部生成随机校准数据进行校准,不需要准备校准数据,比较适合初次尝试对模型结构进行验证。

注意: 需要注意是,使用 skip 方式时,因该方式使用max+内部生成随机校准数据进行校准,故得到模型不可用于精度验证。

转换内部过程解读

模型转换阶段完成浮点模型到X5混合异构模型转换。为了使得这个异构模型快速高效嵌入式运行,模型转换重点解决 输入数据处理模型优化编译 两个问题,本依次围绕两个重点问题展开。

输入数据处理 X5处理器会为某些特定类型模型输入通路提供硬件支撑方案。 例如:视频通路方面视频处理子系统,为图像采集提供图像裁剪、缩放其他图像质量优化功能,这些子系统输出是YUV420 NV12格式图像, 而算法模型往往基于bgr/rgb等一般常用图像格式训练得到的。

针对此种情况提供解决方案是:

  • 每个转换模型提供两种描述,一种用于描述原始浮点模型输入数据( input_type_traininput_layout_train ),另一种用于描述我们需要对接处理器输入数据( input_type_rtinput_layout_rt )。

  • 图像数据的mean/scale也比较常见操作,但YUV420 NV12等处理器支持数据格式适合这样操作,因此,我们这些常见图像处理固化模型中。

经过以上两种方式处理后,模型转换阶段产出***.bin 异构模型输入部分变成如下状态。

input_data_process

数据排布只有NCHW和NHWC两种数据排布格式,N代表数量、C代表channel、H代表高度、W代表宽度, 两种不同排布体现不同内存访问特性。在TensorFlow模型NHWC较常用,Caffe中使用NCHW, X5处理器不会限制使用数据排布,但是两条要求:第一input_layout_train 必须原始模型数据排布一致;第二处理器准备input_layout_rt 一致排布数据,正确数据排布顺利解析数据基础。

模型转换工具根据 input_type_rtinput_type_train 指定数据格式自动添加数据转换节点,根据以往实际使用经验, 并不是任意类型组合需要的,为了避免误用,我们开放一些固定类型组合,如下表:

input_type_train \ input_type_rt nv12 yuv444 rgb bgr gray featuremap
yuv444 Y Y N N N N
rgb Y Y Y Y N N
bgr Y Y Y Y N N
gray N N N N Y N
featuremap N N N N N Y

备注:

  • 表格第一行input_type_rt支持类型,第一列input_type_train 支持类型, 其中Y/N 表示是否支持相应input_type_rtinput_type_train转换。

  • 为了配合计算平台对于输入数据类型要求(int8),减小推理开销,对于 input_type_rt 类型为 rgb(NHWC/NCHW)/bgr(NHWC/NCHW) 的配置, 转换工具转换模型,其输入数据类型int8。 也就是说,对于常规图像数据,需要-128使用(该操作在API中自动进行,无需进行操作)。

  • 模型转换得到最终产出bin模型中, input_type_rtinput_type_train一个内部过程, 您需要关注 input_type_rt数据格式即可。

  • 正确理解每种 input_type_rt 要求,对于嵌入式应用准备推理数据重要,以下 input_type_rt 每种格式说明:

    • rgb、bgr和gray都比较常见图像格式,注意每个数值采用UINT8表示。

    • yuv444是一种常见图像格式,注意每个数值采用UINT8表示。

    • nv12是常见的yuv420图像格式,每个数值采用UINT8表示。

    • nv12有个比较特别情况input_space_and_range 设置 bt601_video (参考input_space_and_range 参数介绍),较于常规nv12情况,它数值范围由[0,255]变成了[16,235], 每个数值仍然采用UINT8表示。

    • featuremap输入模型数据格式type只要求数据四维的,每个数值采用float32表示。例如:雷达语音模型处理常用这个格式。

技巧:

  • 校准数据处理到input_type_train即可,同时注意 不要重复的norm操作

  • 以上 input_type_rtinput_type_train固化算法工具链处理流程中,如果非常确定需要转换, 可两个 input_type 设置相同配置,这样 input_type直通处理,不会影响模型实际执行性能。

  • 同样的,数据处理固化流程中,如果需要任何处理,通过 norm_type 配置关闭这个功能即可,不会影响模型实际执行性能。

模型优化编译 完成模型解析、模型优化、模型校准量化、模型编译几个重要阶段,其内部工作过程如下所示。

model_optimization

备注:

  • input_type_rt* 表示input_type_rt的中间格式。

  • 可视化工具Netron查看 quantized_model.onnx 输入节点数据排布,决定是否预处理增加 layout转换

模型解析阶段 对于Caffe浮点模型完成到ONNX浮点模型转换。 在原始浮点模型根据转换配置yaml文件配置参数决定是否加入数据预处理节点,此阶段产出一个original_float_model.onnx。 这个ONNX模型计算精度仍然是float32,但输入部分加入一个数据预处理节点。

理想状态下,这个预处理节点应该完成 input_type_rtinput_type_train完整转换, 实际情况整个type转换过程配合X5处理器硬件完成,ONNX模型里面没有包含硬件转换部分。 因此ONNX的真实输入类型使用一种中间类型,这种中间类型就是硬件input_type_rt处理结果类型, 数据layout(NCHW/NHWC)会保持原始浮点模型输入layout一致。 每种 input_type_rt特定对应中间类型,如下表:

nv12 yuv444 rgb bgr gray featuremap
yuv444_128 yuv444_128 RGB_128 BGR_128 GRAY_128 featuremap

备注:

表格第一行加粗部分input_type_rt 指定数据类型,第二行特定 input_type_rt 对应中间类型, 这个中间类型就是original_float_model.onnx的输入类型。每个类型解释如下:

  • yuv444_128 是yuv444数据减去128结果,每个数值采用int8表示。

  • RGB_128 是RGB数据减去128的结果,每个数值采用int8表示。

  • BGR_128 是BGR数据减去128的结果,每个数值采用int8表示。

  • GRAY_128 是gray数据减去128的结果,每个数值采用int8表示。

  • featuremap 是一个四维张量数据,每个数值采用float32表示。

模型优化阶段 实现模型一些适用于X5平台算子优化策略,例如BN融合到Conv等。 此阶段产出一个optimized_float_model.onnx,这个ONNX模型计算精度仍然是float32,经过优化不会影响模型计算结果。 模型输入数据要求还是前面的original_float_model一致。

模型校准阶段使用提供校准数据计算必要量化阈值参数,这些参数直接输入量化阶段,不会产生模型状态。

模型量化阶段 使用校准得到参数完成模型量化,此阶段产出一个quantized_model.onnx。 这个模型计算精度已经是int8,使用这个模型可以评估模型量化带来精度损失情况。 这个模型要求输入基本数据格式和layout仍然original_float_model 一样,不过layout和数值表示已经发生变化, 整体较于 original_float_model 输入变化情况描述如下:

  • input_type_rt取值featuremap 时,则输入数据类型使用INT8, 反之, 当 input_type_rt 取值featuremap 时,则输入数据类型为float32。

  • 数据排布layout关系为:input_layout_train以及origin.onnx、calibrated_model.onnx、quanti.onnx输入的layout与原模型输入的layout一致

注意: 如果input_type_rt为nv12时,对应quanti.onnx的输入layout都是NHWC。

模型编译阶段使用X5算法工具链模型编译器,将量化模型转换为X5平台支持计算指令和数据, 这个阶段产出一个 ***.bin 模型,这个bin模型就是在X5嵌入式平台运行模型,也就是模型转换最终产出结果。

转换结果解读

依次介绍模型转换成功状态解读、转换成功分析方法。 确认模型转换成功,需要makertbin 状态信息、相似信息working_dir 产出三个方面确认。 makertbin 状态信息方面,转换成功控制台输出信息尾部给出明确提示信息如下:

  2023-12-06 11:13:08,337 INFO Convert to runtime bin file successfully! 
  2023-12-06 11:13:08,337 INFO End Model Convert

相似信息存在makertbin控制台输出内容中,在 makertbin 状态信息之前,其内容形式如下:

  ======================================================================
  Node    ON   Subgraph  Type     Cosine Similarity  Threshold
  ...    ...     ...     ...       0.999936           127.000000
  ...    ...     ...     ...       0.999868           2.557209
  ...    ...     ...     ...       0.999268           2.133924
  ...    ...     ...     ...       0.996023           3.251645
  ...    ...     ...     ...       0.996656           4.495638

上面列举输出内容中:

  • Node、ON、Subgraph、Type与 hb_mapper checker 工具解读一致的,请参考检查结果解读

  • Threshold是每个层次校准阈值,用于异常状态下向技术支持反馈信息,正常状况需要关注;

  • Cosine Similarity一列反映是Node列中对应算子原始浮点模型量化模型输出结果余弦相似度。

技巧:

一般情况下, 模型输出节点 Cosine Similarity >= 0.99 可认为模型量化正常,输出节点相似低于0.8就明显精度损失, 当然Cosine Similarity只是指明量化数据稳定性一种参考方式,对于模型精度影响存在明显直接关联关系, 完全准确精度情况需要阅读模型精度分析调优内容。

转换产出存放转换配置参数 working_dir 指定路径中,成功完成模型转换后, 您可以目录得到以下文件(***部分通过转换配置参数 output_model_file_prefix 指定内容):

  • ***_original_float_model.onnx

  • ***_optimized_float_model.onnx

  • ***_calibrated_model.onnx

  • ***_quantized_model.onnx

  • ***.bin

转换产出解读介绍每个产出用途。

注意:上板运行前,我们建议您完成模型性能分析调优介绍模型性能&精度评测过程,避免模型转换问题延伸后续嵌入式端。

如果以上验证模型转换成功三个方面中,有任一个出现缺失说明模型转换出现错误。 一般情况下,makertbin 工具出现错误错误信息输出控制台, 例如:我们在Caffe模型转换配置yaml文件prototxtcaffe_model 参数,模型转换工具给出如下提示。

2021-04-21 14:45:34,085 ERROR Key 'model_parameters' error:
Missing keys: 'caffe_model', 'prototxt'
2021-04-21 14:45:34,085 ERROR yaml file parse failed. Please double check your input
2021-04-21 14:45:34,085 ERROR exception in command: makertbin

如果控制台输出日志信息不能帮助发现问题,请参考算法工具链类-常见故障处理章节内容进行查找,若以上步骤不能排除问题,请联系技术支持团队官方技术社区提出问题,我们在24小时提供支持。

转换产出解读

上文提到模型成功转换产出包括以下四个部分,本介绍每个产出用途:

  • ***_original_float_model.onnx

  • ***_optimized_float_model.onnx

  • ***_calibrated_model.onnx

  • ***_quantized_model.onnx

  • ***.bin

***_original_float_model.onnx的产出过程可以参考转换内部过程解读介绍, 这个模型计算精度转换输入原始浮点模型一模一样的,有个重要变化就是为了适配X5平台添加一些数据预处理计算(增加一个预处理算子节点 HzPreprocess, 可以使用netron工具打开onnx模型查看,此算子详情查看预处理HzPreprocess算子说明 内容)。 一般情况下,您需要使用这个模型,若转换结果出现异常时,通过上文介绍定位方法不能解决问题,请这个模型提供技术支持团队官方技术社区提出问题,将有助于帮助快速解决问题。

***_calibrated_model.onnx的产出过程可以参考转换内部过程解读介绍, 这个模型模型转换工具链浮点模型经过结构优化后,通过校准数据计算得到每个节点对应量化参数保存校准节点得到中间产物。

***_optimized_float_model.onnx的产出过程可以参考转换内部过程解读介绍, 这个模型经过一些算子级别优化操作,常见就是算子融合。 通过与original_float模型可视化对比,您可以明显看到一些算子结构级别变化,不过这些影响模型计算精度。 一般情况下,您需要使用这个模型,若转换结果出现异常时,通过上文介绍定位方法不能解决问题,请这个模型提供技术支持团队官方技术社区提出问题,将有助于帮助快速解决问题。

***_quantized_model.onnx的产出过程可以参考转换内部过程解读介绍, 这个模型已经完成校准量化过程,量化模型精度损失情况,可以阅读下文模型精度分析调优内容评估模型。 这个模型精度验证过程必须使用模型,具体使用方式参考模型精度分析调优介绍。

***.bin就是可以用于在X5处理器加载运行模型, 配合 上板运行(runtime)应用开发说明 章节介绍内容, 您可以模型快速在X5处理器部署运行。不过为了确保模型性能精度效果符合预期的, 我们建议完成模型转换模型精度分析调优 介绍性能精度分析过程进入应用开发部署。

注意:

通常模型转换阶段完成可以得到在X5处理器运行模型,但是为了确保您得到模型性能精度符合应用要求的,我们建议每次转换完成后续性能评估精度评估步骤。

模型转换过程生成onnx模型, 该模型中间产物, 只是便于用户验证模型精度情况, 因此保证版本兼容性。 若使用示例评测脚本对onnx模型进行单张图片评测测试集上评测时, 请当前版本工具重新生成的onnx模型进行操作。

6.3.2.5. 模型性能分析

介绍如何使用X5算法工具链提供工具评估模型性能,使用这些工具可以得到实际上执行基本一致性能效果,如果发现评估结果符合预期,建议您尽量根据X5算法工具链提供优化建议解决性能问题,不要模型性能问题延伸应用开发阶段。

开发评测性能

使用 hb_perf 工具评测模型性能,使用方式如下:

  hb_perf  ***.bin

备注: 如果分析pack模型,需要加上一个 -p 参数,命令hb_perf -p ***.bin。 关于模型 pack,请查看其他模型工具(可选)部分介绍。

命令的 ***.bin是模型转换步骤生成定点模型,命令执行完成后,在当前目录生成 hb_perf_result 文件夹,里边包含具体模型分析结果。 以下示例模型MobileNetv1的评测结果:

  hb_perf_result/
  └── mobilenetv1_224x224_nv12
      ├── MOBILENET_subgraph_0.html
      ├── MOBILENET_subgraph_0.json
      ├── mobilenetv1_224x224_nv12
      ├── mobilenetv1_224x224_nv12.html
      ├── mobilenetv1_224x224_nv12.png
      └── temp.hbm

通过浏览器打开 mobilenetv1_224x224_nv12.html页面,其内容如下图:

hb_mapper_perf_2

分析结果主要由Model Performance Summary、Details和BIN Model Structure三个部分组成。 Model Performance Summary是bin模型整体性能评估结果,其中各项指标为:

  • Model Name——模型名称。

  • Model Latency(ms)——模型整体单帧计算耗时(单位为ms)。

  • Total DDR (loaded+stored) bytes per frame(MB per frame)——模型整体BPU部分数据加载存储占用的DDR总量(单位为MB/frame)。

  • Loaded Bytes per Frame——模型运行每帧读取数据量。

  • Stored Bytes per Frame——模型运行每帧存储数据量。

BIN Model Structure部分提供是bin模型图级可视化结果,图中深青色节点表示运行在BPU上节点,灰色节点表示在CPU上计算节点。

查看Details和BIN Model Structure时,您需要了解子图(subgraph)的概念。 如果模型网络结构出现CPU计算算子,模型转换工具将CPU算子前后连续在BPU计算部分分为两个独立图(subgraph)。 具体可以参考 验证模型 部分介绍。

Details是每个模型BPU子图具体信息,在 mobilenetv1_224x224_nv12.html页面中,子图各项指标为:

  • Model Subgraph Name——子图名称。

  • Model Subgraph Calculation Load (OPpf)——子图单帧计算量。

  • Model Subgraph DDR Occupation(Mbpf)——子图单帧读写数据量(单位为MB)。

  • Model Subgraph Latency(ms)——子图单帧计算耗时(单位为ms)。

每个子图结果提供详细参考信息说明。

注意:

参考信息说明页面根据是否启用调试配置( debug ),从而有所区别, 下图的Layer Details仅在yaml配置文件设置 debug 参数True 时才可以拿到, 这个 debug 参数配置方法参考模型转换yaml配置参数说明部分介绍。

Layer Details提供具体算子级别分析,在模型调试分析阶段可以作为参考,例如:如果某些BPU算子导致模型性能低,通过分析结果帮助定位具体算子。

layer_details

其中,每指标解读如下:

  • layer:layer名。

  • ops:计算量。

  • original output shape:原始算子输出shape。

  • aligned output shape:对齐算子输出shape。

  • computing cost (no DDR):计算耗时。

  • load/store cost:数据搬运耗时。

  • active period of time:编译后layer活跃时间段(不代表该layer执行时间,通常多个layer交替/并行执行)。

注意: hb_perf 工具分析结果可以帮助了解bin模型结构,以及模型的BPU计算部分静态分析指标;需要特别注意分析结果中不含CPU部分计算评估,如果需要CPU计算性能情况,请开发板实测模型性能。

开发板实测性能

开发板快速评测模型性能,请使用 hrt_model_exec perf 工具, 可直接开发板评测模型推理性能、获取模型信息等。

使用 hrt_model_exec perf 工具前,请准备:

  1. 确保您已经参考系统更新章节完成开发板系统更新。

  2. 需要将Ubuntu开发机上得到的bin模型拷贝到开发板上(建议放在/userdata目录), 开发板一个Linux系统,可以通过 scp 等Linux系统常用方式完成这个拷贝过程。

hrt_model_exec perf 工具命令如下(注意开发板执行):

./hrt_model_exec perf --model_file mobilenetv1_224x224_nv12.bin \
                      --model_name="" \
                      --core_id=0 \
                      --frame_count=200 \
                      --perf_time=0 \
                      --thread_num=1 \
                      --profile_path="."

hrt_model_exec perf参数解析:

model_file:

需要分析性能的bin模型名称。

model_name:

需要分析性能的bin模型名字。若 model_file 只含一个模型,则可以省略。

core_id:

默认值 0,运行模型使用核心id。

frame_count:

默认值 200,设置推理数,工具执行指定次数分析平均耗时。 当 perf_time0生效。

perf_time:

默认值 0,单位分钟。设置推理时间,工具执行指定时间分析平均耗时。

thread_num:

默认值 1,设置运行线程数,取值范围 [1,8]。若分析极限率,请线程数改大。

profile_path:

默认关闭,统计工具日志产生路径。该参数引入分析结果存放指定目录的profiler.log和profiler.csv文件中。

下述示例在X5开发板测试结果,命令执行完成后,您控制台得到如下日志:

  Running condition:
    Thread number is: 4
    Frame count   is: 1000
    Program run time: 279.004000 ms
  Perf result:
    Frame totally latency is: 1084.040527 ms
    Average    latency    is: 1.084041 ms
    Frame      rate       is: 3584.178005 FPS

技巧: 评估结果Average latencyFrame rate,分别表示平均单帧推理延时模型极限率。 如果获得模型板子运行极限率,请尝试调节 thread_num数值,并调节最优线程数值,不同数值输出不同性能结果。

控制台得到信息只有整体情况,通过设置 profile_path 参数产生的node_profiler.log文件记录更加丰富模型性能信息:

{
    "perf_result": {
      "FPS": 3718.384436330103,
      "average_latency": 1.0366870164871216
    },
    "running_condition": {
      "core_id": 0,
      "frame_count": 1000,
      "model_name": "mobilenetv1_224x224_nv12",
      "run_time": 268.934,
      "thread_num": 4
    }
  }
  ***
  {
    "processor_latency": {
      "BPU_inference_time_cost": {
        "avg_time": 0.8493590000000001,
        "max_time": 1.328,
        "min_time": 0.766
      },
      "CPU_inference_time_cost": {
        "avg_time": 0.074976,
        "max_time": 0.382,
        "min_time": 0.066
      }
    },
    "model_latency": {
      "BPU_MOBILENET_subgraph_0": {
        "avg_time": 0.8493590000000001,
        "max_time": 1.328,
        "min_time": 0.766
      },
      "Dequantize_fc7_1_HzDequantize": {
        "avg_time": 0.029727,
        "max_time": 0.124,
        "min_time": 0.028
      },
      "MOBILENET_subgraph_0_output_layout_convert": {
        "avg_time": 0.011379,
        "max_time": 0.077,
        "min_time": 0.008
      },
      "Preprocess": {
        "avg_time": 0.005363000000000001,
        "max_time": 0.039,
        "min_time": 0.003
      },
      "Softmax_prob": {
        "avg_time": 0.028507,
        "max_time": 0.142,
        "min_time": 0.027
      }
    },
    "task_latency": {
      "TaskPendingTime": {
        "avg_time": 0.021235,
        "max_time": 0.336,
        "min_time": 0.002
      },
      "TaskRunningTime": {
        "avg_time": 0.983558,
        "max_time": 2.208,
        "min_time": 0.904
      }
    }
  }

上述日志内容对应使用hb_perf工具估计性能的BIN Model Structure部分介绍的bin可视化图中, 图中每个节点对应节点在profiler.log文件中,可以通过 name 对应起来,另外,profiler.log文件记录每个节点执行时间,对优化模型算子提供参考,由于模型的BPU节点输入输出特殊要求,如特殊的layout和padding对齐要求,因此需要对BPU节点输入、输出数据进行处理。

  • Preprocess:表示对模型输入数据进行padding和layout转换操作,其耗时统计在Preprocess中。

  • xxxx_input_layout_convert: 表示对BPU节点输入数据进行padding和layout转换操作,其耗时统计在xxxx_input_layout_convert中。

  • xxxx_output_layout_convert: 表示对BPU节点输出数据进行去掉padding和layout转换操作,其耗时统计在xxxx_output_layout_convert中。 profiler 分析模型性能调优中经常使用操作,前检查结果解读 部分提到检查阶段不用过于关注CPU算子,此阶段可以看到CPU算子具体耗时情况,可以根据对应算子耗时情况进行模型性能调优。

模型性能优化

通过以上性能分析结果,您可能发现模型性能结果不及预期,本章节内容介绍提升模型性能建议措施,包括检查yaml配置参数、处理CPU算子、高性能模型设计建议、使用X5平台友好结构&模型几个方面。

注意:章节部分修改建议可能影响原始浮点模型参数空间,因此需要重训模型,为了避免性能调优过程反复调整训练模型,建议您得到满意模型性能前,使用随机参数导出模型验证性能。

检查影响模型性能的yaml参数

模型转换的yaml配置文件中,部分参数实际影响模型最终性能,请检查是否正确按照模型预期配置, 各参数具体含义作用,请参考编译参数章节内容。

  • layer_out_dump:指定模型转换过程是否输出模型中间结果,一般用于调试功能。 如果配置True,则每个卷积算子增加一个量化输出节点,它会显著降低模型上板性能。 所以性能评测时,务必参数配置False

  • compile_mode:该参数用于选择模型编译优化方向带宽还是时延,关注性能时请配置latency

  • optimize_level:该参数用于选择编译器优化等级,实际使用中应配置O3 获取最佳性能。

  • debug:配置True打开编译器的debug模式,能够输出性能仿真相关信息,如帧率、DDR 带宽占用等。 一般用于性能评估阶段,在产品化交付时候,可关闭参数减小模型大小,提高模型执行效率。

  • max_time_per_fc:该参数用于控制编译模型数据指令的function-call的执行长,从而实现模型优先级抢占功能。 设置此参数更改抢占模型的function-call执行时长会影响模型上板性能。

处理CPU算子

根据 hrt_model_exec perf 工具评估,若可以确认模型性能瓶颈是CPU算子导致的,此种情况下,建议您查看模型算子支持列表内容,确认当前运行在CPU上算子是否具备BPU支持能力。

如果算子模型算子支持列表具备BPU支持能力,应该算子参数超过了BPU支持参数约束范围,建议您相应原始浮点模型计算参数调整约束范围内。 为了方便快速知晓超出约束具体参数,建议您使用 验证模型 部分介绍方法一遍检查,工具将会直接给出超出BPU支持范围参数提示。

备注: 修改原始浮点模型参数对模型计算精度影响需要自己控,例如:Convolution的 input_channeloutput_channel 超出范围就是一种典型情况,减少channel后,使该算子被BPU支持,但一处修改可能对模型精度产生影响。

如果算子具备BPU支持能力,就需要根据以下情况做出对应优化操作:

  • CPU 算子处于模型中部

    对于CPU 算子处于模型中部情况,建议您优先尝试参数调整、算子替换修改模型。

  • CPU算子处于模型尾部

    对于CPU算子处于模型尾部情况,请参考以下示例,下面量化/反量化节点为例:

    • 对于模型输入输出相连节点,可以在yaml文件model_parameters配置组(模型参数组)中增加 remove_node_type 参数,并重新编译模型。

        remove_node_type: "Quantize; Dequantize"
      

      使用hb_model_modifier 工具对bin模型进行修改:

        hb_model_modifier x.bin -a Quantize -a Dequantize
      
    • 对于下图这种没有输入输出节点相连模型,则需要使用hb_model_modifier工具判断相连节点是否支持删除按照顺序逐个进行删除。

      nodes_connected

      使用hb_perf工具获取模型结构图片,然后使用以下两条命令可以自上而下移除Quantize节点, 对于Dequantize节点自下而上逐个删除即可,每一步删除节点名称可以通过 hb_model_modifier x.bin 进行查看。

        hb_model_modifier x.bin -r res2a_branch1_NCHW2NHWC_LayoutConvert_Input0
        hb_model_modifier x_modified.bin -r data_res2a_branch1_HzQuantize
      

高性能模型设计建议

根据性能评估结果,CPU上耗时可能很小,那模型性能瓶颈就是BPU推理时间过长。 出现这种情况时,表明模型已经使用所有的BPU的计算器件,因此一步可以提升计算资源利用率进行性能优化。 因为每种处理器自己硬件特性,算法模型计算参数是否符合相应硬件特性,这些直接决定模型计算资源利用率,符合度越高则利用率越高,反之低。

内容重点介绍X5处理器硬件特性:我们提供旨在加速CNN(卷积神经网络)的处理器,主要计算资源集中处理各种卷积计算;建议您模型卷积计算为主模型,因为卷积之外算子导致计算资源利用率降低,不同OP的造成性能影响程度一样。 另外,建议您模型设计时,尽量模型BPU段输入输出维度降低,以减少量化、反量化节点耗时硬件带宽压力。 以典型分割模型为例,我们可以将Argmax算子直接合入模型本身,但需注意,只有满足以下条件,Argmax才支持BPU加速:

  1. Caffe中的Softmax层默认axis=1,而ArgMax层则默认axis=0,算子替换时要保持axis的一致

  2. Argmax的Channel需小于等于64,否则只能在CPU上计算

6.3.2.6. 模型精度分析

基于几十百张校准数据实现浮点模型定点模型转换的PTQ后量化方式,不可避免地会存在一定精度损失。 X5算法工具链的PTQ转换工具经过大量实际使用经验验证,在筛选最优量化参数组合时,大部分情况下,都可以模型精度损失保持1% 以内。

介绍如何正确进行模型精度分析,如果通过评估发现不及预期,则可以参考 精度调优 小节内容进行模型精度调优。

精度分析

提到模型成功转换产出包括以下几个部分:

  • ***_original_float_model.onnx

  • ***_optimized_float_model.onnx

  • ***_calibrated_model.onnx

  • ***_quantized_model.onnx

  • ***.bin

虽然最后的bin模型部署到X5处理器模型,但考虑方便在Ubuntu/CentOS开发机上快速得到模型精度,我们同时支持使用 ***_quantized_model.onnx 来完成模型精度测试; ***_quantized_model.onnxquantized模型和X5处理器运行的bin模型具有一致精度效果。

建议您使用X5开发加载ONNX模型完成推理,基本流程如下所示:

注意:

  1. 示例代码不仅适用于quantized模型,对original和optimized模型同样适用,可以根据不同模型输入类型和layout要求准备数据进行模型推理。

  2. 建议参考使用X5算法工具链模型转换 horizon_model_convert_sample 示例包中的caffe、onnx等示例模型精度验证方法: 04_inference.shpostprocess.py

import numpy as np
# 加载地瓜依赖库
from horizon_tc_ui import HB_ONNXRuntime

# 准备模型运行的输入
input_data = np.load("input.npy")
# 加载模型文件
sess = HB_ONNXRuntime(model_file = "***_quantized_model.onnx")
# 获取模型输入&输出节点信息
input_names = sess.input_names
output_names = sess.output_names
# 准备输入数据,这里我们假设此模型只有1个输入
input_info = {input_names[0]: input_data}
# 开始模型推理,推理的返回值是一个list,依次与output_names指定名称一一对应
output = sess.run(output_names, input_info)

此外, 输入数据准备过程容易出现误操作部分。相对设计&训练原始浮点模型精度验证过程,建议您数据预处理推理输入数据进行调整:主要数据格式(RGB、NV12等)、数据精度(int8、float32等)和数据排布(NCHW或NHWC)。 调整方法模型转换时yaml配置文件设置input_type_traininput_layout_traininput_type_rtinput_layout_rt 四个参数共同决定,其详细规则参考转换内部过程解读 章节介绍。

例如:使用ImageNet训练用于分类原始浮点模型,它只有一个输入节点。这个节点接受BGR顺序通道图片,输入数据排布为NCHW。 那么,在原始浮点模型设计&训练阶段,验证推理模型数据预处理如下:

  1. 图像长宽比scale,短边放到256。

  2. center_crop 方法获取224x224大小图像。

  3. 通道减mean。

  4. 数据乘以scale系数。

使用X5算法工具链转换这个原始浮点模型时, input_type_train 设置 bgrinput_layout_train 设置 NCHWinput_type_rt 设置 bgrinput_layout_rt 设置 NHWC。 根据转换内部过程解读 部分介绍规则, ***_quantized_model.onnx接受输入应该为bgr_128、NHWC排布。 对应示例代码, your_custom_data_prepare 部分提供数据处理过程如下:

  # 本示例使用skimage,如果是opencv会有所区别
  # 需要您特别注意的是,transformers中并没有体现减mean和乘scale的处理
  # mean和scale操作已经融合到了模型中,参考前文norm_type/mean_value/scale_value配置
def your_custom_data_prepare_sample(image_file):
    #skimage读取图片,已经是NHWC排布
    image = skimage.img_as_float(skimage.io.imread(image_file))
    # 长宽等比scale,短边缩放至256
    image = ShortSideResize(image, short_size=256)
    # CenterCrop获取224x224图像
    image = CenterCrop(image, crop_size=224)
    # skimage读取结果通道顺序为RGB,转换为bgr_128需要的BGR顺序
    image = RGB2BGR(image)
    # 如果原模型是 NCHW 输入(input_type_rt为nv12除外)
    if layout == "NCHW":
      image = HWC2CHW(image)
    # skimage读取数值范围为[0.0,1.0],调整为bgr需要的数值范围
    image = image * 255
    # bgr_128是bgr减去128
    image = image - 128
    #bgr_128使用int8
    image = image.astype(np.int8)
    
    return image

精度调优

基于精度分析工作,如果确定模型量化精度符合预期,则主要分为以下两种情况进行解决:

    1. 精度明显损失(损失大于4%)。 这种问题往往由于yaml配置不当,校验数据均衡导致的,建议根据接下来提供建议逐一排查。

    1. 精度损失小(1.5%~3%)。 排除1导致精度问题后,如果仍然出现精度小幅度损失,往往由于模型自身敏感性导致,建议使用X5算法工具链提供精度调优工具进行调优。

    1. 尝试1和2后,如果精度无法满足预期,可以尝试使用我们提供精度debug工具进行进一步尝试。

整体精度问题解决流程示意如下图:

accuracy_problem

精度明显损失(4%以上)

模型精度损失大于4%,通常是因为yaml配置不当,校验数据均衡导致的,建议依次从pipeline、模型转换配置、一致性检查几个方面进行排查。

pipeline检查

pipeline是完成数据预处理、模型转换、模型推理、后处理、精度评测全过程,这些步骤根据上文对应章节进行检查。 在以往实际问题跟进经验中,我们发现大部分情况原始浮点模型训练阶段中有变动,却没有及时更新模型转换步骤,从而精度验证导致异常。

模型转换yaml配置检查

根据PTQ精度评测一致性校验推荐流程,如果定位精度问题发生在original_float.onnx时,建议您重点检查yaml配置文件以及前后处理代码是否有误,其中,yaml配置文件常见误区包括:

  • input_type_rtinput_type_train参数用来区分转后混合异构模型原始浮点模型需要数据格式,需要认真检查是否符合预期,尤其是BGR和RGB通道顺序是否正确。

  • norm_typemean_valuescale_value参数是否配置正确。通过转换配置可以直接模型插入mean和scale操作节点,需要确认是否校验/测试图片进行重复的mean和scale操作 重复预处理错误易发

数据处理一致性检查

  • 正确指定 read_mode:02_preprocess.sh中通过–read_mode参数指定读图方式,支持 opencvskimage。 此外preprocess.py中通过imread_mode参数设定读图方式,也需要做出修改。使用 skimage的图片读取,得到RGB 通道顺序,取值范围0~1,数值类型float; 而使用 opencv,得到BGR 通道顺序,取值范围0~255,数据类型uint8

  • 校准数据存储格式设置正确:目前X5采用numpy.tofile保存校准数据,这种方式不会保存shape和类型信息,在加载需要手动指定,需要确保这些文件序列化序列化过程数据类型、数据尺寸数据排布信息一致的;如果input_type_train为 非featuremap 格式,则通过校准数据存放路径是否包含 “f32” 来判断数据dtype,若包含f32关键字,则按float32解析数据;反之按uint8解析数据。

  • transformer实现方式一致:我们提供一系列常见预处理函数,存放/horizon_model_convert_sample/01_common/python/data/transformer.py 文件中,部分预处理操作实现方式可能有所区别,例如ResizeTransformer,采用是opencv默认插值方式(linear), 若其他插值方式直接修改transformer.py源码,确保训练预处理代码保持一致, 具体使用参考transformer使用方法章节内容。

  • 建议您在X5算法工具链使用过程中,依然使用原始浮点模型训练验证阶段依赖数据处理库。 对于鲁棒性较差模型,不同实现功能resize、crop等典型功能可能引起扰动,进而影响模型精度。

  • 校验图片集是否合理设置。校准图片集数量应该一百张 左右,同时最好可以覆盖数据分布各种场合,例如多任务分类时,校验图片集可以覆盖各个预测分支或者各个类别。 同时避免偏离数据分布异常图片(过曝光等)。

  • 使用 ***_original_float_model.onnx验证一遍精度,正常情况下,这个模型精度应该原始浮点模型精度保持 小数点后三到五位对齐 。 如果验证发现满足这种对齐程度,则表明数据处理需要仔细检查。

精度损失提升(1.5%~3%)

一般情况下,为降低模型精度调优难度,建议您优先尝试calibration_type 配置default。default为自动搜索功能,以第一张校准数据输出节点余弦相似度为依据,从max、max-Percentile 0.99995和KL等校准方法选取最优方案, 最终选取校准方法关注转换日志类似 “Select kl method.”提示。搜索过程中,还会配合是否开启per_channel量化、非对称Asymmetric量化方案。

  • 如果开启per-channel还会打印: Perchannel quantization is enabled

  • 如果开启非对称asymmetric量化还会打印: Asymmetric quantization is enabled

自动搜索精度结果仍然预期差距,较于原始浮点模型精度损失在1.5%到3%范围左右,可尝试以下建议进行调优:

调整校准方式

  • 配置手动指定 calibration_type ,可以选择 mix ,如果最终精度符合预期,再尝试 kl / max

  • calibration_type 设定max 时,同时配置 max_percentile不同位数(取值范围是0.5-1之间),我们推荐优先尝试 0.999990.999950.99990.99950.999 ,通过几个配置观察模型精度变化趋势,最终找到一个最佳位数;

  • 上方尝试基础上,选择余弦相似最高方案,在配置转换尝试启用 per_channel ;

  • yaml中 optimization 参数提供asymmetricbias_correction 选项用于精度调试,实验发现两个参数部分场景可以提升量化精度,可进行进一步尝试。

调准校准数据

  • 可以尝试适当 增加或减少 数据数量(通常来说检测场景分类场景需要校准数据要少;此外可以观察模型输出漏检情况,适当增加对应场景校准数据);

  • 观察模型输出漏检情况,适当增加对应场景校准数据;

  • 不要使用纯黑纯白异常数据,尽量减少使用目标背景图作为校准数据;尽可能全面覆盖典型任务场景,使得校准数据分布训练近似。

部分尾部算子回退到 CPU 高精度计算

  • 一般我们仅会尝试模型输出1~2算子回退CPU,太的CPU算子较大程度影响模型最终性能,判断依据通过观察模型余弦相似度某些中间节点run_on_cpu,发现精度没有提升,这是正常现象,因为反复重量可能还会带来更大精度损失,因此通常建议尾部节点回退至cpu);

  • 指定算子运行在CPU上通过yaml文件node_info 参数。

精度Debug工具

尝试上述两种精度调优方法后,如果精度无法满足预期,可以尝试使用我们精度debug工具; 在PTQ模型量化过程中,造成精度损失原因主要两点:敏感节点量化问题、节点量化误差累积问题。 针对两种情况,为了方便定位问题,我们提供精度debug工具用于协助自主定位模型量化过程产生精度问题。 该工具能够协助校准模型进行节点粒度量化误差分析,快速定位出现精度异常节点。

使用是 X5 产品,那么可以通过配置部分op以int16计算进行尝试精度调优:

模型转换过程中,大部分op默认会以int8的数据计算,在一些场景部分op使用int8计算导致精度损失明显。 针对 X5 产品,目前算法工具链已经提供指定特定op以int16 bit计算能力,详情参考 int16配置说明 参数配置说明。 通过配置量化精度损失敏感op(以余弦相似度为参考)以int16 bit计算,一些场景可以解决精度损失问题。

算法工具链基于提供校准样本对模型进行校准量化保障模型高效部署在X5计算平台上,而模型转换过程中,难免会因为浮点定点量化过程引入精度损失,通常情况造成精度损失主要原因可能以下几点:

  1. 模型一部分节点量化比较敏感引入较大误差,即敏感节点量化问题。

  2. 模型各个节点误差累积导致模型整体出现较大校准误差,主要包含:权重量化导致误差累积、激活量化导致误差累积以及全量量化导致误差累积。

针对情况,X5算法工具链提供精度debug工具用以协助自主定位模型量化过程产生精度问题。 该工具能够协助校准模型进行节点粒度量化误差分析,最终帮助快速定位出现精度异常节点。

精度debug工具提供多种分析功能使用,例如:

  • 获取节点量化敏感度。

  • 获取模型累积误差曲线。

  • 获取指定节点数据分布。

  • 获取指定节点输入数据通道数据分布线图等。

使用方法说明

使用精度debug工具主要以下几个步骤:

  1. 在yaml中模型参数组(model_parameters) 配置参数 debug_mode="dump_calibration_data" ,保存校准数据。

  2. 导入debug模块,加载校准模型数据。

  3. 通过精度debug工具提供的API或命令行,对精度损失明显模型进行分析。

注意:

对于当前版本精度debug调试工具: X5 对应bayes-e 架构模型支持命令行和API方式。

整体流程如下所示:

accuracy_debug_process

校准模型数据保存

首先需要在yaml文件配置 debug_mode="dump_calibration_data" ,以开启精度debug功能, 并保存校准数据(calibration_data),对应校准模型(calibrated_model.onnx)为常态保存。其中:

  1. 校准数据(calibration_data):在校准阶段,模型通过这些数据进行前向推理获取每个量化节点量化参数,包括:缩放因子(scale)和阈值(threshold)。

  2. 校准模型(calibrated_model.onnx):将校准阶段计算得到每个量化节点量化参数保存校准节点中,从而得到校准模型。

注意:

此处保存校准数据与02_preprocess.sh生成校准数据区别?

02_preprocess.sh 得到校准数据是bgr颜色空间数据,在工具链内部数据从bgr转换到yuv444/gray等模型实际输入格式。 而此处保存校准数据经过颜色空间转换以及预处理之后保存的.npy格式数据,该数据可以通过np.load()直接送入模型进行推理。

注意:

校准模型(calibrated_model.onnx)解读

校准模型模型转换工具链浮点模型经过结构优化后,通过校准数据计算得到每个节点对应量化参数保存校准节点得到中间产物。 校准模型主要特点模型包含校准节点,校准节点节点类型为HzCalibration。 这些校准节点主要分为两类: 激活(activation)校准节点权重(weight)校准节点

激活校准节点输入当前节点一个节点输出,并基于当前激活校准节点保存量化参数(scales和thresholds)对输入数据进行量化量化输出。

权重校准节点输入模型原始浮点权重,基于当前权重校准节点保存量化参数(scales和thresholds)对输入原始浮点权重进行量化量化输出。

除却上述校准节点,校准模型其他节点,精度debug工具称为 普通节点(node)普通节点类型包括:Conv、Mul、Add等。

debug_node

calibration_data的文件夹结构如下:

  |--calibration_data :校准数据
  |----input.1 :文件夹名为模型的输入节点并保存对应的输入数据
  |--------0.npy
  |--------1.npy
  |-------- ...
  |----input.2 :对于多输入模型将保存多个文件夹
  |--------0.npy
  |--------1.npy
  |-------- ...
  • 精度debug模块导入使用

接下来需要代码导入debug模块,并通过 get_sensitivity_of_nodes 接口获取节点量化敏感度(默认使用模型输出余弦相似度)。 get_sensitivity_of_nodes详细参数说明可见 get_sensitivity_of_nodes 章节内容。


# 导入debug模块
import horizon_nn.quantizer.debugger as dbg
# 导入log日志模块
import logging

# 若verbose=True时,需要先设置log level为INFO
logging.getLogger().setLevel(logging.INFO)
# 获取节点量化敏感度
node_message = dbg.get_sensitivity_of_nodes(
        model_or_file='./calibrated_model.onnx',
        metrics=['cosine-similarity', 'mse'],
        calibrated_data='./calibration_data/',
        output_node=None,
        node_type='node',
        data_num=None,
        verbose=True,
        interested_nodes=None)
  • 分析结果展示

下方verbose=True打印结果:

  =================node sensitivity=================
  node                  cosine-similarity  mse
  ---------------------------------------------------
  Conv_60               0.77795            68.02103
  Conv_48               0.78428            64.36318
  Conv_82               0.80394            61.09268
  Conv_94               0.80499            65.05224
  Conv_42               0.83787            49.4949
  Conv_88               0.84614            49.81132
  Conv_54               0.86602            41.69972
  Conv_71               0.87148            39.96296
  Conv_65               0.87495            40.45997
  Conv_25               0.89214            34.30351
  Conv_20               0.89829            32.35053
  Conv_77               0.89916            31.9907
  Conv_14               0.90058            32.40179
  Conv_9                0.90107            34.08191
  Conv_37               0.91162            28.21194
  Conv_31               0.91637            28.79291

除此之外,该API会以字典(Dict)的形式节点量化敏感度信息返回以供后续使用分析。

  Out:
  {'Conv_60': {'cosine-similarity': 0.77795, 'mse': 68.02103},
   'Conv_48': {'cosine-similarity': 0.78428, 'mse': 64.36318},
   'Conv_82': {'cosine-similarity': 0.80394, 'mse': 61.09268},
   'Conv_94': {'cosine-similarity': 0.80499, 'mse': 65.05224},
   'Conv_42': {'cosine-similarity': 0.83787, 'mse': 49.4949},
   'Conv_88': {'cosine-similarity': 0.84614, 'mse': 49.81132},
   'Conv_54': {'cosine-similarity': 0.86602, 'mse': 41.69972},
   'Conv_71': {'cosine-similarity': 0.87148, 'mse': 39.96296},
   'Conv_65': {'cosine-similarity': 0.87495, 'mse': 40.45997},
   'Conv_25': {'cosine-similarity': 0.89214, 'mse': 34.30351},
   'Conv_20': {'cosine-similarity': 0.89829, 'mse': 32.35053},
   'Conv_77': {'cosine-similarity': 0.89916, 'mse': 31.9907},
   'Conv_14': {'cosine-similarity': 0.90058, 'mse': 32.40179},
   'Conv_9': {'cosine-similarity': 0.90107, 'mse': 34.08191},
   'Conv_37': {'cosine-similarity': 0.91162, 'mse': 28.21194},
   'Conv_31': {'cosine-similarity': 0.91637, 'mse': 28.79291}}

多功能参考 功能说明 章节。

技巧:

精度debug工具可以通过命令行 hmct-debugger -h/--help 查看每个功能对应命令。 各个命令详细参数用法详见 功能说明 章节。

功能说明
get_sensitivity_of_nodes

功能:获取节点量化敏感度。

命令行格式

hmct-debugger get-sensitivity-of-nodes MODEL_OR_FILE CALIBRATION_DATA --other options

通过 hmct-debugger get-sensitivity-of-nodes -h/--help 查看相关参数。

参数

参数名称 参数配置说明 取值范围说明 选/必选
model_or_file 参数作用:指定校准模型。

参数说明:必选,指定需要分析校准模型。
取值范围:无。

默认配置:无。
必选
metrics 或 - m 参数作用:节点量化敏感度度量方式。

参数说明:指定节点量化敏感度计算方式,该参数可以列表(List),即以多种方式计算量化敏感度,但是输出结果仅以列表第一位计算方式进行排序,排名越靠说明量化节点引入误差越大。
取值范围'cosine-similarity' , 'mse' , 'mre' , 'sqnr' , 'chebyshev'

默认配置'cosine-similarity'
calibrated_data 参数作用:指定校准数据。

参数说明:必选,指定分析需要校准数据。
取值范围:无 。

默认配置:无。
必选
output_node 或 -o 参数作用:指定输出节点。

参数说明:此参数支持指定中间节点作为输出计算节点量化敏感度。若保持默认参数None,则精度debug工具获取模型最终输出,并此基础计算节点量化敏感度。
取值范围:校准模型具有对应校准节点普通节点。

默认配置:None。
node_type 或 -n 参数作用:节点类型。

参数说明:需要计算量化敏感度节点类型,包括:node(普通节点)、weight(权重校准节点)、activation(激活校准节点)。
取值范围'node' , 'weight' , 'activation'

默认配置'node'
data_num 或 -d 参数作用:计算量化敏感度需要数据数量。

参数说明:设置计算节点量化敏感度时所需要数据数量。默认为None,此时默认使用calibration_data中所有数据进行计算。最小设置为1,最大为 calibration_data中数据数量。
取值范围:大于0,小于等于calibration_data中数据总数。

默认配置:None
verbose 或 -v 参数作用:选择是否信息打印终端上。

参数说明:若为True,则量化敏感度信息打印终端上。若metrics包含多种度量方式,则按照第一位进行排序。
取值范围TrueFalse

默认配置False
interested_nodes 或 -i 参数作用:设置感兴趣节点。

参数说明:若指定获取节点量化敏感度,其余节点获取。同时,若该参数指定,将忽视node_type指定节点类型,也就是说参数优先级高于node_type。若保持默认参数None,则计算模型所有量化节点量化敏感度。
取值范围:校准模型所有节点。

默认配置:None。

函数使用方法:


# 导入debug模块
import horizon_nn.quantizer.debugger as dbg
# 导入log日志模块
import logging

# 若verbose=True时,需要先设置log level为INFO
logging.getLogger().setLevel(logging.INFO)
# 获取节点量化敏感度
node_message = dbg.get_sensitivity_of_nodes(
        model_or_file='./calibrated_model.onnx',
        metrics=['cosine-similarity', 'mse'],
        calibrated_data='./calibration_data/',
        output_node=None,
        node_type='node',
        data_num=None,
        verbose=True,
        interested_nodes=None)

命令行使用方法:

  hmct-debugger get-sensitivity-of-nodes calibrated_model.onnx calibration_data -m ['cosine-similarity','mse'] -v True

分析结果展示

描述:首先通过node_type设置需要计算敏感度节点类型,然后工具获取校准模型所有符合node_type的节点,并获取这些节点量化敏感度。 当verbose设置为True时,工具节点量化敏感度进行排序打印终端,排序越靠前,说明节点量化引入量化误差越大。

verbose=True时,打印结果如下:

  =================node sensitivity=================
  node                  cosine-similarity  mse
  ---------------------------------------------------
  Conv_60               0.77795            68.02103
  Conv_48               0.78428            64.36318
  Conv_82               0.80394            61.09268
  Conv_94               0.80499            65.05224
  Conv_42               0.83787            49.4949
  Conv_88               0.84614            49.81132
  Conv_54               0.86602            41.69972
  Conv_71               0.87148            39.96296
  Conv_65               0.87495            40.45997
  Conv_25               0.89214            34.30351
  Conv_20               0.89829            32.35053
  Conv_77               0.89916            31.9907
  Conv_14               0.90058            32.40179
  Conv_9                0.90107            34.08191
  Conv_37               0.91162            28.21194
  Conv_31               0.91637            28.79291

其中:

  • node:节点名。

  • cosine-similarity、mse:各个节点量化敏感度数值。

verbose=True且node_type=’weight’时,打印结果如下:

   ====================================node sensitivity====================================
   weight                                              node     cosine-similarity  mse
   -----------------------------------------------------------------------------------------
   471_HzCalibration                                   Conv_2   0.99978            0.07519
   480_HzCalibration                                   Conv_7   0.99986            0.04823
   609_HzCalibration                                   Conv_88  0.99997            0.01145
   573_HzCalibration                                   Conv_65  0.99997            0.00984
   474_HzCalibration                                   Conv_4   0.99997            0.00963
   468_HzCalibration                                   Conv_0   0.99997            0.0091
   612_HzCalibration                                   Conv_90  0.99997            0.00871
   585_HzCalibration                                   Conv_73  0.99997            0.0095
   483_HzCalibration                                   Conv_9   0.99998            0.00818
   600_HzCalibration                                   Conv_82  0.99998            0.00717
   582_HzCalibration                                   Conv_71  0.99998            0.00659
   603_HzCalibration                                   Conv_84  0.99998            0.00614
   591_HzCalibration                                   Conv_77  0.99998            0.00558
   489_HzCalibration                                   Conv_12  0.99998            0.00515
   564_HzCalibration                                   Conv_60  0.99999            0.00495
   618_HzCalibration                                   Conv_94  0.99999            0.00498
   543_HzCalibration                                   Conv_46  0.99999            0.00502
   552_HzCalibration                                   Conv_52  0.99999            0.00501
   594_HzCalibration                                   Conv_78  0.99999            0.00451
   555_HzCalibration                                   Conv_54  0.99999            0.00452
   ...99classifier.1.weight_conv_weight_HzCalibration  Gemm_99  0.99999            0.00359
   558_HzCalibration                                   Conv_56  0.99999            0.00369

其中:

  • weight:权重校准节点名。

  • node:权重校准节点对应普通节点名,即权重校准节点输出输入。

  • cosine-similarity、mse:各个节点量化敏感度数值。

verbose=True且node_type=’activation’时,打印结果如下:

   ===================================node sensitivity===================================
   activation          node                  threshold  bit  cosine-similarity  mse
   ---------------------------------------------------------------------------------------
   406_HzCalibration   Conv_60               0.91501    8    0.77851            67.82422
   388_HzCalibration   Conv_48               0.55422    8    0.78501            64.16379
   440_HzCalibration   Conv_82               2.01577    8    0.8041             61.0322
   458_HzCalibration   Conv_94               0.51507    8    0.80466            65.14515
   379_HzCalibration   Conv_42               0.53759    8    0.83837            49.35648
   449_HzCalibration   Conv_88               2.34071    8    0.84447            50.29965
   397_HzCalibration   Conv_54               0.81528    8    0.86499            41.99234
   423_HzCalibration   Conv_71               0.84753    8    0.87104            40.09385
   414_HzCalibration   Conv_65               0.80155    8    0.87443            40.63319
   353_HzCalibration   Conv_25               0.67858    8    0.89199            34.34844
   345_HzCalibration   Conv_20               1.06324    8    0.8984             32.31664
   432_HzCalibration   Conv_77               2.54515    16   0.89895            32.0417
   336_HzCalibration   Conv_14               1.01407    8    0.90091            32.30325
   328_HzCalibration   Conv_9                1.61622    8    0.90163            33.78012
   371_HzCalibration   Conv_37               0.91038    8    0.91277            27.84864
   362_HzCalibration   Conv_31               0.65606    8    0.91683            28.65791
   403_HzCalibration   Conv_58               0.95119    8    0.93365            21.32314
   391_HzCalibration   Conv_50;Add_55        2.92598    8    0.93984            19.72109
   382_HzCalibration   Conv_44;Add_49        2.75416    8    0.95122            17.74137
   417_HzCalibration   Conv_67;Add_72        2.85463    8    0.95139            15.81864

其中:

  • activation:激活校准节点名。

  • node:在模型结构激活校准节点普通节点,即激活校准节点输出输入。

  • threshold:校准阈值,若有多个阈值最大值。

  • bit:量化比特。

  • cosine-similarity、mse:各个节点量化敏感度数值。

API返回值:

API返回值字典格式(Key为节点名称,Value为节点量化敏感度信息)保存量化敏感度,格式如下:

  Out: 
  {'Conv_60': {'cosine-similarity': 0.77795, 'mse': 68.02103},
   'Conv_48': {'cosine-similarity': 0.78428, 'mse': 64.36318},
   'Conv_82': {'cosine-similarity': 0.80394, 'mse': 61.09268},
   'Conv_94': {'cosine-similarity': 0.80499, 'mse': 65.05224},
   'Conv_42': {'cosine-similarity': 0.83787, 'mse': 49.4949},
   'Conv_88': {'cosine-similarity': 0.84614, 'mse': 49.81132},
   'Conv_54': {'cosine-similarity': 0.86602, 'mse': 41.69972},
   'Conv_71': {'cosine-similarity': 0.87148, 'mse': 39.96296},
   'Conv_65': {'cosine-similarity': 0.87495, 'mse': 40.45997},
   'Conv_25': {'cosine-similarity': 0.89214, 'mse': 34.30351},
   'Conv_20': {'cosine-similarity': 0.89829, 'mse': 32.35053},
   'Conv_77': {'cosine-similarity': 0.89916, 'mse': 31.9907},
   'Conv_14': {'cosine-similarity': 0.90058, 'mse': 32.40179},
   'Conv_9': {'cosine-similarity': 0.90107, 'mse': 34.08191},
   'Conv_37': {'cosine-similarity': 0.91162, 'mse': 28.21194},
   'Conv_31': {'cosine-similarity': 0.91637, 'mse': 28.79291}}
plot_acc_error

功能:只量化浮点模型一个节点,并依次计算模型浮点模型节点输出误差,获得累积误差曲线。

命令行格式:

  hmct-debugger plot-acc-error MODEL_OR_FILE CALIBRATION_DATA --other options

通过 hmct-debugger plot-acc-error -h/--help 查看相关参数。

参数

参数名称 参数配置说明 取值范围说明 选/必选
save_dir 或 -s 参数作用:保存路径。

参数说明:可选,指定分析结果保存路径。
取值范围:无。

默认配置:无。
calibrated_data 参数作用:指定校准数据。

参数说明:必选,指定需要分析校准数据。
取值范围:无。

默认配置: 无。
必选
model_or_file 参数作用:指定校准模型。

参数说明:必选,指定需要分析校准模型。
取值范围:无 。

默认配置:无。
必选
quantize_node 或 -q 参数作用:只量化模型指定节点,查看误差累积曲线。

参数说明:可参数。指定模型需要量化节点,同时保证其余节点均量化。

通过判断参数是否嵌套列表进而决定节点量化还是部分量化。

例如:

- quantize_node=['Conv_2','Conv_9']:分别量化Conv_2和Conv_9,同时保证其余节点量化。

- quantize_node=[['Conv_2'],['Conv_9','Conv_2']]:只量化Conv_2以及同时量化Conv_2和Conv_9,分别测试模型累积误差。

- quantize_node 包含两个特殊参数:'weight' 和 'activation'。

当:

- quantize_node = ['weight']:只量化权重,不量化激活。

- quantize_node = ['activation']:只量化激活,不量化权重。

- quantize_node = ['weight','activation']:权重激活分别量化。

注:quantize_node和non_quantize_node不可同时为None,必须指定其一。
取值范围:校准模型所有节点。

默认配置:None。
non_quantize_node 或 -nq 参数作用:指定累积误差类型。

参数说明:可参数。指定模型量化节点,同时保证其余节点全都量化。

通过判断参数是否嵌套列表进而决定节点量化还是部分量化。

例如:

- non_quantize_node=['Conv_2','Conv_9']:分别解除Conv_2和Conv_9节点量化,同时保证其余节点全部量化。

- non_quantize_node=[['Conv_2'],['Conv_9','Conv_2']]:只解除Conv_2量化以及同时解除Conv_2和Conv_9量化,分别测试模型累积误差。

注:quantize_node和non_quantize_node不可同时为None,必须指定其一。
取值范围:校准模型所有节点。

默认配置:None。
metric 或 -m 参数作用:误差度量方式。

参数说明:设置计算模型误差计算方式。
取值范围'cosine-similarity' , 'mse' , 'mre' , 'sqnr' , 'chebyshev'

默认配置'cosine-similarity'
average_mode 或 -a 参数作用:指定累积误差曲线输出模式。

参数说明:默认为False。若为True,那么获取累积误差平均值作为结果。
取值范围TrueFalse

默认配置False

# 导入debug模块
import horizon_nn.quantizer.debugger as dbg

dbg.plot_acc_error(
        save_dir: str,
        calibrated_data: str or CalibrationDataSet,
        model_or_file: ModelProto or str,
        quantize_node: List or str,
        non_quantize_node: List or str,
        metric: str = 'cosine-similarity',
        average_mode: bool = False)

分析结果展示

1.指定节点量化累积误差测试

  • 指定节点量化

配置方式:quantize_node=[’Conv_2’, ‘Conv_90’],quantize_node为单列表。

API函数使用方法:


# 导入debug模块
import horizon_nn.quantizer.debugger as dbg

dbg.plot_acc_error(
        save_dir='./',
        calibrated_data='./calibration_data/',
        model_or_file='./calibrated_model.onnx',
        quantize_node=['Conv_2', 'Conv_90'],
        metric='cosine-similarity',
        average_mode=False)

命令行使用方法:

  hmct-debugger plot-acc-error calibrated_model.onnx calibrated_data -q ['Conv_2','Conv_90']

描述:当quantize_node为单列表时,针对设置的quantize_node, 分别单独量化quantize_node中节点保持模型其他节点量化,得到对应模型后, 对模型每个节点输出计算浮点模型对应节点输出之间误差,并得到对应累积误差曲线。

average_mode = False时:

average_mode_false_1

average_mode = True时:

average_mode_true_1

注意:

average_mode

average_mode默认为False。对于一些模型,此时无法通过累积误差曲线判断量化策略更加有效, 因此需要将average_mode设置为True,此时前n个节点累积误差均值作为第n个节点累积误差。

具体计算方式如下,例如:

average_mode=False时,accumulate_error=[1.0, 0.9, 0.9, 0.8]。

将average_mode=True后,accumulate_error=[1.0, 0.95, 0.933, 0.9]。

  • 指定多个节点量化

配置方式:quantize_node=[[’Conv_2’], [’Conv_2’, ‘Conv_90’]],quantize_node为嵌套列表

API使用方法:


# 导入debug模块
import horizon_nn.quantizer.debugger as dbg

dbg.plot_acc_error(
        save_dir='./',
        calibrated_data='./calibration_data/',
        model_or_file='./calibrated_model.onnx',
        quantize_node=[['Conv_2'], ['Conv_2', 'Conv_90']],
        metric='cosine-similarity',
        average_mode=False)

命令行使用方法:

  hmct-debugger plot-acc-error calibrated_model.onnx calibration_data -q [['Conv_2'],['Conv_2','Conv_90']]

描述:当quantize_node为嵌套列表时,针对设置的quantize_node,分别量化quantize_node中的 每个列表指定节点保持模型其他节点量化,得到对应模型后,对模型每个节点输出计算 其浮点模型对应节点输出之间误差,并得到对应累积误差曲线。

  • partial_qmodel_0:只量化Conv_2节点,其余节点量化;

  • partial_qmodel_1:只量化Conv_2和Conv_90节点,其余节点量化。

average_mode=False时:

new_average_mode_false_1

average_mode=True时:

new_average_mode_true_1

2.解除模型部分节点量化累积误差测试

  • 指定节点量化

配置方式:non_quantize_node=[’Conv_2’, ‘Conv_90’],non_quantize_node为单列表。

API使用方法:


# 导入debug模块
import horizon_nn.quantizer.debugger as dbg

dbg.plot_acc_error(
        save_dir='./',
        calibrated_data='./calibration_data/',
        model_or_file='./calibrated_model.onnx',
        non_quantize_node=['Conv_2', 'Conv_90'],
        metric='cosine-similarity',
        average_mode=True)

命令行使用方法:

  hmct-debugger plot-acc-error calibrated_model.onnx calibration_data -nq ['Conv_2','Conv_90'] -a True

描述:当non_quantize_node为单列表时,针对设置的non_quantize_node, 分别解除non_quantize_node中各个节点量化同时保持其他节点全部量化,得到对应模型后, 对模型每个节点输出计算浮点模型对应节点输出之间误差,并得到对应累积误差曲线。

average_mode = False时:

average_mode_false_2

average_mode = True时:

average_mode_true_2

  • 指定多个节点量化

配置方式:non_quantize_node=[[’Conv_2’], [’Conv_2’, ‘Conv_90’]],non_quantize_node为嵌套列表。

API使用方法:


# 导入debug模块
import horizon_nn.quantizer.debugger as dbg

dbg.plot_acc_error(
        save_dir='./',
        calibrated_data='./calibration_data/',
        model_or_file='./calibrated_model.onnx',
        non_quantize_node=[['Conv_2'], ['Conv_2', 'Conv_90']],
        metric='cosine-similarity',
        average_mode=False)

命令行使用方法:

  hmct-debugger plot-acc-error calibrated_model.onnx calibration_data -nq [['Conv_2'],['Conv_2','Conv_90']]

描述:当non_quantize_node为嵌套列表时,针对设置的non_quantize_node, 分别量化non_quantize_node中每个列表指定节点保持模型其他节点均量化, 得到对应模型后,对模型每个节点输出计算浮点模型对应节点输出之间误差, 并得到对应累积误差曲线。

  • partial_qmodel_0:不量化Conv_2节点,其余节点量化;

  • partial_qmodel_1:不量化Conv_2和Conv_90节点,其余节点量化。

average_mode = False时:

new_average_mode_false_2

average_mode = True时:

new_average_mode_true_2

测试技巧

测试部分量化精度时,您可能按照量化敏感度排序进行多组量化策略精度对比,此时可以参考以下用法:


# 导入debug模块
import horizon_nn.quantizer.debugger as dbg

# 首先使用量化敏感度排序函数获取模型中节点的量化敏感度排序
node_message = dbg.get_sensitivity_of_nodes(
        model_or_file='./calibrated_model.onnx',
        metrics='cosine-similarity',
        calibrated_data='./calibration_data/',
        output_node=None,
        node_type='node',
        verbose=False,
        interested_nodes=None)
      
# node_message为字典类型,其key值为节点名称
nodes = list(node_message.keys())

# 通过nodes来指定不量化节点,可以方便使用
dbg.plot_acc_error(
        save_dir='./',
        calibrated_data='./calibration_data/',
        model_or_file='./calibrated_model.onnx',
        non_quantize_node=[nodes[:1],nodes[:2]],
        metric='cosine-similarity',
        average_mode=True)

3.激活权重分别量化

配置方式:quantize_node=[’weight’,’activation’]。

API使用方法:


import horizon_nn.quantizer.debugger as dbg

dbg.plot_acc_error(
        save_dir='./',
        calibrated_data='./calibration_data/',
        model_or_file='./calibrated_model.onnx',
        quantize_node=['weight','activation'],
        metric='cosine-similarity',
        average_mode=False)

命令行使用方法:

  hmct-debugger plot_acc_error calibrated_model.onnx calibration_data -q ['weight','activation']

描述:quantize_node也直接指定’weight’或者’activation’。当:

  • quantize_node = [’weight’]:只量化权重,不量化激活。

  • quantize_node = [’activation’]:只量化激活,不量化权重。

  • quantize_node = [’weight’, ‘activation’]:权重激活分别量化。

weight_activation_quantized

plot_distribution

功能:选取节点,分别获取节点浮点模型校准模型输出,得到输出数据分布。另外,将两个输出结果做差,获取两个输出之间误差分布。

命令行格式

hmct-debugger plot-distribution MODEL_OR_FILE CALIBRATION_DATA --other options

通过 hmct-debugger plot-distribution -h/--help 查看相关参数。

参数

参数名称 参数配置说明 取值范围说明 选/必选
save_dir 或 -s 参数作用:保存路径。

参数说明:可选,指定分析结果保存路径。
取值范围:无。

默认配置:无。
model_or_file 参数作用:指定校准模型。

参数说明:必选,指定需要分析校准模型。
取值范围:无。

默认配置: 无。
必选
calibrated_data 参数作用:指定校准数据。

参数说明:必选,指定分析需要校准数据。
取值范围:无 。

默认配置:无。
必选
nodes_list 或 -n 参数作用:指定需要分析节点。

参数说明:必选,指定需要分析节点。

若nodes_list中节点类型为:

- 权重校准节点:绘制原始权重经过校准之后权重数据分布。

- 激活校准节点:绘制激活校准节点输入数据分布。

- 普通节点:绘制节点量化前后输出数据分布,同时绘制二者之间误差分布。

注:nodes_list为 list 类型,可指定一系列节点,并且上述三种类型节点同时指定。
取值范围:校准模型所有节点。

默认配置:无。
必选

# 导入debug模块
import horizon_nn.quantizer.debugger as dbg

dbg.plot_distribution(
        save_dir: str, 
        model_or_file: ModelProto or str,
        calibrated_data: str or CalibrationDataSet,
        nodes_list: List[str] or str) 

分析结果展示

API使用方法:

  # 导入debug模块
  import horizon_nn.quantizer.debugger as dbg

  dbg.plot_distribution(
          save_dir='./',
          model_or_file='./calibrated_model.onnx',
          calibrated_data='./calibration_data',
          nodes_list=['317_HzCalibration', # 激活节点
                      '471_HzCalibration', # 权重节点
                      'Conv_2']) # 普通节点

命令行使用方法:

hmct-debugger plot-distribution calibrated_model.onnx calibration_data -n ['317_HzCalibration','471_HzCalibration','Conv_2']

node_output:

node_output

weight:

weight

activation:

activation

注意:

上方三幅图中,蓝色三角表示:数据绝对值最大值。红色虚线表示:最小校准阈值。

get_channelwise_data_distribution

功能:绘制指定校准节点输入数据通道数据分布线图。

命令行格式

hmct-debugger get-channelwise-data-distribution MODEL_OR_FILE CALIBRATION_DATA --other options

通过 hmct-debugger get-channelwise-data-distribution -h/--help 查看相关参数。

参数

参数名称 参数配置说明 取值范围说明 选/必选
save_dir 或 -s 参数作用:保存路径。

参数说明:可选,指定分析结果保存路径。
取值范围:无。

默认配置:无。
model_or_file 参数作用:指定校准模型。

参数说明:必选,指定需要分析校准模型。
取值范围:无。

默认配置: 无。
必选
calibrated_data 参数作用:指定校准数据。

参数说明:必选,指定分析需要校准数据。
取值范围:无 。

默认配置:无。
必选
nodes_list 或 -n 参数作用:指定校准节点。

参数说明:必选,指定校准节点。
取值范围:校准模型所有权校准节点激活校准节点。

默认配置:无。
必选
axis 或 -a 参数作用:指定channel所在维度。

参数说明:channel信息所在shape中位置。参数默认为None,此时对于激活校准节点,默认认为节点输入数据第二个维度表示channel信息,即axis=1;对于权重校准节点,会读取节点属性的axis参数作为channel信息。
取值范围:小于节点输入数据维度。

默认配置:None。

# 导入debug模块
import horizon_nn.quantizer.debugger as dbg

dbg.get_channelwise_data_distribution(
        save_dir: str, 
        model_or_file: ModelProto or str,
        calibrated_data: str or CalibrationDataSet,
        nodes_list: List[str],
        axis: int = None)

分析结果展示

描述:针对用户设置校准节点列表node_list,从参数axis中获取channel所在维度,获取节点输入数据通道数据分布。 其中axis默认为None,此时节点权重校准节点,则channel所在维度默认为0;若节点激活校准节点,则channel所在维度默认为1。

权重校准节点:

weight_calibration_node

激活校准节点:

activate_calibration_node

输出结果如下所示:

box_plot

图中:

  • 横坐标表示节点输入数据通道数,图例输入数据有96个通道。

  • 纵坐标表示每个channel的数据分布范围,其中红色实线表示该channel数据中位数,蓝色虚线表示均值。

sensitivity_analysis

功能:针对量化敏感节点,分别分析测试单独量化以及部分量化这些节点模型精度。

命令行格式

hmct-debugger sensitivity-analysis MODEL_OR_FILE CALIBRATION_DATA --other options

通过 hmct-debugger sensitivity-analysis -h/--help 查看相关参数。

参数

参数名称 参数配置说明 取值范围说明 选/必选
model_or_file 参数作用:指定校准模型。

参数说明:必选,指定需要分析校准模型。
取值范围:无。

默认配置: 无。
必选
calibrated_data 参数作用:指定校准数据。

参数说明:必选,指定分析需要校准数据。
取值范围:无 。

默认配置:无。
必选
pick_threshold 或 -p 参数作用:设置选取节点敏感度阈值。

参数说明:可选,此功能计算普通节点量化敏感度,选择敏感度小于pick_threshold的节点作为敏感节点进行分析测试;注意:设置sensitive_nodes时,则直接对sensitive_nodes进行测试,不再另行计算节点敏感度根据pick_threshold选择敏感节点。
取值范围:无。

默认配置:0.999。
data_num 或 -d 参数作用:计算量化敏感度需要数据数量。

参数说明:设置计算节点量化敏感度时所需要数据数量。
取值范围:大于0,小于等于calibration_data中数据总数。

默认配置:1。
sensitive_nodes 或 -sn 参数作用:指定需要分析敏感节点。

参数说明:可选,指定需要分析敏感节点;注:当设置此参数时,则直接对此参数节点进行测试,不再另行计算节点敏感度根据pick_threshold选择敏感节点。
取值范围:校准模型所有节点。

默认配置:无。
save_dir 或 -sd 参数作用:保存路径。

参数说明:可选,指定分析结果保存路径。
取值范围:无。

默认配置:无。

API使用方法:

# 导入debug模块
import horizon_nn.quantizer.debugger as dbg

dbg.sensitivity_analysis(model_or_file='calibrated_model.onnx',
                          calibrated_data='calibration_data',
                          pick_threshold=0.9999,
                          data_num=1,
                          sensitive_nodes=[])

命令行格式

hmct-debugger sensitivity-analysis calibrated_model.onnx calibration_data

分析结果展示

activate_calibration_node

图中:

  • 蓝色虚线:baseline,即浮点模型输出自身余弦相似度,为1。

  • 绿色x :只量化当前节点得到部分量化模型,计算部分量化模型浮点模型最终输出相似度。

  • 红色实线:不量化当前节点以及当前节点所有节点,计算部分量化模型浮点模型最终输出相似度。例如:上中 Conv_92对应相似数值大概在0.995左右,表明解除Conv_2、Conv_7和Conv_92节点量化保持其余所有节点量化得到部分量化模型,该部分量化模型最终输出浮点模型最终输出之间余弦相似度为0.995左右。 横坐标第一个none,在红色实线含义为calibrated_model。

runall

注意:

当前版本 runall 功能适用X5 产品。

功能:一键运行原本debug工具所有功能。

命令行格式

hmct-debugger runall MODEL_OR_FILE CALIBRATION_DATA --other options

通过 hmct-debugger runall -h/--help 查看相关参数。

参数

参数名称 参数配置说明 取值范围说明 选/必选
model_or_file 参数作用:指定校准模型。

参数说明:必选,指定需要分析校准模型。
取值范围:无。

默认配置:无。
必选
calibrated_data 参数作用:指定校准数据。

参数说明:必选,指定分析需要校准数据。
取值范围:无。

默认配置: 无。
必选
save_dir 或 -s 参数作用:保存路径。

参数说明:指定分析结果保存路径。
取值范围:无 。

默认配置:无。
ns_metrics 或 -nm 参数作用:节点量化敏感度度量方式。

参数说明:指定节点量化敏感度计算方式,该参数可以列表(List),即以多种方式计算量化敏感度,但是输出结果仅以列表第一位计算方式进行排序,排名越靠说明量化节点引入误差越大。
取值范围'cosine-similarity' , 'mse' , 'mre' , 'sqnr' , 'chebyshev'

默认配置'cosine-similarity'
output_node 或 -o 参数作用:指定输出节点。

参数说明:此参数支持指定中间节点作为输出计算节点量化敏感度。若保持默认参数None,则精度debug工具获取模型最终输出, 并此基础计算节点量化敏感度。
取值范围:校准模型具有对应校准节点普通节点。

默认配置:None。
node_type 或 -nt 参数作用:节点类型。

参数说明:需要计算量化敏感度节点类型,包括:node(普通节点)、weight(权重校准节点)、activation(激活校准节点)。
取值范围'node' , 'weight' , 'activation'

默认配置'node'
data_num 或 -dn 参数作用:计算量化敏感度需要数据数量。

参数说明:设置计算节点量化敏感度时所需要数据数量。默认为None,此时默认使用calibration_data中所有数据进行计算。 最小设置为1,最大为 calibration_data中数据数量。
取值范围:大于0,小于等于calibration_data中数据总数。

默认配置:None 。
verbose 或 -v 参数作用:选择是否信息打印终端上。

参数说明:若为True,则量化敏感度信息打印终端上。若metrics包含多种度量方式,则按照第一位进行排序。
取值范围TrueFalse

默认配置False
interested_nodes 或 -i 参数作用:设置感兴趣节点。

参数说明:若指定获取节点量化敏感度,其余节点获取。同时,若该参数指定,将忽视node_type指定节点类型,也就是说参数优先级高于node_type。若保持默认参数None,则计算模型所有量化节点量化敏感度。
取值范围:校准模型所有节点。

默认配置:None。
dis_nodes_list 或 -dnl 参数作用:指定需要分析节点。

参数说明:指定需要分析节点。

若nodes_list中节点类型为:

- 权重校准节点:绘制原始权重经过校准之后权重数据分布。

- 激活校准节点:绘制激活校准节点输入数据分布。

- 普通节点:绘制节点量化前后输出数据分布,同时绘制二者之间误差分布。

注:nodes_list为 list 类型,可指定一系列节点,并且上述三种类型节点同时指定。
取值范围:校准模型所有节点。

默认配置:无。
cw_nodes_list 或 -cn 参数作用:指定校准节点。

参数说明:指定校准节点。
取值范围:校准模型所有权校准节点激活校准节点。

默认配置:无。
axis 或 -a 参数作用:指定channel所在维度。

参数说明:channel信息所在shape中位置。参数默认为None,此时对于激活校准节点,默认认为节点输入数据第二个维度表示channel信息,即axis=1;对于权重校准节点,会读取节点属性的axis参数作为channel信息。
取值范围:小于节点输入数据维度。

默认配置:None。
quantize_node 或 -qn 参数作用:只量化模型指定节点,查看误差累积曲线。

参数说明:可参数。指定模型需要量化节点,同时保证其余节点均量化。

通过判断参数是否嵌套列表进而决定节点量化还是部分量化。

例如:

- quantize_node=['Conv_2','Conv_9']:分别量化Conv_2和Conv_9,同时保证其余节点量化。

- quantize_node=[['Conv_2'],['Conv_9','Conv_2']]:只量化Conv_2以及同时量化Conv_2和Conv_9,分别测试模型累积误差。

- quantize_node 包含两个特殊参数:'weight' 和 'activation'。

当:

- quantize_node = ['weight']:只量化权重,不量化激活。

- quantize_node = ['activation']:只量化激活,不量化权重。

- quantize_node = ['weight','activation']:权重激活分别量化。

注:quantize_node和non_quantize_node不可同时为None,必须指定其一。
取值范围:校准模型所有节点。

默认配置:None。
non_quantize_node 或 -nqn 参数作用:指定累积误差类型。

参数说明:可参数。指定模型量化节点,同时保证其余节点全都量化。

通过判断参数是否嵌套列表进而决定节点量化还是部分量化。

例如:

- non_quantize_node=['Conv_2','Conv_9']:分别解除Conv_2和Conv_9节点量化,同时保证其余节点全部量化。

- non_quantize_node=[['Conv_2'],['Conv_9','Conv_2']]:只解除Conv_2量化以及同时解除Conv_2和Conv_9量化,分别测试模型累积误差。

注:quantize_node和non_quantize_node不可同时为None,必须指定其一。
取值范围:校准模型所有节点。

默认配置:None。
ae_metric 或 -am 参数作用:累积误差度量方式。

参数说明:设置计算模型误差计算方式。
取值范围'cosine-similarity' , 'mse' , 'mre' , 'sqnr' , 'chebyshev'

默认配置'cosine-similarity'
average_mode 或 -avm 参数作用:指定累积误差曲线输出模式。

参数说明:默认为False。若为True,那么获取累积误差平均值作为结果。
取值范围TrueFalse

默认配置False
pick_threshold 或 -pt 参数作用:设置选取节点敏感度阈值。

参数说明:可选,此功能计算普通节点量化敏感度,选择敏感度小于pick_threshold的节点作为敏感节点进行分析测试;注:当设置sensitive_nodes时,则直接对sensitive_nodes进行测试,不再另行计算节点敏感度根据pick_threshold选择敏感节点。
取值范围:无。

默认配置:0.999。
sensitive_nodes 或 -sn 参数作用:指定需要分析敏感节点。

参数说明:可选,指定需要分析敏感节点;注:当设置此参数时,则直接对此参数节点进行测试,不再另行计算节点敏感度根据pick_threshold选择敏感节点。
取值范围:校准模型所有节点。

默认配置:无。

API使用方法:


# 导入debug模块
import horizon_nn.quantizer.debugger as dbg

dbg.runall(model_or_file='calibrated_model.onnx',
            calibrated_data='calibration_data')

命令行使用方法:

hmct-debugger runall calibrated_model.onnx calibration_data

runall流程:

runall

所有参数保持默认时,工具依次执行以下功能:

  • step1和step2:分别获取权重校准节点激活校准节点量化敏感度。

  • step3:根据step1和step2的结果,分别权重校准节点的top5和激活校准节点的top5绘制数据分布。

  • step4:针对step3获取节点,分别绘制通道数据分布线图。

  • step5:绘制分别量化权重量化激活累积误差曲线。

  • step6:针对敏感节点进行部分量化以及节点量化精度分析,由于图中示例没有指定sensitive_nodes,因此需要debug工具自行计算普通节点量化敏感度选取敏感度小于指定pick_threshold的节点进行测试分析。

指定 node_type='node' 时,工具获取top5节点,并分别找到每个节点对应校准节点,并获取校准节点数据分布线图。

6.3.2.7. 使用QAT量化感知训练方案进一步提升模型精度

如果通过上述分析,并没有发现任何配置问题,但是精度不能满足要求,则可能是PTQ本身限制。 这时候我们可以改用QAT的方式对模型进行量化。

Horizon Plugin Pytorch参考了PyTorch官方量化接口思路,Plugin采用是Quantization Aware Training(QAT)方案,因此建议阅读 PyTorch官方文档QAT 相关部分。

详细关于Horizon Plugin Pytorch的介绍,您可以参考 高阶指南-QAT量化感知训练 章节。

根据以往的使用调优经验,以上策略已经可以应对各种实际问题。

如果经过以上尝试仍然未能解决问题,请根据精度调优checklist文档步骤填写模型配置具体信息进行检查,确保一步排查完成,并根据checklist锁定模型转换那个具体步骤出现异常,然后填写完整精度调优checklist 信息、原始f浮点模型文件、模型量化相关配置文件一起反馈技术支持团队官方技术社区提出问题,我们在24小时提供支持。

6.3.2.8. 其它工具使用说明

章节主要介绍模型转换工具以外其他debug工具使用方法,这些工具可以协助开发者进行模型修改、模型分析、数据预处理操作,工具列表如下:

  • hb_mapper infer

  • hb_perf

  • hb_pack

  • hb_model_info

  • hb_model_modifier

  • hb_verifier

  • hb_eval_preprocess

  • HB_ONNXRuntime推理

hb_mapper infer 工具

注意:

  • hb_mapper infer 受 onnxruntime 限制,不支持动态的shape infer,因此要求输入模型shape信息明确。

  • 工具支持 infer 含有 shape信息为 ? 的模型。

  • 工具支持输入四维输出小于等于四维非featuremap模型。

命令利用浮点量化模型进行推理,并保存推理结果--output-dir 指定目录里面。

为了验证分析模型编译是否正确,可配置文件layer_out_dump 设置True,它输出conv和输出节点推理结果, 之后可以借助向量比较工具分析模型编译正确与否。

  • 使用方法

hb_mapper infer的使用方法:

  hb_mapper infer --config ${config_file} \
                  --model-file ${quantized_model_file}  \
                  --model-type ${caffe/onnx} \
                  --image-file ${input_node} ${image_file} \
                  --input-layout ${input_layout} \
                  --output-dir ${quantized_output_dir}

使用 hb_mapper infer 命令时,请输入hb_mapper makertbin 命令相同配置文件,以保证输入数据处理部分设置相同的。 简单地说,您hb_mapper makertbin使用校准数据什么样图片数据,那么hb_mapper infer需要使用相同格式图片数据。

注意:使用 hb_mapper infer 命令输入数据选择配置文件以下输入数据配置部分有关:

1.preprocess_on: True,则工具可以接收JPEG图片,自动进行resize等预处理,并转化成 input_type_rt格式。

2.preprocess_on: False,则只能接收已经处理好,储存二进制格式图片文件,因此预处理需要自行完成,并图片转化成相应二进制文件。(请参考脚本02_preprocess.sh)。

  • 命令行参数

    -h, –help 显示帮助信息退出。

    -c, –config 模型编译配置文件。

    –model-file 进行推理模型文件,可以浮点量化ONNX模型。

    –model-type 指定推理原始浮点模型类型,可指定caffeonnx

    –image-file 输入节点名称对应用于推理图像文件。

    –input-layout 模型输入的layout(此参数)。

    –output-dir 推理结果保存路径,如果量化模型,推理结果量化浮点数据。

输出内容output_dir 目录里,输出文件命名规则: ${layername}_float.bin

hb_perf 工具

hb_perf用于分析X5算法工具链量化混合模型性能分析工具。

  • 使用方法

hb_perf [OPTIONS] BIN_FILE
  • 命令行参数

hb_perf的命令行参数:

–version

显示版本退出。

-m

后接模型名称。当指定BIN_FILE为pack模型时, 仅输出指定模型模型编译信息。

–help

显示帮助信息。

  • 输出内容说明

模型信息输出当前目录hb_perf_result 文件夹中。 其中模型为名文件夹,该模型信息将会展示模型名称命名html 文件中。目录结构如下示例所示:

  hb_perf_result/
  └── mobilenetv1
      ├── mobilenetv1
      ├── mobilenetv1.html
      ├── mobilenetv1.png
      ├── MOBILENET_subgraph_0.html
      ├── MOBILENET_subgraph_0.json
      └── temp.hbm

若该模型编译时未设置为debug模式(compiler_parameters.debug:True) 则 hb_perf 工具产生如下提示, 该提示表明子图信息包括逐层信息, 对模型整体信息生成没有影响。

2021-01-12 10:41:40,000 WARNING bpu model don't have per-layer perf info.
2021-01-12 10:41:40,000 WARNING if you need per-layer perf info please enable[compiler_parameters.debug:True] when use makertbin.

hb_pack 工具

hb_pack用于多个混合模型(*.bin)文件打包一个模型文件工具。

  • 使用方法

hb_pack [OPTIONS] BIN_FILE1 BIN_FILE2 BIN_FILE3 -o comb.bin
  • 命令行参数

hb_pack的命令行参数

–version

显示版本退出。

-o, –output_name

pack模型输出名称

–help

显示帮助信息。

  • 输出内容说明

打包模型输出当前目录文件夹中,该模型命名output_name 指定名称。 该打包模型所有模型编译信息性能信息通过 hb_model_infohb_perf 获取得到。

注意: 注意,hb_pack支持已经打包模型再次进行打包,否则工作台将会产生以下提示:

ERROR exception in command: pack
ERROR model: xxx.bin is a packed model, it can not be packed again!

hb_model_info 工具

hb_model_info用于解析混合模型(*.bin)编译依赖参数信息工具。

  • 使用方法

  hb_model_info ${model_file}
  • 命令行参数

hb_model_info的命令行参数

–version

显示版本退出。

-m

后接模型名称。当指定BIN_FILE为pack模型时, 仅输出指定模型模型编译信息。

–help

显示帮助信息。

  • 输出内容说明

输出部分将会模型编译一些输入信息,如下所示:

备注: 以下代码版本号信息发布版本变化,此处仅为示例。

Start hb_model_info....
hb_model_info version 1.3.35
******** efficient_det_512x512_nv12 info *********
############# model deps info #############
hb_mapper version   : 1.3.35
hbdk version        : 3.23.3
hbdk runtime version: 3.13.7
horizon_nn version  : 0.10.10
############# model_parameters info #############
onnx_model          : /release/01_common/model_zoo/mapper/detection/efficient_det/efficientdet_nhwc.onnx
BPU march           : bernoulli2
layer_out_dump      : False
working dir         : /release/04_detection/05_efficient_det/mapper/model_output
output_model_file_prefix: efficient_det_512x512_nv12
############# input_parameters info #############
------
---------input info : data ---------
input_name          : data
input_type_rt       : nv12
input_space&range   : regular
input_layout_rt     : None
input_type_train    : rgb
input_layout_train  : NCHW
norm_type           : data_mean_and_scale
input_shape         : 1x3x512x512
mean_value          : 123.68,116.779,103.939,
scale_value         : 0.017,
cal_data_dir        : /release/04_detection/05_efficient_det/mapper/calibration_data_rgb_f32
---------input info : data end -------
------
############# calibration_parameters info #############
preprocess_on       : False
calibration_type    : max
############# compiler_parameters info #############
hbdk_pass_through_params: --fast --O3
input-source        : {'data': 'pyramid', '_default_value': 'ddr'}
--------- input/output types -
model input types   : [<InputDataType.NV12: 7>]
model output types  : [<InputDataType.F32: 5>, <InputDataType.F32: 5>, <InputDataType.F32: 5>, <InputDataTye.F32: 5>, <InputDataType.F32: 5>, <InputDataType.F32: 5>, <InputDataType.F32: 5>, <InputDataType.F32: 5>, <InputDataType.F32: 5>, <InpuDataType.F32: 5>]

备注:

模型存在删除节点时,模型信息输出末尾打印删除节点名称,同时生成 deleted_nodes_info.txt 文件,文件一行记录对应删除节点初始信息。打印删除节点名称如下所示:

--------- deleted nodes -
deleted nodes: spconvretinanethead0_conv91_fwd_chw_HzDequantize
deleted nodes: spconvretinanethead0_conv95_fwd_chw_HzDequantize
deleted nodes: spconvretinanethead0_conv99_fwd_chw_HzDequantize
deleted nodes: spconvretinanethead0_conv103_fwd_chw_HzDequantize
deleted nodes: spconvretinanethead0_conv107_fwd_chw_HzDequantize
deleted nodes: spconvretinanethead0_conv93_fwd_chw_HzDequantize
deleted nodes: spconvretinanethead0_conv97_fwd_chw_HzDequantize
deleted nodes: spconvretinanethead0_conv101_fwd_chw_HzDequantize
deleted nodes: spconvretinanethead0_conv105_fwd_chw_HzDequantize
deleted nodes: spconvretinanethead0_conv109_fwd_chw_HzDequantize

hb_model_modifier 工具

hb_model_modifier 工具用于*.bin 模型输入端的Transpose、Quantize节点输出端的Transpose、Dequantize、Cast、Reshape、Softmax节点进行删除操作, 并删除节点信息存放在BIN模型中,可以通过 hb_model_info 进行查看。

备注:

  1. hb_model_modifier工具只能删除挨着模型输入输出节点。如果删除节点后面其他节点,则不能进行删除操作。

  2. 模型节点名称需要注意不要包括 “;” “,” 等特殊符号,否则可能影响工具使用。

  3. 工具支持打包模型进行处理,否则提示: ERROR pack model is not supported

  4. 删除节点顺序依次删除, 并且动态更新模型结构; 同时节点删除判断节点是否位于模型输入输出处, 因此节点删除顺序重要。

由于删除特定节点对模型输入情况影响, 因此工具对模型输入只有一条通路情况适用, 若如下图中所示, 同一输入对应多个节点情况支持。

hb_model_modifier

  • 使用方式

1.查看删除节点:

hb_model_modifier model.bin

2.删除单个指定节点(以node1为例):

hb_model_modifier model.bin -r node1

3.删除多个指定节点(以node1、node2、node3为例):

hb_model_modifier model.bin -r node1 -r node2 -r node3

4.删除某类节点(以Dequantize为例):

hb_model_modifier model.bin --all Dequantize

5.删除多种类型节点(以Reshape、Cast、Dequantize为例):

hb_model_modifier model.bin -a Reshape -a Cast -a Dequantize

6.组合使用:

hb_model_modifier model.bin -a Reshape -a Cast -a Dequantize -r node1 -r node2 -r node3
  • 命令行参数

hb_model_modifier的命令行参数

–model_file

runtime 模型文件名称。

-r

后接指定删除节点名称。若有多个节点需要删除, 需要指定多次。

-o

后接修改模型输出名称(仅-r 参数生效)。

-a –all

后接节点类型. 支持一键删除所有对应类型功能. 若有多个类型节点需要删除, 需要指定多次。

  • 输出内容说明

工具不接任何参数,则工具打印出可供候选删除节点(即模型位于输入输出位置所有Transpose、Quantize、Dequantize、Cast、Reshape、Softmax节点)。

其中Quantize节点用于模型 float 类型输入数据量化至 int8 类型,其计算公式如下:

  qx = clamp(round(x / scale) + zero_point, -128, 127)

round(x) 实现浮点数四舍五入, clamp(x) 函数实现数据钳位在-128~127之间整数数值。 zero_point非对称量化零点偏移值,对称量化zero_point = 0

C++的参考实现如下:

  int64_t quantized_value =
      static_cast<int64_t>(std::round(value / static_cast<double(scale)));
  quantized_value = std::min(std::max(quantized_value, min_int_value), max_int_value);

Dequantize节点用于模型 int8int32 类型输出数据量化floatdouble 类型,其计算公式如下:

  deqx = (x - zero_point) * scale

C++的参考实现如下:

  static_cast<float>(value) * scale

备注:

目前工具支持删除:

  1. 输入部位节点为Quantize或Transpose节点;

  2. 输出部位节点为Transpose、Dequanti、Cast、Reshape、Softmax节点。

工具打印信息如下:

hb_model_modifier resnet50_64x56x56_featuremap.bin
2022-04-21 18:22:30,207 INFO Nodes that can be deleted: ['data_res2a_branch1_HzQuantize_TransposeInput0', 'fc1000_reshape_0']

指定 -r 选项后,工具打印模型中该节点类型,储存在bin文件节点信息以及告知指定节点删除:

hb_model_modifier resnet50_64x56x56_featuremap.bin -r data_res2a_branch1_HzQuantize_TransposeInput0
Node 'data_res2a_branch1_HzQuantize_TransposeInput0' found, its OP type is 'Transpose'
Node 'data_res2a_branch1_HzQuantize_TransposeInput0' is removed
modified model saved as resnet50_64x56x56_featuremap_modified.bin

之后可以通过 hb_model_info 工具查看删除节点信息,输出信息末尾打印删除节点名称,同时生成 deleted_nodes_info.txt 文件,文件一行记录对应删除节点初始信息。打印删除节点名称如下所示:

hb_model_info resnet50_64x56x56_featuremap_modified.bin
Start hb_model_info....
hb_model_info version 1.7.0
********* resnet50_64x56x56_featuremap info *********
...
--------- deleted nodes -
deleted nodes: data_res2a_branch1_HzQuantize_TransposeInput0

hb_verifier 工具

hb_verifier 工具用于指定定点模型和runtime模型进行结果验证工具。

使用工具指定图片,则 hb_verifier 工具使用指定图片进行定点模型推理、runtime模型板和X86端模拟器推理,并结果进行比较, 给出是否通过结论(此过程支持自选,您可以根据需要选择进行对比内容)。

工具使用指定图片,进行定点模型推理,runtime模型板和x86端模拟器推理, runtime模型端的推理(如果给定ip可以ping通且板端已经安装 hrt_tools, 若无则可以使用工具链SDK包中 package/boardinstall.sh 脚本进行安装) runtime模型在x86端的推理(确保host端已经安装 hrt_tools, 若无则可以使用工具链SDK包中 package/hostinstall.sh 脚本进行安装), 并三方结果进行比较,给出是否通过结论。 若未指定图片,则工具默认图片进行推理(featuremap模型随机生成tensor数据)。

注意:

  1. package 资料获取方式,请参考交付使用说明

  2. hb_verifier工具支持除Dequantize节点外,有其他节点变化的bin模型与quanti.onnx进行对比。

    如果使用工具前,您使用hb_model_modifier工具删除了bin模型输出最后一个节点节点非Dequantize节点,或者yaml文件配置remove_node_type 参数, 从而删除了bin模型输出最后一个节点节点非Dequantize节点,那么hb_verifier工具不再支持quanti.onnx和删除节点的bin模型对比。

    解决上述问题,需要避免出现上述删除bin模型输出最后一个节点节点非Dequantize节点情况。

  3. 由于hb_verifier工具板端通过SSH进行交互,故如在Docker容器使用工具,请勿使用 docker attach 命令连接容器,使用命令连接容器导致板端交互的SSH认证失败。

  • 使用方式

hb_verifier -m   ${quanti_model},${bin_model} \
            -b   ${board_ip} \
            -s   True / False \  
            -i   ${input_img} \ 
            -c   ${digits}  \
            -r   True / False
            -u   Board username
            -p   Board password
  • 命令行参数

hb_verifier的命令行参数:

–version 显示版本退出。

-h, –help 显示帮助信息。

-m, –model 定点模型名称和bin模型名称,多模型之间用”,”进行区分。

-b, –board-ip 上板测试使用的arm board ip地址。

-s, –run-sim 设置是否使用X86环境的libdnn做bin模型推理,默认为False。

- 当该参数设置为 ``True`` 时,工具将会使用x86环境的libdnn做bin模型推理。

- 当该参数设置为 ``False`` 时,工具不会使用x86环境的libdnn做bin模型推理。

-i, –input-img 指定推理测试使用图片。

若不指定则会使用随机生成的tensor数据。 

若指定图片为二进制形式的图片文件,其文件形式需要为后缀名为 ``.bin`` 形式。

多输入模型添加图片的方式有以下两种传参方式,多张图片之间用","分割:
    
- input_name1:image1,input_name2:image2, ... 

- image1,image2...

注意:多batch模型场景下,hb_verifier工具支持输入配置为binary数据,建议直接指定为单batch图片,或者指定输入使用随机数据进行一致性验证。

-c, –compare_digits 设置比较推理结果数值精确度(即比较数值小数点位数),若进行指定工具默认比较小数点五位。

-r, –dump-all-nodes-results 设置是否保存模型各个算子输出结果,并算子输出名称相同结果进行对比,默认为False。

- 当该参数设置为 ``True`` 时,工具将会获取模型中所有节点的输出,并根据节点输出的名字做匹配,从而进行对比。

- 当该参数设置为 ``False`` 时,工具将会只获取模型最终输出的结果,并进行对比。

注意:注意,目前基于性能考虑,暂支持在X86环境使用dump功能。

-u, –username 用于指定开发板用户名,默认root

-p, –password 如使用开发板带有密码,需键入板端密码。

注意: 如所使用开发板设置密码,请勿主动输入此项。

  • 参考使用场景样例

1.quanti.onnx模型推理、bin模型板端推理,bin模型在X86环境进行推理,并三方推理结果对比:

hb_verifier -m quanti.onnx,model.bin -b *.*.*.* -s True (-i 选填)

2.quanti.onnx模型推理、bin模型板端推理,并两方推理结果对比:

hb_verifier -m quanti.onnx,model.bin -b *.*.*.* (-i 选填)

3.quanti.onnx模型推理、bin模型板端推理,过程保存两方模型各个算子输出,并算子输出名称相同结果进行对比:

hb_verifier -m quanti.onnx,model.bin -b *.*.*.* -r True (-i 选填)

4.quanti.onnx模型推理、bin模型在X86环境进行推理,并两方推理结果对比:

hb_verifier -m quanti.onnx,model.bin -s True (-i 选填)
  • 输出内容说明

结果对比最终终端展示,工具对比多个模型不同场景运行结果,若问题显示如下:

  Comparison results of original output is model_infer_output_0
  raw output 0 and raw output 0 result Strict check PASSED
  Quanti.onnx and Arm result Strict check PASSED

定点模型和runtime模型精度一致时会输出一致结果具体信息,如下方log所示:

  INFO ================== Sim infer log end ==========================
  INFO ***************************************************************
  INFO compare source: Quanti.onnx VS Arm
  INFO compare model name: clr_320x800_bgr_quantized_model VS clr_320x800_bgr
  Compare progress: 100%|###########################| 1/1 [00:00<00:00, 55.47it/s]
  INFO =============== Original output comparison results =================
  INFO Comparison results of original output is model_infer_output_0_output
  INFO mismatch result num: 1000
  INFO total result num: 1000
  INFO mismatch rate: 1.0
  INFO relative mismatch ratio: 0.9997149805034536
  INFO max abs error: 8.36695
  WARNING raw output output and raw output output result Strict check FAILED
  WARNING Quanti.onnx and Arm result Strict check FAILED
  INFO ***************************************************************
  INFO ***************************************************************
  INFO compare source: Quanti.onnx VS Sim
  INFO compare model name: clr_320x800_bgr_quantized_model VS clr_320x800_bgr
  Compare progress: 100%|##########################| 1/1 [00:00<00:00, 135.53it/s]
  INFO =============== Original output comparison results =================
  INFO Comparison results of original output is model_infer_output_0_output
  INFO mismatch result num: 1000
  INFO total result num: 1000
  INFO mismatch rate: 1.0
  INFO relative mismatch ratio: 0.9997149805034536
  INFO max abs error: 8.36695
  WARNING raw output output and raw output output result Strict check FAILED
  WARNING Quanti.onnx and Sim result Strict check FAILED
  INFO ***************************************************************
  INFO ***************************************************************
  INFO compare source: Arm VS Sim
  INFO compare model name: clr_320x800_bgr VS clr_320x800_bgr
  Compare progress: 100%|##########################| 1/1 [00:00<00:00, 150.69it/s]
  INFO Arm and Sim result Strict check PASSED
  INFO ***************************************************************

其中:

  • mismatch result num两种模型精度一致结果个数,包括三种一致情况:

    • mismatch.line_miss num输出结果数量一致个数。

    • mismatch.line_diff num输出结果差距过大个数。

    • mismatch.line_nan num输出为nan的个数。

  • total result num输出数据个数。

  • mismatch rate一致数据个数输出数据个数比例。

  • relative mismatch ratio相对误差比例,取误差比例最大进行展示。

  • max abs error最大绝对误差。

hb_eval_preprocess 工具

用于对模型精度进行评估时,在x86环境图片数据进行预处理。 所谓预处理图片数据送入模型之前特定处理操作。 比如:图片resize、crop和padding等。

  • 使用方法

  hb_eval_preprocess [OPTIONS]
  • 命令行参数

hb_eval_preprocess的命令行参数

–version

显示版本退出。

-m, –model_name

设置模型名称,支持模型范围通过 hb_eval_preprocess --help 查看。

-i, –image_dir

输入图片路径。

-o, –output_dir

输出路径。

-v, –val_txt

设置评测图片文件名称,预处理生成图片文件图片名称对应。

-h, –help

显示帮助信息。

  • 输出内容说明

hb_eval_preprocess 命令将会--output_dir 指定路径生成图片二进制文件。

技巧:关于 hb_eval_preprocess 工具上板模型精度评估应用示例参见嵌入式应用开发《公版模型评测说明》中数据预处理 一节内容。

HB_ONNXRuntime 推理

HB_ONNXRuntime是地瓜基于公版ONNXRuntime封装一套x86端的ONNX模型推理库。 除支持Pytorch、TensorFlow、PaddlePaddle、MXNet等训练框架直接导出的ONNX原始模型外,还支持地瓜工具链进行PTQ转换过程产出阶段ONNX模型进行推理。 使用流程如下所示:

hb_onnxruntime

注意:

注意,X5 BPU架构计算平台使用是int8的计算精度(业内计算平台通用精度),使用X5算法工具链进行PTQ转换过程中, 虽然最终转换生成的bin模型输入 input_type_rt 到 input_type_train 颜色空间转换配合处理器硬件完成, 但是对于转换过程生成的onnx模型(非featuremap输入且 norm_type 未配置为 no_preprocess)前端插入预处理节点包含硬件转换逻辑, 因此onnx模型实际输入只是一种中间类型(除featuremap输入外,其他类型输入做-128操作,即由unit8转为int8), HB_ONNXRuntime内部对此数据转换进行处理,但仅限如下涉及数据损失转换场景:

模型输入为int8:支持传入int8、uint8。

模型输入为uint8:支持传入为int8、uint8。

模型输入为float32:支持传入为int8、uint8及float32。

涉及混合类型输入出现数据损失转换,需先自行完成对应数据转换处理,再进行推理。

  • 使用方法

    使用HB_ONNXRuntime加载ONNX模型推理基本流程如下所示,这份示例代码适用所有ONNX模型推理, 根据不同模型输入类型和layout要求准备数据即可:

import numpy as np
# 加载地瓜依赖库
from horizon_tc_ui import HB_ONNXRuntime
# 准备模型运行的输入
input_data = np.load("input.npy")
# 加载模型文件
sess = HB_ONNXRuntime(model_file = "model.onnx")
# 获取模型输入&输出节点信息
input_names = sess.input_names
output_names = sess.output_names
# 准备输入数据,这里我们假设此模型只有1个输入
input_info = {input_names[0]: input_data}
# 开始模型推理,推理的返回值是一个list,依次与output_names指定名称一一对应
output = sess.run(output_names, input_info)
  • 参数说明

output_names:

用于配置输出名称,支持配置为None或自定义配置。

配置为None,工具内部读取模型输出节点信息解析顺序给出推理结果。

自定义配置,可以配置全量部分output_name,且支持修改输出顺序。则推理完成后,会配置输出名称顺序返回输出。

input_info:

按照输入类型和layout准备模型运行输入,配置格式要求字典形式,输入名称输入数据组成键值对,参考配置示例:{“input_name” : data}。