<jupyter_start><jupyter_text>Micro TVM with TFLite Models**Author**: `<NAME> `_This tutorial is an introduction to working with MicroTVM and a TFLitemodel with Relay.  SetupTo get started, TFLite package needs to be installed as prerequisite.install tflite.. code-block:: bash  pip install tflite=2.1.0 --useror 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 --versionGet the TFLite schema... code-block:: bash  wget https://raw.githubusercontent.com/tensorflow/tensorflow/r1.13/tensorflow/lite/schema/schema.fbsGenerate TFLite package... code-block:: bash  flatc --python schema.fbsAdd 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 setupThis tutorial only supports the STM32F7xx series of boards.Download from : https://www.st.com/en/embedded-software/stm32cubef7.htmlAfter 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 modelThe tutorial downloads a pretrained TFLite model. When working with microcontrollersyou need to be mindful these are highly resource constrained devices as such standardmodels 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)<jupyter_code>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, utils
from tvm import relay<jupyter_output><empty_output><jupyter_text>Load and prepare the Pre-Trained ModelLoad the pretrained TFLite model from a file in your currentdirectory into a buffer<jupyter_code>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()<jupyter_output><empty_output><jupyter_text>Using the buffer, transform into a tflite model python object<jupyter_code>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)<jupyter_output><empty_output><jupyter_text>Print out the version of the model<jupyter_code>version = tflite_model.Version()
print("Model Version: " + str(version))<jupyter_output><empty_output><jupyter_text>Parse the python model object to convert it into a relay moduleand weights.It is important to note that the input tensor name must match whatis contained in the model.If you are unsure what that might be, this can be discovered by usingthe visualize.py script within the Tensorflow project.See : How do I inspect a .tflite file? ``_<jupyter_code>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}
)<jupyter_output><empty_output><jupyter_text>Now we create a build config for relay. turning off two optionsand then calling relay.build which will result in a C sourcefile... code-block:: python<jupyter_code>TARGET = tvm.target.target.micro("host")

with tvm.transform.PassContext(
    opt_level=3, config={"tir.disable_vectorize": True}, disabled_pass=["FuseOps"]
):
    graph, c_mod, c_params = relay.build(mod, target=TARGET, params=params)<jupyter_output><empty_output><jupyter_text>Running on simulated deviceFirst, compile a static microTVM runtime for the targeted device. In this case, the host simulateddevice is used.<jupyter_code>workspace = tvm.micro.Workspace()

compiler = tvm.micro.DefaultCompiler(target=TARGET)
opts = tvm.micro.default_options(os.path.join(tvm.micro.CRT_ROOT_DIR, "host"))

micro_binary = tvm.micro.build_static_runtime(
    # the x86 compiler *expects* you to give the exact same dictionary for both
    # lib_opts and bin_opts. so the library compiler is mutating lib_opts and
    # the binary compiler is expecting those mutations to be in bin_opts.
    # TODO(weberlo) fix this very bizarre behavior
    workspace,
    compiler,
    c_mod,
    lib_opts=opts["bin_opts"],
    bin_opts=opts["bin_opts"],
    # Use the microTVM memory manager. If, in your main.cc, you change TVMPlatformMemoryAllocate and
    # TVMPlatformMemoryFree to use e.g. malloc() and free(), you can omit this extra library.
    extra_libs=[os.path.join(tvm.micro.build.CRT_ROOT_DIR, "memory")],
)<jupyter_output><empty_output><jupyter_text>Next, establish a session with the simulated device and run thecomputation. The `with session` line would typically flash an attachedmicrocontroller, but in this tutorial, it simply launches a subprocessto stand in for an attached microcontroller... code-block:: python<jupyter_code>flasher = compiler.flasher()
with tvm.micro.Session(binary=micro_binary, flasher=flasher) as session:
    graph_mod = tvm.micro.create_local_graph_runtime(
        graph, session.get_system_lib(), session.context
    )

    # Set the model parameters using the lowered parameters produced by `relay.build`.
    graph_mod.set_input(**c_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.
    graph_mod.set_input(input_tensor, tvm.nd.array(np.array([0.5], dtype="float32")))
    graph_mod.run()

    tvm_output = graph_mod.get_output(0).asnumpy()
    print("result is: " + str(tvm_output))<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.086273900202083, 'fraction_numerical': 0.007461526503963936, 'mean_word_length': 5.338916256157636, 'pattern_counts': {'":': 1, '<': 34, '<?xml version=': 0, '>': 34, 'https://': 6, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '8', 'dir': 'jupyter-structured-clean-dedup', 'id': '426294', 'license': 'Apache-2.0', 'n_tokens_mistral': 2039, 'n_tokens_neox': 1943, 'n_words': 618, 'path': '_downloads/fd5c19bd1cb72ca9528fd99a69656225/micro_tflite.ipynb', 'repo_name': 'areusch/tvm-docs-refactor', 'size': '6435'}