4. 模型转换进阶指南

4.1. Pulsar Build 模型编译

本节介绍 pulsar build 命令完整使用方法.

4.1.1. 概述

pulsar build 用于模型优化、量化、编译等操作. 其运行示意图如下:

graph LR; 输入模型[输入模型 onnx] --> pb(pulsar build<br/>+命令行参数) 配置文件[配置文件 config.prototxt] --> pb pb --> 输出模型[输出模型 joint] pb --> 输出配置文件[配置文件 output_config.prototxt]

pulsar build 利用输入模型(model.onnx)和配置文件(config.prototxt), 编译得到输出模型(joint)和输出配置文件(output_config.prototxt).

pulsar build 的命令行参数将会覆盖配置文件中的某些对应部分, 并使 pulsar build 将覆盖过后得到的配置文件输出出来. 配置文件的详细介绍参见 配置文件详细说明.

pulsar build -h 可显示详细命令行参数:

 1root@xxx:/data# pulsar build -h
 2usage: pulsar build [-h] [--config CONFIG] [--output_config OUTPUT_CONFIG]
 3                    [--input INPUT [INPUT ...]] [--output OUTPUT [OUTPUT ...]]
 4                    [--calibration_batch_size CALIBRATION_BATCH_SIZE]
 5                    [--compile_batch_size COMPILE_BATCH_SIZE [COMPILE_BATCH_SIZE ...]]
 6                    [--batch_size_option {BSO_AUTO,BSO_STATIC,BSO_DYNAMIC}]
 7                    [--output_dir OUTPUT_DIR]
 8                    [--virtual_npu {0,311,312,221,222,111,112}]
 9                    [--input_tensor_color {auto,rgb,bgr,gray,nv12,nv21}]
10                    [--output_tensor_color {auto,rgb,bgr,gray,nv12,nv21}]
11                    [--output_tensor_layout {native,nchw,nhwc}]
12                    [--color_std {studio,full}]
13                    [--target_hardware {AX630,AX620,AX170}]
14                    [--enable_progress_bar]
15
16optional arguments:
17  -h, --help            show this help msesage and exit
18  --config CONFIG       .prototxt
19  --output_config OUTPUT_CONFIG
20  --input INPUT [INPUT ...]
21  --output OUTPUT [OUTPUT ...]
22  --calibration_batch_size CALIBRATION_BATCH_SIZE
23  --compile_batch_size COMPILE_BATCH_SIZE [COMPILE_BATCH_SIZE ...]
24  --batch_size_option {BSO_AUTO,BSO_STATIC,BSO_DYNAMIC}
25  --output_dir OUTPUT_DIR
26  --virtual_npu {0,311,312,221,222,111,112}
27  --input_tensor_color {auto,rgb,bgr,gray,nv12,nv21}
28  --output_tensor_color {auto,rgb,bgr,gray,nv12,nv21}
29  --output_tensor_layout {native,nchw,nhwc}
30  --color_std {studio,full}
31                        only support nv12/nv21 now
32  --target_hardware {AX630,AX620,AX170}
33                        target hardware to compile
34  --enable_progress_bar

提示

利用配置文件可以实现复杂功能, 而命令行参数只是起一个辅助作用. 另外, 命令行参数会 override 配置文件中的某些对应配置.

4.1.2. 参数详解

pulsar build 参数解释
--input

本次编译的输入模型路径, 对应 config.prototxt 中的 input_path字段

--output

指定输出模型的文件名, 如 compiled.joint, 对应 config.prototxt 中的 output_path字段

--config

指定用于指导本次编译过程所用的基本配置文件. 如果为 pulsar build 命令指定了命令行参数, 则转换模型过程中优先使用命令行参数中指定的值

--output_config

将本次编译过程所使用的完整配置信息输出到文件

--target_hardware

指定编译输出模型所适用的硬件平台, 目前有 AX630AX620 可选

--virtual_npu

指定推理时使用的虚拟 NPU , 请根据 --target_hardware 参数进行区别. 详情参见 芯片介绍 中的虚拟NPU部分

--output_dir

指定编译过程的工作目录. 默认为当前目录

--calibration_batch_size

转模型过程中, 内部参数校准时所使用数据的 batch_size. 默认值为 32

--batch_size_option

设置 joint 格式模型所支持的 batch 类型:

  • BSO_AUTO: 默认选项, 默认为静态 batch

  • BSO_STATIC: 静态 batch, 推理时固定 batch_size, 性能最优

  • BSO_DYNAMIC: 动态 batch, 推理时支持不超过最大值的任意 batch_size, 使用最灵活

--compile_batch_size

设置 joint 格式模型所支持的 batch size. 默认为 1

  • 当指定了 --batch_size_option BSO_STATIC 时, batch_size 表示 joint 格式模型推理时能用的唯一 batch size

  • 当指定了 --batch_size_option BSO_DYNAMIC 时, batch_size 表示 joint 格式模型推理时所能使用的最大 batch size

--input_tensor_color

指定 输入模型输入数据 的色彩空间, 可选项:

  • 默认选项: auto, 根据模型输入 channel 数自动识别
    • 3-channel 为 bgr

    • 1-channel 为 gray

  • 其他可选项: rgb, bgr, gray, nv12, nv21

--output_tensor_color

指定 输出模型输入数据 的色彩空间, 可选项:

  • 默认选项: auto, 根据模型输入 channel 数自动识别
    • 3-channel 为 bgr

    • 1-channel 为 gray

  • 其他可选项: rgb, bgr, gray, nv12, nv21

