本文是在以下文章的基础上编写,关于SNPE环境部署和服务器端推理可以参考上一篇文章:
边缘计算:万字长文详解高通SNPE inception_v3推理实战_seaside2003的博客-CSDN博客
本文最/关键的是利用SNPE在安卓环境不同的runtimes(CPU/GPU/DSP)上运行神经网络推理。
主要参考“组委会AI模型加速”的文章:
上手SNPE-使用888的HTP推理inceptionV3 - 知乎
高通SNPE官方文档
Snapdragon Neural Processing Engine SDK: Main Page
作者用的手机型号是:Redmi K40 pro,芯片是Snapdragon 888,我使用的是红米note7,芯片是:Snapdragon 660AIE处理器。
高通snpe下载链接:
Qualcomm Neural Processing SDK for AI - Qualcomm Developer Network
要点击Archive找到老版本,网速比较慢,耐心。
打开后,如下界面:
下载后解压,如果也需要1.41.0,可以直接到下面链接下载:
https://developer.qualcomm.com/downloads/qualcomm-neural-processing-sdk-ai-v1410?referrer=node/69030
重要提醒:下载哪个版本很关键否则会报错!!
Tips:为啥选择1.41.0,怎么发现的,我的方法:
因为是老手机,先找老一点的版本,一下不一定能找到,试了几次后,发现snpe 1.41.0是支持我这款手机的),打开index.html,
在浏览器中出现以下界面,点击Overview,在右侧找到Supported Snapdragon Devices,可以看到该版本是支持Snapdragon 660的。
至此,SNPE已经下载完成。
参照上一篇文章
我是利用adb命令,这一步是必须的,否则无法执行adb相关命令,root方法自己网上查找,我的红米简单介绍:
1、手机BL解锁
参考:小米手机官方解锁BootLoader图文教程-适用于全部机型20210925更新-ROM乐园官网
2、开始root
告诉你个简单办法,淘宝吧,我试了几乎所有的刷机软件,结果都无卵用,淘宝20块搞定;
主要参考文章:如何在ubuntu下使用adb连接android手机
Verifying your browser... | myfreax
接下我们看看如何在ubuntu下如何使用adb连接到android手机,正常情况下这会非常简单。
安装android-tools-adb
sudo apt update
sudo apt install android-tools-adb android-tools-fastboot
接下来你需要将手机开启开发者模式。打开你的Android手机的设置,找到关于关于手机或者 关于设备 (手机厂商命名可能不一致),然后点击版本号7次,这时手机就会进入开发者模式
现在回到设置,你会看到一个名为开发者选项 的选项,点击该选项,在里面找到USB调试并启用它
adb start-server
可以使用adb devices命令来检查设备是否已正常连接,在正常的情况下,你应该在终端看到以下输出,其中会包括你的手机部分信息,比如型号,其它手机不清楚
adb devices
List of devices attached
NX507J device
如果你未正常连接到手机,看看你是否遇到下面列出的错误
???????????? no permissions
adb devices
List of devices attached
???????????? no permissions
这是因为当前用户组没有权限访问设备,把当前用户加入到plugdev组
sudo useradd -G plugdev $USER
再次使用 adb devices
命令验证是否正确
adb devices
如果还是没有权限检查设备id并创建udev规则
lsusb
Bus 002 Device 002: ID 8087:8000 Intel Corp.
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 8087:8008 Intel Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 004: ID 0930:6545 Toshiba Corp. Kingston DataTraveler 102/2.0 / HEMA Flash Drive 2 GB / PNY Attache 4GB Stick
Bus 003 Device 003: ID 046d:c077 Logitech, Inc. M105 Optical Mouse
Bus 003 Device 002: ID 17ef:602d Lenovo
Bus 003 Device 006: ID 19d2:ffc1 ZTE WCDMA Technologies MSM
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
创建udev规则 /etc/udev/rules.d/51-android.rules
sudo mkdir -p /etc/udev/rules.d/
sudo touch /etc/udev/rules.d/51-android.rules
sudo gedit /etc/udev/rules.d/51-android.rules
粘贴以下内容
SUBSYSTEM=="usb", ATTRS{idVendor}=="19d2", MODE="0666", GROUP="plugdev
注意:设备的id与ATTRS{idVendor}的值对应
改变规则文件的权限
sudo chmod a+r /etc/udev/rules.d/51-android.rules
重载规则并重启udev服务
sudo udevadm control --reload-rules
sudo service udev restart
sudo udevadm trigger
再次使用adb devices命令验证是否正确,然后你可以使用以下命令登录到手机进行操作
adb shell
以上完成了所有的准备工作,下面正式开始进入安卓环境中执行推理操作。
注意:服务器连接手机,参考文章写的,个别以自己手机为准。
本部分主要讲CPU和GPU实现推理,比较简单,使用DSP比较复杂,因此DSP部分单独讲。
接上一篇文章
(1)将数据和模型推到手机/data/local/tmp/incpv3
依次执行以下3条命令:
adb shell mkdir /data/local/tmp/incpv3
adb push inception_v3.dlc /data/local/tmp/incpv3
adb push data/. /data/local/tmp/incpv3
运行结果如下图:
(2)准备SNPE对应的库libSNPE.so和测试工具snpe-net-run
将需要的SNPE库libSNPE.so,libc++_shared.so和测试的应用snpe-net-run推进手机/data/local/tmp/incpv3/
在此之前要知道自己手机支持的cpu架构,方法如下:
Android设备的Architecture架构
参考:
Android设备的Architecture架构:arm64-v8a armeabi-v7a
Android设备的Architecture架构:arm64-v8a armeabi-v7a - 知乎
adb shell getprop ro.product.cpu.abi
我的红米note7手机执行效果:
因此选择:aarch64-android-clang6.0(不一定太对)
依次执行以下6条命令:
adb shell mkdir -p /data/local/tmp/incpv3/arm64/lib
adb shell mkdir -p /data/local/tmp/incpv3/arm64/bin
adb shell mkdir -p /data/local/tmp/incpv3/dsp/lib
adb push $SNPE_ROOT/lib/aarch64-android-clang6.0/libSNPE.so /data/local/tmp/incpv3/arm64/lib
adb push $SNPE_ROOT/lib/aarch64-android-clang6.0/libc++_shared.so /data/local/tmp/incpv3/arm64/lib
adb push $SNPE_ROOT/bin/aarch64-android-clang6.0/snpe-net-run /data/local/tmp/incpv3/arm64/bin
注意:.so文件的推送,可以使用命令,一次把12个.so文件全部推送到手机上
adb push $SNPE_ROOT/lib/aarch64-android-clang6.0/. /data/local/tmp/incpv3/arm64/lib
这样可防止因为.so文件不正确出错,我是直接都放过来了。
我手机目录中在arm64/lib下,把12个文件都放过来了。
(3) 在CPU和GPU上推理inceptionV3
注意:此部分要进入手机安卓系统进行操作,以上都是服务器的操作。
执行:adb shell就会进入手机安卓系统,因为预先已经把手机环境准备好了,
执行ls命令发现没有权限,执行su命令,再利用ls查看,成功
注意:红框里的是代表已经进入手机,查看的是手机的目录,已经不再是服务器中的了。
依次执行4条命令(export是设置环境变量,注意是临时的,手机每次重新插拔都要重新执行该命令,可以永久写入手机,读者可以自己尝试):
cd /data/local/tmp/incpv3/
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/data/local/tmp/incpv3/arm64/lib
export PATH=$PATH:/data/local/tmp/incpv3/arm64/bin
snpe-net-run --version
如果出现红框里的版本号,恭喜,成功在手机安卓中执行了SNPE。
(4)在CPU上推理inceptionV3, 输出在output_cpu
snpe-net-run --container inception_v3.dlc --input_list target_raw_list.txt --output_dir output_cpu
红框里是输出结果
可以进入output_cpu文件夹, ls -al查看生成的文件。
说明:出现了一堆警告,实际上不影响结果,一开始是没有的,知道的朋友可以告诉我原因。
(5)在GPU上推理inceptionV3, 输出在output_gpu. snpe-net-run --use_gpu
snpe-net-run --container inception_v3.dlc --input_list target_raw_list.txt --output_dir output_gpu --use_gpu
输出结果如下:
(6)解析SNPEDiag.log 得到CPU和GPU的推理速度.
adb pull /data/local/tmp/incpv3/output_cpu .
adb pull /data/local/tmp/incpv3/output_gpu .
如下结果所示
注意:上面的命令是在服务器中执行,不是手机端!!
在服务器端执行解析命令:用snpe-diagview 解析SNPEDiag.log 得到推理的时间
CPU:
snpe-diagview --input_log output_cpu/SNPEDiag_0.log
结果如下:可以看到total inference time:658419us
GPU:
snpe-diagview --input_log output_gpu/SNPEDiag_0.log
可以看到,total inference time:351066us
至此:利用CPU、GPU资源推理已经完成,祝贺。
1、首先查看手机芯片是否支持DSP,可以看到660是支持DSP,但不支持AIP
2、量化模型
DSP 推理模型需要做量化,这里使用INT8,我理解这款芯片只能支持INT8量化。
SNPE 提供了后量化工具 snpe-dlc-quantize,加上选项--enable_hta,这样会生成一些cache数据,提升初始化速度。这个选项具有版本依赖性,如果更换了SNPE的版本,那么需要重新生产cache。
一般后量化需要的样例数据在100-200,这里仅仅演示功能,采用较少的数据。
# 将数据和input-list 拷贝到工作目录下
cp data/cropped . -r
cp data/target_raw_list.txt .
snpe-dlc-quantize --input_dlc inception_v3.dlc --input_list target_raw_list.txt --output_dlc inception_v3_hta.dlc --enable_hta
ls -al
注意:原文中是enable_htp,我全部改为了enable_hta,否则报错,可以自行尝试处理。
出现以下画面,未报错,执行成功,生成inception_v3_hta.dlc文件。
……
注意:输出过程很长有删减。
3、手机端准备660 所需要的DSP库
切换到服务器,向手机端推送.so文件。
切换到手机目录查看:
6个.so库推送成功
向手机推送量化后文件:inception_v3_hta.dlc
adb push inception_v3_hta.dlc /data/local/tmp/incpv3/
4、在660上利用DSP进行推理inceptionV3
设置环境变量,除了LD_LIBRARY_PATH和PATH之外,需要设定ADSP_LIBRARY_PATH来指向.so文件的路径。
注意:尽管上面660芯片仅支持CDSP,但是环境变量名称仍为ADSP_LIBRARY_PATH。
设置环境变量:
export ADSP_LIBRARY_PATH="/data/local/tmp/incpv3/dsp/lib;/system/lib/rfsa/adsp;/system/vendor/lib/rfsa/adsp;/dsp"
注意:此处按高通的说明文档,大部分手机dsp目录是上面的其中之一,所以你的手机中不是每个目录都存在的,直接按上面设置即可,除非你的手机dsp不在上述任何一个。
执行推理:
snpe-net-run --container inception_v3_hta.dlc --input_list target_raw_list.txt --use_dsp --output_dir output_hta
运行结果如下,表明成功:
注意1:这是因为安全考虑,只给开发者开放了 unsignedPD,所以要进行如下设置,
snpe-net-run --use_dsp --platform_options unsignedPD:ON
但我的没报错,我没做此步骤,如果报错,按原作者去处理。
注意2:作者原文是htp,
5、结果回传解析推理时间
结果回传:
adb pull /data/local/tmp/incpv3/output_hta .
结果分析:
snpe-diagview --input_log output_hta/SNPEDiag_0.log
结果如图:
……
注意:中间有删减
到了这一步,就全部结束了,祝贺,你又成长了一大步。
最后,我们一起对比下不同runtimes的推理时间吧:
runtimes |
推理时长(ms) |
cpu |
658 |
gpu |
351 |
dsp |
60 |
可以看出:cpu推理时间是dsp推理时间的11倍,gpu是dsp的5.9倍,dsp还是very good!!