在 Xtensa HiFi4 DSP 上构建和运行 ExecuTorch¶
在本教程中,我们将指导您完成在 Xtensa HiFi4 DSP 上构建 ExecuTorch 并在其上运行简单模型的过程。
Cadence 既是硬件也是软件供应商,为许多计算工作负载提供解决方案,包括在功耗受限的嵌入式设备上运行。 Xtensa HiFi4 DSP 是一种数字信号处理器 (DSP),专门针对运行基于音频的神经网络(如唤醒词检测、自动语音识别 (ASR) 等)进行了优化。
除了芯片之外,HiFi4 神经网络库 (nnlib) 提供了一组优化的库函数,这些函数通常用于 NN 处理,我们在本示例中使用它们来演示如何加速常用操作。
除了能够在 Xtensa HiFi4 DSP 上运行之外,本教程的另一个目标是演示 ExecuTorch 的可移植性及其在 Xtensa HiFi4 DSP 等低功耗嵌入式设备上运行的能力。此工作流程不需要任何委托,它使用自定义运算符和编译器传递来增强模型,使其更适合在 Xtensa HiFi4 DSP 上运行。一个自定义的 量化器 用于将激活和权重表示为 uint8
而不是 float
,并调用相应的运算符。最后,使用 Xtensa 内在函数优化的自定义内核提供了运行时加速。
在本教程中,您将学习如何导出一个量化模型,该模型具有针对 Xtensa HiFi4 DSP 的线性操作。
您还将学习如何在 Xtensa HiFi4 DSP 上编译和部署 ExecuTorch 运行时以及运行先前步骤中生成的量化模型所需的内核。
注意
本教程的 Linux 部分已在 Ubuntu 22.04 LTS 上设计和测试,需要 glibc 2.34。其他发行版提供解决方法,但本教程中不会介绍。
先决条件 (硬件和软件)¶
为了能够在 Xtensa HiFi4 DSP 上成功构建和运行 ExecuTorch,您需要以下硬件和软件组件。
软件¶
x86-64 Linux 系统(用于编译 DSP 二进制文件)
-
此 IDE 支持多个平台,包括 MacOS。您可以在任何支持的平台上使用它,因为您只需要使用它来将 DSP 镜像刷入板子,您将在本教程的后面部分构建这些镜像。
-
用于将固件镜像刷入板子。您可以在安装 MCUXpresso IDE 的同一个平台上安装它。
注意:根据 NXP 板的版本,可能会安装 JLink 之外的其他探针。无论哪种情况,刷入都是使用 MCUXpresso IDE 以类似的方式完成的。
-
将此 SDK 下载到您的 Linux 机器上,解压缩它并记下存储它的路径。您将在后面需要它。
-
将此下载到您的 Linux 机器上。这需要用于为 HiFi4 DSP 构建 ExecuTorch。
对于使用优化内核的情况,nnlib 仓库。
设置开发者环境¶
步骤 1. 为了能够成功安装上面指定的所有软件组件,用户需要完成下面链接的 NXP 教程。虽然教程本身介绍了 Windows 设置,但大多数步骤也可以移植到 Linux 安装中。
注意
在继续下一部分之前,用户应该能够成功地从上面的教程中刷入 **dsp_mu_polling_cm33** 示例应用程序,并在 UART 控制台中看到指示 Cortex-M33 和 HiFi4 DSP 互相通信的输出。
步骤 2. 确保您已完成本页面顶部链接到的 ExecuTorch 设置教程。
工作树描述¶
工作树是
executorch
├── backends
│ └── cadence
│ ├── aot
│ ├── ops_registration
│ ├── tests
│ ├── utils
│ ├── hifi
│ │ ├── kernels
│ │ ├── operators
│ │ └── third-party
│ │ └── hifi4-nnlib
│ └── [other cadence DSP families]
│ ├── kernels
│ ├── operators
│ └── third-party
│ └── [any required lib]
└── examples
└── cadence
├── models
└── operators
AoT (提前) 组件:
AoT 文件夹包含将模型导出到 ExecuTorch .pte
文件所需的所有 Python 脚本和函数。在我们的示例中,export_example.py 是一个 API,它接受一个模型 (nn.Module) 和代表性的输入,并将其通过量化器(来自 quantizer.py)运行。然后,在 quantizer.py 中定义的一些编译过程将用芯片上支持和优化的自定义运算符替换运算符。任何用于计算事物的运算符都应在 ops_registrations.py 中定义,并在其他文件夹中具有相应的实现。
运算符:
运算符文件夹包含两种类型的运算符:来自 ExecuTorch 可移植库 的现有运算符和定义自定义计算的新运算符。前者只是将运算符分派到相关的 ExecuTorch 实现,而后者充当接口,设置自定义内核计算输出所需的一切。
内核:
内核文件夹包含将在 HiFi4 芯片上运行的优化内核。它们使用 Xtensa 内在函数来以低功耗提供高性能。
构建¶
在此步骤中,您将从不同的模型生成 ExecuTorch 程序。然后,您将在运行时构建步骤中使用此程序(.pte
文件)将此程序烘焙到 DSP 映像中。
简单模型:
第一个简单模型旨在测试本教程的所有组件是否正常工作,并且只执行加法运算。生成的文件称为 add.pte
。
cd executorch
python3 -m examples.portable.scripts.export --model_name="add"
量化运算符:
另一个更复杂的模型是自定义运算符,包括
在这两种情况下,生成的文件都称为 CadenceDemoModel.pte
。
cd executorch
python3 -m examples.cadence.operators.quantized_<linear,conv1d>_op
小型模型:RNNT 预测器:
torchaudio RNNT-emformer 模型是一个自动语音识别 (ASR) 模型,由三个不同的子模型组成:编码器、预测器和连接器。 预测器 是一系列基本操作(嵌入、ReLU、线性、层归一化),可以使用以下方法导出
cd executorch
python3 -m examples.cadence.models.rnnt_predictor
生成的文件称为 CadenceDemoModel.pte
。
运行时¶
构建 DSP 固件映像 在此步骤中,您将构建 DSP 固件映像,该映像包含示例 ExecuTorch 运行器以及从上一步生成的程序。此映像加载到 DSP 后将运行此程序包含的模型。
步骤 1. 配置指向已在上一步中安装的 Xtensa 工具链所需的环境变量。需要设置的三个环境变量包括
# Directory in which the Xtensa toolchain was installed
export XTENSA_TOOLCHAIN=/home/user_name/cadence/XtDevTools/install/tools
# The version of the toolchain that was installed. This is essentially the name of the directory
# that is present in the XTENSA_TOOLCHAIN directory from above.
export TOOLCHAIN_VER=RI-2021.8-linux
# The Xtensa core that you're targeting.
export XTENSA_CORE=nxp_rt600_RI2021_8_newlib
步骤 2. 克隆 nnlib 存储库,其中包含针对 HiFi4 DSP 的优化内核和基元,使用 git clone [email protected]:foss-xtensa/nnlib-hifi4.git
。
步骤 3. 运行 CMake 构建。为了运行 CMake 构建,您需要以下路径
上一步生成的程序
NXP SDK 根目录的路径。这应该已在 设置开发环境 部分中安装。这是包含 boards、components、devices 和其他文件夹的目录。
cd executorch
rm -rf cmake-out
# prebuild and install executorch library
cmake -DCMAKE_TOOLCHAIN_FILE=<path_to_executorch>/backends/cadence/cadence.cmake \
-DCMAKE_INSTALL_PREFIX=cmake-out \
-DCMAKE_BUILD_TYPE=Debug \
-DPYTHON_EXECUTABLE=python3 \
-DEXECUTORCH_BUILD_EXTENSION_RUNNER_UTIL=ON \
-DEXECUTORCH_BUILD_HOST_TARGETS=ON \
-DEXECUTORCH_BUILD_EXECUTOR_RUNNER=OFF \
-DEXECUTORCH_BUILD_PTHREADPOOL=OFF \
-DEXECUTORCH_BUILD_CPUINFO=OFF \
-DEXECUTORCH_BUILD_FLATC=OFF \
-DFLATC_EXECUTABLE="$(which flatc)" \
-Bcmake-out .
cmake --build cmake-out -j<num_cores> --target install --config Debug
# build cadence runner
cmake -DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_TOOLCHAIN_FILE=<path_to_executorch>/examples/backends/cadence.cmake \
-DCMAKE_PREFIX_PATH=<path_to_executorch>/cmake-out \
-DMODEL_PATH=<path_to_program_file_generated_in_previous_step> \
-DNXP_SDK_ROOT_DIR=<path_to_nxp_sdk_root> -DEXECUTORCH_BUILD_FLATC=0 \
-DFLATC_EXECUTABLE="$(which flatc)" \
-DNN_LIB_BASE_DIR=<path_to_nnlib_cloned_in_step_2> \
-Bcmake-out/examples/cadence \
examples/cadence
cmake --build cmake-out/examples/cadence -j8 -t cadence_executorch_example
在成功运行上述步骤后,您应该在它们的 CMake 输出目录中看到两个二进制文件。
> ls cmake-xt/*.bin
cmake-xt/dsp_data_release.bin cmake-xt/dsp_text_release.bin
部署和在设备上运行¶
步骤 1. 现在,您将从上一步生成的 DSP 二进制映像复制到您在 设置开发环境 部分中创建的 NXP 工作空间中。将 DSP 映像复制到下面图像中突出显示的 dsp_binary
部分。
注意
只要使用 Linux 上的 Xtensa 工具链构建二进制文件,就可以使用 MCUXpresso IDE(在所有平台(Linux、MacOS、Windows)上都可用)对板进行刷写并运行芯片。
步骤 2. 清理您的工作空间
步骤 3. 点击 调试您的项目,这将使用您的二进制文件刷写板子。
在连接到您板子的 UART 控制台中(默认波特率为 115200),您应该看到类似以下内容的输出
> screen /dev/tty.usbmodem0007288234991 115200
Executed model
Model executed successfully.
First 20 elements of output 0
0.165528 0.331055 ...