--color_std

指定用于在 RGBYUV 之间转换时所采用的转换标准, 可选项: legacy, studiofull, 默认值为 legacy

--enable_progress_bar

编译时显示进度条. 默认不显示

--output_tensor_layout

指定 输出 模型的 输出 tensorlayout, 可选:

  • native: 默认选项, 历史遗留选项, 不推荐使用. 建议显式指定输出 layout

  • nchw

  • nhwc

注意

axera_neuwizard_v0.6.0.1 及以后版本的工具链才支持此参数. 从 axera_neuwizard_v0.6.0.1 开始, 部分 AX620A 模型的输出 tensor 的默认 layout 可能与 axera_neuwizard_v0.6.0.1 之前版本的工具链编译出来的模型不同. AX630A 模型的默认 layout 不受工具链版本的影响

代码示例

1pulsar build --input model.onnx --output compiled.joint --config my_config.prototxt --target_hardware AX620 --virtual_npu 111 --output_config my_output_config.prototxt

小技巧

当生成支持动态 batchjoint 模型时, 可以在 --compile_batch_size 后面指定多个常用的 batch_size, 以提高使用不超过这些值的 batch size 进行推理时的性能.

注意

指定多个 batch size 会增加 joint 模型文件的大小.

4.2. Pulsar Run 模型仿真与对分

本节介绍 pulsar run 命令完整使用方法.

4.2.1. 概述

pulsar run 用于在 x86 平台上对 joint 模型进行 x86仿真精度对分.

graph LR; 目标模型[目标模型<br/>joint] --> pulsar_run(pulsar run<br/>+命令行参数) 参考模型[参考模型<br/>onnx] --> pulsar_run 图像文件[图像文件<br/>jpg / png] --> pulsar_run pulsar_run --> 对分结果 pulsar_run --> gt[目标模型的仿真 inference 结果<br/>+<br/>上板输入数据]

pulsar run -h 可显示详细命令行参数:

 1root@xxx:/data# pulsar run -h
 2usage: pulsar run [-h] [--use_onnx_ir] [--input INPUT [INPUT ...]]
 3                  [--layer LAYER [LAYER ...]] [--output_gt OUTPUT_GT]
 4                  [--config CONFIG]
 5                  model [model ...]
 6
 7positional arguments:
 8  model
 9
10optional arguments:
11  -h, --help                   show this help msesage and exit
12  --use_onnx_ir                use NeuWizard IR for refernece onnx
13  --input INPUT [INPUT ...]    input paths or .json
14  --layer LAYER [LAYER ...]    input layer namse
15  --output_gt OUTPUT_GT        save gt data in dir
16  --config CONFIG
pulsar run 参数解释

必要参数

model.joint model.onnx

--input

可以指定多个输入数据, 并作为仿真 inference 的输入数据. 支持 jpgpngbin 等格式, 需要保证其个数与模型输入层个数一致

--layer
不是必需项
当模型有多路输入时, 用于指定输入数据对应哪一层. 其顺序与 --input 呈对照关系
比如 --input file1.bin file2.bin --layer layerA layerB 就代表给 layerA 输入 file1.bin、给 layerB 输入 file2.bin, 需要保证 --layer 的长度与 --input 的长度一致
--use_onnx_ir
当使用 onnx 格式模型作为对分参考模型时, 此选项用以告诉 pulsar run 在内部用 NeuWizard IR 推理 onnx 模型. 默认不使用 NeuWizard IR
此选项只有在指定了 --onnx 时才有意义, 该选项可忽略
--output_gt

指定用于存放目标模型的仿真 inference 结果和上板输入数据的目录. 默认不输出

--config

指定配置文件, 用于指导 pulsar run 在内部转换参考模型. 一般使用 pulsar build--output_config 选项输出的配置文件

pulsar run 代码示例

pulsar run model.onnx compiled.joint --input test.jpg --config my_output_config.prototxt --output_gt gt

4.3. Pulsar Info 查看模型信息

注意

注意: 只有在版本号大于 0.6.1.2docker 工具链中才能正常使用 pulsar info 功能.

对于旧版本工具链转出的 .joint 模型, 无法通过 pulsar info 查看正确的信息, 需要利用新版本工具链重新转换. 原因在于旧版本 joint 中的 Performance.txt 文件不包含 onnx layer name 信息, 需要重新转换生成.

pulsar info 用于查看 onnxjoint 模型的信息, 并支持将模型信息保存为 html, grid, jira 等格式.

用法命令

pulsar info model.onnx/model.joint

参数列表

$ pulsar info -h

usage: pulsar info [-h] [--output OUTPUT] [--output_json OUTPUT_JSON]
                  [--layer_mapping] [--performance] [--part_info]
                  [--tablefmt TABLEFMT]
                  model

positional arguments:
  model

optional arguments:
  -h, --help            show this help msesage and exit
  --output OUTPUT       path to output dir
  --output_json OUTPUT_JSON
  --layer_mapping
  --performance
  --part_info
  --tablefmt TABLEFMT   possible formats (html, grid, jira, etc.)

参数说明

pulsar info 参数解释
--output

指定模型信息保存目录, 默认不保存

--output_json

以 Json 形式保存模型的完整信息, 默认不保存

--layer_mapping

显示 Joint 模型的 layer_mapping 信息, 默认不显示

