本文是在以下文章的基础上编写,关于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版本与芯片相对应

高通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已经下载完成。

二、服务器环境部署SNPE

参照上一篇文章

三、手机环境准备

第一步:手机root

我是利用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服务

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

注意:设备的idATTRS{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

以上完成了所有的准备工作,下面正式开始进入安卓环境中执行推理操作。

注意:服务器连接手机,参考文章写的,个别以自己手机为准。

四、安卓环境利用不同的runtimes进行推理运算

(一)CPUGPU实现推理

本部分主要讲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) CPUGPU上推理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 得到CPUGPU的推理速度.

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资源推理已经完成,祝贺。

(二)DSP实现推理

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!!

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