骁龙神经处理引擎SDK参考指南(25)

骁龙神经处理引擎SDK参考指南(25)


6.5.6 量化 DLC 的 UDO DSP 教程

概述

本教程介绍了为 DSP 运行时创建 UDO 包并使用该包执行 Inception-V3 模型所需的步骤。本教程中选择了 Softmax 操作来演示使用 SNPE 实现 UDO。本教程还介绍了 DSP V68 的离线缓存生成步骤。

SNPE SDK 为这个例子提供资源

  • $SNPE_ROOT/示例/NativeCpp/UdoExample/Softmax

有关 UDO 的一般信息可在UDO 概述中找到。

有关在不使用 UDO 的情况下运行 Inception-V3 网络的信息,请参阅Inception-V3 教程。

本教程将生成为 CPU、GPU 和 DSP 运行时运行 Inception-V3 网络所需的工件。此处概述了单独为 DSP 运行时编译和执行 Inception-V3 网络所需的步骤。有关为 CPU 和 GPU 运行时运行 Inception-V3 网络的信息,请访问Inception-V3 UDO 教程。

先决条件

以下教程假定已遵循一般SNPE 设置以支持 SDK 环境、TensorFlow 环境和所需的平台依赖项。此外,我们需要一个提取的 QNN-SDK(不需要 QNN-SDK 设置)来生成框架代码和构建库。有关 QNN-SDK 的详细信息,请参阅页面上的 QNN 文档 Q N N S D K R O O T / d o c s / i n d e x . h t m l ,其中 Q N N S D K R O O T 是 Q N N − S D K 安装的位置。将设置 QNN_SDK_ROOT/docs/index.html,其中QNN_SDK_ROOT是 QNN-SDK 安装的位置。将 设置 QNNSDKROOT/docs/index.html,其中QNNSDKROOTQNNSDK安装的位置。将设置QNN_SDK_ROOT为解压缩的 QNN-SDK 位置。本教程中列出的步骤使用 inception_v3_2016_08_28_frozen.pb 形式的 Tensorflow 模型。有关获取 Inception-V3 模型的详细信息,请访问教程设置。

介绍

以下是开发和运行 UDO 的步骤

  • 1.)包生成
  • 2.)框架模型转换为DLC
  • 3.)包实现
  • 4.)包编译
  • 5.)模型执行

步骤 1-4 在 x86 主机上离线运行,并且是执行步骤 5 所必需的。步骤 5 提供有关使用 SNPE 命令行可执行文件snpe-net-run执行的信息。或者,用户可以使用提供的设置脚本自动执行步骤 1-4 。

第 1 步:包生成

生成 SoftmaxUdoPackage 需要snpe-udo-package-generator工具和提供的 UDO 插件:Softmax_Quant.json。该插件位于 $SNPE_ROOT/examples/NativeCpp/UdoExample/Softmax/config 下。可以在此处找到有关创建 UDO 插件的更多信息。

使用以下内容生成 SoftmaxUdoPackage:

export SNPE_UDO_ROOT=$SNPE_ROOT/share/SnpeUdo
snpe-udo-package-generator -p $SNPE_ROOT/examples/NativeCpp/UdoExample/Softmax/config/Softmax_Quant.json -o $SNPE_ROOT/models/inception_v3/

同样对于 DSP V68 示例,Config 位于以下位置

  • $SNPE_ROOT/examples/NativeCpp/UdoExample/Softmax/config/Softmax_v68.json

此命令在 $SNPE_ROOT/models/inception_v3/SoftmaxUdoPackage 中创建基于 Softmax 的包。
有关 snpe-udo-package-generator 工具的更多信息,请访问此处。

第二步:框架模型转换为DLC

有关将模型转换为 DLC 的信息,请参阅 Inception V3 UDO 模型转换。

这将生成一个名为 inception_v3_udo.dlc 的 DLC,其中包含作为 UDO 的 Softmax,位于 $SNPE_ROOT/models/inception_v3/dlc。