可以用于查看 onnx layer 与转换后的 lava layer 间的对应关系

--performance

显示 Joint 模型的 performance 信息, 默认不显示

--part

显示 Joint 模型每个部分的全部信息, 默认不显示

--tablefmt
指定模型信息显示和保存格式, 可选项:
  • simple: 默认选择项

  • grid

  • html

  • jira

  • … 任意 tabulate 库支持的 tablefmt 格式

示例: 查看模型基本信息

pulsar info resnet18.joint

# output log
[24 18:40:10 wrapper_pulsar_info.py:32] Information of resnet18.joint:
IO Meta Info:
NAME                  I/O?    SHAPE             DTYPE    LAYOUT
--------------------  ------  ----------------  -------  --------
data                  INPUT   [1, 224, 224, 3]  uint8    NHWC
resnetv15_dense0_fwd  OUTPUT  [1, 1000]         float32  NCHW

Approx System Memory: 13.84 MB
Approx Standard Memory: 0 B
Approx Memory: 13.84 MB

Virtual NPU: AX620_VNPU_111
Static Batch: 1
Toolchain Version: dfdce086b

示例: 查看 onnx layer 与编译后模型的 layer 之间的对应关系

layer_mapping

其中 ORIGIN_NAmse 为原 onnxlayer name, 而 LAVA_NAmse 则为编译后模型的 layer name.

备注

pulsar info 中指定参数:

  • --layer_mapping 参数可查看 onnx_layer_name 与转换后模型 layer_name 之间的对应关系

  • --performance 参数可以查看各个 layerperformance 信息

4.4. Pulsar Version 查看工具链版本

pulsar version 用于获取工具的版本信息.

提示

如果需要向我们提供工具链的错误信息, 请将您所使用的工具链版本信息一并提交给我们.

代码示例

pulsar version

示例结果

0.5.34.2
7ca3b9d5

4.5. 配套工具

Pulsar 工具链还提供了其他常用的网络模型处理工具, 有助于使用者对网络模型进行格式转换等功能.

4.5.1. Caffe2ONNX

PulsarDocker 镜像中预装了 dump_onnx.sh 工具, 提供将 Caffe 模型转换成 ONNX 模型的功能, 从而间接拓展了 pulsar buildCaffe 模型的支持. 具体使用方法如下所示:

dump_onnx.sh -h 可显示详细命令行参数:

1root@xxx:/data$ dump_onnx.sh
2Usage: /root/caffe2onnx/dump_onnx.sh [prototxt] [caffemodel] [onnxfile]

选项解释

  • [prototxt]

    输入的 caffe 模型的 *.prototxt 文件路径

  • [caffemodel]

    输入的 caffe 模型的 *.caffemodel 文件路径

  • [onnxfile]

    输出的 *.onnx 模型文件路径

代码示例

1root@xxx:/data$ dump_onnx.sh model/mobilenet.prototxt model/mobilenet.caffemodel model/mobilenet.onnx

log 信息示例如下

 1root@xxx:/data$ dump_onnx.sh model/mobilenet.prototxt model/mobilenet.caffemodel model/mobilenet.onnx
 22. start model conversion
 3=================================================================
 4Converting layer: conv1 | Convolution
 5Input:  ['data']
 6Output:  ['conv1']
 7=================================================================
 8Converting layer: conv1/bn | BatchNorm
 9Input:  ['conv1']
10Output:  ['conv1']
11=================================================================
12Converting layer: conv1/scale | Scale
13Input:  ['conv1']
14Output:  ['conv1']
15=================================================================
16Converting layer: relu1 | ReLU
17Input:  ['conv1']
18Output:  ['conv1']
19=================================================================
20####省略若干行 ############
21=================================================================
22Node:  prob
23OP Type:  Softmax
24Input:  ['fc7']
25Output:  ['prob']
26====================================================================
272. onnx model conversion done
284. save onnx model
29model saved as: model/mobilenet.onnx

4.5.2. parse_nw_model

功能

统计 joint 模型 cmm 使用情况

1usage: parse_nw_model.py [-h] [--model MODEL]
2
3optional arguments:
4  -h, --help     show this help msesage and exit
5  --model MODEL  dot_neu or joint file

使用方法示例

以下命令只适用于工具链 docker 环境

1python3 /root/python_modules/super_pulsar/super_pulsar/tools/parse_nw_model.py --model yolox_l.joint
2python3 /root/python_modules/super_pulsar/super_pulsar/tools/parse_nw_model.py --model part_0.neu

返回结果示例

1{'McodeSize': 90816, 'WeightsNum': 1, 'WeightsSize': 568320, 'ringbuffer_size': 0, 'input_num': 1, 'input_size': 24576, 'output_num': 16, 'output_size': 576}

字段说明

字段

说明

单位

Byte

McodeSize

二进制代码 Size

WeightsNum

表示权重个数

WeightsSize

权重 Size

ringbuffer_size

表示模型运行期间需要申请的 DDR Swap 空间

input_num

表示模型的输入 Tensor 数

input_size

输入 Tensor Size

output_num

输出 Tensor 数

output_size

输出 Tensor Size

提示

该脚本统计 joint 模型中所有 .neuCMM 内存, 返回结果为所有 .neu 文件的解析结果之和.

4.5.3. joint 模型初始化速度补丁工具

概述

提示

