forked from apache/tvm
-
Notifications
You must be signed in to change notification settings - Fork 30
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add MicroTVM tutorial using the STM32F746 discovery board (apache#5655)
* Add MicroTVM tutorial using the STM32F746 discovery board with a sample tflite model Signed-off-by: Tom Gall <tom.gall@linaro.org> * Fix: add a reference to the new turtorials/micro directory Signed-off-by: Tom Gall <tom.gall@linaro.org> * fix: Cosmetic, align Micro TVM text with divider Signed-off-by: Tom Gall <tom.gall@linaro.org> * Fixes to remove warnings, spaces for readability, code blocks Signed-off-by: Tom Gall <tom.gall@linaro.org> * remove use of dload in favor of requests for obtaining the TFLite model Signed-off-by: Tom Gall <tom.gall@linaro.org> * add setup for CMSIS_ST_PATH comment out portion of tutorial that will not run without a physical board available Signed-off-by: Tom Gall <tom.gall@linaro.org> * Fix warning due to ** in python but part of a comment block The block is commented out since it can only run on device Signed-off-by: Tom Gall <tom.gall@linaro.org> * Numerous reworks to address feedback. Within docs/conf.py place the microTVM tutorial prior to the VTA tutorials Within the micro_tflite - rework section headers - reorder code so model prep code is all in one place as well as code for running on device - address indentation feedback - remove '' '' usage which I mistakenly thought was getting around a sphinx issue involving ** Signed-off-by: Tom Gall <tom.gall@linaro.org> * Change disable_vectorize to use current approach with tvm.transform.PassContext Change to pull example model from github with download_testdata Add 2.5K tflite model Couple of small changes following https://sphinx-gallery.github.io/stable/syntax.html Signed-off-by: Tom Gall <tom.gall@linaro.org> * remove use of relay.build_config in favor of PassContext Signed-off-by: Tom Gall <tom.gall@linaro.org> * Couple of minor 4 space fix ups Signed-off-by: Tom Gall <tom.gall@linaro.org> * Change to use tvm.transform.PassContext for disable_victorize and disabling FuseOps Signed-off-by: Tom Gall <tom.gall@linaro.org> * Remove binary module from repo Change download_testdata back to pull model from linaro server Signed-off-by: Tom Gall <tom.gall@linaro.org> * Couple of small cosmetic changes. (spaces and extra lines) Signed-off-by: Tom Gall <tom.gall@linaro.org> * Convert link to tf docs to examine a tf lite model to use RST syntax Signed-off-by: Tom Gall <tom.gall@linaro.org>
- Loading branch information
Showing
3 changed files
with
223 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
.. _tutorial-micro: | ||
|
||
Micro TVM | ||
--------- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,218 @@ | ||
# 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. | ||
""" | ||
Micro TVM with TFLite Models | ||
============================ | ||
**Author**: `Tom Gall <https://github.com/tom-gall>`_ | ||
This tutorial is an introduction to working with MicroTVM and a TFLite | ||
model with Relay. | ||
""" | ||
|
||
# %% | ||
# Setup | ||
# ----- | ||
# | ||
# To get started, TFLite package needs to be installed as prerequisite. | ||
# | ||
# install tflite | ||
# | ||
# .. code-block:: bash | ||
# | ||
# pip install tflite=2.1.0 --user | ||
# | ||
# or you could generate TFLite package yourself. The steps are the following: | ||
# | ||
# Get the flatc compiler. | ||
# Please refer to https://github.com/google/flatbuffers for details | ||
# and make sure it is properly installed. | ||
# | ||
# .. code-block:: bash | ||
# | ||
# flatc --version | ||
# | ||
# Get the TFLite schema. | ||
# | ||
# .. code-block:: bash | ||
# | ||
# wget https://raw.githubusercontent.com/tensorflow/tensorflow/r1.13/tensorflow/lite/schema/schema.fbs | ||
# | ||
# Generate TFLite package. | ||
# | ||
# .. code-block:: bash | ||
# | ||
# flatc --python schema.fbs | ||
# | ||
# Add the current folder (which contains generated tflite module) to PYTHONPATH. | ||
# | ||
# .. code-block:: bash | ||
# | ||
# export PYTHONPATH=${PYTHONPATH:+$PYTHONPATH:}$(pwd) | ||
# | ||
# To validate that the TFLite package was installed successfully, ``python -c "import tflite"`` | ||
# | ||
# CMSIS needs to be downloaded and the CMSIS_ST_PATH environment variable setup | ||
# This tutorial only supports the STM32F7xx series of boards. | ||
# Download from : https://www.st.com/en/embedded-software/stm32cubef7.html | ||
# After you've expanded the zip file | ||
# | ||
# .. code-block:: bash | ||
# | ||
# export CMSIS_ST_PATH=/path/to/STM32Cube_FW_F7_V1.16.0/Drivers/CMSIS | ||
|
||
# %% | ||
# Recreating your own Pre-Trained TFLite model | ||
# -------------------------------------------- | ||
# | ||
# The tutorial downloads a pretrained TFLite model. When working with microcontrollers | ||
# you need to be mindful these are highly resource constrained devices as such standard | ||
# models like MobileNet may not fit into their modest memory. | ||
# | ||
# For this tutorial, we'll make use of one of the TF Micro example models. | ||
# | ||
# If you wish to replicate the training steps see: | ||
# https://github.com/tensorflow/tensorflow/tree/master/tensorflow/lite/micro/examples/hello_world/train | ||
# | ||
# .. note:: | ||
# | ||
# If you accidentally download the example pretrained model from: | ||
# wget https://storage.googleapis.com/download.tensorflow.org/models/tflite/micro/hello_world_2020_04_13.zip | ||
# this will fail due to an unimplemented opcode (114) | ||
|
||
import os | ||
import numpy as np | ||
import tvm | ||
import tvm.micro as micro | ||
from tvm.contrib.download import download_testdata | ||
from tvm.contrib import graph_runtime, util | ||
from tvm import relay | ||
|
||
# %% | ||
# Load and prepare the Pre-Trained Model | ||
# -------------------------------------- | ||
# | ||
# Load the pretrained TFLite model from a file in your current | ||
# directory into a buffer | ||
|
||
model_url = 'https://people.linaro.org/~tom.gall/sine_model.tflite' | ||
model_file = 'sine_model.tflite' | ||
model_path = download_testdata(model_url, model_file, module='data') | ||
|
||
tflite_model_buf = open(model_path, "rb").read() | ||
|
||
###################################################################### | ||
# Using the buffer, transform into a tflite model python object | ||
try: | ||
import tflite | ||
tflite_model = tflite.Model.GetRootAsModel(tflite_model_buf, 0) | ||
except AttributeError: | ||
import tflite.Model | ||
tflite_model = tflite.Model.Model.GetRootAsModel(tflite_model_buf, 0) | ||
|
||
###################################################################### | ||
# Print out the version of the model | ||
version = tflite_model.Version() | ||
print ("Model Version: " + str(version)) | ||
|
||
###################################################################### | ||
# Parse the python model object to convert it into a relay module | ||
# and weights. | ||
# It is important to note that the input tensor name must match what | ||
# is contained in the model. | ||
# | ||
# If you are unsure what that might be, this can be discovered by using | ||
# the visualize.py script within the Tensorflow project. | ||
# See : How do I inspect a .tflite file? `<https://www.tensorflow.org/lite/guide/faq>`_ | ||
|
||
input_tensor = "dense_4_input" | ||
input_shape = (1,) | ||
input_dtype = "float32" | ||
|
||
mod, params = relay.frontend.from_tflite(tflite_model, | ||
shape_dict={input_tensor: input_shape}, | ||
dtype_dict={input_tensor: input_dtype}) | ||
|
||
# %% | ||
# Running on device | ||
# ---------------------------------------------- | ||
# | ||
# Setup the device config which is what will be used to communicate | ||
# with the microcontroller (a STM32F746 Discovery board) | ||
TARGET = 'c -device=micro_dev' | ||
dev_config = micro.device.arm.stm32f746xx.generate_config("127.0.0.1", 6666) | ||
|
||
###################################################################### | ||
# Next with the dev_config, we establish a micro session and create | ||
# a context | ||
# | ||
# .. code-block:: python | ||
# | ||
# with micro.Session(dev_config) as sess: | ||
# ctx = tvm.micro_dev(0) | ||
|
||
###################################################################### | ||
# Now we create a build config for relay. turning off two options | ||
# and then calling relay.build which will result in a C source | ||
# file. | ||
# | ||
# .. code-block:: python | ||
# | ||
# with tvm.transform.PassContext(opt_level=3, config={'tir.disable_vectorize': True},disabled_pass=['FuseOps']): | ||
# graph, c_mod, params = relay.build(mod, target=TARGET, params=params) | ||
|
||
###################################################################### | ||
# With the c_mod that is the handle to our C source code, we create a | ||
# micro module, followed by a compiled object which behind the scenes | ||
# is linked to the microTVM runtime for running on the target board | ||
# | ||
# .. code-block:: python | ||
# | ||
# micro_mod = micro.create_micro_mod(c_mod, dev_config) | ||
# mod = graph_runtime.create(graph, micro_mod, ctx) | ||
|
||
###################################################################### | ||
# Pass the weights to get ready to perform inference | ||
# | ||
# .. code-block:: python | ||
# | ||
# mod.set_input(**params) | ||
|
||
###################################################################### | ||
# The model consumes a single float32 value and returns a predicted | ||
# sine value. | ||
# To pass the input value we construct a tvm.nd.array object | ||
# with a single contrived number as input. For this model values of | ||
# 0 to 2Pi are acceptable. | ||
# | ||
# .. code-block:: python | ||
# | ||
# mod.set_input(input_tensor, tvm.nd.array(np.array([0.5], dtype="float32"))) | ||
|
||
###################################################################### | ||
# Run the model on device | ||
# | ||
# .. code-block:: python | ||
# | ||
# mod.run() | ||
|
||
###################################################################### | ||
# Get output from the run and print | ||
# | ||
# .. code-block:: python | ||
# | ||
# tvm_output = mod.get_output(0).asnumpy() | ||
# print("result is: "+str(tvm_output)) |