第 3 步:包实现

生成的包创建了操作实现的骨架,用户必须填充该骨架才能创建功能性 UDO。与 SNPE 兼容的其余代码脚手架由snpe-udo-package-generator提供。
本教程的 UDO 实现在 $SNPE_ROOT/examples/NativeCpp/UdoExample/Softmax/src 下提供。

V65 和 V66 的 DSP 实现

在 SNPE DSP 上的具有 UDO 层的网络上运行推理需要一个注册库和一个实现库。注册库将在CPU上运行,并指定了UDO的DSP实现库。
有关为 DSP V65 和 V66运行时实现 UDO 的更多信息,请参阅为 DSP V65 和 V66 实现 UDO。
DSP V65和V66需要实现的包中的文件是

  • SoftmaxUdoPackage/jni/src/DSP/Softmax.cpp

提供的示例实现位于该位置

  • $SNPE_ROOT/examples/NativeCpp/UdoExample/Softmax/src/DSP/Softmax.cpp

将提供的实现复制到包中:

cp -f $SNPE_ROOT/examples/NativeCpp/UdoExample/Softmax/src/DSP/Softmax.cpp $SNPE_ROOT/models/inception_v3/SoftmaxUdoPackage/jni/src/DSP/

可选地,用户可以在包中提供他们自己的实现。

V68 或更高版本的 DSP 实现

与所有其他 SNPE 运行时类似,需要注册库和实现库才能在 SNPE DSP 上使用 UDO 层在网络上运行推理。注册库将在CPU上运行,并指定了UDO的DSP实现库。

有关为 DSP V68 或更高版本运行时实现 UDO 的更多信息,请参阅为 DSP V68 或更高版本实现 UDO。此示例中的目录路径和位置特定于 DSP V68。对于以后的运行时,请将路径中的DSP_V68替换为相应的 DSP 架构(例如DSP_V69 )。

DSP V68及以后版本需要实现的包中文件为

  • SoftmaxUdoPackage/jni/src/DSP_V68/SoftmaxImplLibDsp.cpp

提供的示例实现位于该位置

  • $SNPE_ROOT/examples/NativeCpp/UdoExample/Softmax/src/DSP_v68/SoftmaxImplLibDsp.cpp

将提供的实现复制到包中:

cp -f $SNPE_ROOT/examples/NativeCpp/UdoExample/Softmax/src/DSP_v68/SoftmaxImplLibDsp.cpp $SNPE_ROOT/models/inception_v3/SoftmaxUdoPackage/jni/src/DSP_V68/

可选地,用户可以在包中提供他们自己的实现。

第四步:编译包
Hexagon DSP 运行时编译

DSP 运行时的编译使用 make 系统。为了构建 DSP V65 和 V66 运行时的实现库,需要安装和设置 Hexagon-SDK。有关详细信息,请按照页面上的设置说明进行操作$HEXAGON_SDK_ROOT/docs/readme.html,HEXAGON_SDK_ROOTHexagon-SDK 的安装位置位于此处。为 DSP 编译 UDO 的信息在为 DSP 编译 UDO中可用。