对于 neuwizard-0.5.29.9 及更早版本工具链转换的 joint 模型文件, 可以使用 optimize_joint_init_time.py 工具离线刷新, 以减少 joint 模型加载时间, 推理结果和时间不变.

使用方法

cd /root/python_modules/super_pulsar/super_pulsar/tools
python3 optimize_joint_init_time.py --input old.joint --output new.joint

4.5.4. joint 模型中的 ONNX 子图转为 AXEngine 子图

使用方法

提示

如下一条指令即可将名为 input.jointjoint 模型(以 ONNX 作为 CPU 后端实现)转为 joint 模型(以 AXEngine 作为 CPU 后端实现), 并且开启优化模式.

python3 /root/python_modules/super_pulsar/super_pulsar/tools/joint_onnx_to_axe.py --input input.joint --output output.joint --optimize_slim_model

参数释义

参数释义
--input

转换工具的输入 joint 模型路径

--output

转换工具的输出 joint 模型路径

--optimize_slim_model

开启优化模式. 当网络输出特征图较小时建议开启, 否则不建议

4.5.5. wbt_tool 使用说明

背景

  • 某些模型在不同使用场景下需要不同的网络权重, 例如 VD 模型的使用场景分为白天和夜晚, 两个网络结构一样, 但权重不一样, 是否可以设置成不同场景使用不同的权重, 即同一个模型保存多组权重信息

  • 可以通过 Pulsar 工具链 Docker 中提供的 wbt_tool 脚本可以实现一个模型, 多套参数的需求

工具概述

工具路径: /root/python_modules/super_pulsar/super_pulsar/tools/wbt_tool.py, 注意需要给 wbt_tool.py 可执行权限

# 添加可执行权限
chmod a+x /root/python_modules/super_pulsar/super_pulsar/tools/wbt_tool.py
wbt_tool 功能参数
info

查看操作, 可以查看 joint 模型的 wbt 名称信息, 如果是 None, 在 fuse 时需要手动指定

fuse

合并操作, 将多个网络结构一样, 网络权重不同的 joint 模型, 合成一个具有多份权重的 joint 模型

split

拆分操作, 将一个具有多份权重的 joint 模型, 拆分成多个网络结构一样, 网络权重不同的 joint 模型

使用限制

警告

不支持含多份 wbtjoint 模型之间的合并, 有需求时请先拆分成多个含单份 wbtjoint 模型, 再和其他模型合并.

示例1

查看模型 model.jointwbt 信息:

<wbt_tool> info model.joint

part_0.neu's wbt_namse:
    index 0: wbt_#0
    index 1: wbt_#1

提示

其中 <wbt_tool>/root/python_modules/super_pulsar/super_pulsar/tools/wbt_tool.py

示例2

合并名为 model1.joint, model2.joint 的两个模型至名为 model.joint 的模型, 使用 joint 模型中自带的 wbt_name

<wbt_tool> fuse --input model1.joint model2.joint --output model.joint

注意

如果 wbt_tool info 查看到 joint 模型的 wbt_nameNone, 需要手动指定 wbt_name, 否则 fuse 时会报错.

示例3

拆分名为 model.joint 的模型至两个名为 model1.joint, model2.joint 的模型

<wbt_tool> split --input model.joint --output model1.joint model2.joint

示例4

合并名为 model1.joint, model2.joint 的两个模型至名为 model.joint 的模型, 且规定 model1.joint 模型中的 wbt_namewbt1, wbt2, model2.joint 模型中的 wbt_namewbt2

<wbt_tool> fuse --input model1.joint model2.joint --output model.joint --wbt_name wbt1 wbt2

示例5

拆分名为 model.joint 的模型, 该模型有四个 wbt 参数, index0, 1, 2, 3, 只取 index1, 3 的那两个 wbt, 包装为 joint 模型, 并取名为 model_idx1.joint, model_idx3.joint

<wbt_tool> split --input model.joint --output model_idx1.joint model_idx3.joint --indexes 1 3

注意

如果有使用上的问题, 请联系相关 FAE 同学进行支持.

4.6. 不同场景下的 config prototxt 配置方法

提示

Pulsar 通过合理配置 config 可以完成复杂的功能, 下面对一些常见场景下 config 配置进行说明. 注意: 本节所提供的代码示例均为代码片段, 需要用户手动添加到合适的位置.

4.6.1. 搜索 PTQ 模型混合比特配置

前置工作

确保当前的 onnx 模型和配置文件 config_origin.prototxtpulsar build 时可以成功转换为 joint 模型.

复制并修改配置文件

COPY 配置文件 config_origin.prototxt 并将其命名为 mixbit.prototxt, 然后对 mixbit.prototxt 作如下修改:

  • output_type 指定为 OUTPUT_TYPE_SUPERNET

  • neuwizard_conf 内添加 task_conf 并按需添加混合比特搜索相关配置

