%%shell
# Installs the latest dev build of TVM from PyPI. If you wish to build
# from source, see https://tvm.apache.org/docs/install/from_source.html
pip install apache-tvm --pre

1. microTVM CLI 工具#

Author: Mehrdad Hessar

本教程介绍了如何为微型设备编译小模型,构建在 Zephyr 平台上执行此模型的程序,使用 tvmc micro 命令刷写程序并运行该模型。在开始本教程之前,您需要安装 Python 和 Zephyr 依赖项。

安装 microTVM Python 依赖#

TVM 不包括用于 Python 串行通信的软件包,因此在使用 microTVM 之前,必须先安装。还需要 TFLite 来加载模型。

%%bash
pip install pyserial==3.5 tflite==2.1

安装 Zephyr#

%%bash
# Install west and ninja
python3 -m pip install west
apt-get install -y ninja-build

# Install ZephyrProject
ZEPHYR_PROJECT_PATH="/content/zephyrproject"
export ZEPHYR_BASE=${ZEPHYR_PROJECT_PATH}/zephyr
west init ${ZEPHYR_PROJECT_PATH}
cd ${ZEPHYR_BASE}
git checkout v3.2-branch
cd ..
west update
west zephyr-export
chmod -R o+w ${ZEPHYR_PROJECT_PATH}

# Install Zephyr SDK
cd /content
ZEPHYR_SDK_VERSION="0.15.2"
wget "https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v${ZEPHYR_SDK_VERSION}/zephyr-sdk-${ZEPHYR_SDK_VERSION}_linux-x86_64.tar.gz"
tar xvf "zephyr-sdk-${ZEPHYR_SDK_VERSION}_linux-x86_64.tar.gz"
mv "zephyr-sdk-${ZEPHYR_SDK_VERSION}" zephyr-sdk
rm "zephyr-sdk-${ZEPHYR_SDK_VERSION}_linux-x86_64.tar.gz"

# Install python dependencies
python3 -m pip install -r "${ZEPHYR_BASE}/scripts/requirements.txt"

使用 TVMC Micro#

TVMC 是作为 TVM Python 软件包的一部分安装的命令行工具。访问此软件包取决于您的机器设置。在许多情况下,您可以直接使用 tvmc 命令。或者,如果您的 Python 路径中有 TVM 作为 Python 模块,您可以使用 python -m tvm.driver.tvmc 命令访问此驱动程序。本教程将简单地使用名为 tvmc 的 TVMC 命令。

要检查您的机器上是否安装了 TVMC 命令,您可以运行:

tvmc --help

要为 MicroTVM 编译模型,使用 tvmc compile 子命令。此命令的输出将与 tvmc micro 子命令一起在接下来的步骤中使用。您可以使用以下命令检查 TVMC Micro 的可用性:

tvmc micro --help

您可以使用 tvmc micro 执行的主要任务包括 createbuildflash。要了解特定子命令下的选项,请使用 tvmc micro <subcommand> --help。在本教程中,我们将使用每个子命令。

获取微模型#

在本教程中,将使用 tflite micro 中的 Micro Speech 模型。Micro Speech 是一种深度可分离卷积层模型,用于识别语音中的关键词。

在本教程中,将使用 tflite 格式的模型。

wget https://github.com/tensorflow/tflite-micro/raw/a56087ffa2703b4d5632f024a8a4c899815c31bb/tensorflow/lite/micro/examples/micro_speech/micro_speech.tflite

将 TFLite 模型编译为模型库格式。#

模型库格式(Model Library Format,简写为 MLF)是 TVM 为 micro 目标提供的输出格式。MLF 是 tarball,其中包含 TVM 编译器输出的每个部分的文件,可以在 TVM 环境之外的 micro 目标上使用。了解更多关于“模型库格式”的信息,请参考 Model 库格式

在这里,我们为 qemu_x86 Zephyr板生成 MLF 文件。您可以选择使用 aotgraph 执行器类型来运行本教程,但我们建议在微小的 TVM 目标中使用 aot,因为 aot 使用静态内存分配的预先编译。要为 micro_speech tflite 模型生成 MLF 输出,请执行以下操作:

tvmc compile micro_speech.tflite \
    --target='c -keys=cpu -model=host' \
    --runtime=crt \
    --runtime-crt-system-lib 1 \
    --executor='aot' \
    --output model.tar \
    --output-format mlf \
    --pass-config tir.disable_vectorize=1

这将生成包含 TVM 编译器输出文件的 model.tar 文件。要针对不同的 Zephyr 设备运行此命令,您需要更新 target。例如,对于 nrf5340dk_nrf5340_cpuapp 板,目标是 --target='c -keys=cpu -model=nrf5340dk'

使用模型库格式创建 Zephyr 项目。#

为了生成 Zephyr 项目,使用 TVM Micro 子命令 create。将 MLF 格式和项目路径传递给 create 子命令,以及项目选项。每个平台(Zephyr/Arduino)的项目选项在其项目 API 服务器文件中定义。要为不同的 Zephyr 板构建 Zephyr 项目,请更改 zephyr_board 项目选项。要生成 Zephyr 项目,请运行:

tvmc micro create \
    project \
    model.tar \
    zephyr \
    --project-option project_type=host_driven board=qemu_x86

这将为 qemu_x86 Zephyr板生成 Host-Driven Zephyr 项目。在 Host-Driven 模板项目中,Graph 执行器将在主机上运行,并通过使用 RPC 机制向设备发出命令,在 Zephyr 设备上执行模型。阅读有关Host-Driven Execution 的更多信息。

要获取有关TVMC Micro create 子命令的更多信息:

tvmc micro create --help

使用 TVMC Micro 构建和 Flash Zephyr 项目#

下一步是构建 Zephyr 项目,其中包括运行小型模型所生成的 TVM 代码、在主机驱动模式下运行模型的 Zephyr 模板代码以及 TVM 运行时源代码/头文件。要构建该项目:

tvmc micro build \
    project \
    zephyr

这将在 project 目录中构建项目,并在 project/build 下生成二进制文件。

接下来,我们将 Zephyr 二进制文件烧录(flash)到 Zephyr 设备上。对于 qemu_x86 Zephyr 开发板,此步骤实际上不会执行任何操作,因为将使用 QEMU,但对于物理硬件,您需要执行此步骤。

tvmc micro flash \
    project \
    zephyr

在 Micro Target 运行微模型#

烧录设备后,编译的模型和 TVM RPC 服务器被编程到设备上。Zephyr 开发板正在等待主机打开通信通道。MicroTVM 设备通常使用串行通信(UART)进行通信。使用 TVMC 运行已烧录的模型,我们使用 tvmc run 子命令并传递 --device micro 来指定设备类型。该命令将打开通信通道,在主机上使用 Graph Executor 设置输入值并在设备上运行完整模型。然后它从设备获取输出。

tvmc run \
    --device micro \
    project \
    --fill-mode ones \
    --print-top 4

具体来说,此命令将模型的输入设置为全为 1,并显示输出的四个值及其索引。

# Output:
# INFO:__main__:b'[100%] [QEMU] CPU: qemu32,+nx,+pae\n'
# remote: microTVM Zephyr runtime - running
# INFO:__main__:b'[100%] Built target run\n'
# [[   3    2    1    0]
#  [ 113 -120 -121 -128]]