为了构建 DSP V68 或更高版本运行时的实现库,需要安装和设置 Hexagon-SDK 4.0+。 H E X A G O N S D K 4 R O O T / d o c s / r e a d m e . h t m l 有关 H e x a g o n − S D K 的详细信息,请按照页面上的设置说明进行操作, H E X A G O N S D K R O O T H e x a g o n − S D K 的安装位置位于此处。此外,我们需要一个提取的 Q N N − S D K (不需要 Q N N − S D K 设置)来构建库。有关 Q N N − S D K 的详细信息,请参阅页面上的 Q N N 文档 HEXAGON_SDK4_ROOT/docs/readme.html有关 Hexagon-SDK 的详细信息,请按照页面上的设置说明进行操作, HEXAGON_SDK_ROOTHexagon-SDK 的安装位置位于此处。此外,我们需要一个提取的 QNN-SDK(不需要 QNN-SDK 设置)来构建库。有关 QNN-SDK 的详细信息,请参阅页面上的 QNN 文档 HEXAGONSDK4ROOT/docs/readme.html有关HexagonSDK的详细信息,请按照页面上的设置说明进行操作,HEXAGONSDKROOTHexagonSDK的安装位置位于此处。此外,我们需要一个提取的QNNSDK(不需要QNNSDK设置)来构建库。有关QNNSDK的详细信息,请参阅页面上的QNN文档QNN_SDK_ROOT/docs/index.html,其中QNN_SDK_ROOT是 QNN-SDK 安装的位置。将 设置$QNN_SDK_ROOT为解压缩的 QNN-SDK 位置。有关为 DSP V68 或更高版本编译 UDO 的信息,请参阅为 DSP_V68 或更高版本编译 UDO。

在 DSP V68 的情况下为离线缓存生成编译:

cd SoftmaxUdoPackage
make dsp_x86 X86_CXX=<path_to_x86_64_clang>

为离线缓存生成编译后的预期工件是

  • UDO DSP实现库:SoftmaxUdoPackage/libs/x86-64_linux_clang/libUdoSoftmaxUdoPackageImplDsp.so

安装脚本

SNPE SDK 提供了一个选项,可以自动执行上述步骤 1-4 中概述的 UDO 的 dlc 转换、包生成、包实现和包编译步骤。该选项是Inception V3 安装脚本的扩展。要为 UDO 启用 Inception-V3 设置,请使用–udo或-u选项运行脚本。

usage: $SNPE_ROOT/models/inception_v3/scripts/setup_inceptionv3.py [-h] -a ASSETS_DIR [-d] [-r RUNTIME] [-u] [-l [HTP_SOC]]

Prepares the inception_v3 assets for tutorial examples.

required arguments:
  -a ASSETS_DIR, --assets_dir ASSETS_DIR
                        directory containing the inception_v3 assets

optional arguments:
  -d, --download        Download inception_v3 assets to inception_v3 example
                        directory
  -r RUNTIME, --runtime RUNTIME
                        Choose a runtime to set up tutorial for. Choices: cpu,
                        gpu, dsp, aip, all. 'all' option is only supported
                        with --udo flag
  -u, --udo             Generate and compile a user-defined operation package
                        to be used with inception_v3. Softmax is simulated as
                        a UDO for this script.
  -l [HTP_SOC], --htp_soc [HTP_SOC]
                        Specify SOC target for generating HTP Offline Cache.
                        For example: "--htp_soc sm8450" for waipio, default
                        value is sm8550

–udo 扩展与 setup_inceptionv3.py 脚本通常使用的选项兼容。当启用 --udo 选项时,-r 或 --runtime 选项控制包实现和编译的运行时。此外,–udo 选项支持使用“所有”运行时选项来为 CPU、GPU 和 DSP/AIP 运行时创建和编译 SoftmaxUdo 包。选择“aip”或“dsp”运行时选项会额外编译 x86 库以量化模型。选择“cpu”运行时选项可为 x86 和 Android 目标进行编译。如果未设置 ANDROID_NDK_ROOT,将跳过 Android 目标的编译。如果未提供运行时选项,则会为 CPU 运行时编译包。

使用 UDO 设置脚本的命令是:

python3 $SNPE_ROOT/models/inception_v3/scripts/setup_inceptionv3.py -a ~/tmpdir -d -u -r <runtime_of_choice>

对于 DSP V68:

python3 $SNPE_ROOT/models/inception_v3/scripts/setup_inceptionv3.py -a ~/tmpdir -d -u -r <runtime_of_choice> -l

这将填充步骤 4中的工件。