config 示例如下:

 1# 基本配置参数: 输入输出
 2...
 3output_type: OUTPUT_TYPE_SUPERNET
 4...
 5
 6# neuwizard 工具的配置参数
 7neuwizard_conf {
 8    ...
 9    task_conf{
10      task_strategy: TASK_STRATEGY_SUPERNET # 不可修改
11      supernet_options{
12        strategy: SUPERNET_STRATEGY_MIXBIT # 不可修改
13        mixbit_params{
14          target_w_bit: 8 # 设置平均 weight bit, 支持小数但数值必须在 w_bit_choices 的区间内
15          target_a_bit: 6 # 设置平均 feature bit, 支持小数但数值必须在 f_bit_choices 的区间内
16          w_bit_choices: 8 # weight 比特目前仅支持 [4, 8], 由于 prototxt 的限制必须分行写各个选项
17          a_bit_choices: 4 # feature 比特目前仅支持 [4, 8, 16], 由于 prototxt 的限制必须分行写各个选项
18          a_bit_choices: 8
19          # 目前支持 MIXBIT_METRIC_TYPE_HAWQv2, MIXBIT_METRIC_TYPE_MSE, MIXBIT_METRIC_TYPE_COS_SIM 三种,
20          # 其中 hawqv2 速度较慢且可能需要开小 calibration batchsize, 推荐使用 MIXBIT_METRIC_TYPE_MSE
21          metric_type: MIXBIT_METRIC_TYPE_MSE
22        }
23      }
24    }
25  ...
26}

注意

目前 metric_type 支持配置

  • MIXBIT_METRIC_TYPE_HAWQv2

  • MIXBIT_METRIC_TYPE_MSE

  • MIXBIT_METRIC_TYPE_COS_SIM

三种, 其中 HAWQv2 速度较慢且可能需要开小 calibration batchsize, 推荐使用 MIXBIT_METRIC_TYPE_MSE.

进行 mixbit 搜索

在工具链 docker 中执行如下命令

1pulsar build --config mixbit.prototxt --input your.onnx  # 如果模型路径已经配置在 config 中, 可省略 --input xxx

编译结束后会在当前目录产生 mixbit_operator_config.prototxt 文件和 onnx_op_bits.txt 文件.

  • mixbit_operator_config.prototxt 是可直接用于配置 prototxt 的混合比特搜索结果

  • onnx_op_bits.txt 中输出了 .onnx 模型中各权重层的输入 featureweight bit, 以及各 bitsensitivity 计算结果 (数值越小表明对模型表现影响越小)

注意

在搜 mixbit 时, mixbit.prototxt 中如果配置了 evaluation_conf 域, 编译过程中会报错, 但是不影响最终的输出结果, 因此可以忽略.

mixbit 搜索结果添加至配置文件, 编译出基于 mixbit 配置的模型.

mixbit_operator_config.prototxt 中的所有内容直接复制到 config_origin.prototxt (不包含上述混合比特相关配置) 文件中的 neuwizard_conf->operator_conf 内, 示例如下:

 1# neuwizard 工具的配置参数
 2neuwizard_conf {
 3    ...
 4    operator_conf{
 5      ...
 6      operator_conf_items {
 7          selector {
 8              op_name: "192"
 9          }
10          attributes {
11              input_feature_type: UINT4
12              weight_type: INT8
13          }
14      }
15      operator_conf_items {
16          selector {
17              op_name: "195"
18          }
19          attributes {
20              input_feature_type: UINT8
21              weight_type: INT4
22          }
23      }
24      ...
25  }
26  ...
27}

在工具链 docker 中执行如下命令:

1# 命令的参数需要根据实际需求配置, 这里仅用于说明问题
2pulsar build --config config_origin.prototxt --input your.onnx

最后得到编译后的混合比特模型 your.joint. 以下分别测试了 Resnet18Mobilenetv2 在配置不同比特时模型的表现情况.

Resnet18

resnet18

Float top1

QPS

search time

float

69.88%

/

/

8w8f

69.86%

92.92

/

[mse or cos_sim] 6w8f

68.58%

135.39

4s

hawqv2 6w8f

68.58%

135.39

3min

[mse or cos_sim] 5w8f

66.52%

153.14

4s

hawqv2 5w8f

66.52%

153.14

3min

hawqv2 5w7f

65.72%

157.59

7min

[mse or cos_sim] 5w7f

65.8%

157.35

8s

4w8f

55.66%

169.35

/

Mobilenetv2

mobilenetv2

float top1

QPS

search time

float

72.3%

/

/

8w8f

71.02%

165.78

/

hawqv2 6w8f

68.96%

172.10

61min

[mse or cos_sim] 6w8f

69.2%

173.33

6s

[mse or cos_sim] 8w6f

69.56%

174.30

4s

备注

上述繁琐的操作本质上是将搜索出的结果配置到 config_origin.prototxt 中, 基于搜索的配置编译出 joint 模型.

4.6.2. 逐层对分

注意

注意: 只有在版本号大于 0.6.1.2docker 工具链中才能正常使用逐层对分功能.

需要在配置文件中加入以下内容

dataset_conf_error_measurement {
      path: "../dataset/imagenet-1k-images.tar"
      type: DATASET_TYPE_TAR         # 数据集类型为 tar package
      size: 256                      # 量化校准过程中实际使用的图片张数
 }

 evaluation_conf {
      path: "neuwizard.evaluator.error_measure_evaluator"
      type: EVALUATION_TYPE_ERROR_MEASURE
      source_ir_types: IR_TYPE_ONNX
      ir_types: IR_TYPE_LAVA
      score_compare_per_layer: true
 }

完整示例如下(以 resnet18 config 为例)

# 基本配置参数:输入输出
input_type: INPUT_TYPE_ONNX
output_type: OUTPUT_TYPE_JOINT

# 硬件平台选择
target_hardware: TARGET_HARDWARE_AX620

# CPU 后端选择,默认采用 AXE
cpu_backend_settings {
    onnx_setting {
        mode: DISABLED
    }
    axe_setting {
        mode: ENABLED
        axe_param {
            optimize_slim_model: true
        }
    }
}

