构建 ExecuTorch Android 示例应用
这是从 PyTorch Android 演示应用 分叉而来的。
本指南解释了如何使用演示应用为 Android 设置 ExecuTorch。该应用采用 DeepLab v3 模型进行图像分割任务。模型通过 XNNPACK FP32 后端 导出到 ExecuTorch。
你将学到什么
-
如何为 Android arm64-v8a 设置构建目标
-
如何使用 JNI 包装器为 Android 构建所需的 ExecuTorch 运行时
-
如何使用所需的 JNI 库和模型文件构建应用程序
先决条件
-
参考 设置 ExecuTorch 来配置仓库和开发环境。
-
下载并安装 Android Studio 和 SDK。
-
支持的主机操作系统:CentOS, macOS Ventura (M1/x86_64)。有关 Qualcomm HTP 的特定要求,请参见下文。
-
仅限 Qualcomm HTP1: 要在 Qualcomm 的 AI Engine Direct 上构建和运行,请按照 使用 Qualcomm AI Engine Direct 后端构建和运行 ExecuTorch 了解硬件和软件的先决条件。本教程使用的版本是 2.19,使用的芯片是 SM8450。
此演示应用程序和教程仅针对 arm64-v8a ABI 进行过验证。
构建
预先编译 (Ahead-Of-Time)
我们为 Android 演示应用中的 ExecuTorch 运行时生成模型文件。
XNNPACK 委托
要将 DeepLab v3 委托给 XNNPACK 后端,请按照以下步骤导出模型:
python3-mexamples.xnnpack.aot_compiler--model_name="dl3"--delegate
mkdir-pexamples/demo-apps/android/ExecuTorchDemo/app/src/main/assets/
cpdl3_xnnpack_fp32.pteexamples/demo-apps/android/ExecuTorchDemo/app/src/main/assets/
有关降低到 XNNPACK 的详细教程,请参阅 XNNPACK 后端。
Qualcomm Hexagon NPU
要将模型委托给 Qualcomm Hexagon NPU,请按照此处的教程操作。
生成模型后,将模型复制到 assets
目录。
python-mexamples.qualcomm.scripts.deeplab_v3-bbuild-android-mSM8450-s<adb_connected_device_serial>
cpdeeplab_v3/dlv3_qnn.pteexamples/demo-apps/android/ExecuTorchDemo/app/src/main/assets/
运行时
我们构建了运行模型所需的 ExecuTorch 运行时库。
XNNPACK
- 使用 XNNPACK 后端构建库的 CMake 目标:
exportANDROID_NDK=<path-to-android-ndk>
exportANDROID_ABI=arm64-v8a
# Run the following lines from the `executorch/` folder
./install_requirements.sh--clean
mkdircmake-android-out
# Build the core executorch library
cmake.-DCMAKE_INSTALL_PREFIX=cmake-android-out\
*DCMAKE_TOOLCHAIN_FILE="${ANDROID_NDK}/build/cmake/android.toolchain.cmake"\
*DANDROID_ABI="${ANDROID_ABI}"\
*DEXECUTORCH_BUILD_XNNPACK=ON\
*DEXECUTORCH_BUILD_EXTENSION_DATA_LOADER=ON\
*DEXECUTORCH_BUILD_EXTENSION_MODULE=ON\
*DEXECUTORCH_BUILD_EXTENSION_RUNNER_UTIL=ON\
*DEXECUTORCH_BUILD_EXTENSION_TENSOR=ON\
*Bcmake-android-out
cmake--buildcmake-android-out-j16--targetinstall
当我们设置 EXECUTORCH_BUILD_XNNPACK=ON
时,我们将构建目标 xnnpack_backend
,该目标随后通过 CMake 链接到 libexecutorch_jni 中。
- 构建 Android 扩展:
# Build the android extension
cmakeextension/android\
*DCMAKE_TOOLCHAIN_FILE="${ANDROID_NDK}"/build/cmake/android.toolchain.cmake\
*DANDROID_ABI="${ANDROID_ABI}"\
*DCMAKE_INSTALL_PREFIX=cmake-android-out\
*Bcmake-android-out/extension/android
cmake--buildcmake-android-out/extension/android-j16
libexecutorch_jni.so
封装了来自 xnnpack_backend
的所需 XNNPACK 后端运行时库,并使用 fbjni 添加了一个额外的 JNI 层。随后,这将暴露给 Java 应用程序。
Qualcomm Hexagon NPU
- 使用 Qualcomm Hexagon NPU (HTP) 后端(包含 XNNPACK)构建库的 CMake 目标:
exportANDROID_NDK=<path-to-android-ndk>
exportANDROID_ABI=arm64-v8a
exportQNN_SDK_ROOT=<path-to-qnn-sdk>
./install_requirements.sh--clean
mkdircmake-android-out
cmake.-DCMAKE_INSTALL_PREFIX=cmake-android-out\
*DCMAKE_TOOLCHAIN_FILE="${ANDROID_NDK}/build/cmake/android.toolchain.cmake"\
*DANDROID_ABI="${ANDROID_ABI}"\
*DEXECUTORCH_BUILD_XNNPACK=ON\
*DEXECUTORCH_BUILD_QNN=ON\
*DQNN_SDK_ROOT="${QNN_SDK_ROOT}"\
*DEXECUTORCH_BUILD_EXTENSION_DATA_LOADER=ON\
*DEXECUTORCH_BUILD_EXTENSION_MODULE=ON\
*DEXECUTORCH_BUILD_EXTENSION_RUNNER_UTIL=ON\
*DEXECUTORCH_BUILD_EXTENSION_TENSOR=ON\
*Bcmake-android-out
cmake--buildcmake-android-out-j16--targetinstall
与 XNNPACK 库类似,通过此设置,我们编译了 libexecutorch_jni.so
,但它还增加了一个静态库 qnn_executorch_backend
,该库封装了 Qualcomm HTP 运行时库并注册了 Qualcomm HTP 后端。随后,这一功能会被暴露给 Java 应用程序。
当我们启用 CMake 选项 EXECUTORCH_BUILD_QNN
时,qnn_executorch_backend
会被构建。它将包含来自 backends/qualcomm 的 CMakeLists.txt,其中我们使用 add_library(qnn_executorch_backend STATIC)
。
- 构建 Android 扩展:
cmakeextension/android\
*DCMAKE_TOOLCHAIN_FILE="${ANDROID_NDK}"/build/cmake/android.toolchain.cmake\
*DANDROID_ABI="${ANDROID_ABI}"\
*DCMAKE_INSTALL_PREFIX=cmake-android-out\
*Bcmake-android-out/extension/android
cmake--buildcmake-android-out/extension/android-j16
通过演示应用在设备上部署
通过 XNNPACK 部署模型的步骤
mkdir-pexamples/demo-apps/android/ExecuTorchDemo/app/src/main/jniLibs/arm64-v8a
cpcmake-android-out/extension/android/libexecutorch_jni.so\
examples/demo-apps/android/ExecuTorchDemo/app/src/main/jniLibs/arm64-v8a/libexecutorch.so
这使得 Android 应用程序能够将带有 XNNPACK 后端的 ExecuTorch 运行时作为 JNI 库加载。随后,Java 代码中的 NativePeer.java
将加载这个共享库。
通过 Qualcomm AI Engine Direct 部署模型的步骤
mkdir-p../examples/demo-apps/android/ExecuTorchDemo/app/src/main/jniLibs/arm64-v8a
我们需要向应用程序推送一些额外的 Qualcomm HTP 后端库。请参考 Qualcomm 文档。
cp${QNN_SDK_ROOT}/lib/aarch64-android/libQnnHtp.so${QNN_SDK_ROOT}/lib/hexagon-v69/unsigned/libQnnHtpV69Skel.so${QNN_SDK_ROOT}/lib/aarch64-android/libQnnHtpV69Stub.so${QNN_SDK_ROOT}/lib/aarch64-android/libQnnSystem.so\
examples/demo-apps/android/ExecuTorchDemo/app/src/main/jniLibs/arm64-v8a
复制核心库:
cpcmake-android-out/extension/android/libexecutorch_jni.so\
examples/demo-apps/android/ExecuTorchDemo/app/src/main/jniLibs/arm64-v8a/libexecutorch.so
cpcmake-android-out/lib/libqnn_executorch_backend.so\
examples/demo-apps/android/ExecuTorchDemo/app/src/main/jniLibs/arm64-v8a/libqnn_executorch_backend.so
运行应用程序
-
使用 Android Studio 打开项目
examples/demo-apps/android/ExecuTorchDemo
。 -
运行 应用程序 (^R)。
在手机或模拟器上,您可以尝试运行模型:
关键点
通过本教程,我们学习了如何构建带有 XNNPACK(或 Qualcomm HTP)后端的 ExecuTorch 运行时库,并将其暴露到 JNI 层,以构建运行分割模型的 Android 应用程序。