1 使用场景
[注1] Pytorch、TensorFlow、PaddPaddle 框架导出 ONNX 模型的示例可参考:
[注2] 地平线 PTQ 工具链转换产出物说明可参考: 4.1.1.6.4. 转换产出物解读
2 使用说明
2.1 原始 ONNX 模型推理
评测各训练框架导出的 ONNX 原始模型精度,可以帮助我们首先确认 ONNX 模型本身:
推理是否正常,否则后续喂给 PTQ 工具链做转换也会报错
精度是否正确,即和原训练框架模型推理结果是否一致或差异很小,以便排除 ONNX 模型导出环节存在问题
# 数据前处理,与训练框架中模型推理时保持一致
# 可以复用原始框架中的推理数据,并将其转换成numpy
# BGR->RGB、Resize、CenterCrop···
# HWC->CHW
# normalization
return data
# 模型后处理
# 加载模型文件
sess = HB_ONNXRuntime(MODEL_PATH)
main()
对比公版 ONNXRuntime,推理代码的差异有以下3处:
加载运行库 | ONNX | import onnxruntime as rt |
|---|---|---|
HB_ONNXRuntime | from horizon_tc_ui import HB_ONNXRuntime | |
加载模型文件 | ONNX | sess = rt.InferenceSession(MODEL_PATH) |
HB_ONNXRuntime | sess = HB_ONNXRuntime(MODEL_PATH) | |
推理模型 | ONNX | outputs = sess.run(output_names, feed_dict) |
HB_ONNXRuntime | outputs = sess.run_feature(output_names, feed_dict, input_offset=0) |
2.2 PTQ各阶段模型推理
首先,我们需要理解 PTQ 各阶段模型的推理精度和测试意义:
***_original_float_model.onnx | 浮点模型,只在原始 ONNX 模型前插入预处理节点 |
|---|---|
***_optimized_float_model.onnx | 浮点模型,已完成图优化,其推理结果与 ***_original_float_model.onnx 一致,正常无需测试 |
***_calibrated_model.onnx | 主要用于精度debug工具[注3],正常无需关注,下文不再涉及 |
***_quantized_model.onnx | 定点模型,其推理结果与板端部署所用的 ***.bin 模型一致 |
[注3] 工具说明请参考: 4.1.2.11. 精度debug工具
其中,数据前处理的基础操作与原始模型一致,但处理后的数据类型和 layout 会稍有差异,这与 yaml 文件中的部分配置项有关。地平线 PTQ 工具链支持在模型前端插入一个 BPU 可加速的预处理节点,依次完成:
- input_type_rt 到 input_type_train 数据类型的转换;
- (data - mean_value) * scale_value 的数据归一化。
针对这四个参数的补充说明如下:
input_type_rt | 模型在板端部署时拿到的推理数据类型,通常为 featuremap、nv12 或 gray: - featuremap:float32,非图像输入 - nv12:uint8,XJ3/J5视频通路输出即为nv12 - gray:uint8,灰度图,对应nv12的单y分量 |
|---|---|
input_type_train | 模型训练时拿到的数据类型类型,通常为 RGB/BGR,gray 或 featuremap |
mean_value & scale_value | 数据前处理过程中的归一化操作,可以集成在模型中使用 BPU 加速,在推理 PTQ 产出的各阶段模型时需注意避免在推理代码中重复操作 |
nv12 | yuv444 | rgb | bgr | gray | featuremap |
|---|---|---|---|---|---|
yuv444_128 | yuv444_128 | RGB_128 | BGR_128 | GRAY_128 | featuremap |
- 对于 XJ3 工具链,图像输入模型的 ***_quantized_model.onnx 模型都会被强制更改为 NHWC,其他模型保持和原始模型一致(通常为 NCHW)
- 对于 J5 工具链,如果模型的 input_type_rt 配置为 nv12,那么 ***_quantized_model.onnx 模型会被强制更改为 NHWC,其他模型保持和原始模型一致(通常为 NCHW)
对于 featuremap 输入的模型,无论是 XJ3 还是 J5 工具链,都会保持和原始模型一致
[注4] ONNX 可视化开源工具:Netron
综上,各阶段 ONNX 模型的差异整理如下,具体使用时对应修改本文 2.1 章节中的推理代码即可。
1)图像输入:
***_original_float_*** | ***_optimized_float_*** | ***_quantized_*** | ||
|---|---|---|---|---|
数据类型 | input_type_rt 对应的中间类型,但不减 128,通过推理接口实现 | |||
数据 layout | 同原始模型 | 同原始模型 | XJ3 | NHWC |
J5 输入类型为nv12 | NHWC | |||
J5 输入类型非nv12 | 同原始模型 | |||
数据归一化 | 请配置在 yaml 中,推理代码中删除 | |||
推理接口 | sess.run(output_names, feed_dict, input_offset=128) | |||
2)Featuremap 输入:
***_original_float_*** | ***_optimized_float_*** | ***_quantized_*** | |
|---|---|---|---|
数据类型 | featuremap | ||
数据 layout | 同原始模型 | ||
数据归一化 | 请在前处理代码中直接完成,仅 channel=3 时可通过 yaml 配置 | ||
推理接口 | sess.run_feature(output_names, feed_dict, input_offset=0) | ||
3)图像 + Featuremap 混合多输入:
***_original_float_*** | ***_optimized_float_*** | ***_quantized_*** | |
|---|---|---|---|
数据类型 | input_type_rt 对应的中间类型,图像输入涉及 -128 的操作请在数据前处理中完成 | ||
数据 layout | 同原始模型 | ||
数据归一化 | 图像请配置在 yaml 中,推理代码中删除; featuremap 请在前处理代码中直接完成,仅 channel=3 时可通过 yaml 配置 | ||
推理接口 | sess.hb_session.run(output_names, feed_dict) | ||
2.3 补充说明
3 附录
公版 ONNXRuntime 推理原始 ONNX 模型的参考代码如下:
# 数据前处理,与训练框架中模型推理时保持一致
# 可以复用原始框架中的推理数据,并将其转换成numpy
# BGR->RGB、Resize、CenterCrop···
# HWC->CHW
# normalization
return data
# 模型后处理
# 加载模型文件
sess = rt.InferenceSession(MODEL_PATH)
main()