# 模型输入数据类型设置
src_input_tensors {
    color_space: TENSOR_COLOR_SPACE_RGB
}

dst_input_tensors {
    color_space: TENSOR_COLOR_SPACE_RGB
    # color_space: TENSOR_COLOR_SPACE_NV12  # 若输入数据是 NV12, 则使用该配置
}

# neuwizard 工具的配置参数
neuwizard_conf {
    operator_conf {
        input_conf_items {
            attributes {
                input_modifications {
                    affine_preprocess {
                        slope: 1
                        slope_divisor: 255
                        bias: 0
                    }
                }
                input_modifications {
                    input_normalization {
                        mean: [0.485,0.456,0.406]  ## 均值
                        std: [0.229,0.224,0.255]   ## 方差
                    }
                }
            }
        }
    }
    dataset_conf_calibration {
        path: "../dataset/imagenet-1k-images.tar" # 设置 PTQ 校准数据集路径
        type: DATASET_TYPE_TAR         # 数据集类型:tar 包
        size: 256                      # 量化校准过程中实际使用的图片张数
        batch_size: 1
    }

    dataset_conf_error_measurement {
        path: "../dataset/imagenet-1k-images.tar"
        type: DATASET_TYPE_TAR         # 数据集类型: tar 包
        size: 4                        # 逐层对分过程中实际使用的图片张数
    }

    evaluation_conf {
        path: "neuwizard.evaluator.error_measure_evaluator"
        type: EVALUATION_TYPE_ERROR_MEASURE
        source_ir_types: IR_TYPE_ONNX
        ir_types: IR_TYPE_LAVA
        score_compare_per_layer: true
    }
}

# 输出 layout 设置, 建议使用 NHWC, 速度更快
dst_output_tensors {
    tensor_layout:NHWC
}

# pulsar compiler 的配置参数
pulsar_conf {
    ax620_virtual_npu: AX620_VIRTUAL_NPU_MODE_111   # 业务场景需要使用 ISP, 则必须使用 vNPU 111 配置, 1.8Tops 算力给用户的算法模型
    batch_size: 1
    debug : false
}

pulsar build 过程中, 会打印出模型每一层的精度损失情况, 如下图所示.

comparation

警告

注意, 添加此配置后会大幅度增加模型的编译时间.

4.6.3. 多路输入, 不同路配置不同 CSC

CSC 为色彩空间转换 (Color Space Convert) 的缩写. 以下配置表示输入模型(即 ONNX 模型)的 data_0 输入色彩空间为 BGR, 而编译后的输出模型(即 JOINT 模型)的 data_0 的输入色彩空间将被修改为 NV12, 详细信息可以参考 tensor_conf配置.

简而言之, 就是编译前的模型, 输入 tensor 是什么属性, 而编译后的模型, 输入 tensor 又是什么属性.

代码示例1

1src_input_tensors {
2  tensor_name: "data_0"
3  color_space: TENSOR_COLOR_SPACE_BGR  # 用于描述或说明模型的 `data_0` 路输入的色彩空间
4}
5dst_input_tensors {
6  tensor_name: "data_0"
7  color_space: TENSOR_COLOR_SPACE_NV12  # 用于修改输出模型的 `data_0` 路输入的色彩空间
8}

其中 tensor_name 用于选择某一路 tensor . color_space 用于配置当前 tensor 的色彩空间.

提示

color_space 的默认值为 TENSOR_COLOR_SPACE_AUTO , 会根据模型输入 channel 数自动识别, 3-channel 为 BGR; 1-channel 为 GRAY . 所以如果色彩空间为 BGR 时, 可以不配置 src_input_tensors , 但是有时候为了更好地描述信息, src_input_tensorsdst_input_tensors 通常会成对出现.

代码示例2

1src_input_tensors {
2  color_space: TENSOR_COLOR_SPACE_AUTO
3}
4dst_input_tensors {
5  color_space: TENSOR_COLOR_SPACE_AUTO
6}

根据输入 tensorchannel 数自动选择, 此配置项可省略, 但不推荐.

代码示例3

1src_input_tensors {
2tensor_name: "data_0"
3  color_space: TENSOR_COLOR_SPACE_RGB  # 原始输入模型的 `data_0` 输入的色彩空间是 RGB
4}
5dst_input_tensors {
6  tensor_name: "data_0"
7  color_space: TENSOR_COLOR_SPACE_NV12
8  color_standard: CSS_ITU_BT601_STUDIO_SWING
9}

以上配置表示输入模型(即 ONNX 模型)的 data_0 输入色彩空间为 RGB, 而编译后的输出模型(即 JOINT 模型)的 data_0 的输入色彩空间将被修改为 NV12, 同时将 color_standard 配置为 CSS_ITU_BT601_STUDIO_SWING .

4.6.4. cpu_lstm 配置

提示

如果模型中存在 lstm 结构, 可以参考如下配置文件进行配置, 保证模型在此结构上不会出现异常.

1operator_conf_items {
2  selector {}
3  attributes {
4    lstm_mode: LSTM_MODE_CPU
5  }
6}

