概述
本教程描述了创建 UDO 包和使用该包执行 Inception-V3 模型所需的步骤。本教程中选择了 Softmax 操作来演示使用 SNPE 实现 UDO。
SNPE SDK 为这个例子提供资源
有关 UDO 的一般信息可在UDO 概述中找到。
有关在不使用 UDO 的情况下运行 Inception-V3 网络的信息,请参阅Inception-V3 教程。
先决条件
以下教程假定已遵循一般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,其中QNNSDKROOT是QNN−SDK安装的位置。将设置QNN_SDK_ROOT为解压缩的 QNN-SDK 位置。本教程中列出的步骤使用 inception_v3_2016_08_28_frozen.pb 形式的 Tensorflow 模型。有关获取 Inception-V3 模型的详细信息,请访问教程设置。
介绍
以下是开发和运行 UDO 的步骤
1.)包生成2.)框架模型转换为DLC3.)包实现4.)包编译5.)模型执行
步骤 1-4 在 x86 主机上离线运行,并且是执行步骤 5 所必需的。步骤 5 提供有关使用 SNPE 命令行可执行文件snpe-net-run执行的信息。或者,用户可以使用提供的设置脚本自动执行步骤 1-4 。
第 1 步:包生成
生成 SoftmaxUdoPackage 需要snpe-udo-package-generator工具和提供的 UDO 插件:Softmax.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.json -o $SNPE_ROOT/models/inception_v3/
此命令在 $SNPE_ROOT/models/inception_v3/SoftmaxUdoPackage 中创建基于 Softmax 的包。
有关 snpe-udo-package-generator 工具的更多信息,请访问此处。
第二步:框架模型转换为DLC
将 Tensorflow Inception-V3 模型转换为 DLC 需要使用snpe-tensorflow-to-dlc工具。snpe-tensorflow-to-dlc 工具通过 --udo 命令行选项使用在包生成中使用的相同 Softmax.json。这一步中,<INCEPTION_V3_PATH>指的是inception_v3 pb文件的路径。例如,运行 setup_inceptionv3.py 脚本后 <INCEPTION_V3_PATH> 是 $SNPE_ROOT/models/inception_v3/tensorflow。
使用以下内容转换 Inception-V3:
snpe-tensorflow-to-dlc --input_network <INCEPTION_V3_PATH>/inception_v3_2016_08_28_frozen.pb --input_dim 'input' 1,299,299,3 --out_node InceptionV3/Predictions/Reshape_1 --output_path $SNPE_ROOT/models/inception_v3/dlc/inception_v3_udo.dlc --udo $SNPE_ROOT/examples/NativeCpp/UdoExample/Softmax/config/Softmax.json
这将生成一个名为 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 下提供。
CPU 实现(Android 和 x86)
包中需要为CPU实现的文件是
提供的示例实现位于该位置
$SNPE_ROOT/examples/NativeCpp/UdoExample/Softmax/src/CPU/Softmax.cpp
将提供的实现复制到包中:
cp -f $SNPE_ROOT/examples/NativeCpp/UdoExample/Softmax/src/CPU/Softmax.cpp $SNPE_ROOT/models/inception_v3/SoftmaxUdoPackage/jni/src/CPU/src/ops/
可选地,用户可以在包中提供他们自己的实现。
V65 和 V66 的 DSP 实现
与所有其他 SNPE 运行时类似,需要注册库和实现库才能在 SNPE DSP 上运行具有 UDO 层的网络推理。注册库将在CPU上运行,并指定了UDO的DSP实现库。
有关为 DSP V65 和 V66运行时实现 UDO 的更多信息,请参阅为 DSP V65 和 V66 实现 UDO。
DSP V65和V66需要实现的包中的文件是
提供的示例实现位于该位置
将提供的实现复制到包中:
cp -f $SNPE_ROOT/examples/NativeCpp/UdoExample/Softmax/src/DSP/Softmax.cpp $SNPE_ROOT/models/inception_v3/SoftmaxUdoPackage/jni/src/DSP/
可选地,用户可以在包中提供他们自己的实现。
V68 及更高版本的 DSP 实现
有关为 DSP V68 或更高版本运行时实现 UDO 的更多信息,请参阅为 DSP V68 或更高版本实现 UDO。此示例中的目录路径和位置特定于 DSP V68。对于以后的运行时,请将路径中的DSP_V68替换为相应的 DSP 架构(例如DSP_V69 )。
DSP V68及以后版本需要实现的包中文件为
提供的示例实现位于该位置
将提供的实现复制到包中:
cp -f $SNPE_ROOT/examples/NativeCpp/UdoExample/Softmax/src/DSP_v68/SoftmaxImplLibDsp.cpp $SNPE_ROOT/models/inception_v3/SoftmaxUdoPackage/jni/src/DSP_V68/
可选地,用户可以在包中提供他们自己的实现。
第四步:编译包
x86 主机编译
在 x86 主机上编译使用 make build 系统。使用以下内容编译 CPU 实现:
cd $SNPE_ROOT/models/inception_v3/SoftmaxUdoPackage
make cpu_x86
在 x86 主机上为 CPU 编译后的预期工件是
Android CPU 运行时编译
Android 上的 CPU 运行时编译使用 Android NDK。ANDROID_NDK_ROOT 环境变量必须设置为包含 ndk-build 的目录才能编译包。
export ANDROID_NDK_ROOT=<path_to_android_ndk>
建议将 ANDROID_NDK_ROOT 添加到 PATH 环境变量中以访问 ndk-build。
export PATH=$ANDROID_NDK_ROOT:$PATH
编译包时还必须指定目标体系结构。
export UDO_APP_ABI=<target_architecture>
本教程使用 arm64-v8a 架构 - 建议但不要求使用 arm64-v8a 作为本教程其余部分的目标架构。如果没有提供目标体系结构,则 arm64-v8a 和 armeabi-v7a 都是目标。
一旦 ANDROID_NDK_ROOT 成为 PATH 的一部分,为 Android CPU 目标编译包:
cd $SNPE_ROOT/models/inception_v3/SoftmaxUdoPackage
make cpu_android PLATFORM=$UDO_APP_ABI
为 Android CPU 编译后的预期工件是
Hexagon DSP 运行时编译
DSP 运行时的编译使用 make 系统。为了构建 DSP V65 和 V66 运行时的实现库,需要安装和设置 Hexagon-SDK。有关详细信息,请按照页面上的设置说明进行操作$HEXAGON_SDK_ROOT/docs/readme.html,HEXAGON_SDK_ROOTHexagon-SDK 的安装位置位于此处。为 DSP 编译 UDO 的信息在为 DSP 编译 UDO中可用。
安装脚本
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]Prepares the inception_v3 assets for quired arguments:-a ASSETS_DIR, --assets_dir ASSETS_DIRdirectory containing the inception_v3 assetsoptional arguments:-d, --download Download inception_v3 assets to inception_v3 exampledirectory-r RUNTIME, --runtime RUNTIMEChoose a runtime to set up tutorial for. Choices: cpu,gpu, dsp, aip, all. 'all' option is only supportedwith --udo flag-u, --udo Generate and compile a user-defined operation packageto be used with inception_v3. Softmax is simulated asa UDO for this script.
–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>
例如,要创建和编译包含所有运行时库的包,请运行:
python3 $SNPE_ROOT/models/inception_v3/scripts/setup_inceptionv3.py -a ~/tmpdir -d -u -r all
这将填充步骤 4中的工件。
注意:安装脚本针对 arm64-v8a 平台架构进行编译。在使用 make 时为不同的目标集 PLATFORM 进行编译。有关更多信息,请参见第 4 步。
模型执行
使用 snpe-net-run 执行
使用 UDO 执行 Inception-V3 与使用不使用 UDO的snpe-net-run大致相同。
SNPE SDK 提供snpe-net-run的Linux 和 Android 二进制文件
对于 UDO,snpe-net-run 通过 --udo_package_path 选项使用注册库。还必须更新 LD_LIBRARY_PATH 以包括从包编译生成的特定于运行时的工件。
x86 主机执行
要在 x86 主机上执行网络,请运行:
cd $SNPE_ROOT/models/inception_v3
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$SNPE_ROOT/models/inception_v3/SoftmaxUdoPackage/libs/x86-64_linux_clang/
snpe-net-run --container dlc/inception_v3_udo.dlc --input_list data/cropped/ --udo_package_path SoftmaxUdoPackage/libs/x86-64_linux_clang/libUdoSoftmaxUdoPackageReg.so
安卓目标执行
在 Android 目标上执行的教程将使用 arm64-v8a 架构。本教程的这一部分适用于所有运行时(CPU、GPU、DSP)。
# 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_ /data/local/tmp/inception_v3_udo
adb push dlc/inception_v3_udo.dlc /data/local/tmp/inception_v3_udo
rm -rf data/rawfiles
Android CPU 执行
将模型和数据放置在设备上后,将 UDO 库放置在设备上:
cd $SNPE_ROOT/models/inception_v3
adb shell "mkdir -p /data/local/tmp/inception_v3_udo/cpu"
adb push SoftmaxUdoPackage/libs/arm64-v8a/libUdoSoftmaxUdoPackageImplCpu.so /data/local/tmp/inception_v3_udo/cpu
adb push SoftmaxUdoPackage/libs/arm64-v8a/libUdoSoftmaxUdoPackageReg.so /data/local/tmp/inception_v3_udo/cpu
adb push SoftmaxUdoPackage/libs/arm64-v8a/libc++_shared.so /data/local/tmp/inception_v3_udo/cpu
现在设置所需的环境变量并在设备上运行 snpe-net-run:
adb shell
cd /data/local/tmp/inception_v3_udo/
export LD_LIBRARY_PATH=/data/local/tmp/inception_v3_udo/cpu/:$LD_LIBRARY_PATH
snpe-net-run --container inception_v3_udo.dlc --input_list target_ --udo_package_path cpu/libUdoSoftmaxUdoPackageReg.so
Android GPU 执行
使用 GPU 运行时的执行过程与 CPU 的执行过程非常相似。首先,使用以下命令将 UDO 库放置在设备上:
cd $SNPE_ROOT/models/inception_v3
adb shell "mkdir -p /data/local/tmp/inception_v3_udo/gpu"
adb push SoftmaxUdoPackage/libs/arm64-v8a/libUdoSoftmaxUdoPackageImplGpu.so /data/local/tmp/inception_v3_udo/gpu
adb push SoftmaxUdoPackage/libs/arm64-v8a/libUdoSoftmaxUdoPackageReg.so /data/local/tmp/inception_v3_udo/gpu
adb push SoftmaxUdoPackage/libs/arm64-v8a/libc++_shared.so /data/local/tmp/inception_v3_udo/gpu
adb push SoftmaxUdoPackage/libs/arm64-v8a/libOpenCL.so /data/local/tmp/inception_v3_udo/gpu
现在设置所需的环境变量并运行 snpe-net-run 到设备:
adb shell
cd /data/local/tmp/inception_v3_udo/
export LD_LIBRARY_PATH=/data/local/tmp/inception_v3_udo/gpu/:$LD_LIBRARY_PATH
snpe-net-run --container inception_v3_udo.dlc --input_list target_ --udo_package_path gpu/libUdoSoftmaxUdoPackageReg.so --use_gpu
Hexagon DSP 执行
DSP 在设备上的执行过程与 CPU 和 GPU 大体相同。然而,DSP 运行时需要量化的网络参数。虽然 DSP 允许未量化的 DLC,但通常建议对 DLC 进行量化以提高性能。本教程将使用量化的 DLC 作为示例。量化 DLC 需要snpe-dlc-quantize工具。
量化 DLC 以在 DSP 上使用:
cd $SNPE_ROOT/models/inception_v3/
snpe-dlc-quantize --input_dlc dlc/inception_v3_udo.dlc --input_list data/cropped/ --udo_package_path SoftmaxUdoPackage/libs/x86-64_linux_clang/libUdoSoftmaxUdoPackageReg.so --output_dlc dlc/inception_v3_udo_quantized.dlc
有关snpe-dlc-quantize的更多信息,请访问量化。有关 UDO 特定量化的信息,请访问使用 UDO 量化 DLC。有关 DSP/AIP 运行时的信息,请访问DSP 运行时或AIP 运行时。
现在将量化模型推送到设备:
adb push dlc/inception_v3_udo_quantized.dlc /data/local/tmp/inception_v3_udo
注意:请参阅量化 DLC 的 UDO DSP 教程以使用量化 dlc 在 DSP 运行时执行。
在 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_ --udo_package_path dsp/libUdoSoftmaxUdoPackageReg.so --use_dsp
AIP执行
由于 HTA 硬件不支持 UDO,因此在 AIP 运行时执行默认为 DSP UDO 实现。HTA 硬件仅在量化模型上运行,因此与 DSP 运行时一样,将使用量化模型。为 AIP 量化 DLC 的命令是:
cd $SNPE_ROOT/models/inception_v3/
snpe-dlc-quantize --input_dlc dlc/inception_v3_udo.dlc --input_list data/cropped/ --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_ --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
包含这一行
@Overrideprotected NeuralNetwork params) {NeuralNetwork network = null;try {SNPE.addOpPackage(mApplication,"libUdoSoftmaxUdoPackageReg.so"); // Add this line to register packagefinal SNPE.NeuralNetworkBuilder builder = new SNPE.NeuralNetworkBuilder(mApplication)...
现在可以构建和运行 APK
./gradlew assembleDebug
本文发布于:2024-01-28 23:14:30,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170645487510993.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |