Cadence Xtensa 后端¶
本教程将引导您完成为 Xtensa HiFi4 DSP 构建 ExecuTorch 并在其上运行简单模型的设置过程。
Cadence 是一家软硬件供应商,提供许多计算工作负载的解决方案,包括在功耗受限的嵌入式设备上运行。 Xtensa HiFi4 DSP 是一款数字信号处理器 (DSP),它针对运行基于音频的神经网络进行了优化,例如语音唤醒检测、自动语音识别 (ASR) 等。
除了芯片之外,HiFi4 神经网络库 (nnlib) 还提供了一组常用的 NN 处理优化库函数,我们在此示例中利用这些函数来演示如何加速常见操作。
除了能在 Xtensa HiFi4 DSP 上运行之外,本教程的另一个目标是展示 ExecuTorch 的可移植性以及其在 Xtensa HiFi4 DSP 等低功耗嵌入式设备上运行的能力。此工作流程不需要任何代理 (delegates),它使用自定义运算符和编译器通道来增强模型,使其更适合在 Xtensa HiFi4 DSP 上运行。一个自定义的 量化器 用于将激活和权重表示为 uint8
而非 float
,并调用相应的运算符。最后,使用 Xtensa 指令集优化的自定义内核提供运行时加速。
在本教程中,您将学习如何导出针对 Xtensa HiFi4 DSP 的线性运算的量化模型。
您还将学习如何编译并部署 ExecuTorch 运行时,其中包含在上一步生成的量化模型在 Xtensa HiFi4 DSP 上运行所需的内核。
注意
本教程的 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 (Ahead-of-Time) 组件:
AoT 文件夹包含将模型导出到 ExecuTorch .pte
文件所需的所有 Python 脚本和函数。在本例中,export_example.py 是一个 API,它接收一个模型 (nn.Module) 和代表性输入,并通过量化器 (quantizer.py) 运行它。然后,一些编译器通道(也在 quantizer.py 中定义)将用自定义运算符替换现有运算符,这些自定义运算符在芯片上受支持并经过优化。计算所需的任何运算符都应在 ops_registrations.py 中定义,并在其他文件夹中有相应的实现。
操作符:
operators 文件夹包含两种运算符:来自 ExecuTorch 可移植库 的现有运算符以及定义自定义计算的新运算符。前者只是将运算符分派到相关的 ExecuTorch 实现,而后者充当接口,设置自定义内核计算输出所需的一切。
内核:
kernels 文件夹包含将在 HiFi4 芯片上运行的优化内核。它们使用 Xtensa 指令集来在低功耗下提供高性能。
构建¶
在此步骤中,您将从不同的模型生成 ExecuTorch 程序。然后,您将在运行时构建步骤中使用此程序(.pte
文件)将此程序嵌入到 DSP 映像中。
简单模型:
第一个简单的模型旨在测试本教程的所有组件是否正常工作,它只执行一个加法操作。生成的 .pte 文件名为 add.pte
。
cd executorch
python3 -m examples.portable.scripts.export --model_name="add"
量化运算符:
另一个更复杂的模型是自定义运算符,包括:
在这两种情况下,生成的 .pte 文件都名为 CadenceDemoModel.pte
。
cd executorch
python3 -m examples.cadence.operators.quantized_<linear,conv1d>_op
小型模型:RNNT 预测器:
torchaudio 的 RNNT-emformer 模型是一个自动语音识别 (ASR) 模型,由三个不同的子模型组成:编码器、预测器和连接器。 预测器 是由基本运算符(embedding、ReLU、linear、layer norm)组成的序列,可以使用以下方式导出:
cd executorch
python3 -m examples.cadence.models.rnnt_predictor
生成的 .pte 文件名为 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. 使用 git clone git@github.com:foss-xtensa/nnlib-hifi4.git
克隆 nnlib 仓库,其中包含 HiFi4 DSP 的优化内核和原语。
步骤 3. 运行 CMake 构建。为了运行 CMake 构建,您需要以下路径:
上一步生成的程序
NXP SDK 根目录的路径。这应该已经在 设置开发者环境 部分安装。这是包含 boards、components、devices 等文件夹的目录。
cd executorch
./install_executorch.sh --clean
mkdir 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_EXECUTOR_RUNNER=OFF \
-DEXECUTORCH_BUILD_PTHREADPOOL=OFF \
-DEXECUTORCH_BUILD_CPUINFO=OFF \
-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> \
-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 来刷新板卡并在芯片上运行,该 IDE 在所有平台(Linux、MacOS、Windows)上都可用。
步骤 2. 清理您的工作空间
步骤 3. 点击 Debug your Project,这将使用您的二进制文件刷新板卡。
在连接到您的板卡的 UART 控制台上(默认波特率为 115200),您应该会看到类似以下的输出:
> screen /dev/tty.usbmodem0007288234991 115200
Executed model
Model executed successfully.
First 20 elements of output 0
0.165528 0.331055 ...