一个完整的配置文件参考(包含 cpu_lstm, rgb, nv12)示例

 1input_type: INPUT_TYPE_ONNX
 2output_type: OUTPUT_TYPE_JOINT
 3
 4src_input_tensors {
 5  tensor_name: "data"
 6  color_space: TENSOR_COLOR_SPACE_RGB
 7}
 8dst_input_tensors {
 9  tensor_name: "data"
10  color_space: TENSOR_COLOR_SPACE_NV12
11  color_standard: CSS_ITU_BT601_STUDIO_SWING
12}
13
14target_hardware: TARGET_HARDWARE_AX630  # 可以使用命令行参数覆盖此配置
15neuwizard_conf {
16  operator_conf {
17    input_conf_items {
18      attributes {
19        input_modifications {
20          input_normalization {  # 输入数据归一化, mean/std 的顺序与输入 tensor 的色彩空间有关
21              mean: 0
22              mean: 0
23              mean: 0
24              std: 255.0326
25              std: 255.0326
26              std: 255.0326
27          }
28        }
29      }
30    }
31    operator_conf_items {  # lstm
32      selector {}
33      attributes {
34        lstm_mode: LSTM_MODE_CPU
35      }
36    }
37  }
38  dataset_conf_calibration {
39    path: "../imagenet-1k-images.tar"
40    type: DATASET_TYPE_TAR
41    size: 256
42    batch_size: 32
43  }
44}
45pulsar_conf {
46  batch_size: 1
47}

只有 cpu_lstm 的情况下, 完整配置文件参考如下:

 1input_type: INPUT_TYPE_ONNX
 2output_type: OUTPUT_TYPE_JOINT
 3input_tensors {
 4  color_space: TENSOR_COLOR_SPACE_AUTO
 5}
 6output_tensors {
 7  color_space: TENSOR_COLOR_SPACE_AUTO
 8}
 9target_hardware: TARGET_HARDWARE_AX630
10neuwizard_conf {
11  operator_conf {
12    input_conf_items {
13      attributes {
14        input_modifications {
15          affine_preprocess {  # 对数据做 affine 操作, 即 `* k + b` , 用于改变编译后模型的输入数据类型
16            slope: 1           # 即将输入数据类型由浮点数 [0, 1) 类型修改为 uint8
17            slope_divisor: 255
18            bias: 0
19          }
20        }
21      }
22    }
23    operator_conf_items {
24      selector {}
25      attributes {
26        lstm_mode: LSTM_MODE_CPU
27      }
28    }
29  }
30  dataset_conf_calibration {
31    path: "../imagenet-1k-images.tar"
32    type: DATASET_TYPE_TAR
33    size: 256
34    batch_size: 32
35  }
36}
37pulsar_conf {
38  batch_size: 1
39}

提示

attributes 可以直接修改数据类型, 属于 强制类型转换 , 而 input_modifications 中的 affine 将浮点类型的数据转换为 UINT8 时, 会有 * k + b 操作.

4.6.5. 动态 Q

动态 Q 值会被自动计算, 可以通过 run_joint 打印的log信息查看具体值.

代码示例

1dst_output_tensors {
2  data_type: INT16
3}

4.6.6. 静态 Q

与动态 Q 值的区别在于显式配置 quantization_value.

代码示例

1dst_output_tensors {
2  data_type: INT16
3  quantization_value: 256
4}

关于 Q 值的详细描述参见 Q值介绍

4.6.7. FLOAT 输入配置

如果期望 onnx 编译后的 joint 模型, 能在上板时以 FLOAT32 类型作为输入, 可以按照以下示例对 prototxt 配置.

代码示例

1operator_conf {
2  input_conf_items {
3    attributes {
4      type: FLOAT32   # 这里约定了编译后的模型以 float32 作为输入类型
5    }
6  }
7}

4.6.8. 多路输入, 不同路设置不同的数据类型

如果期望双路 onnx 编译后的 joint 模型, 能在上板时一路以 UINT8 为输入, 另一路以 FLOAT32 为输入, 可以参考以下示例 prototxt 配置.

代码示例

 1operator_conf {
 2  input_conf_items {
 3    selector {
 4      op_name: "input1"
 5    }
 6    attributes {
 7      type: UINT8
 8    }
 9  }
10  input_conf_items {
11    selector {
12      op_name: "input2"
13    }
14    attributes {
15      type: FLOAT32
16    }
17  }
18}

4.6.9. 16bit 量化

提示

在量化精度不足时, 可以考虑 16bit 量化.

代码示例

1operator_conf_items {
2  selector {
3
4  }
5  attributes {
6    input_feature_type: UINT16
7    weight_type: INT8
8  }
9}

4.6.10. Joint Layout配置

在工具链 axera/neuwizard:0.6.0.1 之前, 工具链编译后模型的输出 Layout 根据情况而异, 无法配置.

0.6.0.1 版本之后, 如果不在 pulsar build 或者配置选项中配置编译后模型输出 Layout, 则工具链默认设置编译后模型输出 LayoutNCHW.

通过配置文件修改 joint 输出 Layout 参考如下:

1dst_output_tensors {
2  tensor_layout: NHWC
3}

显式配置方式为: 在 pulsar build 编译指令中添加 --output_tensor_layout nhwc 选项.

提示

由于硬件内部是默认 NHWClayout 排布, 因此更推荐使用 NHWC 以获得更高的 FPS.

4.6.11. 多路 Calibration 数据集

