8.3 自定义运算符

8.3.1 使用自定义 op 包执行浅层模型

构建示例操作包

包含 Relu 操作的示例 Op 包的源代码适用于 CPU、GPU、DSP 和 HTP 后端。每个后端对于构建 Op Package 消耗品都有不同的要求qnn-net-run。

CPU后端编译

CPU 后端示例 Op 包位于:

${QNN_SDK_ROOT}/examples/QNN/OpPackage/CPU

默认情况下,为 Linux x86-64 和 Android 架构构建 CPU 示例 Op 包,并且依赖于 Android NDK 工具链。确保已ANDROID_NDK_ROOT设置。请参阅设置以获取更多信息。

要构建 CPU 示例 Op 包:

$ cd ${QNN_SDK_ROOT}/examples/QNN/OpPackage/CPU
$ make

这将产生工件:

  • ${QNN_SDK_ROOT}/examples/QNN/OpPackage/CPU/libs/<目标>/libQnnCpuOpPackageExample.so

笔记
可以使用提供的 make 目标指定所需的体系结构:cpu_aarch64-android、cpu_x86

笔记
要仅针对 Linux x86-64 架构进行编译,请将命令“make”替换为“make cpu_x86”。要仅针对 Android 架构进行编译,请将命令“make”替换为“make cpu_android”。

针对 GPU 后端进行编译
GPU 后端示例 Op 包位于:

${QNN_SDK_ROOT}/examples/QNN/OpPackage/GPU

GPU Op Package 的编译依赖于 Android NDK 工具链。确保已ANDROID_NDK_ROOT设置。请参阅设置以获取更多信息。

编译示例 GPU Op 包

$ cd ${QNN_SDK_ROOT}/examples/QNN/OpPackage/GPU
$ make

这将产生工件:

  • ${QNN_SDK_ROOT}/examples/QNN/OpPackage/GPU/libs/<目标>/libQnnGpuOpPackageExample.so

编译 HTP 后端
HTP 后端示例操作包位于:

${QNN_SDK_ROOT}/examples/QNN/OpPackage/HTP

HTP 仿真 x86 编译
为 HTP 仿真编译示例 Op 包依赖于 clang++ 和 Hexagon SDK。

$ export X86_CXX=<path-to-clang++>
$ export HEXAGON_SDK_ROOT=<path-to-hexagon-sdk>
$ export QNN_INCLUDE=${QNN_SDK_ROOT}/include/QNN

要编译示例 HTP 仿真操作包以在 Linux x86-64 架构上使用:

$ cd ${QNN_SDK_ROOT}/examples/QNN/OpPackage/HTP
$ make htp_x86

这将产生工件:

  • ${QNN_SDK_ROOT}/examples/QNN/OpPackage/HTP/build/x86_64-linux-clang/libQnnHtpOpPackageExample.so

HTP HexagonV68编译
为 HTP Hexagon V68 编译示例 Op 包依赖于 Hexagon SDK。

$ export HEXAGON_SDK_ROOT=<path-to-hexagon-sdk>
$ export QNN_INCLUDE=${QNN_SDK_ROOT}/include/QNN

要编译示例 HTP Op 包以在 Hexagon V68 架构上使用:

$ cd ${QNN_SDK_ROOT}/examples/QNN/OpPackage/HTP
$ make htp_v68

这将产生工件:

  • ${QNN_SDK_ROOT}/examples/QNN/OpPackage/HTP/build/hexagon-v68/libQnnHtpOpPackageExample.so

HTP ARM 编译
为 HTP Hexagon V68 编译示例 Op 包依赖于 Android NDK。

$ export ANDROID_NDK_ROOT=<path-to-android-ndk>
$ export QNN_INCLUDE=${QNN_SDK_ROOT}/include/QNN

要编译示例 HTP Op 包以在 Android ARM 架构上使用:

$ cd ${QNN_SDK_ROOT}/examples/QNN/OpPackage/HTP
$ make htp_aarch64

这将产生工件:

  • ${QNN_SDK_ROOT}/examples/QNN/OpPackage/HTP/build/aarch64-android/libQnnHtpOpPackageExample.so

DSP后端编译
DSP 后端示例操作包位于:

${QNN_SDK_ROOT}/examples/QNN/OpPackage/DSP

为 DSP 编译示例 Op 包依赖于 Hexagon SDK。

$ export HEXAGON_SDK_ROOT=<path-to-hexagon-sdk>
$ export QNN_SDK_ROOT=${QNN_SDK_ROOT}

编译示例 DSP Op 包:

$ cd ${QNN_SDK_ROOT}/examples/QNN/OpPackage/DSP
$ make

这将产生工件:

  • ${QNN_SDK_ROOT}/examples/QNN/OpPackage/DSP/build/DSP/libQnnDspOpPackageExample.so

构建示例模型
本教程中的浅层模型是 QNN 转换器的后期使用。有关 QNN 转换器的信息可以在“工具”页面上找到。

该模型位于:

${QNN_SDK_ROOT}/examples/QNN/converter/models/qnn_model_float.cpp

此外,对于 HTP 和 DSP 后端,还有一个量化模型

${QNN_SDK_ROOT}/examples/QNN/converter/models/qnn_model_8bit_quantized.cpp

本教程的其余部分将使用 qnn_model_float.cpp。对于量化模型,将 qnn_model_float.cpp 替换为 qnn_model_8bit_quantized.cpp,将 qnn_model_float.bin 替换为 qnn_model_8bit_quantized.bin。

为了使用示例 Op 包,而不是 QNN 的默认 Op 包,必须手动编辑模型以引用示例。该过程概述如下:

$ vim ${QNN_SDK_ROOT}/examples/QNN/converter/models/qnn_model_float.cpp

前:

242   VALIDATE(convReluModel.addNode(
243                QNN_OPCONFIG_VERSION_1,                              // Op_Config_t Version
244                "InceptionV3_InceptionV3_Conv2d_1a_3x3_Relu",        // Node Name
245                "qti.aisw",                                          // Package Name Default
后:

242   VALIDATE(convReluModel.addNode(
243                QNN_OPCONFIG_VERSION_1,                             // Op_Config_t Version
244                "InceptionV3_InceptionV3_Conv2d_1a_3x3_Relu",       // Node Name
245                "examples.OpPackage",                               // Package Name To Change

填充适当的 Op 包名称后,可以使用 为所需目标构建模型qnn-model-lib-generator。在生成模型之前,请确保ANDROID_NDK_ROOT已设置。请参阅设置 以获取更多信息。

要构建模型,请使用:

$ ${QNN_SDK_ROOT}/bin/x86_64-linux-clang/qnn-model-lib-generator \
  -c ${QNN_SDK_ROOT}/examples/QNN/converter/models/qnn_model_float.cpp \
  -b ${QNN_SDK_ROOT}/examples/QNN/converter/models/qnn_model_float.bin \
  -o ${QNN_SDK_ROOT}/examples/QNN/example_libs # This can be any path

这将产生以下工件:

${QNN_SDK_ROOT}/examples/QNN/example_libs/<目标>/libqnn_model_float.so

笔记
任何输出路径都可以与 -o 标志一起使用。本教程的其余部分将使用 ${QNN_SDK_ROOT}/examples/QNN/example_libs 来引用包含模型库的目录。

CPU后端执行
在 Linux x86 上运行 CPU 后端
当库可发现时,qnn-net-run与以下内容一起使用:

$ cd ${QNN_SDK_ROOT}/examples/QNN/converter/models # access input data
$ ${QNN_SDK_ROOT}/bin/x86_64-linux-clang/qnn-net-run \
              --backend ${QNN_SDK_ROOT}/lib/x86_64-linux-clang/libQnnCpu.so \
              --model ${QNN_SDK_ROOT}/examples/QNN/example_libs/x86_64-linux-clang/libqnn_model_float.so \
              --input_list ${QNN_SDK_ROOT}/examples/QNN/converter/models/input_list_float.txt \
              --op_packages ${QNN_SDK_ROOT}/examples/QNN/OpPackage/CPU/libs/x86_64-linux-clang/libQnnCpuOpPackageExample.so:QnnOpPackage_interfaceProvider

运行的输出将位于默认的 ./output 目录中。

笔记
如果未给 提供完整路径qnn-net-run,则所有库都必须添加到 LD_LIBRARY_PATH 并可由系统库加载器发现。

在 Android 上运行 CPU 后端
在 Android 目标上运行 CPU 后端与在 Linux x86 目标上运行非常相似。

首先,在设备上为示例创建一个目录:

# make oppackage if necessary
$ adb shell "mkdir /data/local/tmp/oppackage"
$ adb shell "mkdir /data/local/tmp/oppackage/CPU"

现在将必要的库推送到设备:

$ adb push ${QNN_SDK_ROOT}/lib/aarch64-android/libQnnCpu.so /data/local/tmp/oppackage/CPU
$ adb push ${QNN_SDK_ROOT}/examples/QNN/OpPackage/CPU/libs/aarch64-android/libQnnCpuOpPackageExample.so /data/local/tmp/oppackage/CPU
$ adb push ${QNN_SDK_ROOT}/examples/QNN/example_libs/aarch64-android/*.so /data/local/tmp/oppackage/CPU

现在将输入数据和输入列表推送到设备:

$ adb push ${QNN_SDK_ROOT}/examples/QNN/converter/models/input_data_float /data/local/tmp/oppackage/CPU
$ adb push ${QNN_SDK_ROOT}/examples/QNN/converter/models/input_list_float.txt /data/local/tmp/oppackage/CPU

推送qnn-net-run工具:

$ adb push ${QNN_SDK_ROOT}/bin/aarch64-android/qnn-net-run /data/local/tmp/oppackage/CPU

现在在设备上设置环境:

$ adb shell
$ cd /data/local/tmp/oppackage/CPU
$ export LD_LIBRARY_PATH=/data/local/tmp/oppackage/CPU

qnn-net-run最后,与以下内容一起使用:

$ ./qnn-net-run --backend libQnnCpu.so --model libqnn_model_float.so --input_list input_list_float.txt --op_packages libQnnCpuOpPackageExample.so:QnnOpPackage_interfaceProvider

运行的输出将位于默认的 ./output 目录中。

GPU后端执行

在 Android 上运行 GPU 后端
在 Android 目标上运行 GPU 后端与在 Android 上运行 CPU 后端非常相似。

首先,在设备上为示例创建一个目录:

# make oppackage if necessary
$ adb shell "mkdir /data/local/tmp/oppackage"
$ adb shell "mkdir /data/local/tmp/oppackage/GPU"

现在将必要的库推送到设备:

$ adb push ${QNN_SDK_ROOT}/lib/aarch64-android/libQnnGpu.so /data/local/tmp/oppackage/GPU
$ adb push ${QNN_SDK_ROOT}/examples/QNN/OpPackage/GPU/libs/aarch64-android/libQnnGpuOpPackageExample.so /data/local/tmp/oppackage/GPU
$ adb push ${QNN_SDK_ROOT}/examples/QNN/example_libs/aarch64-android/*.so /data/local/tmp/oppackage/GPU

现在将输入数据和输入列表推送到设备:

$ adb push ${QNN_SDK_ROOT}/examples/QNN/converter/models/input_data_float /data/local/tmp/oppackage/GPU
$ adb push ${QNN_SDK_ROOT}/examples/QNN/converter/models/input_list_float.txt /data/local/tmp/oppackage/GPU

推送qnn-net-run工具:

$ adb push ${QNN_SDK_ROOT}/bin/aarch64-android/qnn-net-run /data/local/tmp/oppackage/GPU

现在在设备上设置环境:

$ adb shell
$ cd /data/local/tmp/oppackage/GPU
$ export LD_LIBRARY_PATH=/data/local/tmp/oppackage/GPU

qnn-net-run最后,与以下内容一起使用:

$ ./qnn-net-run --backend libQnnGpu.so --model libqnn_model_float.so --input_list input_list_float.txt --op_packages libQnnGpuOpPackageExample.so:QnnOpPackage_interfaceProvider

运行的输出将位于默认的 ./output 目录中。

HTP 后端执行

在 Linux x86 上运行 HTP 模拟后端
编译适当的库后,qnn-net-run可与以下内容一起使用:

$ cd ${QNN_SDK_ROOT}/examples/QNN/converter/models
$ ${QNN_SDK_ROOT}/bin/x86_64-linux-clang/qnn-net-run \
              --backend ${QNN_SDK_ROOT}/lib/x86_64-linux-clang/libQnnHtp.so \
              --model ${QNN_SDK_ROOT}/examples/QNN/example_libs/x86_64-linux-clang/libqnn_model_8bit_quantized.so \
              --input_list ${QNN_SDK_ROOT}/examples/QNN/converter/models/input_list_float.txt \
              --op_packages ${QNN_SDK_ROOT}/examples/QNN/OpPackage/HTP/build/x86_64-linux-clang/libQnnHtpOpPackageExample.so:exampleInterfaceProvider

运行的输出将位于默认的 ./output 目录中。

笔记
如果未给 提供完整路径qnn-net-run,则所有库都必须添加到 LD_LIBRARY_PATH 并可由系统库加载器发现。

使用离线准备图在 Android 上运行 HTP 后端
在 Android 目标上运行 HTP 后端与运行 CPU 和 GPU 后端非常相似。在本教程中,我们首先在 x86 主机上准备图形,然后将序列化的上下文二进制文件传递到设备 HTP 后端来执行。要在 HTP 后端运行图形,除了 hexagon-v68 版本之外,还需要 aarch64 版本的 OpPackage。

此外,可以通过生成序列化上下文来在设备上运行 HTP。与原始 libqnn_model_8bit_quantized.so 模型相比,HTP 可以更有效地初始化此序列化上下文。要生成上下文,请运行:

$ ${QNN_SDK_ROOT}/bin/x86_64-linux-clang/qnn-context-binary-generator \
              --backend ${QNN_SDK_ROOT}/lib/x86_64-linux-clang/libQnnHtp.so \
              --model ${QNN_SDK_ROOT}/examples/QNN/example_libs/x86_64-linux-clang/libqnn_model_8bit_quantized.so \
              --op_packages ${QNN_SDK_ROOT}/examples/QNN/OpPackage/HTP/build/x86_64-linux-clang/libQnnHtpOpPackageExample.so:exampleInterfaceProvider
              --binary_file qnn_model_8bit_quantized.serialized

这会在以下位置创建上下文:

  • ./output/qnn_model_8bit_quantized.serialized.bin

首先,在设备上为示例创建一个目录:

# make oppackage if necessary
$ adb shell "mkdir /data/local/tmp/oppackage"
$ adb shell "mkdir /data/local/tmp/oppackage/HTP"

现在将必要的库推送到设备:

$ adb push ${QNN_SDK_ROOT}/lib/aarch64-android/libQnnHtp.so /data/local/tmp/oppackage/HTP
$ adb push ${QNN_SDK_ROOT}/lib/aarch64-android/libQnnHtpPrepare.so /data/local/tmp/oppackage/HTP
$ adb push ${QNN_SDK_ROOT}/lib/aarch64-android/libQnnHtpV68Stub.so /data/local/tmp/oppackage/HTP
$ adb push ${QNN_SDK_ROOT}/examples/QNN/OpPackage/HTP/build/hexagon-v68/libQnnHtpOpPackageExample.so /data/local/tmp/oppackage/HTP
$ adb push ${QNN_SDK_ROOT}/examples/QNN/OpPackage/HTP/build/aarch64-android/libQnnHtpOpPackageExample.so /data/local/tmp/oppackage/HTP/libQnnHtpOpPackageExample_Cpu.so
$ adb push ${QNN_SDK_ROOT}/examples/QNN/example_libs/aarch64-android/*.so /data/local/tmp/oppackage/HTP
$ adb push ./output/qnn_model_8bit_quantized.serialized.bin /data/local/tmp/oppackage/HTP
$ # Additionally, the HTP requires Hexagon specific libraries
$ adb push ${QNN_SDK_ROOT}/lib/hexagon-v68/unsigned/libQnnHtpV68Skel.so /data/local/tmp/oppackage/HTP

现在将输入数据和输入列表推送到设备:

$ adb push ${QNN_SDK_ROOT}/examples/QNN/converter/models/input_data_float /data/local/tmp/oppackage/HTP
$ adb push ${QNN_SDK_ROOT}/examples/QNN/converter/models/input_list_float.txt /data/local/tmp/oppackage/HTP

推送qnn-net-run工具:

$ adb push ${QNN_SDK_ROOT}/bin/aarch64-android/qnn-net-run /data/local/tmp/oppackage/HTP

现在在设备上设置环境:

$ adb shell
$ cd /data/local/tmp/oppackage/HTP
$ export LD_LIBRARY_PATH=/data/local/tmp/oppackage/HTP
$ export ADSP_LIBRARY_PATH="/data/local/tmp/oppackage/HTP"

qnn-net-run最后,与以下内容一起使用:

$ ./qnn-net-run --backend libQnnHtp.so --retrieve_context qnn_model_8bit_quantized.serialized.bin --input_list input_list_float.txt --op_packages libQnnHtpOpPackageExample_Cpu.so:exampleInterfaceProvider:CPU,libQnnHtpOpPackageExample_Htp.so:exampleInterfaceProvider:HTP

在这种情况下,两个 op 包被传递到 qnn-net-run。第一个 libQnnHtpOpPackageExample_Cpu.so 是 op 包的 ARM aarch64 版本。第二个 op 包 libQnnHtpOpPackageExample_Htp.so 是同一 op 包的 hexagon v68 版本。“:CPU”和“:HTP”是可选的目标参数,指定后端必须在其上注册op包的目标平台。“CPU”目标表示op包是为CPU(ARM aarch64)编译的。“HTP”目标表示 op 包是为设备上的 HTP 编译的。

使用设备上准备好的图表在 Android 上运行 HTP 后端
在本教程中,我们在 Android ARM (CPU) 端准备模型。

首先,在设备上为示例创建一个目录:

# make oppackage if necessary
$ adb shell "mkdir /data/local/tmp/oppackage"
$ adb shell "mkdir /data/local/tmp/oppackage/HTP"

现在将必要的库推送到设备:

$ adb push ${QNN_SDK_ROOT}/lib/aarch64-android/libQnnHtp.so /data/local/tmp/oppackage/HTP
$ adb push ${QNN_SDK_ROOT}/lib/aarch64-android/libQnnHtpPrepare.so /data/local/tmp/oppackage/HTP
$ adb push ${QNN_SDK_ROOT}/lib/aarch64-android/libQnnHtpV68Stub.so /data/local/tmp/oppackage/HTP
$ adb push ${QNN_SDK_ROOT}/examples/QNN/OpPackage/HTP/build/hexagon-v68/libQnnHtpOpPackageExample.so /data/local/tmp/oppackage/HTP/libQnnHtpOpPackageExample_Htp.so
$ adb push ${QNN_SDK_ROOT}/examples/QNN/OpPackage/HTP/build/aarch64-android/libQnnHtpOpPackageExample.so /data/local/tmp/oppackage/HTP/libQnnHtpOpPackageExample_Cpu.so
$ adb push ${QNN_SDK_ROOT}/examples/QNN/example_libs/aarch64-android/*.so /data/local/tmp/oppackage/HTP
$ # Additionally, the HTP requires Hexagon specific libraries
$ adb push ${QNN_SDK_ROOT}/lib/hexagon-v68/unsigned/libQnnHtpV68Skel.so /data/local/tmp/oppackage/HTP

现在将输入数据和输入列表推送到设备:

$ adb push ${QNN_SDK_ROOT}/examples/QNN/converter/models/input_data_float /data/local/tmp/oppackage/HTP
$ adb push ${QNN_SDK_ROOT}/examples/QNN/converter/models/input_list_float.txt /data/local/tmp/oppackage/HTP

推送qnn-net-run工具:

$ adb push ${QNN_SDK_ROOT}/bin/aarch64-android/qnn-net-run /data/local/tmp/oppackage/HTP

现在在设备上设置环境:

$ adb shell
$ cd /data/local/tmp/oppackage/HTP
$ export LD_LIBRARY_PATH=/data/local/tmp/oppackage/HTP
$ export ADSP_LIBRARY_PATH="/data/local/tmp/oppackage/HTP"

qnn-net-run最后,与以下内容一起使用:

$ ./qnn-net-run --backend libQnnHtp.so --model libqnn_model_8bit_quantized.so --input_list input_list_float.txt --op_packages libQnnHtpOpPackageExample_Cpu.so:exampleInterfaceProvider:CPU,libQnnHtpOpPackageExample_Htp.so:exampleInterfaceProvider:HTP

在这种情况下,两个 op 包被传递到 qnn-net-run。第一个 libQnnHtpOpPackageExample_Cpu.so 是 op 包的 ARM aarch64 版本。第二个 op 包 libQnnHtpOpPackageExample_Htp.so 是同一 op 包的 hexagon v68 版本。“:CPU”和“:HTP”是可选的目标参数,指定后端必须在其上注册op包的目标平台。“CPU”目标表示op包是为CPU(ARM aarch64)编译的。“HTP”目标表示 op 包是为设备上的 HTP 编译的。

DSP后端执行
在 Android 上运行 DSP 后端
在 Android 目标上运行 DSP 后端与在 Android 上运行 HTP 后端非常相似。以下假设在 Hexagon DSP v66 设备上运行。

首先,在设备上为示例创建一个目录:

# make oppackage if necessary
$ adb shell "mkdir /data/local/tmp/oppackage"
$ adb shell "mkdir /data/local/tmp/oppackage/DSP"

现在将必要的库推送到设备:

$ adb push ${QNN_SDK_ROOT}/lib/aarch64-android/libQnnDsp.so /data/local/tmp/oppackage/DSP
$ adb push ${QNN_SDK_ROOT}/lib/aarch64-android/libQnnDspV66Stub.so /data/local/tmp/oppackage/DSP
$ adb push ${QNN_SDK_ROOT}/examples/QNN/OpPackage/DSP/build/DSP/libQnnDspOpPackageExample.so /data/local/tmp/oppackage/DSP
$ adb push ${QNN_SDK_ROOT}/examples/QNN/example_libs/aarch64-android/*.so /data/local/tmp/oppackage/DSP
$ adb push ${QNN_SDK_ROOT}/examples/QNN/example_libs/aarch64-android/libqnn_model_8bit_quantized.so /data/local/tmp/oppackage/DSP
$ # Additionally, the DSP requires Hexagon specific libraries
$ adb push ${QNN_SDK_ROOT}/lib/hexagon-v66/unsigned/libQnnDspV66Skel.so /data/local/tmp/oppackage/DSP

现在将输入数据和输入列表推送到设备:

$ adb push ${QNN_SDK_ROOT}/examples/QNN/converter/models/input_data_float /data/local/tmp/oppackage/DSP
$ adb push ${QNN_SDK_ROOT}/examples/QNN/converter/models/input_list_float.txt /data/local/tmp/oppackage/DSP

推送qnn-net-run工具:

$ adb push ${QNN_SDK_ROOT}/bin/aarch64-android/qnn-net-run /data/local/tmp/oppackage/DSP

现在在设备上设置环境:

$ adb shell
$ cd /data/local/tmp/oppackage/DSP
$ export VENDOR_LIB=/vendor/lib/ # /vendor/lib64/ if aarch64
$ export LD_LIBRARY_PATH=/data/local/tmp/oppackage/DSP:/vendor/dsp/cdsp:$VENDOR_LIB
$ export ADSP_LIBRARY_PATH="/data/local/tmp/oppackage/DSP;/vendor/dsp/cdsp;/vendor/lib/rfsa/adsp;/system/lib/rfsa/adsp;/dsp"

qnn-net-run最后,与以下内容一起使用:

$ ./qnn-net-run --backend libQnnDsp.so --model libqnn_model_8bit_quantized.so --input_list input_list_float.txt --op_packages libQnnDspOpPackageExample.so:ExampleReluPackageInterfaceProvider

8.3.2 使用自定义操作转换和执行 CNN 模型

本教程假设已在安装中遵循一般安装说明。

此外,本教程需要获取 Inception V3 Tensorflow 模型文件和示例图像。这是由提供的安装脚本处理的setup_inceptionv3.py。该脚本位于:

${QNN_SDK_ROOT}/examples/Models/InceptionV3/scripts/setup_inceptionv3.py

用法如下:

usage: setup_inceptionv3.py [-h] -a ASSETS_DIR [-c] [-cu] [-d]
                            [-g {cpu,dsp,htp}] [-q]

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:
  -c, --convert_model   Convert and compile model once acquired.
  -cu, --custom         Convert the model using Relu as a custom operation.
                        Only available if --c or --convert_model option is
                        chosen
  -d, --download        Download inception_v3 assets to inception_v3 example
                        directory
  -g {cpu,dsp,htp}, --generate_packages {cpu,dsp,htp}
                        Generate and compile custom op packages for HTP, CPU
                        and DSP
  -q, --quantize_model  Quantize the model during conversion. Only available
                        if --c or --convert_model option is chosen

要运行脚本,请使用:

$ python3 ${QNN_SDK_ROOT}/examples/Models/InceptionV3/scripts/setup_inceptionv3.py -a ~/tmpdir -d

这将填充模型文件:

${QNN_SDK_ROOT}/examples/Models/InceptionV3/tensorflow/inception_v3_2016_08_28_frozen.pb

原始图像位于:

${QNN_SDK_ROOT}/examples/Models/InceptionV3/data/cropped

笔记
如果在 Windows 上开发,请在 WSL (x86) 上运行上述步骤。

自定义操作 XML 配置创建
自定义操作在 QNN 中定义为 XML 文件,其中包含根据XML OpDef Schema Breakdown中概述的 XML 架构对其输入、输出和属性的描述。

有关编写配置的说明可以在XML OpDef Schema Breakdown中找到,并在示例 XML Op Def Configs中显示示例。

在 SDK 中,用户可以在以下位置找到工作示例:

${QNN_SDK_ROOT}/examples/QNN/OpPackageGenerator

给定定义操作和包含该操作的模型的自定义操作配置文件,任何可用的 qnn 转换器都将生成模型工件。同样,可以将配置文件提供给qnn-op-package-generator工具来生成 QNN op 包框架。

在本教程中,以下 XML 配置文件可与上面获得的 Inceptionv3 模型一起使用:

${QNN_SDK_ROOT}/examples/QNN/OpPackageGenerator/ReluOpPackageHtp.xml
${QNN_SDK_ROOT}/examples/QNN/OpPackageGenerator/ReluOpPackageCpu.xml
${QNN_SDK_ROOT}/examples/QNN/OpPackageGenerator/ReluOpPackageDsp.xml

创建 QNN 自定义操作包
创建自定义 op 包包括包生成、实现和编译到共享库。尽管用户可以手动创建自己的包,但我们强烈推荐此工作流程以避免意外错误。我们将在以下部分中介绍这些步骤。

生成自定义 Op 包骨架
对于以下部分,假设已运行设置指令并且 qnn-op-package-generator可以使用该工具。在本教程中,可以分别为CPU、DSP和HTP后端生成包。

笔记
CPU后端的包可以在Windows主机上生成。详细信息如下。

要在Linux上生成 CPU 包,请运行:

$  ${QNN_SDK_ROOT}/bin/x86_64-linux-clang/qnn-op-package-generator \
   -p ${QNN_SDK_ROOT}/examples/QNN/OpPackageGenerator/ReluOpPackageCpu.xml     \
   -o ${QNN_SDK_ROOT}/examples/Models/InceptionV3/InceptionV3OpPackage/CPU # this can be any path

上述命令将产生以下工件:

  • ${QNN_SDK_ROOT}/examples/Models/InceptionV3/InceptionV3OpPackage/CPU/ReluOpPackage

要在Windows上生成 CPU 包,请打开 WSL (x86) 并运行:

$ ${QNN_SDK_ROOT}/bin/x86_64-linux-clang/qnn-op-package-generator \
  -p ${QNN_SDK_ROOT}/examples/QNN/OpPackageGenerator/ReluOpPackageCpu.xml \
  -o ${QNN_SDK_ROOT}/examples/Models/InceptionV3/InceptionV3OpPackage/CPU \
  --gen_cmakelists

上述命令将产生以下工件:

  • ${QNN_SDK_ROOT}/examples/Models/InceptionV3/InceptionV3OpPackage/CPU/ReluOpPackage

生成 DSP 包:

$  ${QNN_SDK_ROOT}/bin/x86_64-linux-clang/qnn-op-package-generator \
   -p ${QNN_SDK_ROOT}/examples/QNN/OpPackageGenerator/ReluOpPackageDsp.xml     \
   -o ${QNN_SDK_ROOT}/examples/Models/InceptionV3/InceptionV3OpPackage/DSP # this can be any path

上述命令将产生以下工件:*${QNN_SDK_ROOT}/examples/Models/InceptionV3/InceptionV3OpPackage/DSP/ReluOpPackage

生成 HTP 包:

$    ${QNN_SDK_ROOT}/bin/x86_64-linux-clang/qnn-op-package-generator  \
     -p ${QNN_SDK_ROOT}/examples/QNN/OpPackageGenerator/ReluOpPackageHtp.xml \
     -o ${QNN_SDK_ROOT}/examples/Models/InceptionV3/InceptionV3OpPackage/HTP # this can be any path

上述命令将产生以下工件:*${QNN_SDK_ROOT}/examples/Models/InceptionV3/InceptionV3OpPackage/HTP/ReluOpPackage

编译 QNN 自定义操作包
上一节中生成的工件将是包含部分完整的框架源文件和用于生成 QNN op 包共享库的 makefile 的目录。这些框架文件提供了用户可以用来实现自定义操作的所有挂钩。

对于本教程,生成的示例应替换为 SDK 中已完成的示例。使用完成的源代码,可以为相关目标编译生成的包。

或者,可以通过-g参数使用提供的设置脚本生成和编译CPU、DSP 和 HTP包中的每一个。

$ python3 ${QNN_SDK_ROOT}/examples/Models/InceptionV3/scripts/setup_inceptionv3.py -a ~/tmpdir -g <cpu or dsp or htp>

笔记
必须在命令行上正确设置环境变量才能复制编译步骤。请参阅下面的手动编译说明,以进一步了解后端特定要求。

Linux 上的 CPU 编译
首先,应使用以下命令将生成的示例替换为 SDK 中已完成的示例:

$ cd ${QNN_SDK_ROOT}/examples/Models/InceptionV3/InceptionV3OpPackage/CPU/ReluOpPackage
$ cp ${QNN_SDK_ROOT}/examples/QNN/OpPackageGenerator/generated/CPU/Relu.cpp ./src/ops

可以使用以下命令编译CPU op包:

$ export CXX=<path-to-clang++>/clang++
$ export ANDROID_NDK_ROOT=<path-to-ndk-build>
$ cd ${QNN_SDK_ROOT}/examples/Models/InceptionV3/InceptionV3OpPackage/CPU/ReluOpPackage && make cpu

并产生以下工件:

  • ${QNN_SDK_ROOT}/examples/Models/InceptionV3/InceptionV3OpPackage/CPU/ReluOpPackage/libs/x86_64-linux-clang/libReluOpPackage.so

  • ${QNN_SDK_ROOT}/examples/Models/InceptionV3/InceptionV3OpPackage/CPU/ReluOpPackage/libs/aarch64-android/libReluOpPackage.so

在 Windows 上针对 CPU 进行编译

首先,应使用以下命令将生成的示例替换为 SDK 中已完成的示例:

$ cd ${QNN_SDK_ROOT}/examples/Models/InceptionV3/InceptionV3OpPackage/CPU/ReluOpPackage
$ cp ${QNN_SDK_ROOT}/examples/QNN/OpPackageGenerator/generated/CPU/Relu.cpp ./src/ops

现在,打开。Developer PowerShell for VS 2022

可以使用以下命令编译CPU op包:

笔记
在为 Windows 编译 CPU op 包时,用户可以在调用 cmake 时使用以下标志选择 x64 或 arm64 架构:。-A [x64 | arm64]

要编译 Windows 主机的 CPU op 包,请使用以下命令:

$ cd ${QNN_SDK_ROOT}\examples\Models\InceptionV3\InceptionV3OpPackage\CPU\ReluOpPackage
$ cmake -S . -B build -A x64
$ cd build
$ cmake --build . --config release

这将生成${QNN_SDK_ROOT}\examples\Models\InceptionV3\InceptionV3OpPackage\CPU\ReluOpPackage\build\Release\ReluOpPackage.dll用于在 Windows 主机上执行的文件。

要为 Windows 设备编译 CPU op 包,步骤与上面相同,只是第二行中的参数变为。-A x64-A arm64

Linux 上的 DSP 编译
首先,应使用以下命令将生成的示例替换为 SDK 中已完成的示例:

$ cd ${QNN_SDK_ROOT}/examples/Models/InceptionV3/InceptionV3OpPackage/DSP/ReluOpPackage
$ cp ${QNN_SDK_ROOT}/examples/QNN/OpPackageGenerator/generated/DSP/Relu.cpp ./src/ops
$ cp ${QNN_SDK_ROOT}/examples/QNN/OpPackageGenerator/generated/DSP/DspOps.hpp ./include

可以使用以下命令编译 DSP op 包:

$ export X86_CXX=<path-to-clang++>
$ export HEXAGON_SDK_ROOT=<path-to-hexagon-sdk>
$ cd ${QNN_SDK_ROOT}/examples/Models/InceptionV3/InceptionV3OpPackage/DSP/ReluOpPackage && make all

请参阅编译器工具链以了解该硬件所需的 HEXAGON_SDK_ROOT 和 X86_CXX 的正确版本。

这将为 DSP 产生以下工件:

  • ${QNN_SDK_ROOT}/examples/Models/InceptionV3/InceptionV3OpPackage/DSP/ReluOpPackage/build/DSP/libQnnReluOpPackage.so

在 Linux 上编译 HTP
首先,应使用以下命令将生成的示例替换为 SDK 中已完成的示例:

$ cd ${QNN_SDK_ROOT}/examples/Models/InceptionV3/InceptionV3OpPackage/HTP/ReluOpPackage
$ cp ${QNN_SDK_ROOT}/examples/QNN/OpPackageGenerator/generated/HTP/Relu.cpp ./src/ops

可以使用以下命令编译 HTP op 包:

$ export X86_CXX=<path-to-clang++>
$ export HEXAGON_SDK_ROOT=<path-to-hexagon-sdk>
$ export QNN_INCLUDE=${QNN_SDK_ROOT}/include/QNN
$ export ANDROID_NDK_ROOT=<path-to-ndk-build>
$ cd ${QNN_SDK_ROOT}/examples/Models/InceptionV3/InceptionV3OpPackage/HTP/ReluOpPackage && make all

请参阅编译器工具链以了解该硬件所需的 HEXAGON_SDK_ROOT 和 X86_CXX 的正确版本。

这将为 HTP 生成以下工件:

  • ${QNN_SDK_ROOT}/examples/Models/InceptionV3/InceptionV3OpPackage/HTP/ReluOpPackage/build/aarch64-android/libQnnReluOpPackage.so

  • ${QNN_SDK_ROOT}/examples/Models/InceptionV3/InceptionV3OpPackage/HTP/ReluOpPackage/build/hexagon-v68/libQnnReluOpPackage.so

  • ${QNN_SDK_ROOT}/examples/Models/InceptionV3/InceptionV3OpPackage/HTP/ReluOpPackage/build/x86_64-linux-clang/libQnnReluOpPackage.so

请参阅编译器工具链以了解该硬件所需的 HEXAGON_SDK_ROOT 和 X86_CXX 的正确版本。

型号转换
获取模型资产后,可以将模型转换为一系列 QNN API 调用,并随后构建供应用程序使用。通过提供配置作为任何可用 QNN 转换器的输入,Inception V3 中的 Relu 操作可以作为自定义操作转换为 QNN 模型。这是使用--op_package_config或 -opc选项完成的

笔记
HTP 和 DSP 后端需要使用量化模型。请参阅模型量化以生成量化模型。

要转换 Inception V3 模型,请使用qnn-tensorflow-converter:

$ ${QNN_SDK_ROOT}/bin/x86_64-linux-clang/qnn-tensorflow-converter \
  --input_network ${QNN_SDK_ROOT}/examples/Models/InceptionV3/tensorflow/inception_v3_2016_08_28_frozen.pb \
  --input_dim input 1,299,299,3 \
  --out_node InceptionV3/Predictions/Reshape_1 \
  --output_path ${QNN_SDK_ROOT}/examples/Models/InceptionV3/model/Inception_v3.cpp \
  --op_package_config ${QNN_SDK_ROOT}/examples/Models/InceptionV3/InceptionV3OpPackage/CPU/ReluOpPackage/config/ReluOpPackageCpu.xml

这将产生以下工件:

  • ${QNN_SDK_ROOT}/examples/Models/InceptionV3/model/Inception_v3.cpp

  • ${QNN_SDK_ROOT}/examples/Models/InceptionV3/model/Inception_v3.bin

这些工件包括一个包含 API 调用序列的 .cpp 文件和一个包含与模型关联的静态数据的 .bin 文件。

模型中的所有 Relu Op 节点应具有与 XML 配置中提供的名称相同的包名称。这对于将操作与前面部分中生成的共享库绑定起来至关重要。用户应注意与包名为 qti.aisw的其他操作的对比,qti.aisw 是 SDK 提供的默认内置操作包。此外,虽然此处使用了ReluOpPackageCpu.xml,但也可以替换之前列出的任何其他配置文件来进行转换。

笔记
如果在 Windows 上开发,请在 WSL (x86) 环境中运行上述内容。

模型量化
要使用量化模型而不是浮点模型,我们需要使用--op_package_lib 或 -opl–选项向转换器提供上面创建的 CPU Op Package。如果没有此选项, 将使用默认的qti.aisw包。

下面的命令使用自定义操作配置和库转换和量化模型:

$ ${QNN_SDK_ROOT}/bin/x86_64-linux-clang/qnn-tensorflow-converter \
  --input_network ${QNN_SDK_ROOT}/examples/Models/InceptionV3/tensorflow/inception_v3_2016_08_28_frozen.pb \
  --input_dim input 1,299,299,3 \
  --out_node InceptionV3/Predictions/Reshape_1 \
  --output_path ${QNN_SDK_ROOT}/examples/Models/InceptionV3/model/Inception_v3_quantized.cpp \
  --op_package_config ${QNN_SDK_ROOT}/examples/Models/InceptionV3/InceptionV3OpPackage/CPU/ReluOpPackage/config/ReluOpPackageCpu.xml  \
  --input_list ${QNN_SDK_ROOT}/examples/Models/InceptionV3/data/cropped/raw_list.txt \
  --op_package_lib ${QNN_SDK_ROOT}/examples/Models/InceptionV3/InceptionV3OpPackage/CPU/ReluOpPackage/libs/x86_64-linux-clang/libReluOpPackage.so:ReluOpPackageInterfaceProvider

这将产生以下工件:

  • ${QNN_SDK_ROOT}/examples/Models/InceptionV3/model/Inception_v3_quantized.cpp

  • ${QNN_SDK_ROOT}/examples/Models/InceptionV3/model/Inception_v3_quantized.bin

  • ${QNN_SDK_ROOT}/examples/Models/InceptionV3/model/Inception_v3_quantized_quantization_encodings.json

笔记
在转换期间量化模型时,输入列表必须包含输入数据的绝对路径。

模型构建
模型转换后,它将被构建到共享库中qnn-model-lib-generator:

Linux 主机上的模型构建

$ ${QNN_SDK_ROOT}/bin/x86_64-linux-clang/qnn-model-lib-generator \
  -c ${QNN_SDK_ROOT}/examples/Models/InceptionV3/model/Inception_v3.cpp \
  -b ${QNN_SDK_ROOT}/examples/Models/InceptionV3/model/Inception_v3.bin \
  -o ${QNN_SDK_ROOT}/examples/Models/InceptionV3/model_libs # This can be any path

这将产生以下工件:

  • ${QNN_SDK_ROOT}/examples/Models/InceptionV3/model_libs/aarch64-android/libInception_v3.so

  • ${QNN_SDK_ROOT}/examples/Models/InceptionV3/model_libs/x86_64-linux-clang/libInception_v3.so

笔记
默认情况下,库是为所有目标构建的。要针对特定​​目标进行编译,请将 -t 选项与 qnn-model-lib-generator 结合使用。 的选择是 aarch64-android 和 x86_64-linux-clang。

或者,可以使用提供的设置脚本完成上述步骤。要使用以下脚本转换并构建模型 Inception V3:

$ python3 ${QNN_SDK_ROOT}/examples/Models/InceptionV3/scripts/setup_inceptionv3.py -a ~/tmpdir -d -c -cu

这将产生与上面相同的工件。

构建量化模型的步骤与上述相同:

$ ${QNN_SDK_ROOT}/bin/x86_64-linux-clang/qnn-model-lib-generator \
  -c ${QNN_SDK_ROOT}/examples/Models/InceptionV3/model/Inception_v3_quantized.cpp \
  -b ${QNN_SDK_ROOT}/examples/Models/InceptionV3/model/Inception_v3_quantized.bin \
  -o ${QNN_SDK_ROOT}/examples/Models/InceptionV3/model_libs # This can be any path

这将产生以下工件:

${QNN_SDK_ROOT}/examples/Models/InceptionV3/model_libs/aarch64-android/libInception_v3_quantized.so

${QNN_SDK_ROOT}/examples/Models/InceptionV3/model_libs/x86_64-linux-clang/libInception_v3_quantized.so

或者,可以使用提供的设置脚本完成上述步骤。要使用以下脚本转换、量化和构建模型 Inception V3:

$ python3 ${QNN_SDK_ROOT}/examples/Models/InceptionV3/scripts/setup_inceptionv3.py -a ~/tmpdir -d -c -q --custom

笔记
当同时选择量化和自定义选项时,即使未提供 --generate_packages,也会生成并编译 cpu op 包,因为需要该库来实现精确量化。

这将产生与上面相同的工件。

Windows 主机上的模型构建
要将模型文件构建到 Windows 主机上的 DLL 库中,我们将使用:.Developer PowerShell for VS 2022

确保使用 Windows 环境设置设置环境${QNN_SDK_ROOT}变量。

$ py -3 ${QNN_SDK_ROOT}\bin\x86_64-windows-msvc\qnn-model-lib-generator `
    -c ${QNN_SDK_ROOT}\examples\Models\InceptionV3\model\Inception_v3.cpp `
    -b ${QNN_SDK_ROOT}\examples\Models\InceptionV3\model\Inception_v3.bin `
    -o ${QNN_SDK_ROOT}\examples\Models\InceptionV3\model_lib ` # this can be any path

这将产生以下工件:

  • ${QNN_SDK_ROOT}\examples\Models\InceptionV3\model_lib\x64\Inception_v3.dll

  • ${QNN_SDK_ROOT}\examples\Models\InceptionV3\model_lib\ARM64\Inception_v3.dll

笔记
通过指定所需的平台,可以为 x64 或 ARM64 平台构建模型 DLL 库。

要将量化模型文件构建到 Windows 主机上的 DLL 库中,我们将再次使用:.Developer PowerShell for VS 2022

确保使用 Windows 环境设置设置环境${QNN_SDK_ROOT}变量。

$ py -3 ${QNN_SDK_ROOT}\bin\x86_64-windows-msvc\qnn-model-lib-generator `
    -c ${QNN_SDK_ROOT}\examples\Models\InceptionV3\model\Inception_v3_quantized.cpp `
    -b ${QNN_SDK_ROOT}\examples\Models\InceptionV3\model\Inception_v3_quantized.bin `
    -o ${QNN_SDK_ROOT}\examples\Models\InceptionV3\model_lib `

这将产生以下工件:

  • ${QNN_SDK_ROOT}\examples\Models\InceptionV3\model_lib\x64\Inception_v3_quantized.dll

  • ${QNN_SDK_ROOT}\examples\Models\InceptionV3\model_lib\ARM64\Inception_v3_quantized.dll

CPU后端执行
在Linux主机上执行

qnn-net-run编译模型库后,可以使用以下命令执行模型:

$ cd ${QNN_SDK_ROOT}/examples/Models/InceptionV3
$ ${QNN_SDK_ROOT}/bin/x86_64-linux-clang/qnn-net-run \
              --backend ${QNN_SDK_ROOT}/lib/x86_64-linux-clang/libQnnCpu.so \
              --model model_libs/x86_64-linux-clang/libInception_v3.so \
              --input_list data/cropped/raw_list.txt \
              --op_packages InceptionV3OpPackage/CPU/ReluOpPackage/libs/x86_64-linux-clang/libReluOpPackage.so:ReluOpPackageInterfaceProvider

这将产生以下结果:

${QNN_SDK_ROOT}/examples/Models/InceptionV3/output

要查看结果,请使用:

$ python3 ${QNN_SDK_ROOT}/examples/Models/InceptionV3/scripts/show_inceptionv3_classifications.py -i data/cropped/raw_list.txt \
                                                                               -o output/ \
                                                                               -l data/imagenet_slim_labels.txt

在Android上执行
在 Android 目标上运行 CPU 后端与在 Linux x86 目标上运行非常相似。

首先,在设备上为示例创建一个目录:

# make inception_v3 directory if necessary
$ adb shell "mkdir /data/local/tmp/inception_v3"

现在将必要的库推送到设备:

$ adb push ${QNN_SDK_ROOT}/lib/aarch64-android/libQnnCpu.so /data/local/tmp/inception_v3
$ adb push ${QNN_SDK_ROOT}/examples/Models/InceptionV3/InceptionV3OpPackage/CPU/ReluOpPackage/libs/aarch64-android/libReluOpPackage.so /data/local/tmp/inception_v3
$ adb push ${QNN_SDK_ROOT}/examples/Models/InceptionV3/model_libs/aarch64-android/*.so /data/local/tmp/inception_v3

现在将输入数据和输入列表推送到设备:

$ adb push ${QNN_SDK_ROOT}/examples/Models/InceptionV3/data/cropped /data/local/tmp/inception_v3
$ adb push ${QNN_SDK_ROOT}/examples/Models/InceptionV3/data/target_raw_list.txt /data/local/tmp/inception_v3

推送qnn-net-run工具:

$ adb push ${QNN_SDK_ROOT}/bin/aarch64-android/qnn-net-run /data/local/tmp/inception_v3

现在在设备上设置环境:

$ adb shell
$ cd /data/local/tmp/inception_v3
$ export LD_LIBRARY_PATH=/data/local/tmp/inception_v3

qnn-net-run最后,与以下内容一起使用:

$ ./qnn-net-run --backend libQnnCpu.so --model libInception_v3.so --input_list target_raw_list.txt \
                --op_packages libReluOpPackage.so:ReluOpPackageInterfaceProvider

运行的输出将位于默认的 ./output 目录中。退出设备并查看结果:

$ exit
$ cd ${QNN_SDK_ROOT}/examples/Models/InceptionV3
$ adb pull /data/local/tmp/inception_v3/output output_android
$ python3 ${QNN_SDK_ROOT}/examples/Models/InceptionV3/scripts/show_inceptionv3_classifications.py -i data/cropped/raw_list.txt \
                                                                               -o output_android/ \
                                                                               -l data/imagenet_slim_labels.txt

在 Windows 主机上执行
请确保在 Windows 主机上的模型构建和Windows 上的 CPU部分的编译已完成,然后再继续。

首先,在 Windows 主机上创建以下文件夹:${QNN_SDK_ROOT}\tmp\qnn_inception_v3_test_package。

现在,将必要的库和输入数据复制到:${QNN_SDK_ROOT}\tmp\qnn_inception_v3_test_package。

- ${QNN_SDK_ROOT}/lib/x86_64-windows-msvc/QnnCpu.dll
- ${QNN_SDK_ROOT}/examples/Models/InceptionV3/model_lib/x64/Inception_v3.dll (generated above)
- ${QNN_SDK_ROOT}/examples/Models/InceptionV3/InceptionV3OpPackage/CPU/ReluOpPackage/build/Release/ReluOpPackage.dll (x64 version as generated above)
- ${QNN_SDK_ROOT}/examples/Models/InceptionV3/data/cropped
- ${QNN_SDK_ROOT}/examples/Models/InceptionV3/data/target_raw_list.txt

编译模型库后,qnn-net-run.exe可以使用以下命令对模型进行推理:Developer PowerShell for VS 2022

$ cd ${QNN_SDK_ROOT}\tmp\qnn_inception_v3_test_package

$ ${QNN_SDK_ROOT}\bin\x86_64-windows-msvc\qnn-net-run.exe --backend .\QnnCpu.dll --model .\Inception_v3.dll --input_list .\target_raw_list.txt --op_packages .\ReluOpPackage.dll:ReluOpPackageInterfaceProvider

推理完成后,我们可以检查分类结果。默认情况下,输出将位于该${QNN_SDK_ROOT}\tmp\qnn_inception_v3_test_package\output目录中。

将以下文件和目录复制到${QNN_SDK_ROOT}\tmp\qnn_inception_v3_test_package.

- ${QNN_SDK_ROOT}/examples/Models/InceptionV3/data/imagenet_slim_labels
- ${QNN_SDK_ROOT}/examples/Models/InceptionV3/scripts/show_inceptionv3_classifications.py

查看结果:

$ py -3 .\show_inceptionv3_classifications.py `
     -i .\cropped\raw_list.txt `
     -o .\output `
     -l .\imagenet_slim_labels.txt

在 Windows 设备上执行
请确保在继续之前已完成Windows 主机上的模型构建和Windows 上的 CPU 编译部分。

将以下文件从开发主机复制到 Windows 设备的测试文件夹:

  • ${QNN_SDK_ROOT}/bin/aarch64-windows-msvc/qnn-net-run.exe
  • ${QNN_SDK_ROOT}/lib/aarch64-windows-msvc/QnnCpu.dll
  • ${QNN_SDK_ROOT}/examples/Models/InceptionV3/model_lib/ARM64/Inception_v3.dll (generated above)
  • ${QNN_SDK_ROOT}/examples/Models/InceptionV3/InceptionV3OpPackage/CPU/ReluOpPackage/build/Release/ReluOpPackage.dll (arm64 version as generated above)
  • ${QNN_SDK_ROOT}/examples/Models/InceptionV3/data/cropped
  • ${QNN_SDK_ROOT}/examples/Models/InceptionV3/data/target_raw_list.txt
    最后,连接到 Windows 设备并使用qnn-net-run.exe以下命令PowerShell:
$ .\qnn-net-run.exe --backend .\QnnCpu.dll `
                    --model .\Inception_v3.dll `
                    --input_list .\target_raw_list.txt `
                    --op_packages .\ReluOpPackage.dll:ReluOpPackageInterfaceProvider

这将在 处产生结果.\output。

查看结果:

${QNN_SDK_ROOT}\tmp\qnn_inception_v3_test_package首先,在开发主机上创建一个目录。

将output文件夹从 Windows 设备复制回${QNN_SDK_ROOT}\tmp\qnn_inception_v3_test_package。

还将以下文件和目录复制到${QNN_SDK_ROOT}\tmp\qnn_inception_v3_test_package.

  • ${QNN_SDK_ROOT}/examples/Models/InceptionV3/data/cropped
  • ${QNN_SDK_ROOT}/examples/Models/InceptionV3/data/imagenet_slim_labels
  • ${QNN_SDK_ROOT}/examples/Models/InceptionV3/scripts/show_inceptionv3_classifications.py
    在开发主机上,打开查看结果:Developer PowerShell for VS 2022
$ cd ${QNN_SDK_ROOT}\tmp\qnn_inception_v3_test_package
$ py -3 .\show_inceptionv3_classifications.py `
     -i .\cropped\raw_list.txt `
     -o .\output `
     -l .\imagenet_slim_labels.txt

DSP后端执行
在Android上执行
在 Android 目标上运行 DSP 后端与在 Android 目标上运行 CPU 和 HTP 后端非常相似。本节的其余部分将假设目标具有 v66 DSP。

与HTP后端类似,DSP后端也需要量化模型。要生成量化模型,请参阅模型量化。

首先,在设备上为示例创建一个目录:

# make inception_v3 directory if necessary
$ adb shell "mkdir /data/local/tmp/inception_v3"

现在将必要的库推送到设备:

$ adb push ${QNN_SDK_ROOT}/lib/aarch64-android/libQnnDsp.so /data/local/tmp/inception_v3
$ adb push ${QNN_SDK_ROOT}/lib/hexagon-v66/unsigned/libQnnDspV66Skel.so /data/local/tmp/inception_v3
$ adb push ${QNN_SDK_ROOT}/lib/aarch64-android/libQnnDspV66Stub.so /data/local/tmp/inception_v3
$ adb push ${QNN_SDK_ROOT}/examples/Models/InceptionV3/model_libs/aarch64-android/libInception_v3_quantized.so  /data/local/tmp/inception_v3
$ adb push ${QNN_SDK_ROOT}/examples/Models/InceptionV3/InceptionV3OpPackage/DSP/ReluOpPackage/build/DSP/libQnnReluOpPackage.so /data/local/tmp/inception_v3

现在将输入数据和输入列表推送到设备:

$ adb push ${QNN_SDK_ROOT}/examples/Models/InceptionV3/data/cropped /data/local/tmp/inception_v3
$ adb push ${QNN_SDK_ROOT}/examples/Models/InceptionV3/data/target_raw_list.txt /data/local/tmp/inception_v3

推送qnn-net-run工具:

$ adb push ${QNN_SDK_ROOT}/bin/aarch64-android/qnn-net-run /data/local/tmp/inception_v3

现在在设备上设置环境:

$ adb shell
$ cd /data/local/tmp/inception_v3
$ export VENDOR_LIB=/vendor/lib/ # /vendor/lib64/ if aarch64
$ export LD_LIBRARY_PATH=/data/local/tmp/inception_v3:/vendor/dsp/cdsp:$VENDOR_LIB
$ export ADSP_LIBRARY_PATH="/data/local/tmp/inception_v3;/vendor/dsp/cdsp;/vendor/lib/rfsa/adsp;/system/lib/rfsa/adsp;/dsp"

qnn-net-run最后,与以下内容一起使用:

$ ./qnn-net-run --backend libQnnDsp.so --model libInception_v3_quantized.so --input_list target_raw_list.txt --output_dir output_android \
                --op_packages libQnnReluOpPackage.so

运行的输出将位于 ./output_android 目录中。退出设备并查看结果:

$ exit
$ cd ${QNN_SDK_ROOT}/examples/Models/InceptionV3
$ adb pull /data/local/tmp/inception_v3/output_android
$ python3 ${QNN_SDK_ROOT}/examples/Models/InceptionV3/scripts/show_inceptionv3_classifications.py -i data/cropped/raw_list.txt \
                                                                               -o output_android/ \
                                                                               -l data/imagenet_slim_labels.txt

HTP 后端执行
在Linux主机上执行
可以通过使用 HTP 模拟后端在 Linux 主机上运行 HTP 后端。qnn-net-run编译模型库后,可以使用以下命令执行模型:

$ cd ${QNN_SDK_ROOT}/examples/Models/InceptionV3
$ ${QNN_SDK_ROOT}/bin/x86_64-linux-clang/qnn-net-run \
              --backend ${QNN_SDK_ROOT}/lib/x86_64-linux-clang/libQnnHtp.so \
              --model ${QNN_SDK_ROOT}/examples/Models/InceptionV3/model_libs/x86_64-linux-clang/libInception_v3_quantized.so \
              --input_list data/cropped/raw_list.txt \
              --op_packages ${QNN_SDK_ROOT}/examples/Models/InceptionV3/InceptionV3OpPackage/HTP/ReluOpPackage/build/x86_64-linux-clang/libQnnReluOpPackage.so:ReluOpPackageInterfaceProvider

笔记
为了使用 HTP 仿真后端,需要一个量化模型。有关量化的更多信息,请参阅模型量化。

这将产生以下结果:

${QNN_SDK_ROOT}/examples/Models/InceptionV3/output

要查看结果,请使用:

$ python3 ${QNN_SDK_ROOT}/examples/Models/InceptionV3/scripts/show_inceptionv3_classifications.py -i data/cropped/raw_list.txt \
                                                                               -o output/ \
                                                                               -l data/imagenet_slim_labels.txt

笔记
不支持在 Windows 主机上运行 HTP 模拟后端。

使用离线准备图在 Android 上运行 HTP 后端
要在 HTP 后端运行图形,除了 hexagon-v68 版本之外,还需要 aarch64 版本的 OpPackage。在 Android 目标上运行具有序列化上下文的 HTP 后端与在 Android 目标上运行 CPU 和 DSP 后端非常相似。

使用 HTP 后端在设备上运行模型可以通过生成序列化上下文来完成。与原始 libqnn_model_8bit_quantized.so 模型相比,HTP 可以更有效地初始化此序列化上下文。要生成上下文,请运行:

$ ${QNN_SDK_ROOT}/bin/x86_64-linux-clang/qnn-context-binary-generator \
              --backend ${QNN_SDK_ROOT}/lib/x86_64-linux-clang/libQnnHtp.so \
              --model ${QNN_SDK_ROOT}/examples/Models/InceptionV3/model_libs/x86_64-linux-clang/libInception_v3_quantized.so \
              --op_packages ${QNN_SDK_ROOT}/examples/Models/InceptionV3/InceptionV3OpPackage/HTP/ReluOpPackage/build/x86_64-linux-clang/libQnnReluOpPackage.so:ReluOpPackageInterfaceProvider \
              --binary_file Inception_v3_quantized.serialized

这会在以下位置创建上下文:

${QNN_SDK_ROOT}/examples/Models/InceptionV3/output/Inception_v3_quantized.serialized.bin

首先,在设备上为示例创建一个目录:

# make inception_v3 directory if necessary
$ adb shell "mkdir /data/local/tmp/inception_v3"

现在将必要的库推送到设备:

$ adb push ${QNN_SDK_ROOT}/lib/hexagon-v68/unsigned/libQnnHtpV68Skel.so /data/local/tmp/inception_v3
$ adb push ${QNN_SDK_ROOT}/lib/aarch64-android/libQnnHtpV68Stub.so /data/local/tmp/inception_v3
$ adb push ${QNN_SDK_ROOT}/lib/aarch64-android/libQnnHtp.so /data/local/tmp/inception_v3
$ adb push ${QNN_SDK_ROOT}/lib/aarch64-android/libQnnHtpPrepare.so /data/local/tmp/inception_v3
$ adb push ${QNN_SDK_ROOT}/examples/Models/InceptionV3/model_libs/aarch64-android/* /data/local/tmp/inception_v3
$ adb push ${QNN_SDK_ROOT}/examples/Models/InceptionV3/InceptionV3OpPackage/HTP/ReluOpPackage/libs/hexagon_v68/libQnnReluOpPackage.so /data/local/tmp/inception_v3
$ adb push ${QNN_SDK_ROOT}/examples/Models/InceptionV3/InceptionV3OpPackage/HTP/ReluOpPackage/libs/aarch64-android/libQnnReluOpPackage.so /data/local/tmp/inception_v3/libQnnReluOpPackage_Cpu.so
$ adb push ${QNN_SDK_ROOT}/examples/Models/InceptionV3/output/Inception_v3_quantized.serialized.bin /data/local/tmp/inception_v3

现在将输入数据和输入列表推送到设备:

$ adb push ${QNN_SDK_ROOT}/examples/Models/InceptionV3/data/cropped /data/local/tmp/inception_v3
$ adb push ${QNN_SDK_ROOT}/examples/Models/InceptionV3/data/target_raw_list.txt /data/local/tmp/inception_v3

推送qnn-net-run工具:

$ adb push ${QNN_SDK_ROOT}/bin/aarch64-android/qnn-net-run /data/local/tmp/inception_v3

现在在设备上设置环境:

$ adb shell
$ cd /data/local/tmp/inception_v3
$ export LD_LIBRARY_PATH=/data/local/tmp/inception_v3
$ export ADSP_LIBRARY_PATH="/data/local/tmp/inception_v3"

qnn-net-run最后,与以下内容一起使用:

$ ./qnn-net-run --backend libQnnHtp.so --input_list target_raw_list.txt --retrieve_context Inception_v3_quantized.serialized.bin
                --op_packages libQnnReluOpPackage_Cpu.so:ReluOpPackageInterfaceProvider:CPU,libQnnReluOpPackage_Htp.so:ReluOpPackageInterfaceProvider:HTP

在这种情况下,op 包的两个目标变体将传递给 qnn-net-run。第一个 libQnnReluOpPackage_Cpu.so 是 ARM aarch64 构建,而第二个 libQnnReluOpPackage_Htp.so 是 hexagon v68 构建

“:CPU”和“:HTP”是可选的目标参数,指定后端必须在其上注册op包的目标平台。“CPU”目标表示op包是为CPU(ARM aarch64)编译的。“HTP”目标表示 op 包是为设备上的 HTP 编译的。

运行的输出将位于默认的 ./output 目录中。退出设备并查看结果:

$ exit
$ cd ${QNN_SDK_ROOT}/examples/Models/InceptionV3
$ adb pull /data/local/tmp/inception_v3/output output_android
$ python3 ${QNN_SDK_ROOT}/examples/Models/InceptionV3/scripts/show_inceptionv3_classifications.py -i data/cropped/raw_list.txt \
                                                                               -o output_android/ \
                                                                               -l data/imagenet_slim_labels.txt

使用设备上准备好的图表在 Android 上运行 HTP 后端
在 Android 目标上运行带有 ARM (CPU) 准备的 HTP 后端与使用离线准备图运行 HTP 后端非常相似。

首先,在设备上为示例创建一个目录:

# make oppackage if necessary
$ adb shell "mkdir /data/local/tmp/oppackage"
$ adb shell "mkdir /data/local/tmp/oppackage/HTP"

现在将必要的库推送到设备:

$ adb push ${QNN_SDK_ROOT}/lib/hexagon-v68/unsigned/libQnnHtpV68Skel.so /data/local/tmp/inception_v3
$ adb push ${QNN_SDK_ROOT}/lib/aarch64-android/libQnnHtp.so /data/local/tmp/inception_v3
$ adb push ${QNN_SDK_ROOT}/lib/aarch64-android/libQnnHtpPrepare.so /data/local/tmp/inception_v3
$ adb push ${QNN_SDK_ROOT}/lib/aarch64-android/libQnnHtpV68Stub.so /data/local/tmp/inception_v3
$ adb push ${QNN_SDK_ROOT}/examples/Models/InceptionV3/model_libs/aarch64-android/* /data/local/tmp/inception_v3
$ adb push ${QNN_SDK_ROOT}/examples/Models/InceptionV3/InceptionV3OpPackage/HTP/ReluOpPackage/build/aarch64-android/libQnnReluOpPackage.so /data/local/tmp/inception_v3/libQnnReluOpPackage_Cpu.so
$ adb push ${QNN_SDK_ROOT}/examples/Models/InceptionV3/InceptionV3OpPackage/HTP/ReluOpPackage/build/hexagon_v68/libQnnReluOpPackage.so /data/local/tmp/inception_v3/libQnnReluOpPackage_Htp.so

现在将输入数据和输入列表推送到设备:

$ adb push ${QNN_SDK_ROOT}/examples/Models/InceptionV3/data/cropped /data/local/tmp/inception_v3
$ adb push ${QNN_SDK_ROOT}/examples/Models/InceptionV3/data/target_raw_list.txt /data/local/tmp/inception_v3

推送qnn-net-run工具:

$ adb push ${QNN_SDK_ROOT}/bin/aarch64-android/qnn-net-run /data/local/tmp/inception_v3

现在在设备上设置环境:

$ adb shell
$ cd /data/local/tmp/inception_v3
$ export LD_LIBRARY_PATH=/data/local/tmp/inception_v3
$ export ADSP_LIBRARY_PATH="/data/local/tmp/inception_v3"

qnn-net-run最后,与以下内容一起使用:

$ ./qnn-net-run --backend libQnnHtp.so --input_list target_raw_list.txt \
                 --model libInception_v3_quantized.so \
                 --op_packages libQnnReluOpPackage_Cpu.so:ReluOpPackageInterfaceProvider:CPU,libQnnReluOpPackage_Htp.so:ReluOpPackageInterfaceProvider:HTP

在这种情况下,op 包的两个目标变体将传递给 qnn-net-run。第一个 libQnnReluOpPackage_Cpu.so 是 ARM aarch64 构建,而第二个 libQnnReluOpPackage_Htp.so 是 hexagon v68 构建

“:CPU”和“:HTP”是可选的目标参数,指定后端必须在其上注册op包的目标平台。“CPU”目标表示op包是为CPU(ARM aarch64)编译的。“HTP”目标表示 op 包是为设备上的 HTP 编译的。

运行的输出将位于默认的 ./output 目录中。退出设备并查看结果:

$ exit
$ cd ${QNN_SDK_ROOT}/examples/Models/InceptionV3
$ adb pull /data/local/tmp/inception_v3/output output_android
$ python3 ${QNN_SDK_ROOT}/examples/Models/InceptionV3/scripts/show_inceptionv3_classifications.py -i data/cropped/raw_list.txt \
                                                                               -o output_android/ \
                                                                               -l data/imagenet_slim_labels.txt

使用离线准备图在 Windows 设备上运行 HTP 后端
通过生成序列化上下文,可以使用 Windows 上的 HTP 后端运行模型。与原始 qnn_model_8bit_quantized.dll 模型相比,HTP 可以更有效地初始化此序列化上下文。要生成上下文,请qnn-context-binary-generator在 WSL 中运行:

$ ${QNN_SDK_ROOT}/bin/x86_64-linux-clang/qnn-context-binary-generator \
              --backend ${QNN_SDK_ROOT}/lib/x86_64-linux-clang/libQnnHtp.so \
              --model ${QNN_SDK_ROOT}/examples/Models/InceptionV3/model_libs/x86_64-linux-clang/libInception_v3_quantized.so \
              --op_packages ${QNN_SDK_ROOT}/examples/Models/InceptionV3/InceptionV3OpPackage/HTP/ReluOpPackage/build/x86_64-linux-clang/libQnnReluOpPackage.so:ReluOpPackageInterfaceProvider \
              --output_dir ${QNN_SDK_ROOT}/examples/Models/InceptionV3/output \
              --binary_file Inception_v3_quantized.serialized

这会在以下位置创建上下文:

${QNN_SDK_ROOT}/examples/Models/InceptionV3/output/Inception_v3_quantized.serialized.bin

将以下文件从开发主机复制到 Windows 设备的测试文件夹:

${QNN_SDK_ROOT}/examples/Models/InceptionV3/InceptionV3OpPackage/HTP/ReluOpPackage/build/hexagon-v68/libQnnReluOpPackage.so

${QNN_SDK_ROOT}/examples/Models/InceptionV3/output/Inception_v3_quantized.serialized.bin

${QNN_SDK_ROOT}/examples/Models/InceptionV3/data/cropped

${QNN_SDK_ROOT}/examples/Models/InceptionV3/data/target_raw_list.txt

${QNN_SDK_ROOT}/bin/aarch64-windows-msvc/qnn-net-run.exe

${QNN_SDK_ROOT}/lib/aarch64-windows-msvc/QnnHtp.dll

${QNN_SDK_ROOT}/lib/aarch64-windows-msvc/QnnHtpV68Stub.dll

${QNN_SDK_ROOT}/lib/hexagon-v68/unsigned/libQnnHtpV68Skel.so

最后,连接到 Windows 设备并qnn-net-run在 中运行以下命令"PowerShell":

$ .\qnn-net-run.exe --backend QnnHtp.dll `
                     --input_list target_raw_list.txt `
                     --retrieve_context Inception_v3_quantized.serialized.bin `
                     --op_packages libQnnReluOpPackage.so:ReluOpPackageInterfaceProvider

这将产生以下结果:

  • .\output

查看结果:

${QNN_SDK_ROOT}\tmp\qnn_inception_v3_test_package首先,在 Windows 主机上创建一个目录。

将输出文件夹从 Windows 设备复制回${QNN_SDK_ROOT}\tmp\qnn_inception_v3_test_package.

还将以下文件和目录从 SDK 复制到${QNN_SDK_ROOT}\tmp\qnn_inception_v3_test_package.

  • ${QNN_SDK_ROOT}/examples/Models/InceptionV3/data/cropped

  • ${QNN_SDK_ROOT}/examples/Models/InceptionV3/data/imagenet_slim_labels.txt

  • ${QNN_SDK_ROOT}/examples/Models/InceptionV3/scripts/show_inceptionv3_classifications.py

在Windows主机上,打开查看结果:“Developer PowerShell for VS 2022”

$ cd ${QNN_SDK_ROOT}\tmp\qnn_inception_v3_test_package
$ py -3 .\show_inceptionv3_classifications.py -i .\cropped\raw_list.txt `
                                                -o output `
                                                -l .\imagenet_slim_labels.txt

笔记
Windows 不支持使用 HTP 后端运行设备上准备好的图表。

8.4 Windows

8.4.1 Windows 休眠教程

介绍
休眠是Windows系统的一种电源状态。本教程介绍如何在运行 QNN 应用程序时安全地进入休眠状态,并提供演示用于释放系统资源的 QNN API 调用的代码片段。

  1. 自由语境

  2. 免费设备

  3. 免费后端

  4. 关闭后端库

安全冬眠的步骤

自由语境

任何在 QNN 后端创建的上下文都应该被释放:

来自 SampleApp 的免费上下文

1 if (QNN_CONTEXT_NO_ERROR !=
2       m_qnnFunctionPointers.qnnInterface.contextFree(context, profileBackendHandle)) {
3   QNN_ERROR("Could not free context");
4   return StatusCode::FAILURE;
5 }

免费设备
接下来应该释放通过 QNN API 创建的设备:

1 if (QNN_DEVICE_NO_ERROR !=
2       m_qnnFunctionPointers.qnnInterface.deviceFree(deviceHandle)) {
3   QNN_ERROR("Failed to free device");
4   return StatusCode::FAILURE;
5 }

免费后端
然后应用程序应该释放创建的所有后端:

SampleApp 的免费后端

1 if (QNN_BACKEND_NO_ERROR !=
2       m_qnnFunctionPointers.qnnInterface.backendFree(backendHandle)) {
3   QNN_ERROR("Could not free backend");
4   return StatusCode::FAILURE;
5 }

关闭后端库
最后,应用程序应该关闭后端库:

从 SampleApp 加载后端,如下所示:

1 if (libBackendHandle) {
2   pal::dynamicloading::dlClose(libBackendHandle);
3 }

完整 SampleApp 休眠示例
现在我们可以使用SampleApp作为示例将所有步骤整合在一起。

 1 // Free context first
 2 if (QNN_CONTEXT_NO_ERROR !=
 3       m_qnnFunctionPointers.qnnInterface.contextFree(context, profileBackendHandle)) {
 4   QNN_ERROR("Could not free context");
 5   return StatusCode::FAILURE;
 6 }
 7
 8 // Free device if needed
 9 if (QNN_DEVICE_NO_ERROR !=
10       m_qnnFunctionPointers.qnnInterface.deviceFree(deviceHandle)) {
11   QNN_ERROR("Failed to free device");
12   return StatusCode::FAILURE;
13 }
14
15 // Free backend
16 if (QNN_BACKEND_NO_ERROR !=
17       m_qnnFunctionPointers.qnnInterface.backendFree(backendHandle)) {
18   QNN_ERROR("Could not free backend");
19   return StatusCode::FAILURE;
20 }
21
22 // Close backhandle
23 if (libBackendHandle) {
24   pal::dynamicloading::dlClose(libBackendHandle);
25 }
26
27 // This turns device into hibernation mode
28 SetSuspendState(true, true, false);
29 // Get back from hibernation
30 return EXIT_SUCCESS;

8.4.2 ARM64X教程

介绍

Windows SDK 提供 ARM64X 二进制文件,兼容 Windows ARM 设备上的 x86-64、ARM64 和 ARM64EC 应用程序。ARM64X 仅在 SC8380XP(Snapdragon 8cx Gen 4)上受支持。

使用 ARM64EC qnn-net-run 和离线准备图进行端到端 HTP 推理

将以下文件复制到 SC8380XP 目标设备

  • $QNN_SDK_ROOT/bin/arm64x-windows-msvc/qnn-net-run.exe

  • $QNN_SDK_ROOT/lib/arm64x-windows-msvc/QnnHtp.dll

  • $QNN_SDK_ROOT/lib/arm64x-windows-msvc/QnnHtpV73Stub.dll

  • $QNN_SDK_ROOT/lib/hexagon-v73/unsigned/libQnnHtpV73Skel.so

  • Inception_v3_quantized.serialized.bin(有关更多详细信息,请参阅使用 QNN 转换和执行 CNN 模型)

在目标设备上运行以下推理命令

$ .\qnn-net-run.exe --input_list .\input_list.txt --retrieve_context .\Inception_v3_quantized.serialized.bin --backend QnnHtp.dll
使用 ARM64EC qnn-net-run 进行端到端 HTP 推理和在线准备图
将以下文件复制到 SC8380XP 目标设备

$QNN_SDK_ROOT/bin/arm64x-windows-msvc/qnn-net-run.exe

$QNN_SDK_ROOT/lib/arm64x-windows-msvc/QnnHtp.dll

$QNN_SDK_ROOT/lib/arm64x-windows-msvc/QnnHtpV73Stub.dll

$QNN_SDK_ROOT/lib/arm64x-windows-msvc/QnnHtpPrepare.dll

$QNN_SDK_ROOT/lib/hexagon-v73/unsigned/libQnnHtpV73Skel.so

Inception_v3_quantized.dll(有关更多详细信息,请参阅使用 QNN 转换和执行 CNN 模型,并在运行 qnn-model-lib-generator 时使用 -t windows-x86_64)

在目标设备上运行以下推理命令

$ .\qnn-net-run.exe --input_list .\input_list.txt --model .\Inception_v3_quantized.dll --backend QnnHtp.dll

使用 ARM64 qnn-net-run 和离线准备图进行端到端 HTP 推理

将以下文件复制到 SC8380XP 目标设备

  • $QNN_SDK_ROOT/bin/aarch64-windows-msvc/qnn-net-run.exe

  • $QNN_SDK_ROOT/lib/arm64x-windows-msvc/QnnHtp.dll

  • $QNN_SDK_ROOT/lib/arm64x-windows-msvc/QnnHtpV73Stub.dll

  • $QNN_SDK_ROOT/lib/hexagon-v73/unsigned/libQnnHtpV73Skel.so

  • Inception_v3_quantized.serialized.bin(有关更多详细信息,请参阅使用 QNN 转换和执行 CNN 模型)

在目标设备上运行以下推理命令

$ .\qnn-net-run.exe --input_list .\input_list.txt --retrieve_context .\Inception_v3_quantized.serialized.bin --backend QnnHtp.dll
使用 ARM64 qnn-net-run 进行端到端 HTP 推理,并带有在线准备的图
将以下文件复制到 SC8380XP 目标设备

  • $QNN_SDK_ROOT/bin/aarch64-windows-msvc/qnn-net-run.exe

  • $QNN_SDK_ROOT/lib/arm64x-windows-msvc/QnnHtp.dll

  • $QNN_SDK_ROOT/lib/arm64x-windows-msvc/QnnHtpV73Stub.dll

  • $QNN_SDK_ROOT/lib/arm64x-windows-msvc/QnnHtpPrepare.dll

  • $QNN_SDK_ROOT/lib/hexagon-v73/unsigned/libQnnHtpV73Skel.so

Inception_v3_quantized.dll(有关更多详细信息,请参阅使用 QNN 转换和执行 CNN 模型,并在运行 qnn-model-lib-generator 时使用 -t windows-aarch64)

在目标设备上运行以下推理命令

$ .\qnn-net-run.exe --input_list .\input_list.txt --model .\Inception_v3_quantized.dll --backend QnnHtp.dll

使用 x64 qnn-sample-app 和离线准备图进行端到端 HTP 推理

  1. 将以下文件复制到 SC8380XP 目标设备
  • $QNN_SDK_ROOT/examples/QNN/SampleApp/build/src/Release/qnn-sample-app.exe(有关更多详细信息,请参阅示例应用程序教程:创建和构建示例 C++ 应用程序)

  • $QNN_SDK_ROOT/lib/arm64x-windows-msvc/QnnHtp.dll

  • $QNN_SDK_ROOT/lib/arm64x-windows-msvc/QnnHtpV73Stub.dll

  • $QNN_SDK_ROOT/lib/arm64x-windows-msvc/QnnSystem.dll

  • $QNN_SDK_ROOT/lib/hexagon-v73/unsigned/libQnnHtpV73Skel.so

  • Inception_v3_quantized.serialized.bin(有关更多详细信息,请参阅使用 QNN 转换和执行 CNN 模型)

  1. 在目标设备上运行以下推理命令

$ .\qnn-sample-app.exe --system_library .\QnnSystem.dll --input_list .\input_list.txt --retrieve_context .\Inception_v3_quantized.serialized.bin --backend QnnHtp.dll

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