From a92508dca0825aebf786416469aa184a7bd3fea5 Mon Sep 17 00:00:00 2001 From: Tom Gall Date: Fri, 22 May 2020 14:39:58 -0500 Subject: [PATCH 01/15] Add MicroTVM tutorial using the STM32F746 discovery board with a sample tflite model Signed-off-by: Tom Gall --- tutorials/micro/README.txt | 4 + tutorials/micro/micro_tflite.py | 183 ++++++++++++++++++++++++++++++++ 2 files changed, 187 insertions(+) create mode 100644 tutorials/micro/README.txt create mode 100644 tutorials/micro/micro_tflite.py diff --git a/tutorials/micro/README.txt b/tutorials/micro/README.txt new file mode 100644 index 000000000000..1cc4cd91bf83 --- /dev/null +++ b/tutorials/micro/README.txt @@ -0,0 +1,4 @@ +.. _tutorial-micro: + +Micro TVM +---------------------------- diff --git a/tutorials/micro/micro_tflite.py b/tutorials/micro/micro_tflite.py new file mode 100644 index 000000000000..d9aa66aadd7e --- /dev/null +++ b/tutorials/micro/micro_tflite.py @@ -0,0 +1,183 @@ +# 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 `_ + +This article is an introduction to working with MicroTVM and TFLite models with Relay. + +To get started, TFLite package needs to be installed as prerequisite. + +.. code-block:: bash + + # install tflite + pip install tflite=2.1.0 --user + + +or you could generate TFLite package yourself. The steps are the following: + +.. code-block:: bash + + # Get the flatc compiler. + # Please refer to https://github.com/google/flatbuffers for details + # and make sure it is properly installed. + flatc --version + + # Get the TFLite schema. + wget https://raw.githubusercontent.com/tensorflow/tensorflow/r1.13/tensorflow/lite/schema/schema.fbs + + # Generate TFLite package. + flatc --python schema.fbs + + # Add current folder (which contains generated tflite module) to PYTHONPATH. + export PYTHONPATH=${PYTHONPATH:+$PYTHONPATH:}$(pwd) + + +To validate that the TFLite package was installed successfully, ``python -c "import tflite"`` + +First we need to download 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 + +.. code-block:: bash + + # if you download the example pretrained model from + wget https://storage.googleapis.com/download.tensorflow.org/models/tflite/micro/hello_world_2020_04_13.zip + unzip hello_world_2020_04_13.zip + this will fail due to an unimplemented opcode (114) + I've saved an older version of the pre-trailed model and made it available on linaro.org + +""" +###################################################################### +# Python imports for tvm, numpy etc +# ---------------------------------------------- +import os +import numpy as np +import tvm +import tvm.micro as micro +import dload + +from tvm.contrib import graph_runtime, util +from tvm import relay + + +###################################################################### +# Load the pretrained TFLite model from a file in your current +# directory into a buffer +print (os.getcwd()) +model_url = 'https://people.linaro.org/~tom.gall/sine_model.tflite' + +model_file = dload.save(model_url) +print (model_file) +###################################################################### +# Uncomment the following code to load the model from a local +# directory +# Load the pretrained TFLite model from a file in your current +# directory into a buffer +# model_dir ="./" +#tflite_model_file = os.path.join(model_dir, "sine_model.tflite") +tflite_model_buf = open(model_file, "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)) + + +###################################################################### +# 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) + + +###################################################################### +# 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}) + +###################################################################### +# Next with the dev_config, we establish a micro session and create +# a context +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 + disable_vectorize = tvm.target.build_config(disable_vectorize=True) + disable_fusion = relay.build_config(disabled_pass={'FuseOps'}) + with disable_vectorize, disable_fusion: + graph, c_mod, params = relay.build(mod, target=TARGET, params=params) + +###################################################################### +# With the c_mod that is the handle to our c sourcecode, 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 + 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 do some inference + mod.set_input(**params) + +###################################################################### +# The model consumes a single float32. Construct a tvm.nd.array object +# with a single contrived number as input. For this model values of +# 0 to 2Pi are acceptible. + mod.set_input(input_tensor, tvm.nd.array(np.array([0.5], dtype="float32"))) + + +###################################################################### +# Run the model ON DEVICE +# You'll need to uncomment this line for the example to work +# mod.run() + +###################################################################### +# Get output from the run and print +# Uncomment the following two lines for the example to work, +# tvm_output = mod.get_output(0).asnumpy() + +# print("result is: "+str(tvm_output)) + + From 53a1302a047810f5c0c0762eab388b71d49630e7 Mon Sep 17 00:00:00 2001 From: Tom Gall Date: Thu, 4 Jun 2020 16:06:01 -0500 Subject: [PATCH 02/15] Fix: add a reference to the new turtorials/micro directory Signed-off-by: Tom Gall --- docs/conf.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index 7ece63bd7aa8..33228beb1754 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -203,7 +203,8 @@ '../tutorials/deployment', '../vta/tutorials/frontend', '../vta/tutorials/optimize', - '../vta/tutorials/autotvm']) + '../vta/tutorials/autotvm', + '../tutorials/micro']) sphinx_gallery_conf = { 'backreferences_dir': 'gen_modules/backreferences', From cab1b7150eb51921da0d435b56ad8e06c763ca0e Mon Sep 17 00:00:00 2001 From: Tom Gall Date: Thu, 4 Jun 2020 16:10:52 -0500 Subject: [PATCH 03/15] fix: Cosmetic, align Micro TVM text with divider Signed-off-by: Tom Gall --- tutorials/micro/README.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tutorials/micro/README.txt b/tutorials/micro/README.txt index 1cc4cd91bf83..0654353e3426 100644 --- a/tutorials/micro/README.txt +++ b/tutorials/micro/README.txt @@ -1,4 +1,4 @@ .. _tutorial-micro: Micro TVM ----------------------------- +--------- From 5b11e0648347e91bc0ab786e2ba5f1205c7df15e Mon Sep 17 00:00:00 2001 From: Tom Gall Date: Mon, 8 Jun 2020 17:15:58 -0500 Subject: [PATCH 04/15] Fixes to remove warnings, spaces for readability, code blocks Signed-off-by: Tom Gall --- tutorials/micro/micro_tflite.py | 121 ++++++++++++++++++-------------- 1 file changed, 69 insertions(+), 52 deletions(-) diff --git a/tutorials/micro/micro_tflite.py b/tutorials/micro/micro_tflite.py index d9aa66aadd7e..ad0ad1a38f36 100644 --- a/tutorials/micro/micro_tflite.py +++ b/tutorials/micro/micro_tflite.py @@ -15,59 +15,73 @@ # specific language governing permissions and limitations # under the License. """ +.. _tutorial-micro-tflite: + Micro TVM with TFLite Models ============================ **Author**: `Tom Gall `_ -This article is an introduction to working with MicroTVM and TFLite models with Relay. - -To get started, TFLite package needs to be installed as prerequisite. - -.. code-block:: bash - - # install tflite - pip install tflite=2.1.0 --user - - -or you could generate TFLite package yourself. The steps are the following: - -.. code-block:: bash - - # Get the flatc compiler. - # Please refer to https://github.com/google/flatbuffers for details - # and make sure it is properly installed. - flatc --version - - # Get the TFLite schema. - wget https://raw.githubusercontent.com/tensorflow/tensorflow/r1.13/tensorflow/lite/schema/schema.fbs - - # Generate TFLite package. - flatc --python schema.fbs - - # Add current folder (which contains generated tflite module) to PYTHONPATH. - export PYTHONPATH=${PYTHONPATH:+$PYTHONPATH:}$(pwd) - - -To validate that the TFLite package was installed successfully, ``python -c "import tflite"`` - -First we need to download 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 - -.. code-block:: bash - - # if you download the example pretrained model from - wget https://storage.googleapis.com/download.tensorflow.org/models/tflite/micro/hello_world_2020_04_13.zip - unzip hello_world_2020_04_13.zip - this will fail due to an unimplemented opcode (114) - I've saved an older version of the pre-trailed model and made it available on linaro.org - +This tutorial is an introduction to working with MicroTVM and TFLite models 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 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"`` +# +# First we need to download 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 +# +# .. code-block:: bash +# +# if you download the example pretrained model from +# wget https://storage.googleapis.com/download.tensorflow.org/models/tflite/micro/hello_world_2020_04_13.zip +# unzip hello_world_2020_04_13.zip +# this will fail due to an unimplemented opcode (114) +# I've saved an older version of the pre-trailed model and made it available on linaro.org + ###################################################################### # Python imports for tvm, numpy etc # ---------------------------------------------- @@ -95,7 +109,7 @@ # Load the pretrained TFLite model from a file in your current # directory into a buffer # model_dir ="./" -#tflite_model_file = os.path.join(model_dir, "sine_model.tflite") +# tflite_model_file = os.path.join(model_dir, "sine_model.tflite") tflite_model_buf = open(model_file, "rb").read() ###################################################################### @@ -171,13 +185,16 @@ ###################################################################### # Run the model ON DEVICE # You'll need to uncomment this line for the example to work +# +# .. code-block:: python +# # mod.run() ###################################################################### # Get output from the run and print # Uncomment the following two lines for the example to work, +# +# .. code-block:: python +# # tvm_output = mod.get_output(0).asnumpy() - # print("result is: "+str(tvm_output)) - - From 273a97a00adff3de8e0edfe15ecbc293cd43cce9 Mon Sep 17 00:00:00 2001 From: Tom Gall Date: Mon, 8 Jun 2020 21:35:53 -0500 Subject: [PATCH 05/15] remove use of dload in favor of requests for obtaining the TFLite model Signed-off-by: Tom Gall --- tutorials/micro/micro_tflite.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tutorials/micro/micro_tflite.py b/tutorials/micro/micro_tflite.py index ad0ad1a38f36..cff87f7deda6 100644 --- a/tutorials/micro/micro_tflite.py +++ b/tutorials/micro/micro_tflite.py @@ -89,7 +89,7 @@ import numpy as np import tvm import tvm.micro as micro -import dload +import requests from tvm.contrib import graph_runtime, util from tvm import relay @@ -98,11 +98,11 @@ ###################################################################### # Load the pretrained TFLite model from a file in your current # directory into a buffer -print (os.getcwd()) model_url = 'https://people.linaro.org/~tom.gall/sine_model.tflite' +model_file = 'sine_model.tflite' +r = requests.get(model_url, allow_redirects=True) -model_file = dload.save(model_url) -print (model_file) +open(model_file,'wb').write(r.content) ###################################################################### # Uncomment the following code to load the model from a local # directory From de42e5200999e5ecc16a3c110dfdba7a9d142d5c Mon Sep 17 00:00:00 2001 From: Tom Gall Date: Tue, 9 Jun 2020 11:59:23 -0500 Subject: [PATCH 06/15] 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 --- tutorials/micro/micro_tflite.py | 46 +++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/tutorials/micro/micro_tflite.py b/tutorials/micro/micro_tflite.py index cff87f7deda6..e19b560a42cc 100644 --- a/tutorials/micro/micro_tflite.py +++ b/tutorials/micro/micro_tflite.py @@ -65,7 +65,15 @@ # # To validate that the TFLite package was installed successfully, ``python -c "import tflite"`` # -# First we need to download a pretrained TFLite model. When working with microcontrollers +# 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 +# +# Next we need to download 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. # @@ -153,33 +161,43 @@ ###################################################################### # Next with the dev_config, we establish a micro session and create # a context -with micro.Session(dev_config) as sess: - ctx = tvm.micro_dev(0) +# .. 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 - disable_vectorize = tvm.target.build_config(disable_vectorize=True) - disable_fusion = relay.build_config(disabled_pass={'FuseOps'}) - with disable_vectorize, disable_fusion: - graph, c_mod, params = relay.build(mod, target=TARGET, params=params) +# .. code-block:: python +# +# disable_vectorize = tvm.target.build_config(disable_vectorize=True) +# disable_fusion = relay.build_config(disabled_pass={'FuseOps'}) +# with disable_vectorize, disable_fusion: +# graph, c_mod, params = relay.build(mod, target=TARGET, params=params) ###################################################################### # With the c_mod that is the handle to our c sourcecode, 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 - micro_mod = micro.create_micro_mod(c_mod, dev_config) - mod = graph_runtime.create(graph, micro_mod, ctx) +# .. 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 do some inference - mod.set_input(**params) +# .. code-block:: python +# +# mod.set_input(**params) ###################################################################### # The model consumes a single float32. Construct a tvm.nd.array object # with a single contrived number as input. For this model values of # 0 to 2Pi are acceptible. - mod.set_input(input_tensor, tvm.nd.array(np.array([0.5], dtype="float32"))) +# .. code-block:: python +# +# mod.set_input(input_tensor, tvm.nd.array(np.array([0.5], dtype="float32"))) ###################################################################### @@ -188,7 +206,7 @@ # # .. code-block:: python # -# mod.run() +# mod.run() ###################################################################### # Get output from the run and print @@ -196,5 +214,5 @@ # # .. code-block:: python # -# tvm_output = mod.get_output(0).asnumpy() -# print("result is: "+str(tvm_output)) +# tvm_output = mod.get_output(0).asnumpy() +# print("result is: "+str(tvm_output)) From 7130b22176943d20319165c795323e6bc0732f94 Mon Sep 17 00:00:00 2001 From: Tom Gall Date: Tue, 9 Jun 2020 13:45:05 -0500 Subject: [PATCH 07/15] 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 --- tutorials/micro/micro_tflite.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/tutorials/micro/micro_tflite.py b/tutorials/micro/micro_tflite.py index e19b560a42cc..8b2e6a8f7139 100644 --- a/tutorials/micro/micro_tflite.py +++ b/tutorials/micro/micro_tflite.py @@ -62,7 +62,6 @@ # # 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 @@ -71,6 +70,7 @@ # After you've expanded the zip file # # .. code-block:: bash +# # export CMSIS_ST_PATH=/path/to/STM32Cube_FW_F7_V1.16.0/Drivers/CMSIS # # Next we need to download a pretrained TFLite model. When working with microcontrollers @@ -159,8 +159,11 @@ dtype_dict={input_tensor: input_dtype}) ###################################################################### +# You'll need to uncomment the following blocks of code for the +# example to run on device. # Next with the dev_config, we establish a micro session and create # a context +# # .. code-block:: python # # with micro.Session(dev_config) as sess: @@ -169,6 +172,7 @@ ###################################################################### # Now we create a build config for relay. turning off two options # and then calling relay.build which will result in a C source +# # .. code-block:: python # # disable_vectorize = tvm.target.build_config(disable_vectorize=True) @@ -189,7 +193,7 @@ # Pass the weights to get ready to do some inference # .. code-block:: python # -# mod.set_input(**params) +# ``mod.set_input(**params)`` ###################################################################### # The model consumes a single float32. Construct a tvm.nd.array object @@ -199,10 +203,8 @@ # # mod.set_input(input_tensor, tvm.nd.array(np.array([0.5], dtype="float32"))) - ###################################################################### -# Run the model ON DEVICE -# You'll need to uncomment this line for the example to work +# Run the model on device # # .. code-block:: python # @@ -210,7 +212,6 @@ ###################################################################### # Get output from the run and print -# Uncomment the following two lines for the example to work, # # .. code-block:: python # From fc8caab0ae821ccee7b35c0d90f566dc1a7429a8 Mon Sep 17 00:00:00 2001 From: Tom Gall Date: Wed, 10 Jun 2020 17:02:01 -0500 Subject: [PATCH 08/15] 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 --- docs/conf.py | 4 +- tutorials/micro/micro_tflite.py | 100 ++++++++++++++++---------------- 2 files changed, 51 insertions(+), 53 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 33228beb1754..3cc8d0a04499 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -201,10 +201,10 @@ '../tutorials/dev', '../tutorials/topi', '../tutorials/deployment', + '../tutorials/micro', '../vta/tutorials/frontend', '../vta/tutorials/optimize', - '../vta/tutorials/autotvm', - '../tutorials/micro']) + '../vta/tutorials/autotvm']) sphinx_gallery_conf = { 'backreferences_dir': 'gen_modules/backreferences', diff --git a/tutorials/micro/micro_tflite.py b/tutorials/micro/micro_tflite.py index 8b2e6a8f7139..48b4f0fbd443 100644 --- a/tutorials/micro/micro_tflite.py +++ b/tutorials/micro/micro_tflite.py @@ -15,13 +15,12 @@ # specific language governing permissions and limitations # under the License. """ -.. _tutorial-micro-tflite: - Micro TVM with TFLite Models ============================ **Author**: `Tom Gall `_ -This tutorial is an introduction to working with MicroTVM and TFLite models with Relay. +This tutorial is an introduction to working with MicroTVM and a TFLite +model with Relay. """ ###################################################################### # Setup @@ -30,6 +29,7 @@ # To get started, TFLite package needs to be installed as prerequisite. # # install tflite +# # .. code-block:: bash # # pip install tflite=2.1.0 --user @@ -56,7 +56,7 @@ # # flatc --python schema.fbs # -# Add current folder (which contains generated tflite module) to PYTHONPATH. +# Add the current folder (which contains generated tflite module) to PYTHONPATH. # # .. code-block:: bash # @@ -71,28 +71,27 @@ # # .. code-block:: bash # -# export CMSIS_ST_PATH=/path/to/STM32Cube_FW_F7_V1.16.0/Drivers/CMSIS +# export CMSIS_ST_PATH=/path/to/STM32Cube_FW_F7_V1.16.0/Drivers/CMSIS + +###################################################################### +# Recreating your own Pre-Trained TFLite model +# -------------------------------------------- # -# Next we need to download a pretrained TFLite model. When working with microcontrollers +# 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. +# 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 # -# .. code-block:: bash +# .. note:: # -# if you download the example pretrained model from -# wget https://storage.googleapis.com/download.tensorflow.org/models/tflite/micro/hello_world_2020_04_13.zip -# unzip hello_world_2020_04_13.zip -# this will fail due to an unimplemented opcode (114) -# I've saved an older version of the pre-trailed model and made it available on linaro.org +# 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) -###################################################################### -# Python imports for tvm, numpy etc -# ---------------------------------------------- import os import numpy as np import tvm @@ -102,22 +101,17 @@ 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' r = requests.get(model_url, allow_redirects=True) open(model_file,'wb').write(r.content) -###################################################################### -# Uncomment the following code to load the model from a local -# directory -# Load the pretrained TFLite model from a file in your current -# directory into a buffer -# model_dir ="./" -# tflite_model_file = os.path.join(model_dir, "sine_model.tflite") tflite_model_buf = open(model_file, "rb").read() ###################################################################### @@ -134,14 +128,6 @@ version = tflite_model.Version() print ("Model Version: " + str(version)) - -###################################################################### -# 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) - - ###################################################################### # Parse the python model object to convert it into a relay module # and weights @@ -159,61 +145,73 @@ dtype_dict={input_tensor: input_dtype}) ###################################################################### -# You'll need to uncomment the following blocks of code for the -# example to run on device. +# 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) +# 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 # -# disable_vectorize = tvm.target.build_config(disable_vectorize=True) -# disable_fusion = relay.build_config(disabled_pass={'FuseOps'}) -# with disable_vectorize, disable_fusion: -# graph, c_mod, params = relay.build(mod, target=TARGET, params=params) +# disable_vectorize = tvm.target.build_config(disable_vectorize=True) +# disable_fusion = relay.build_config(disabled_pass={'FuseOps'}) +# with disable_vectorize, disable_fusion: +# graph, c_mod, params = relay.build(mod, target=TARGET, params=params) ###################################################################### -# With the c_mod that is the handle to our c sourcecode, we create a +# 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) +# 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 do some inference +# Pass the weights to get ready to perform inference +# # .. code-block:: python # -# ``mod.set_input(**params)`` +# mod.set_input(**params) ###################################################################### -# The model consumes a single float32. Construct a tvm.nd.array object +# 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 acceptible. +# 0 to 2Pi are acceptable. +# # .. code-block:: python # -# mod.set_input(input_tensor, tvm.nd.array(np.array([0.5], dtype="float32"))) +# mod.set_input(input_tensor, tvm.nd.array(np.array([0.5], dtype="float32"))) ###################################################################### # Run the model on device # # .. code-block:: python # -# mod.run() +# 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)) +# tvm_output = mod.get_output(0).asnumpy() +# print("result is: "+str(tvm_output)) From 5c9ea502db3d29f6bf417a6a3cb28db1ebaff1ce Mon Sep 17 00:00:00 2001 From: Tom Gall Date: Thu, 11 Jun 2020 16:04:24 -0500 Subject: [PATCH 09/15] 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 --- tutorials/micro/micro_tflite.py | 40 +++++++++++++++--------------- tutorials/micro/sine_model.tflite | Bin 0 -> 2656 bytes 2 files changed, 20 insertions(+), 20 deletions(-) create mode 100644 tutorials/micro/sine_model.tflite diff --git a/tutorials/micro/micro_tflite.py b/tutorials/micro/micro_tflite.py index 48b4f0fbd443..015ee0f74491 100644 --- a/tutorials/micro/micro_tflite.py +++ b/tutorials/micro/micro_tflite.py @@ -22,12 +22,13 @@ 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 @@ -73,16 +74,16 @@ # # 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. +# 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 # @@ -96,23 +97,22 @@ import numpy as np import tvm import tvm.micro as micro -import requests - +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 +# +# 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_url = 'https://github.com/apache/incubator-tvm/tutorials/micro/' model_file = 'sine_model.tflite' -r = requests.get(model_url, allow_redirects=True) +model_path = download_testdata(module_url, model_file, module='data') -open(model_file,'wb').write(r.content) -tflite_model_buf = open(model_file, "rb").read() +tflite_model_buf = open(model_path, "rb").read() ###################################################################### # Using the buffer, transform into a tflite model python object @@ -135,7 +135,7 @@ # 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 +# 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" @@ -144,9 +144,10 @@ 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' @@ -168,9 +169,8 @@ # # .. code-block:: python # -# disable_vectorize = tvm.target.build_config(disable_vectorize=True) # disable_fusion = relay.build_config(disabled_pass={'FuseOps'}) -# with disable_vectorize, disable_fusion: +# with tvm.transform.PassContext(opt_level=3, config={'tir.disable_vectorize': True}), disable_fusion # graph, c_mod, params = relay.build(mod, target=TARGET, params=params) ###################################################################### @@ -191,10 +191,10 @@ # mod.set_input(**params) ###################################################################### -# The model consumes a single float32 value and returns a predicted +# 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 +# with a single contrived number as input. For this model values of # 0 to 2Pi are acceptable. # # .. code-block:: python diff --git a/tutorials/micro/sine_model.tflite b/tutorials/micro/sine_model.tflite new file mode 100644 index 0000000000000000000000000000000000000000..e03d484111505fa720f5cc7ae907efc9f92ff848 GIT binary patch literal 2656 zcmb7G3s98T75*U$f)HdT$Y4c4#P~wN7YVxm*>xa3f~XJ>LO@(#K~jPU3kIPSt0E7f zfJ6C{%1Er5Gkk)icCNxky?h5#L@;)G23%t*Ek)=Y46Op=iGDu^WAgK zfA87fisLw+&D+;9*6( zZGUuvJXRqOTg91>Etl4k2@V8nf+;zO2z9hpMF=D?J`tgBLZfMTqR}v2O2~hwxw+T; z8szSe7kX58;Ypx3p2==Q{4NJP%G1zttQz#fE+`8U^i<`(Es*;+h0r{B3x+qk;?Q6j z=s*3HYwyaYmeR$+Dx&2o7y3<0rhoFd4w#&q`V|_5Et4?aHuEk&ZR0N?llvwf@rp+p zjrR+DM{`r)z_G^wo+C=bj!qmkML6DIq;j`841td0!r9NCg4KI!@Vd|rH@yBTd|lp% zn?^+r7+v~Eyxa}e&Cj?;jV*^P^x|z7xPX(oB zhWKD=3xqi4g2Ra{^r%#$$vXvLsCR|GxnVQT4v0Vx(@a=~dgwBmiK{(7!t({gXj#1g zLPw2MPH!ne>fF~-(DOatp+sQ=cNfHE2GzR?R} zFAKD`{fUoPe~I5@%*Q}KHH>X2#wAb$+41Ru^$*VkU(X$Uew{ts4*HR|_4LK1zP8Fc zX}2)l>XLBov@5zfbwPGn7Dy}oupns+L)I8ddi&-wKiJmlqp0C7U*emKXFXbRb*cv*IR7vH;iL&j z6D@@Z_m4p_WrZj6=AgsHaX$UgXJ{wQ!2SB$g`WOaII-10_0yj!Av5kh5G`M#x;p;~ zbm4MkoaJIke%fMiNnOnkuXw;$??~I&92^AbzfyJBHv^LMELB{N8$WRGQ|!9Y!~5s_ z5v!c)q2}Br4DKAp9vd@B`IFO-@7o1Kse|IIi>cUbD1i?BMq#tJKDuyks>Tggfpg(G z;X{oLw4d4r$HQGQ(k2!M?`NS^1u)% zVVLGp!X)WYv_3#^d8W~@{|4s6IGqV(p5|fpd4xFmfp~eeB2pF=yv8X^9vvqSUgzX3 zkBX{*Wc zz1xhWQ$%Ny#l_ZGjxW9oUA!-;moCOvzKafuIb6%nzAYHP9pS~eS!~-Va7CmdkyLJq zd^bJMi=gv)MNBT*y1g@2Wz z#e5kT8#yyRdKS|+n4N%G)A_JUvRcx39?Oe-jDyvfaWkFqvoWaU)7j|rO~V-*(!K`M Odo$gL_F!?)F#Zqk`+8#l literal 0 HcmV?d00001 From 6db4e6cde1cf68f996cc079449f02cfb96073af4 Mon Sep 17 00:00:00 2001 From: Tom Gall Date: Fri, 12 Jun 2020 11:26:05 -0500 Subject: [PATCH 10/15] remove use of relay.build_config in favor of PassContext Signed-off-by: Tom Gall --- tutorials/micro/micro_tflite.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tutorials/micro/micro_tflite.py b/tutorials/micro/micro_tflite.py index 015ee0f74491..90b0ff7b8007 100644 --- a/tutorials/micro/micro_tflite.py +++ b/tutorials/micro/micro_tflite.py @@ -160,7 +160,7 @@ # .. code-block:: python # # with micro.Session(dev_config) as sess: -# ctx = tvm.micro_dev(0) +# ctx = tvm.micro_dev(0) ###################################################################### # Now we create a build config for relay. turning off two options @@ -169,9 +169,8 @@ # # .. code-block:: python # -# disable_fusion = relay.build_config(disabled_pass={'FuseOps'}) -# with tvm.transform.PassContext(opt_level=3, config={'tir.disable_vectorize': True}), disable_fusion -# graph, c_mod, params = relay.build(mod, target=TARGET, params=params) +# 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 From 8e3ca48b3739a1d43bfd49a50812846fcd028928 Mon Sep 17 00:00:00 2001 From: Tom Gall Date: Mon, 15 Jun 2020 15:38:13 -0500 Subject: [PATCH 11/15] Couple of minor 4 space fix ups Signed-off-by: Tom Gall --- tutorials/micro/micro_tflite.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tutorials/micro/micro_tflite.py b/tutorials/micro/micro_tflite.py index 90b0ff7b8007..117940a8440a 100644 --- a/tutorials/micro/micro_tflite.py +++ b/tutorials/micro/micro_tflite.py @@ -169,7 +169,9 @@ # # .. code-block:: python # -# with tvm.transform.PassContext(opt_level=3, config={'tir.disable_vectorize': True},disabled_pass=['FuseOps']): +# disable_vectorize = tvm.target.build_config(disable_vectorize=True) +# disable_fusion = relay.build_config(disabled_pass={'FuseOps'}) +# with disable_vectorize, disable_fusion: # graph, c_mod, params = relay.build(mod, target=TARGET, params=params) ###################################################################### From 742279e7376f7942d0bf08b71fd6f62982430256 Mon Sep 17 00:00:00 2001 From: Tom Gall Date: Mon, 15 Jun 2020 15:42:53 -0500 Subject: [PATCH 12/15] Change to use tvm.transform.PassContext for disable_victorize and disabling FuseOps Signed-off-by: Tom Gall --- tutorials/micro/micro_tflite.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tutorials/micro/micro_tflite.py b/tutorials/micro/micro_tflite.py index 117940a8440a..90b0ff7b8007 100644 --- a/tutorials/micro/micro_tflite.py +++ b/tutorials/micro/micro_tflite.py @@ -169,9 +169,7 @@ # # .. code-block:: python # -# disable_vectorize = tvm.target.build_config(disable_vectorize=True) -# disable_fusion = relay.build_config(disabled_pass={'FuseOps'}) -# with disable_vectorize, disable_fusion: +# 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) ###################################################################### From c0d0173d08b580b12c3c2107e45e7bb2a2c25282 Mon Sep 17 00:00:00 2001 From: Tom Gall Date: Wed, 17 Jun 2020 14:39:58 -0500 Subject: [PATCH 13/15] Remove binary module from repo Change download_testdata back to pull model from linaro server Signed-off-by: Tom Gall --- tutorials/micro/micro_tflite.py | 4 ++-- tutorials/micro/sine_model.tflite | Bin 2656 -> 0 bytes 2 files changed, 2 insertions(+), 2 deletions(-) delete mode 100644 tutorials/micro/sine_model.tflite diff --git a/tutorials/micro/micro_tflite.py b/tutorials/micro/micro_tflite.py index 90b0ff7b8007..d84a71cf2d3d 100644 --- a/tutorials/micro/micro_tflite.py +++ b/tutorials/micro/micro_tflite.py @@ -108,9 +108,9 @@ # Load the pretrained TFLite model from a file in your current # directory into a buffer -model_url = 'https://github.com/apache/incubator-tvm/tutorials/micro/' +model_url = 'https://people.linaro.org/~tom.gall/sine_model.tflite' model_file = 'sine_model.tflite' -model_path = download_testdata(module_url, model_file, module='data') +model_path = download_testdata(model_url, model_file, module='data') tflite_model_buf = open(model_path, "rb").read() diff --git a/tutorials/micro/sine_model.tflite b/tutorials/micro/sine_model.tflite deleted file mode 100644 index e03d484111505fa720f5cc7ae907efc9f92ff848..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2656 zcmb7G3s98T75*U$f)HdT$Y4c4#P~wN7YVxm*>xa3f~XJ>LO@(#K~jPU3kIPSt0E7f zfJ6C{%1Er5Gkk)icCNxky?h5#L@;)G23%t*Ek)=Y46Op=iGDu^WAgK zfA87fisLw+&D+;9*6( zZGUuvJXRqOTg91>Etl4k2@V8nf+;zO2z9hpMF=D?J`tgBLZfMTqR}v2O2~hwxw+T; z8szSe7kX58;Ypx3p2==Q{4NJP%G1zttQz#fE+`8U^i<`(Es*;+h0r{B3x+qk;?Q6j z=s*3HYwyaYmeR$+Dx&2o7y3<0rhoFd4w#&q`V|_5Et4?aHuEk&ZR0N?llvwf@rp+p zjrR+DM{`r)z_G^wo+C=bj!qmkML6DIq;j`841td0!r9NCg4KI!@Vd|rH@yBTd|lp% zn?^+r7+v~Eyxa}e&Cj?;jV*^P^x|z7xPX(oB zhWKD=3xqi4g2Ra{^r%#$$vXvLsCR|GxnVQT4v0Vx(@a=~dgwBmiK{(7!t({gXj#1g zLPw2MPH!ne>fF~-(DOatp+sQ=cNfHE2GzR?R} zFAKD`{fUoPe~I5@%*Q}KHH>X2#wAb$+41Ru^$*VkU(X$Uew{ts4*HR|_4LK1zP8Fc zX}2)l>XLBov@5zfbwPGn7Dy}oupns+L)I8ddi&-wKiJmlqp0C7U*emKXFXbRb*cv*IR7vH;iL&j z6D@@Z_m4p_WrZj6=AgsHaX$UgXJ{wQ!2SB$g`WOaII-10_0yj!Av5kh5G`M#x;p;~ zbm4MkoaJIke%fMiNnOnkuXw;$??~I&92^AbzfyJBHv^LMELB{N8$WRGQ|!9Y!~5s_ z5v!c)q2}Br4DKAp9vd@B`IFO-@7o1Kse|IIi>cUbD1i?BMq#tJKDuyks>Tggfpg(G z;X{oLw4d4r$HQGQ(k2!M?`NS^1u)% zVVLGp!X)WYv_3#^d8W~@{|4s6IGqV(p5|fpd4xFmfp~eeB2pF=yv8X^9vvqSUgzX3 zkBX{*Wc zz1xhWQ$%Ny#l_ZGjxW9oUA!-;moCOvzKafuIb6%nzAYHP9pS~eS!~-Va7CmdkyLJq zd^bJMi=gv)MNBT*y1g@2Wz z#e5kT8#yyRdKS|+n4N%G)A_JUvRcx39?Oe-jDyvfaWkFqvoWaU)7j|rO~V-*(!K`M Odo$gL_F!?)F#Zqk`+8#l From 7728108bf35db3dc16491149b50ff2a721eff07b Mon Sep 17 00:00:00 2001 From: Tom Gall Date: Wed, 24 Jun 2020 13:56:55 -0500 Subject: [PATCH 14/15] Couple of small cosmetic changes. (spaces and extra lines) Signed-off-by: Tom Gall --- tutorials/micro/micro_tflite.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tutorials/micro/micro_tflite.py b/tutorials/micro/micro_tflite.py index d84a71cf2d3d..bb3fc5dcea06 100644 --- a/tutorials/micro/micro_tflite.py +++ b/tutorials/micro/micro_tflite.py @@ -130,12 +130,14 @@ ###################################################################### # Parse the python model object to convert it into a relay module -# and weights +# 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" From 83c8d1439766116597714381d9ad1722bdcbcb53 Mon Sep 17 00:00:00 2001 From: Tom Gall Date: Wed, 24 Jun 2020 14:39:40 -0500 Subject: [PATCH 15/15] Convert link to tf docs to examine a tf lite model to use RST syntax Signed-off-by: Tom Gall --- tutorials/micro/micro_tflite.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tutorials/micro/micro_tflite.py b/tutorials/micro/micro_tflite.py index bb3fc5dcea06..9838df724a3a 100644 --- a/tutorials/micro/micro_tflite.py +++ b/tutorials/micro/micro_tflite.py @@ -136,7 +136,7 @@ # # 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 +# See : How do I inspect a .tflite file? ``_ input_tensor = "dense_4_input" input_shape = (1,)