嵌入式AI学习打卡 09 onnx 部署网络到边缘设备

102 阅读4分钟

适合谁看:资深的嵌入式系统底层专家。技能栈(C、SoC、Bootloader、驱动、系统移植、DSP优化、Cache调优、功耗分析)是芯片设计的核心和基础,具备从硬件(SoC)底层固件(ROM Bootloader)再到操作系统层(驱动、RTOS)的全栈知识和实战经验,希望向嵌入式场景的AI部署方向拓展,寻求新的发展空间。


ONNX Runtime为边缘设备部署机器学习/深度学习/大模型应用提供了丰富的选择,咱来看看基本的流程是啥样的。

image.png

  1. 准备模型 首先要做的就是明确应用的需求,找一个能满足需求的模型。看你是想做图像分类、视频流目标检测、文本处理还是数据预测,去 ONNX model zoo 里找一个合适的网络。

如果你想自己训练一个模型,没有现成的onnx文件可用的话,就看你用的什么框架,用框架提供的的接口转换成onnx格式。

选择模型的时候需要注意模型的大小,因为这玩意得存在SD卡上,运行的时候又得加载到ram里,所以至少要保证ram能放得下。

  1. 开发应用 这一步比较简单,就是用ONNX的API加载和运行模型。ONNX的官网上有一个筛选工具,能看到你的的开发环境和目标板支持的语言接口版本:

image.png

比如这里,选择瑞芯微的rockchip npu做加速器,并且是Linux环境 arm64 处理器,可以看到这种情况有python/c/c++三种语言的API可以使用。

具体安装可以参考这个

image.png

提供的包还挺多,推荐使用下面这几种,根据自己的环境选择:

image.png

这些包应该是测试比较充分,完整包含所有特性,可以直接用,看能不能跑起来,先把流程跑通,再考虑优化。

这里有一个 execution provider 的概念,可以理解为计算在哪儿运行。以CPU为provider的话,就是在CPU上计算。

一开始测试的时候,如果模型是量化的,可以选CPU作为provider,不是量化的话,就首选XNNPACK。所有的计算都在CPU上做是最简单的。

如果这种方式没法满足性能要求的话,就可以尝试NNAPI/CoreML。当然性能是和硬件、模型都有关的。同一个模型在不同的硬件上的性能表现也不同,所以可以多试试,不用急着换硬件方案,选几个类似的模型,找表现最好的那个。

  1. 评估

我们主要关注四点:

  • 应用的二进制文件大小(磁盘容量,启动时间)
  • 模型的大小(内存、运行效率)

上面两个是基础要求,不满足肯定没法选;下面两个是性能要求,和应用开发、用户体验有关系了。

  • 应用延迟(响应实时性,决定是否可用)
  • 功耗(毕竟边缘设备是功耗敏感的)
  1. 优化 然后细说怎么根据性能测试的结果做优化。

首先介绍两种减小模型大小的方法:

一种是量化模型。其实就是减少模型权重的位宽,把32位权重量化成8位的,原始模型的体积大约可缩小至原来的1/4。具体操作步骤可参阅ONNX Runtime的量化指南。

另一种是寻找具有相同输入、输出和架构的移动端优化模型。例如MobileNet和MobileBert就是专为移动设备优化的典型模型。也就是找现成可用的,毕竟从时间成本来看,筛选优于调试。

然后是减小应用的二进制大小,这个得定制runtime。在ORT转换的时候会生成一个配置文件,里面有用到的操作和类型的清单,以这个为输入定制精简版的runtime,可以减小应用的二进制文件的大小,这个和编译的链接时优化类似,去掉不必要的操作依赖啥的。

效果就和模型有关,如果模型用到的操作种类比较少,那效果估计就比较好,就像文件压缩,文件内容越单一,重复越多,那压缩的效果就越好。