如下配置描述了双路输入模型中每一路采用不同 calibration 数据集的情况, 其中 input0.tarinput1.tar 分别是与训练数据集相关的数据集合.

 1dataset_conf_calibration {
 2  dataset_conf_items {
 3    selector {
 4      op_name: "0"      # 一路输入的 tensor name.
 5    }
 6    path: "input0.tar"  # 使用的校准数据集 `input0.tar`
 7  }
 8  dataset_conf_items {
 9    selector {
10      op_name: "1"      # 另一路输入的 tensor name.
11    }
12    path: "input1.tar"  # 使用的校准数据集 `input1.tar`
13  }
14  type: DATASET_TYPE_TAR
15  size: 256
16}

4.6.12. Calibration 数据集为非图像类型

对于检测和分类模型, 训练数据一般为 UINT8 图像组成的数据集, 而对于诸如 ST-GCN 等行为识别模型, 其训练数据一般为 float 类型的坐标点构成的集合. 目前 Pulsar 工具链支持配置非图像集的 calibration, 接下来对具体配置方法进行说明.

注意

  • calibration 数据集应与训练数据集和测试数据集具有相同的分布

  • calibration 为非图像的情况下需要给出由 .bin 组成的 tar 文件

  • .bin 必须保证与 onnx 模型输入的 shapedtype 一致

ST-GCN 为例, 说明如何配置非图像集的 calibration.

ST-GCN双路输入示例

multi_input_model

从上图可知:

  • 双路 STGCN 模型的输入 tensor_name 分别为 01, dtypefloat32

  • 按照 多路 calibration 的配置方法, 可以很容易地将 config 配置正确

  • tar 文件的具体制作方式, 将在后文中说明

双路输入但不需要配对

在模型双路输入不需要配对的情况下, 说明如何制作 calibration.tar 文件.

参考代码

 1import numpy as np
 2import os
 3import tarfile
 4
 5
 6def makeTar(outputTarName, sourceDir):
 7    # 打 tar 包
 8    with tarfile.open( outputTarName, "w" ) as tar:
 9        tar.add(sourceDir, arcname=os.path.basename(sourceDir))
10
11input_nums = 2   # 双路输入, 如 stgcn
12case_nums = 100  # 每个 tar 中包含 100 个 bin 文件
13
14# 通过 numpy 创建 bin 文件
15for input_num in range(input_nums):
16    for num in range(case_nums):
17        if not os.path.exists(f"stgcn_tar_{input_num}"):
18            os.makedirs(f"stgcn_tar_{input_num}")
19        if input_num == 0:
20            # 输入 shape 和 dtype 必须和原始模型的输入 tensor 保持一致
21            # 这里的 input 是一个随机值, 仅仅作为一个 example
22            # 在实际应用中应读取具体的训练或测试数据集
23            input = np.random.rand(1, 3, 30, 14).astype(np.float32)
24        elif input_num == 1:
25            input = np.random.rand(1, 2, 29, 14).astype(np.float32)
26        else:
27            assert False
28        input.tofile(f"./stgcn_tar_{input_num}/cnt_input_{input_num}_{num}.bin")
29
30    # create tar file.
31    makeTar(f"stgcn_tar_{input_num}.tar", f"./stgcn_tar_{input_num}" )

将上述脚本生成的 tar 文件的路径配置到 config 中的 dataset_conf_calibration.dataset_conf_items.path 处即可,

双路输入需要配对

  • 如果双路输入需要配对, 只需要确保两个 tar 中的 .bin 文件名字对应相同即可

  • stgcn_tar_0.tar 中的 cnt_input_0_0.bin, cnt_input_0_1.bin, …, cnt_input_0_n.bin , 而 stgcn_tar_1.tar 中的文件命名为 cnt_input_1_0.bin, cnt_input_1_1.bin, …, cnt_input_1_n.bin, 两个 tar 中的文件名字对应不同, 因此无法配对输入

  • 简而言之, 当需要输入之间配对时, 配对输入的文件名字要相同

提示

注意:
  • tofile 时不支持设置 dtype

  • 如果想要读入 bin 文件, 还原原始数据, 须指明 dtype, 且与 tofile 时的 dtype 保持一致, 否则会报错或出现元素个数不同的情况

  • 例如, tofiledtypefloat64, 元素个数为 1024, 而读取时候为 float32, 那么元素个数将变更为 2048, 不符合预期

代码示例如下:
1input_0 = numpy.fromfile("./cnt_input_0_0.bin", dtype=np.float32)
2input_0_reshape = input_0.reshape(1, 3, 30, 14)

当执行 fromfile 操作时的 dtypetofile 不同时, reshape 操作会报错

calibrationfloat 集时, 需要在 config 中指明输入 tensordtype, 默认是 UINT8. 如果没有指明, 可能会出现 ZeroDivisionError.

注意

对于 float 输入, 注意还需要配置以下内容:

1operator_conf {
2  input_conf_items {
3    attributes {
4      type: FLOAT32
5    }
6  }
7}

4.6.13. 配置动态 batch

设置动态 batch 后, 在推理时支持 不超过最大值 的任意 batch_size, 使用较灵活, 配置参考如下:

1pulsar_conf {
2  batch_size_option: BSO_DYNAMIC  # 使得编译后的模型支持动态 batch
3  batch_size: 1
4  batch_size: 2
5  batch_size: 4  # 最大 batch_size 为 4, 要求 batch_size 为 1 2 或 4 时推理保持较高性能
6}

4.6.14. 配置静态 batch

动态 batch_size 相比, 静态 batch 的配置更为简单, 配置参考如下:

1pulsar_conf {
2  batch_size: 8  # batch_size 为 8, 也可以是其他值
3}