• 文档 >
  • 使用高通 AI 引擎直连后端构建和运行 ExecuTorch
快捷方式

使用高通 AI 引擎直连后端构建和运行 ExecuTorch

在本教程中,我们将引导您完成构建适用于高通 AI 引擎直连的 ExecuTorch 并在其上运行模型的过程。

高通 AI 引擎直连在源代码和文档中也称为 QNN。

您将在本教程中学习什么
  • 在本教程中,您将学习如何为高通 AI 引擎直连降低和部署模型。

我们建议您在此之前完成的教程

什么是高通 AI 引擎直连?

高通 AI 引擎直连 旨在为 AI 开发提供统一的低级 API。

开发人员可以使用这些 API 与高通 SoC 上的各种加速器进行交互,包括 Kryo CPU、Adreno GPU 和 Hexagon 处理器。更多详细信息请参见 此处

目前,此 ExecuTorch 后端可以通过高通 AI 引擎直连 API 将 AI 计算委托给 Hexagon 处理器。

先决条件(硬件和软件)

主机操作系统

目前,QNN 后端经过验证的 Linux 主机操作系统是 Ubuntu 22.04 LTS x64(更新本教程时)。通常,我们在与 QNN 验证相同的 OS 版本上验证后端。版本记录在 QNN SDK 中。

硬件:

您需要一部通过 adb 连接的 Android 智能手机,并在以下 Qualcomm SoC 之一上运行

  • SM8450(骁龙 8 Gen 1)

  • SM8475(骁龙 8 Gen 1+)

  • SM8550(骁龙 8 Gen 2)

  • SM8650(骁龙 8 Gen 3)

此示例已通过 SM8550 和 SM8450 验证。

软件:

  • 遵循 ExecuTorch 推荐的 Python 版本。

  • 用于编译 AOT 部分的编译器,例如,Ubuntu LTS 附带的 GCC 编译器。

  • Android NDK。此示例已通过 NDK 26c 验证。

  • 高通 AI 引擎直连 SDK

    • 单击“获取软件”按钮下载 QNN SDK 版本。

    • 但是,在更新本教程时,上述网站提供的 QNN SDK 版本不高于 2.22.6。

    • 以下是下载各种 QNN 版本的公共链接。希望它们很快就能公开发现。

    • QNN 2.26.0

安装了高通 AI 引擎直连 SDK 的目录如下所示

├── benchmarks
├── bin
├── docs
├── examples
├── include
├── lib
├── LICENSE.pdf
├── NOTICE.txt
├── NOTICE_WINDOWS.txt
├── QNN_NOTICE.txt
├── QNN_README.txt
├── QNN_ReleaseNotes.txt
├── ReleaseNotes.txt
├── ReleaseNotesWindows.txt
├── sdk.yaml
└── share

设置您的开发环境

约定

$QNN_SDK_ROOT 指的是高通 AI 引擎直连 SDK 的根目录,即包含 QNN_README.txt 的目录。

$ANDROID_NDK_ROOT 指的是 Android NDK 的根目录。

$EXECUTORCH_ROOT 指的是 executorch git 存储库的根目录。

设置环境变量

我们设置 LD_LIBRARY_PATH 以确保动态链接器可以找到 QNN 库。

此外,我们设置 PYTHONPATH,因为这更容易开发和导入 ExecuTorch Python API。

export LD_LIBRARY_PATH=$QNN_SDK_ROOT/lib/x86_64-linux-clang/:$LD_LIBRARY_PATH
export PYTHONPATH=$EXECUTORCH_ROOT/..

构建

以下构建说明的示例脚本在此处。我们建议使用此脚本,因为 ExecuTorch 构建命令可能会不时更改。上述脚本正在积极使用。它更新频率高于本教程。示例用法为

cd $EXECUTORCH_ROOT
./backends/qualcomm/scripts/build.sh
# or
./backends/qualcomm/scripts/build.sh --release

AOT(提前)组件:

需要 x64 上的 Python API 来将模型编译为高通 AI 引擎直连二进制文件。

cd $EXECUTORCH_ROOT
mkdir build-x86
cd build-x86
# Note that the below command might change.
# Please refer to the above build.sh for latest workable commands.
cmake .. \
  -DCMAKE_INSTALL_PREFIX=$PWD \
  -DEXECUTORCH_BUILD_QNN=ON \
  -DQNN_SDK_ROOT=${QNN_SDK_ROOT} \
  -DEXECUTORCH_BUILD_DEVTOOLS=ON \
  -DEXECUTORCH_BUILD_EXTENSION_MODULE=ON \
  -DEXECUTORCH_BUILD_EXTENSION_TENSOR=ON \
  -DEXECUTORCH_ENABLE_EVENT_TRACER=ON \
  -DPYTHON_EXECUTABLE=python3 \
  -DEXECUTORCH_SEPARATE_FLATCC_HOST_PROJECT=OFF

# nproc is used to detect the number of available CPU.
# If it is not applicable, please feel free to use the number you want.
cmake --build $PWD --target "PyQnnManagerAdaptor" "PyQnnWrapperAdaptor" -j$(nproc)

# install Python APIs to correct import path
# The filename might vary depending on your Python and host version.
cp -f backends/qualcomm/PyQnnManagerAdaptor.cpython-310-x86_64-linux-gnu.so $EXECUTORCH_ROOT/backends/qualcomm/python
cp -f backends/qualcomm/PyQnnWrapperAdaptor.cpython-310-x86_64-linux-gnu.so $EXECUTORCH_ROOT/backends/qualcomm/python

# Workaround for fbs files in exir/_serialize
cp $EXECUTORCH_ROOT/schema/program.fbs $EXECUTORCH_ROOT/exir/_serialize/program.fbs
cp $EXECUTORCH_ROOT/schema/scalar_type.fbs $EXECUTORCH_ROOT/exir/_serialize/scalar_type.fbs

运行时:

示例 qnn_executor_runner 可执行文件将用于运行编译后的 pte 模型。

用于 Android 构建 qnn_executor_runner 的命令

cd $EXECUTORCH_ROOT
mkdir build-android
cd build-android
# build executorch & qnn_executorch_backend
cmake .. \
    -DCMAKE_INSTALL_PREFIX=$PWD \
    -DEXECUTORCH_BUILD_QNN=ON \
    -DQNN_SDK_ROOT=$QNN_SDK_ROOT \
    -DEXECUTORCH_BUILD_DEVTOOLS=ON \
    -DEXECUTORCH_BUILD_EXTENSION_MODULE=ON \
    -DEXECUTORCH_BUILD_EXTENSION_TENSOR=ON \
    -DEXECUTORCH_ENABLE_EVENT_TRACER=ON \
    -DPYTHON_EXECUTABLE=python3 \
    -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_ROOT/build/cmake/android.toolchain.cmake \
    -DANDROID_ABI='arm64-v8a' \
    -DANDROID_NATIVE_API_LEVEL=23

# nproc is used to detect the number of available CPU.
# If it is not applicable, please feel free to use the number you want.
cmake --build $PWD --target install -j$(nproc)

cmake ../examples/qualcomm \
    -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_ROOT/build/cmake/android.toolchain.cmake \
    -DANDROID_ABI='arm64-v8a' \
    -DANDROID_NATIVE_API_LEVEL=23 \
    -DCMAKE_PREFIX_PATH="$PWD/lib/cmake/ExecuTorch;$PWD/third-party/gflags;" \
    -DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=BOTH \
    -DPYTHON_EXECUTABLE=python3 \
    -Bexamples/qualcomm

cmake --build examples/qualcomm -j$(nproc)

# qnn_executor_runner can be found under examples/qualcomm
# The full path is $EXECUTORCH_ROOT/build-android/examples/qualcomm/qnn_executor_runner
ls examples/qualcomm

**注意:**如果您想构建发布版本,请将 -DCMAKE_BUILD_TYPE=Release 添加到 cmake 命令选项中。

在设备上部署和运行

AOT 编译模型

有关确切流程,请参阅 此脚本。在本教程中,我们使用 deeplab-v3-resnet101 作为示例。运行以下命令进行编译

cd $EXECUTORCH_ROOT

python -m examples.qualcomm.scripts.deeplab_v3 -b build-android -m SM8550 --compile_only --download

您可能会看到如下内容