注意:安装脚本针对 arm64-v8a 平台架构进行编译。在使用 make 时为不同的目标集 PLATFORM 进行编译。有关更多信息,请参见第 4 步。

模型执行

使用 snpe-net-run 执行

为 UDO 执行 Inception-V3 与在没有 UDO 的情况下使用snpe-net-run大致相同。

SNPE SDK 提供snpe-net-run的Linux 和 Android 二进制文件

  • $SNPE_ROOT/bin/x86_64-linux-clang
  • $SNPE_ROOT/bin/arm-android-clang8.0
  • $SNPE_ROOT/bin/aarch64-android-clang8.0
  • $SNPE_ROOT/bin/aarch64-oe-linux-gcc8.2
  • $SNPE_ROOT/bin/aarch64-oe-linux-gcc9.3
  • $SNPE_ROOT/bin/aarch64-ubuntu-gcc7.5

对于 UDO,snpe-net-run 通过 --udo_package_path 选项使用注册库。还必须更新 LD_LIBRARY_PATH 以包括从包编译生成的特定于运行时的工件。

安卓目标执行

在 Android 目标上执行的教程将使用 arm64-v8a 架构。

# architecture: arm64-v8a - compiler: clang - STL: libc++
export SNPE_TARGET_ARCH=aarch64-android-clang8.0
export SNPE_TARGET_STL=libc++_shared.so

然后,将 SNPE 二进制文件和库推送到目标设备:

adb shell "mkdir -p /data/local/tmp/snpeexample/$SNPE_TARGET_ARCH/bin"
adb shell "mkdir -p /data/local/tmp/snpeexample/$SNPE_TARGET_ARCH/lib"

adb push $SNPE_ROOT/lib/$SNPE_TARGET_ARCH/$SNPE_TARGET_STL \
      /data/local/tmp/snpeexample/$SNPE_TARGET_ARCH/lib
