From f93f2a63c0152696598b928de709f925a83f1d68 Mon Sep 17 00:00:00 2001 From: Mehrdad Hessar Date: Thu, 27 Jan 2022 09:10:56 -0800 Subject: [PATCH] [microTVM][tvmc] Add TVMC Micro tutorial for Zephyr (#10024) --- docs/conf.py | 1 + .../work_with_microtvm/micro_autotune.py | 7 +- .../how_to/work_with_microtvm/micro_tvmc.py | 198 ++++++++++++++++++ tests/micro/common/test_tvmc.py | 2 +- 4 files changed, 203 insertions(+), 5 deletions(-) create mode 100644 gallery/how_to/work_with_microtvm/micro_tvmc.py diff --git a/docs/conf.py b/docs/conf.py index 2f650a88c936..702821c470f4 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -316,6 +316,7 @@ def git_describe_version(original_version): "micro_reference_vm.py", "micro_tflite.py", "micro_ethosu.py", + "micro_tvmc.py", ], } diff --git a/gallery/how_to/work_with_microtvm/micro_autotune.py b/gallery/how_to/work_with_microtvm/micro_autotune.py index 394a946cf3d5..c6516563fac3 100644 --- a/gallery/how_to/work_with_microtvm/micro_autotune.py +++ b/gallery/how_to/work_with_microtvm/micro_autotune.py @@ -18,7 +18,7 @@ """ .. _tutorial-micro-autotune: -Autotuning with micro TVM +Autotuning with microTVM ========================= **Authors**: `Andrew Reusch `_, @@ -28,11 +28,10 @@ """ import numpy as np -import subprocess import pathlib import tvm -from tvm.relay.backend import Executor, Runtime +from tvm.relay.backend import Runtime #################### # Defining the model @@ -67,7 +66,7 @@ params = {"weight": weight_sample} ####################### -# Defining the target # +# Defining the target ####################### # Now we define the TVM target that describes the execution environment. This looks very similar # to target definitions from other microTVM tutorials. Alongside this we pick the C Runtime to code diff --git a/gallery/how_to/work_with_microtvm/micro_tvmc.py b/gallery/how_to/work_with_microtvm/micro_tvmc.py new file mode 100644 index 000000000000..423e0f1dde37 --- /dev/null +++ b/gallery/how_to/work_with_microtvm/micro_tvmc.py @@ -0,0 +1,198 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +""" +.. _tutorial-micro-tvmc: + +Executing a Tiny Model with TVMC Micro +====================================== +**Author**: `Mehrdad Hessar `_ + +This tutorial explains how to compile a tiny model for a micro device, +build a program on Zephyr platform to execute this model, flash the program +and run the model all using `tvmc micro` command. +""" + +###################################################################### +# .. note:: +# This tutorial is explaining using TVMC Mirco on Zephyr platform. You need +# to install Zephyr dependencies before processing with this tutorial. Alternatively, +# you can run this tutorial in one of the following ways which has Zephyr depencencies already installed. +# +# * Use `microTVM Reference Virtual Machines `_. +# * Use QEMU docker image provided by TVM. Following these you will download and login to the docker image: +# +# .. code-block:: bash +# +# cd tvm +# ./docker/bash.sh tlcpack/ci-qemu +# + + +############################################################ +# Using TVMC Micro +############################################################ +# +# TVMC is a command-line tool which is installed as a part of TVM Python packages. Accessing this +# package varies based on your machine setup. In many cases, you can use the ``tvmc`` command directly. +# Alternatively, if you have TVM as a Python module on your ``$PYTHONPATH``, you can access this +# driver with ``python -m tvm.driver.tvmc`` command. This tutorial will use TVMC command as +# ``tvmc`` for simplicity. +# +# To check if you have TVMC command installed on your machine, you can run: +# +# .. code-block:: bash +# +# tvmc --help +# +# To compile a model for microtvm we use ``tvmc compile`` subcommand. The output of this command +# is used in next steps with ``tvmc micro`` subcommands. You can check the availability of TVMC Micro using: +# +# .. code-block:: bash +# +# tvmc micro --help +# +# The main tasks that you can perform using ``tvmc micro`` are ``create``, ``build`` and ``flash``. +# To read about specific options under a givern subcommand, use +# ``tvmc micro --help``. We will use each subcommand in this tutorial. +# + +############################################################ +# Obtain a Tiny Model +############################################################ +# +# For this tutorial, we will use Magic Wand model from tflite micro. Magic Wand is a +# Depthwise Convolution Layer model which recognizes gestures with an accelerometer. +# +# For this tutorial we will be using the model in tflite format. +# +# .. code-block:: bash +# +# wget https://github.com/tensorflow/tflite-micro/raw/main/tensorflow/lite/micro/examples/magic_wand/magic_wand.tflite +# + +############################################################ +# Compiling a TFLite model to a Model Library Format +############################################################ +# +# Model Library Format (MLF) is an output format that TVM provides for micro targets. MLF is a tarball +# containing a file for each piece of the TVM compiler output which can be used on micro targets outside +# TVM environment. Read more about `Model Library Format `_. +# +# Here, we generate a MLF file for ``qemu_x86`` Zephyr board. To generate MLF output for the ``magic_wand`` tflite model: +# +# .. code-block:: bash +# +# tvmc compile magic_wand.tflite \ +# --target='c -keys=cpu -link-params=0 -model=host' \ +# --runtime=crt \ +# --runtime-crt-system-lib 1 \ +# --executor='graph' \ +# --executor-graph-link-params 0 \ +# --output model.tar \ +# --output-format mlf \ +# --pass-config tir.disable_vectorize=1 \ +# --disabled-pass=AlterOpLayout +# +# This will generate a ``model.tar`` file which contains TVM compiler output files. To run this command for +# a different Zephyr device, you need to update ``target``. For instance, for ``nrf5340dk_nrf5340_cpuapp`` board +# the target is ``--target='c -keys=cpu -link-params=0 -model=nrf5340dk'``. +# + + +############################################################ +# Create a Zephyr Project Using Model Library Format +############################################################ +# +# To generate a Zephyr project we use TVM Micro subcommand ``create``. We pass the MLF format and the path +# for the project to ``create`` subcommand along with project options. Project options for each +# platform (Zephyr/Arduino) are defined in their Project API server file. To generate Zephyr project, run: +# +# .. code-block:: bash +# +# tvmc micro create \ +# project \ +# model.tar \ +# zephyr \ +# --project-option project_type=host_driven zephyr_board=qemu_x86 +# +# This will generate a ``Host-Driven`` Zephyr project for ``qemu_x86`` Zephyr board. In Host-Driven template project, +# the Graph Executor will run on host and perform the model execution on Zephyr device by issuing commands to the +# device using an RPC mechanism. Read more about `Host-Driven Execution `_. +# +# To get more information about TVMC Micro ``create`` subcommand: +# +# .. code-block:: bash +# +# tvmc micro create --help +# + +############################################################ +# Build and Flash Zephyr Project Using TVMC Micro +############################################################ +# +# Next step is to build the Zephyr project which includes TVM generated code for running the tiny model, Zephyr +# template code to run a model in Host-Driven mode and TVM runtime source/header files. To build the project: +# +# .. code-block:: bash +# +# tvmc micro build \ +# project \ +# zephyr \ +# --project-option zephyr_board=qemu_x86 +# +# This will build the project in ``project`` directory and generates binary files under ``project/build``. To build +# Zephyr project for a different Zephyr board, change ``zephyr_board`` project option. +# +# Next, we flash the Zephyr binary file to Zephyr device. For ``qemu_x86`` Zephyr board this step does not +# actually perform any action since QEMU will be used, however you need this step for physical hardware. +# +# .. code-block:: bash +# +# tvmc micro flash \ +# project \ +# zephyr \ +# --project-option zephyr_board=qemu_x86 +# + +############################################################ +# Run Tiny Model on Micro Target +############################################################ +# +# After flashing the device, the compiled model and TVM RPC server are programmed on the device. +# The Zephyr board is waiting for host to open a communication channel. MicroTVM devices typicall communicate +# using a serial communication (UART). To run the flashed model on the device using TVMC, we use ``tvmc run`` subcommand +# and pass ``--device micro`` to specify the device type. This command will open a communication channel, set input +# values using ``Graph Executor`` on host and run full model on the device. Then it gets output from the device. +# +# .. code-block:: bash +# +# tvmc run \ +# --device micro \ +# project \ +# --project-option zephyr_board=qemu_x86 \ +# --fill-mode ones +# --print-top 4 +# # 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. 1. 2. 0. ] +# # [0.47213247 0.41364592 0.07525456 0.03896701]] +# +# Specifically, this command sets the input of the model to all ones and shows the four values of the output with their indices. diff --git a/tests/micro/common/test_tvmc.py b/tests/micro/common/test_tvmc.py index eb0b3a628442..a3e8a9e8b5a4 100644 --- a/tests/micro/common/test_tvmc.py +++ b/tests/micro/common/test_tvmc.py @@ -80,7 +80,7 @@ def test_tvmc_model_build_only(board, output_dir): shutil.rmtree(out_dir_temp) os.mkdir(out_dir_temp) - model_path = model_path = download_testdata(MODEL_URL, MODEL_FILE, module="data") + model_path = download_testdata(MODEL_URL, MODEL_FILE, module="data") tar_path = str(output_dir / "model.tar") project_dir = str(output_dir / "project")