系列文章目录
本文持续迭代更新。。。
背景
算法工程师(此篇文章以CV模型为例),会使用通过大量的数据训练模型的效果,比如检测框能够精准的识别人体或者物体,此项操作多为在原型机上验证的结果,比如英特尔CPU+英伟达GPU显卡的工控机。
通常来说该模型的输入输出、weights 、activation均为FP32的数据类型,该模型直接部署在嵌入式平台会存在算力不足、DDR带宽不足、PCIe带宽不足等性能问题,顾需要通过一些优化方法将优化现有模型,从而能够在嵌入式板卡上达到性能要求。
一、设定性能目标
业务目标主要针对业务场景来设定,常用的性能指标有Inference/second,每秒推理帧数,仅代表推理阶段性能;Frame/second,每秒处理帧数,代表整个pipeline的性能指标,包括前处理和后处理,代表实际应用场景中所需达到的业务指标。
二、优化拆解
1.初步评测
我们需要先将模型转换为嵌入式开发板上能跑的模型,灌入数据测试性能。
- 补充原始模型推理步骤及数据
2.Simpifier简化
如果获取模型文件为onnx,则先通过ONNX Simplifier简化:
官网:https://github.com/daquexian/onnx-simplifier
工具安装:
pip3 install -U pip && pip3 install onnx-simplifier
命令执行:
onnxsim model.onnx model_simplified.onnx
在线版本(比较早期):
https://convertmodel.com
以resnet50为例,以resnet50为例可以看到执行结果:
$ onnxsim model.onnx model_simplified.onnx
Simplifying...
Finish! Here is the difference:
┏━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┓
┃ ┃ Original Model ┃ Simplified Model ┃
┡━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━┩
│ AveragePool │ 1 │ 1 │
│ BatchNormalization │ 53 │ 0 │
│ Conv │ 53 │ 53 │
│ Gemm │ 1 │ 1 │
│ MaxPool │ 1 │ 1 │
│ Relu │ 49 │ 49 │
│ Reshape │ 1 │ 1 │
│ Softmax │ 1 │ 1 │
│ Sum │ 16 │ 16 │
│ Model Size │ 97.7MiB │ 97.4MiB │
└────────────────────┴────────────────┴──────────────────┘
可以看到模型简化对某些网络可以起到很好的作用,但对某些网络不一定能起到作用,比如上述resnet50没有起到明显的作用。但有些模型经过优化后文件大小可以缩小数倍。
onnx simplifier主要有实现constant folding/propagation(即消除结果恒为常量的算子)和图变换(即合并 conv 和 bn 等)。
3.模型的编译部署评估
模型算法原始模型(TF、ONNX、Pytorch等)通常运行在x86 CPU+GPU的环境,而嵌入式平台多为arm架构CPU+专用AI芯片,所以就会有AI芯片对应的工具链和软件栈。模型运行在这个环境上需要将原始的onnx等模型转换为各平台可以执行的模型文件,例如华为平台的转换后的文件为.om文件。其核心部分为模型编译优化,编译器的部分可以开篇详述。
模型的编译优化会有大量的配置参数,因此会产生多种组合,每种组合的performance个有区别,因此需要对不用的边编译结果做性能对比,选取合适的编译参数。
============= Results ===============
cores bs ols mos instances dealloc-dly split-size limit-vtcm-percent InfRate(Inf/sec) Latency(us) PowerEfficiency(Inf/watt)
1 1 1 1 1 1 3 2048 100 36.495 27401.013838 7.462642
2 1 1 1 1 2 3 2048 100 68.730 29099.374363 7.692309
3 1 1 1 1 4 3 2048 100 119.796 33390.096497 7.339472
4 1 1 1 1 8 3 2048 100 173.551 46095.960265 7.031244
5 1 1 1 1 14 3 2048 100 196.841 71123.394008 6.666663
6 2 1 1 1 1 3 2048 100 70.713 14141.671263 7.526892
7 2 1 1 1 2 3 2048 100 129.763 15412.713948 8.045959
8 2 1 1 1 4 3 2048 100 217.572 18384.718622 7.070708
9 2 1 2 1 1 3 2048 100 110.299 9066.265333 8.000004
10 2 1 2 1 2 3 2048 100 201.608 9920.241260 7.407392
11 2 1 2 1 4 3 2048 100 328.708 12168.855032 6.999991
12 2 1 1 2 1 3 2048 100 100.030 9997.000900 8.046017
13 2 1 1 2 2 3 2048 100 186.786 10707.440600 7.500000
14 2 1 1 2 4 3 2048 100 307.210 13020.409492 7.291661
15 2 1 2 2 1 3 2048 100 97.637 10242.018907 8.333359
16 2 1 2 2 2 3 2048 100 180.205 11098.471186 8.450696
17 2 1 2 2 4 3 2048 100 292.666 13667.457101 7.777791
4.模型推理性能瓶颈识别
总结
以上就是针对单个模型部署的大体框架,本文仅仅简单介绍了单一网络的转化,而不同的网络实际部署时会出现不同的问题,例如性能瓶颈,原厂的平台会提供工具会使我们方便快捷的找到瓶颈,进而有针对性的做出性能优化。
参考资料
文章出处登录后可见!