adb push $SNPE_ROOT/lib/$SNPE_TARGET_ARCH/*.so \
      /data/local/tmp/snpeexample/$SNPE_TARGET_ARCH/lib
adb push $SNPE_ROOT/bin/$SNPE_TARGET_ARCH/snpe-net-run \
      /data/local/tmp/snpeexample/$SNPE_TARGET_ARCH/bin

接下来,更新目标设备上的环境变量以包含 SNPE 库和二进制文件:

adb shell
export SNPE_TARGET_ARCH=aarch64-android-clang8.0
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/data/local/tmp/snpeexample/$SNPE_TARGET_ARCH/lib
export PATH=$PATH:/data/local/tmp/snpeexample/$SNPE_TARGET_ARCH/bin

最后,向设备推送Inception-V3 UDO模型和输入数据:

cd $SNPE_ROOT/models/inception_v3
mkdir data/rawfiles && cp data/cropped/*.raw data/rawfiles/
adb shell "mkdir -p /data/local/tmp/inception_v3_udo"
adb push data/rawfiles /data/local/tmp/inception_v3_udo/cropped
adb push data/target_raw_list.txt /data/local/tmp/inception_v3_udo
adb push dlc/inception_v3_udo.dlc /data/local/tmp/inception_v3_udo
rm -rf data/rawfiles

Hexagon DSP 执行

DSP 在设备上的执行过程与 CPU 和 GPU 大体相同。然而,DSP 运行时需要量化的网络参数。虽然 DSP 允许未量化的 DLC,但通常建议对 DLC 进行量化以提高性能。本教程将使用量化的 DLC 作为示例。量化 DLC 需要snpe-dlc-quantize工具。

注意:在下面的命令中,应该使用在Model DLC Conversion生成的输入 dlc 。此外,在参数“udo_package_path”下提供编译 x86 主机后生成的注册库的路径。可以在此处找到有关编译 x86 的更多信息。

量化 DLC 以在 DSP 上使用:

cd $SNPE_ROOT/models/inception_v3/
snpe-dlc-quantize --input_dlc dlc/inception_v3_udo.dlc --input_list data/cropped/raw_list.txt --udo_package_path SoftmaxUdoPackage/libs/x86-64_linux_clang/libUdoSoftmaxUdoPackageReg.so --output_dlc dlc/inception_v3_udo_quantized.dlc

要使用离线缓存生成量化 DLC 以在 DSP V68 上使用:

将x86编译后生成的注册库libUdoSoftmaxUdoPackageReg.so和实现库libUdoSoftmaxUdoPackageImplCpu.so复制到SoftmaxUdoPackage/libs/x86-64_linux_clang。可以在此处找到有关编译 x86 的更多信息。

cd $SNPE_ROOT/models/inception_v3/
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:SoftmaxUdoPackage/libs/x86-64_linux_clang
snpe-dlc-quantize --input_dlc dlc/inception_v3_udo.dlc --input_list data/cropped/raw_list.txt --udo_package_path SoftmaxUdoPackage/libs/x86-64_linux_clang/libUdoSoftmaxUdoPackageReg.so --output_dlc dlc/inception_v3_udo_quantized.dlc --enable_htp

有关snpe-dlc-quantize的更多信息,请访问量化。有关 UDO 特定量化的信息,请访问使用 UDO 量化 DLC。有关 DSP/AIP 运行时的信息,请访问DSP 运行时或AIP 运行时。

现在将量化模型推送到设备:

adb push dlc/inception_v3_udo_quantized.dlc /data/local/tmp/inception_v3_udo

在 DSP 上执行之前,将 DSP 的 SNPE 库推送到设备:

adb shell "mkdir -p /data/local/tmp/snpeexample/dsp/lib"
adb push $SNPE_ROOT/lib/dsp/*.so /data/local/tmp/snpeexample/dsp/lib

现在将特定于 DSP 的 UDO 库推送到设备。根据配置中指定的 DSP 架构,dsp_v68目录可以是dsp_v60或dsp(使用较旧的 SNPE SDK)。

cd $SNPE_ROOT/models/inception_v3/
adb shell "mkdir -p /data/local/tmp/inception_v3_udo/dsp"
adb push SoftmaxUdoPackage/libs/dsp_v68/*.so /data/local/tmp/inception_v3_udo/dsp
adb push SoftmaxUdoPackage/libs/arm64-v8a/libUdoSoftmaxUdoPackageReg.so /data/local/tmp/inception_v3_udo/dsp # Pushes reg lib

然后设置所需的环境变量并在设备上运行 snpe-net-run :

adb shell
cd /data/local/tmp/inception_v3_udo/
export LD_LIBRARY_PATH=/data/local/tmp/inception_v3_udo/dsp/:$LD_LIBRARY_PATH
export ADSP_LIBRARY_PATH="/data/local/tmp/inception_v3_udo/dsp/;/data/local/tmp/snpeexample/dsp/lib;/system/lib/rfsa/adsp;/system/vendor/lib/rfsa/adsp;/dsp"
snpe-net-run --container inception_v3_udo_quantized.dlc --input_list target_raw_list.txt --udo_package_path dsp/libUdoSoftmaxUdoPackageReg.so --use_dsp

AIP执行

由于 HTA 硬件不支持 UDO,因此在 AIP 运行时执行默认为 DSP UDO 实现。HTA 硬件仅在量化模型上运行,因此与 DSP 运行时一样,将使用量化模型。

注意:在下面的命令中,应该使用在Model DLC Conversion生成的输入 dlc 。还要在参数“udo_package_path”下提供编译 x86 主机后生成的注册库的路径。可以在此处找到有关编译 x86 的更多信息。

为 AIP 量化 DLC 的命令是:

cd $SNPE_ROOT/models/inception_v3/
snpe-dlc-quantize --input_dlc dlc/inception_v3_udo.dlc --input_list data/cropped/raw_list.txt --udo_package_path SoftmaxUdoPackage/libs/x86-64_linux_clang/libUdoSoftmaxUdoPackageReg.so --output_dlc dlc/inception_v3_udo_quantized.dlc --enable_hta

现在将量化模型推送到设备:

adb push dlc/inception_v3_udo_quantized.dlc /data/local/tmp/inception_v3_udo

在使用 AIP 运行时执行之前,使用以下命令将 DSP 的 SNPE 库推送到设备:

adb shell "mkdir -p /data/local/tmp/snpeexample/dsp/lib"
adb push $SNPE_ROOT/lib/dsp/*.so /data/local/tmp/snpeexample/dsp/lib

现在将特定于 DSP 的 UDO 库推送到设备。根据配置中指定的 DSP 架构,dsp_v68目录可以是dsp_v60或dsp(使用较旧的 SNPE SDK)。

cd $SNPE_ROOT/models/inception_v3/
adb shell "mkdir -p /data/local/tmp/inception_v3_udo/dsp"
adb push SoftmaxUdoPackage/libs/dsp_v68/*.so /data/local/tmp/inception_v3_udo/dsp
adb push SoftmaxUdoPackage/libs/arm64-v8a/libUdoSoftmaxUdoPackageReg.so /data/local/tmp/inception_v3_udo/dsp # Pushes reg lib

然后设置所需的环境变量并在设备上运行 snpe-net-run :

adb shell
cd /data/local/tmp/inception_v3_udo/
export LD_LIBRARY_PATH=/data/local/tmp/inception_v3_udo/dsp/:$LD_LIBRARY_PATH
export ADSP_LIBRARY_PATH="/data/local/tmp/inception_v3_udo/dsp/;/data/local/tmp/snpeexample/dsp/lib;/system/lib/rfsa/adsp;/system/vendor/lib/rfsa/adsp;/dsp"
snpe-net-run --container inception_v3_udo_quantized.dlc --input_list target_raw_list.txt --udo_package_path dsp/libUdoSoftmaxUdoPackageReg.so --use_aip

与 Android APK 整合

本教程的这一部分概述了如何将 SNPE UDO 库和用于包注册的 Java API 集成到 Android 应用程序中。通常,要使应用程序可以发现本机共享库,它们必须放在项目中

<project>/app/src/main/jniLibs/<platform_abi>

一旦应用程序可以访问这些库,就可以使用提供的Java API注册注册库。将使用示例图像分类器应用程序复制此过程。以下假设已遵循示例应用程序设置的其余部分。本教程将为具有 arm64-v8a ABI 的平台发布说明。

首先,创建包含 UDO 库的必要目录。以下步骤将填充所有运行时实现库。

mkdir app/src/main/jniLibs/
cp -a $SNPE_ROOT/models/inception_v3/SoftmaxUdoPackage/libs/arm64-v8a/ app/src/main/jniLibs/

如果要使用 DSP 作为运行时,复制实现库如下:

cp $SNPE_ROOT/models/inception_v3/SoftmaxUdoPackage/libs/dsp/*.so app/src/main/jniLibs/arm64-v8a/

如果尚未完成,运行setup_inceptionv3.sh会将启用 UDO 的 Inception-V3 模型添加到项目中。

bash ./setup_inceptionv3.sh

现在可以注册 Java API。编辑文件 $SNPE_ROOT/examples/android/image-classifiers/app/src/main/java/com/qualcomm/qti/snpe/imageclassifiers/tasks/LoadNetworkTask.java

包含这一行

@Override
    protected NeuralNetwork doInBackground(File... params) {
        NeuralNetwork network = null;
        try {
            SNPE.addOpPackage(mApplication,"libUdoSoftmaxUdoPackageReg.so"); // Add this line to register package
            final SNPE.NeuralNetworkBuilder builder = new SNPE.NeuralNetworkBuilder(mApplication)
        ...

现在可以构建和运行 APK

./gradlew assembleDebug
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值