【ATU Book-i.MX8系列 - NPU】 NPU 实际操作

一.   概述

本文主要将介绍恩智浦近期所推广的 AI 芯片 : 神经处理单元( Neural Process Unit,  NPU )

此篇主要探讨 NPU 的进阶使用介绍,像是如何利用 NPU 的进行推理,如何加快暖开机时间,如何显示 NPU 推理时的细节资讯,亦或是如何选用 NPU 或 GPU 进行推理。

如下图文章架构图所示,此架构图隶属于 i.MX8M Plus 的方案博文中,并属于机器学习内的 硬体层(Hardware Layer) 的 NPU 部分,目前章节介绍 “NPU 实际操作”。此外,方块图的右侧也展示了一些小图示,加注说明其中的对应关系。比如说应用层就会对应上 eIQ  的使用。推理引擎层则是各式各样的推理引擎,如 TensorFlow Lite 、 ONNX Runtime 、 ArmNN 等等,硬体加速层则由 OpenVX 以最佳的方式来驱动硬体。

 

若新读者欲理解更多人工智能、机器学习以及深度学习的资讯,可点选查阅下方博文

 大大通精彩博文   【ATU Book-i.MX8系列】博文索引

 

NPU 系列博文-文章架构示意图

 

 

二.  NPU 实际操作

首先会向读者介绍 NPU 的实际操作概念,也就是如何利用推理引擎来完成机器学习的应用 ,以及如何查看 NPU 相关执行资讯。 最后说明何谓 NPU 的暖开机,并如何减少暖开机所花费时间 !! 以及一些关于 NPU 环境变数的设定  !!

 操作概念 : 

对于恩智浦的 NPU 的使用方式,就如 eIQ 系列所述,大致上就是从 推理引擎(inference engine) 的层级来选择 CPU 、 GPU 或是 NPU 进行推理(Inference),也就是最常见的应用端的做法。

如同下方架构图所示,从 TensorFlow Lite 推理引擎来观察,可以发现将以 XNNPACK Delegate (专门用于 Arm 加速)NNAPI Delegate(专门用于 GPU/NPU 加速) VX Delegate(专门用于 GPU/NPU 加速) 等委托服务来进行推理 !!再进一步探讨下去,就能发现其来源是由 OVXLib 与 OpenVX Driver 进行动作,也就是引用 OpenVX 的动态连结库,也就用到硬体加速层,利用此库的优化来达到硬体加速最佳化之目的。 而 NXP 提供完善的 API 应用,让读者或是软体工程师仅须要选择哪种 Delegate ,就能达到不同硬体加速的使用体验

PS : 其中 ArmN、ONNX、DeepViewRT 等推理引擎的操作概念相近

 

TensorFlow Lite 推理方式示意图
资料来源 : 官方网站

 

 

 操作方式 ( C/C++ ) : 

此范例使用 TensorFlow Lite 框架结合轻量化网路模型 MobileNet 去分类物件,并提供不同的后端推理方式给予读者作参考。

 (1) 开启终端机,进入范例之所在位置 (开发板系统内) 

cd /usr/bin/tensorflow-lite-2.6.0/examples​

 (2) 后端推理方式

 -  范例之运行 ARM NEON 后端推理方式

./label_image -m mobilenet_v1_1.0_224_quant.tflite -i grace_hopper.bmp -l labels.txt 

 -  范例之运行 XNNPACK delegate 后端推理方式

./label_image -m mobilenet_v1_1.0_224_quant.tflite -i grace_hopper.bmp -l labels.txt --use_xnnpack=true

  -  范例之运行 NNAPI delegate 后端推理方式

./label_image -m mobilenet_v1_1.0_224_quant.tflite -i grace_hopper.bmp -l labels.txt -a 1

  -  范例之运行 VX delegate 后端推理方式

./label_image -m mobilenet_v1_1.0_224_quant.tflite -i grace_hopper.bmp -l labels.txt --external_delegate_path=/usr/lib/libvx_delegate.so

(3) 运行结果

在 i.MX8M Plus 实测结果依序为 军服(military uniform) 76.4 % 、温莎领带(Windsor tie) 12.1 % 、 领结(bow tie)  1.56 %,故此图片最相似于 军服(military uniform) 的特征分类。其中所花费的推理时间为  ARM NENO 约 44.59 ms 、XNNPACK delegate 约 43.46 ms 、NNAPI delegate (NPU) 约 2.767 ms 、VX delegate (NPU) 约 2.576 ms 。


*** BSP 5.10.35 运行结果 ***

 

 操作方式 ( Python ) : 

此范例使用 TensorFlow lite 框架结合轻量化网路模型 MobileNet去分类物件,但与 C/C++ 的差异是 Python 对于底层的支援性较差一些。

在最新的 BSP 版本中,仅提供 XNNPACK 与 VX Delegate

(1) 开启终端机输入

python3

(2) 后端推理方式

 -  范例之运行 XNNPACK delegate 后端推理方式

#以 TensorFlow Lite 进行推理 (此处为部分代码)
interpreter = tflite.Interpreter(model)

  -  范例之运行 NNAPI delegate 后端推理方式

#(于 BSP L5.10.52 后取消此 Delegate)

  -  范例之运行 VX delegate 后端推理方式

#以 TensorFlow Lite 进行推理 (此处为部分代码)
ext_delegate = [ tflite.load_delegate("/usr/lib/libvx_delegate.so") ]
interpreter = tflite.Interpreter(model, experimental_delegates=ext_delegate)

 PS : 若欲查看整段 python 代码,请点选此处

(3) 运行结果

如下图所示,在 i.MX8M Plus 实测成功识别出 史奇派克犬(schipperke) 则机率为 76 %。

 
*** BSP 5.10.52 运行结果,其中 XNNPACK 数据有差距,由底层描述变更所导致 ***

 

 

 NPU 资讯显示方式 :  

原厂提供一种方式能够显示 NPU 所计算的架构层、权重等讯息,启用步骤如下 :

第一步 : 进入 Uboot

请重新开机,在启动时按下 Enter 进入 Uboot 环境中。

第二步 : 设置环境变数,并离开 Uboot

$ editenv mmcargs 

$ galcore.showArgs=1 galcore.gpuProfiler=1
$ boot

第三步 : 重新启动后,回到 i.MX8M Plus 之 Linux OS 系统下设置环境变数

$ export CNN_PERF=1 NN_EXT_SHOW_PERF=1 VIV_VX_DEBUG_LEVEL=1 VIV_VX_PROFILE=1

第四步 : 进行推理,并产出记录档

范例 - C / C++ 推理演示 :

$ cd /usr/bin/tensorflow-lite-2.6.0/examples
$ ./label_image -m mobilenet_v1_1.0_224_quant.tflite -t 1 -i grace_hopper.bmp -l labels.txt -a 1 -v 0 > viv_test_app_profile.log 2>&1

范例 - Python 推理演示 :

$ pyeiq --run object_classification_tflite > viv_test_app_profile.log

 

推理资讯 : 其 NPU 资讯将记录于 viv_test_app_profile.log 中

  如下,可以看出 NPU 神经网路的架构方式以及每个网路层的详细资讯

 

  

 

 暖开机(Warm-up Time) :  

暖开机(Warm-Up Time) 就如同 “NPU 架构探讨” 所提即到一样。在刚启用 NPU 运算时,将会耗费大量的时间进行事前的推理规划。这就类似在建立神经网路中的神经元,当有电流讯号去刺激神经元时,细胞就将开始被激活与产生相应的活动。故这里将探讨如何加快 NPU 暖开机的启用时间

在进行 NPU 的推理时,将会进行初始化、暖开机、推理演算动作。然而对于首次启动而言,暖开机的时间远远大于推理的时间,就如同下表所示。在推理 MobileNet V1 模组时,暖开机时间约花费 7896 ms,而实际推理时间仅需 3.36 ms !!

 

资料来源 : 官方网站

 

因此,暖开机所花费的时间是相当耗费的 ! 这里提供一种改善方式,能使暖开机所花费的时间大幅度减少。此方式就是将所建立过的神经网路关系纪录至档案(.nb) 中,当再次启用此推理时就仅以读档的方式即可完成推理,这种方式就称作 Graph Catching  !! 如同下表所示,在推理 MobileNet V1 模组时,没有进行 Graph Catching 的方式须耗费 7896 ms。反之,有进行 Graph Catching 的方式仅须耗费 2192 ms !! 数据显示,能大幅度减少暖开机时间 !!

 

资料来源 : 官方网站

 

Graph Catching使用方式 :

在 i.MX8M Plus 之 Linux OS 环境中,输入以下指令…

$ export VIVANTE_VX_CACHE_GRAPH_BINARY_DIR=`pwd`
$ export VIV_VX_ENABLE_CACHE_GRAPH_BINARY=”1”

在首次执行 NPU 推理后,即可产生 .nb 档案

 

 

Graph Catching 使用展示 :

如下图所示,第一次整个推理时间花费 100.792 ms ,第二次整个推理时间花费约 13 .35 ms 。以达到速度上的改善 !!

 

 

 系统环境调整 : 

最后,提供一些关于 NPU 底层的环境变数设定,可依照附件表格来变更底层的操作方式。

 

 

▼ 如何切换 NPU 或 GPU ?

开启终端机,设置环境变数 (Device 端)

 -  切换至 NPU

$ export USE_GPU_INFERENCE 0

  -  切换至 GPU

export USE_GPU_INFERENCE 1

  

▼ 如何使用 Graph Catching?

开启终端机设置环境变数 (Device 端) , 即可读取相应的 .nb 档案。能够大幅度减少 暖开机(WarmUp-time) 时间。

$ export VIVANTE_VX_CACHE_GRAPH_BINARY_DIR=`pwd`
$ export VIV_VX_ENABLE_CACHE_GRAPH_BINARY=”1”

 

 

四.  结语

本文已向读者阐明 NPU 在机器学习框架 TensorFlow Lite 之各个委托代理的用法,不论是 C/C++ 或是 Python 皆能透过变更代码或改变参数的方式来选择不同的硬体来进行模组推理(Inference)。并介绍了如何让系统显示 NPU 运行时的相关资讯,像是模组解析的过程之类的讯息。同时,也说明暖开机的运作原理,以及如何产生出 .nb 档案来缩减暖开机时间。最后,提供一些关于 NPU 的环境变数,让开发者可以查阅此表格来达到不同的应用目的。比如说 NPU 与 GPU的切换,仅须要透过设置环境变数即可达成。而关于 NPU 的细节介绍,这里就告一段落了!! 谢谢各位收看 !!

 

五.  参考文件

[1] 官方文件 - i.MX Machine Learning User's Guide
[2] 官方文件 - ISP and NPU
[3] 官方文件 - i.MX 8M Plus NPU Warmup Time

如有任何相关 NPU 技术问题,欢迎至博文底下留言提问 !!
接下来还会分享更多 NPU 的技术文章 !!敬请期待 【ATU Book-i.MX8 系列 - NPU
 !!

★博文内容均由个人提供,与平台无关,如有违法或侵权,请与网站管理员联系。

★文明上网,请理性发言。内容一周内被举报5次,发文人进小黑屋喔~

评论