[INFO][Qnn ExecuTorch] Destroy Qnn context
[INFO][Qnn ExecuTorch] Destroy Qnn device
[INFO][Qnn ExecuTorch] Destroy Qnn backend

opcode         name                      target                       args                           kwargs
-------------  ------------------------  ---------------------------  -----------------------------  --------
placeholder    arg684_1                  arg684_1                     ()                             {}
get_attr       lowered_module_0          lowered_module_0             ()                             {}
call_function  executorch_call_delegate  executorch_call_delegate     (lowered_module_0, arg684_1)   {}
call_function  getitem                   <built-in function getitem>  (executorch_call_delegate, 0)  {}
call_function  getitem_1                 <built-in function getitem>  (executorch_call_delegate, 1)  {}
output         output                    output                       ([getitem_1, getitem],)        {}

编译后的模型为 ./deeplab_v3/dlv3_qnn.pte

在 QNN HTP 模拟器上测试模型推理

在将模型部署到设备之前,我们可以通过 HTP 模拟器测试模型推理。

让我们为 x64 主机构建 qnn_executor_runner

# assuming the AOT component is built.
cd $EXECUTORCH_ROOT/build-x86
cmake ../examples/qualcomm \
  -DCMAKE_PREFIX_PATH="$PWD/lib/cmake/ExecuTorch;$PWD/third-party/gflags;" \
  -DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=BOTH \
  -DPYTHON_EXECUTABLE=python3 \
  -Bexamples/qualcomm

cmake --build examples/qualcomm -j$(nproc)

# qnn_executor_runner can be found under examples/qualcomm
# The full path is $EXECUTORCH_ROOT/build-x86/examples/qualcomm/qnn_executor_runner
ls examples/qualcomm/

要运行 HTP 模拟器,动态链接器需要访问 QNN 库和 libqnn_executorch_backend.so。我们将以下两个路径设置为 LD_LIBRARY_PATH 环境变量

  1. $QNN_SDK_ROOT/lib/x86_64-linux-clang/

  2. $EXECUTORCH_ROOT/build-x86/lib/

第一个路径用于包含HTP模拟器的QNN库。它已在AOT编译部分配置。

第二个路径用于 libqnn_executorch_backend.so

因此,我们可以通过以下方式运行 ./deeplab_v3/dlv3_qnn.pte

cd $EXECUTORCH_ROOT/build-x86
export LD_LIBRARY_PATH=$EXECUTORCH_ROOT/build-x86/lib/:$LD_LIBRARY_PATH
examples/qualcomm/qnn_executor_runner --model_path ../deeplab_v3/dlv3_qnn.pte

我们应该看到如下一些输出。请注意,模拟器可能需要一些时间才能完成。

I 00:00:00.354662 executorch:qnn_executor_runner.cpp:213] Method loaded.
I 00:00:00.356460 executorch:qnn_executor_runner.cpp:261] ignoring error from set_output_data_ptr(): 0x2
I 00:00:00.357991 executorch:qnn_executor_runner.cpp:261] ignoring error from set_output_data_ptr(): 0x2
I 00:00:00.357996 executorch:qnn_executor_runner.cpp:265] Inputs prepared.

I 00:01:09.328144 executorch:qnn_executor_runner.cpp:414] Model executed successfully.
I 00:01:09.328159 executorch:qnn_executor_runner.cpp:421] Write etdump to etdump.etdp, Size = 424
[INFO] [Qnn ExecuTorch]: Destroy Qnn backend parameters
[INFO] [Qnn ExecuTorch]: Destroy Qnn context
[INFO] [Qnn ExecuTorch]: Destroy Qnn device
[INFO] [Qnn ExecuTorch]: Destroy Qnn backend

在搭载高通SoC的Android智能手机上运行模型推理

步骤1. 我们需要将所需的QNN库推送到设备。

# make sure you have write-permission on below path.
DEVICE_DIR=/data/local/tmp/executorch_qualcomm_tutorial/
adb shell "mkdir -p ${DEVICE_DIR}"
adb push ${QNN_SDK_ROOT}/lib/aarch64-android/libQnnHtp.so ${DEVICE_DIR}
adb push ${QNN_SDK_ROOT}/lib/aarch64-android/libQnnSystem.so ${DEVICE_DIR}
adb push ${QNN_SDK_ROOT}/lib/aarch64-android/libQnnHtpV69Stub.so ${DEVICE_DIR}
adb push ${QNN_SDK_ROOT}/lib/aarch64-android/libQnnHtpV73Stub.so ${DEVICE_DIR}
adb push ${QNN_SDK_ROOT}/lib/aarch64-android/libQnnHtpV75Stub.so ${DEVICE_DIR}
adb push ${QNN_SDK_ROOT}/lib/hexagon-v69/unsigned/libQnnHtpV69Skel.so ${DEVICE_DIR}
adb push ${QNN_SDK_ROOT}/lib/hexagon-v73/unsigned/libQnnHtpV73Skel.so ${DEVICE_DIR}
adb push ${QNN_SDK_ROOT}/lib/hexagon-v75/unsigned/libQnnHtpV75Skel.so ${DEVICE_DIR}

步骤2. 我们还需要通过设置 ADSP_LIBRARY_PATHLD_LIBRARY_PATH 来指示Android和Hexagon上的动态链接器在哪里可以找到这些库。因此,我们可以像这样运行 qnn_executor_runner

adb push ./deeplab_v3/dlv3_qnn.pte ${DEVICE_DIR}
adb push ${EXECUTORCH_ROOT}/build-android/examples/qualcomm/executor_runner/qnn_executor_runner ${DEVICE_DIR}
adb push ${EXECUTORCH_ROOT}/build-android/lib/libqnn_executorch_backend.so ${DEVICE_DIR}
adb shell "cd ${DEVICE_DIR} \
           && export LD_LIBRARY_PATH=${DEVICE_DIR} \
           && export ADSP_LIBRARY_PATH=${DEVICE_DIR} \
           && ./qnn_executor_runner --model_path ./dlv3_qnn.pte"

您应该会看到如下内容

I 00:00:00.257354 executorch:qnn_executor_runner.cpp:213] Method loaded.
I 00:00:00.323502 executorch:qnn_executor_runner.cpp:262] ignoring error from set_output_data_ptr(): 0x2
I 00:00:00.357496 executorch:qnn_executor_runner.cpp:262] ignoring error from set_output_data_ptr(): 0x2
I 00:00:00.357555 executorch:qnn_executor_runner.cpp:265] Inputs prepared.
I 00:00:00.364824 executorch:qnn_executor_runner.cpp:414] Model executed successfully.
I 00:00:00.364875 executorch:qnn_executor_runner.cpp:425] Write etdump to etdump.etdp, Size = 424
[INFO] [Qnn ExecuTorch]: Destroy Qnn backend parameters
[INFO] [Qnn ExecuTorch]: Destroy Qnn context
[INFO] [Qnn ExecuTorch]: Destroy Qnn backend

模型仅被执行。如果我们想提供真实的输入并获取模型输出,我们可以使用

cd $EXECUTORCH_ROOT
python -m examples.qualcomm.scripts.deeplab_v3 -b build-android -m SM8550 --download -s <device_serial>

<device_serial> 可以通过 adb devices 命令找到。

执行上述命令后,预处理的输入和输出将分别放置在 $EXECUTORCH_ROOT/deeplab_v3$EXECUTORCH_ROOT/deeplab_v3/outputs 文件夹中。

命令行参数在 utils.py 中编写。模型、输入和输出位置通过 --model_path--input_list_path--output_folder_path 传递给 qnn_executorch_runner

通过ExecuTorch的Android演示应用程序运行模型

使用高通AI引擎直接后端的Android演示应用程序可以在 examples 中找到。请参考Android演示应用程序 教程

支持的模型列表

请参考 $EXECUTORCH_ROOT/examples/qualcomm/scripts/EXECUTORCH_ROOT/examples/qualcomm/oss_scripts/ 以获取支持的模型列表。

未来计划

  • 提高llama3-8B-Instruct的性能并支持批处理预填充。

  • 我们将支持来自 高通AI Hub 的预编译二进制文件。

常见问题解答

如果您在重现教程时遇到任何问题,请在ExecuTorch存储库中提交GitHub问题,并使用 #qcom_aisw 标签

文档

访问PyTorch的全面开发者文档

查看文档

教程

获取初学者和高级开发人员的深入教程

查看教程

资源

查找开发资源并获得问题的解答

查看资源