Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
T
tic
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wenyuanbo
tic
Commits
3e5a172d
Commit
3e5a172d
authored
Mar 02, 2019
by
Hiroyuki Makino
Committed by
Tianqi Chen
Mar 01, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[Doc] Relay tutorial - Deploy the Pretrained Model on Raspberry Pi (#2693)
parent
1342151e
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
207 additions
and
0 deletions
+207
-0
tutorials/relay/deploy_model_on_rasp.py
+207
-0
No files found.
tutorials/relay/deploy_model_on_rasp.py
0 → 100644
View file @
3e5a172d
"""
.. _tutorial-deploy-model-on-rasp:
Deploy the Pretrained Model on Raspberry Pi
===========================================
**Author**: `Ziheng Jiang <https://ziheng.org/>`_,
\
`Hiroyuki Makino <https://makihiro.github.io/>`_
This is an example of using Relay to compile a ResNet model and deploy
it on Raspberry Pi.
"""
import
tvm
import
tvm.relay
as
relay
from
tvm
import
rpc
from
tvm.contrib
import
util
,
graph_runtime
as
runtime
######################################################################
# .. _build-tvm-runtime-on-device:
#
# Build TVM Runtime on Device
# ---------------------------
#
# The first step is to build tvm runtime on the remote device.
#
# .. note::
#
# All instructions in both this section and next section should be
# executed on the target device, e.g. Raspberry Pi. And we assume it
# has Linux running.
#
# Since we do compilation on local machine, the remote device is only used
# for running the generated code. We only need to build tvm runtime on
# the remote device.
#
# .. code-block:: bash
#
# git clone --recursive https://github.com/dmlc/tvm
# cd tvm
# mkdir build
# cp cmake/config.cmake build
# cd build
# cmake ..
# make runtime -j4
#
# After building runtime successfully, we need to set environment varibles
# in :code:`~/.bashrc` file. We can edit :code:`~/.bashrc`
# using :code:`vi ~/.bashrc` and add the line below (Assuming your TVM
# directory is in :code:`~/tvm`):
#
# .. code-block:: bash
#
# export PYTHONPATH=$PYTHONPATH:~/tvm/python
#
# To update the environment variables, execute :code:`source ~/.bashrc`.
######################################################################
# Set Up RPC Server on Device
# ---------------------------
# To start an RPC server, run the following command on your remote device
# (Which is Raspberry Pi in our example).
#
# .. code-block:: bash
#
# python -m tvm.exec.rpc_server --host 0.0.0.0 --port=9090
#
# If you see the line below, it means the RPC server started
# successfully on your device.
#
# .. code-block:: bash
#
# INFO:root:RPCServer: bind to 0.0.0.0:9090
#
######################################################################
# Prepare the Pre-trained Model
# -----------------------------
# Back to the host machine, which should have a full TVM installed (with LLVM).
#
# We will use pre-trained model from
# `MXNet Gluon model zoo <https://mxnet.incubator.apache.org/api/python/gluon/model_zoo.html>`_.
# You can found more details about this part at tutorial :ref:`tutorial-from-mxnet`.
from
mxnet.gluon.model_zoo.vision
import
get_model
from
mxnet.gluon.utils
import
download
from
PIL
import
Image
import
numpy
as
np
# one line to get the model
block
=
get_model
(
'resnet18_v1'
,
pretrained
=
True
)
######################################################################
# In order to test our model, here we download an image of cat and
# transform its format.
img_name
=
'cat.png'
download
(
'https://github.com/dmlc/mxnet.js/blob/master/data/cat.png?raw=true'
,
img_name
)
image
=
Image
.
open
(
img_name
)
.
resize
((
224
,
224
))
def
transform_image
(
image
):
image
=
np
.
array
(
image
)
-
np
.
array
([
123.
,
117.
,
104.
])
image
/=
np
.
array
([
58.395
,
57.12
,
57.375
])
image
=
image
.
transpose
((
2
,
0
,
1
))
image
=
image
[
np
.
newaxis
,
:]
return
image
x
=
transform_image
(
image
)
######################################################################
# synset is used to transform the label from number of ImageNet class to
# the word human can understand.
synset_url
=
''
.
join
([
'https://gist.githubusercontent.com/zhreshold/'
,
'4d0b62f3d01426887599d4f7ede23ee5/raw/'
,
'596b27d23537e5a1b5751d2b0481ef172f58b539/'
,
'imagenet1000_clsid_to_human.txt'
])
synset_name
=
'synset.txt'
download
(
synset_url
,
synset_name
)
with
open
(
synset_name
)
as
f
:
synset
=
eval
(
f
.
read
())
######################################################################
# Now we would like to port the Gluon model to a portable computational graph.
# It's as easy as several lines.
# We support MXNet static graph(symbol) and HybridBlock in mxnet.gluon
shape_dict
=
{
'data'
:
x
.
shape
}
func
,
params
=
relay
.
frontend
.
from_mxnet
(
block
,
shape_dict
)
# we want a probability so add a softmax operator
func
=
relay
.
Function
(
func
.
params
,
relay
.
nn
.
softmax
(
func
.
body
),
None
,
func
.
type_params
,
func
.
attrs
)
######################################################################
# Here are some basic data workload configurations.
batch_size
=
1
num_classes
=
1000
image_shape
=
(
3
,
224
,
224
)
data_shape
=
(
batch_size
,)
+
image_shape
######################################################################
# Compile The Graph
# -----------------
# To compile the graph, we call the :any:`relay.build` function
# with the graph configuration and parameters. However, You cannot to
# deploy a x86 program on a device with ARM instruction set. It means
# Relay also needs to know the compilation option of target device,
# apart from arguments :code:`net` and :code:`params` to specify the
# deep learning workload. Actually, the option matters, different option
# will lead to very different performance.
######################################################################
# If we run the example on our x86 server for demonstration, we can simply
# set it as :code:`llvm`. If running it on the Raspberry Pi, we need to
# specify its instruction set. Set :code:`local_demo` to False if you want
# to run this tutorial with a real device.
local_demo
=
True
if
local_demo
:
target
=
tvm
.
target
.
create
(
'llvm'
)
else
:
target
=
tvm
.
target
.
arm_cpu
(
'rasp3b'
)
# The above line is a simple form of
# target = tvm.target.create('llvm -device=arm_cpu -model=bcm2837 -target=armv7l-linux-gnueabihf -mattr=+neon')
with
relay
.
build_config
(
opt_level
=
3
):
graph
,
lib
,
params
=
relay
.
build
(
func
,
target
,
params
=
params
)
# After `relay.build`, you will get three return values: graph,
# library and the new parameter, since we do some optimization that will
# change the parameters but keep the result of model as the same.
# Save the library at local temporary directory.
tmp
=
util
.
tempdir
()
lib_fname
=
tmp
.
relpath
(
'net.tar'
)
lib
.
export_library
(
lib_fname
)
######################################################################
# Deploy the Model Remotely by RPC
# --------------------------------
# With RPC, you can deploy the model remotely from your host machine
# to the remote device.
# obtain an RPC session from remote device.
if
local_demo
:
remote
=
rpc
.
LocalSession
()
else
:
# The following is my environment, change this to the IP address of your target device
host
=
'10.77.1.162'
port
=
9090
remote
=
rpc
.
connect
(
host
,
port
)
# upload the library to remote device and load it
remote
.
upload
(
lib_fname
)
rlib
=
remote
.
load_module
(
'net.tar'
)
# create the remote runtime module
ctx
=
remote
.
cpu
(
0
)
module
=
runtime
.
create
(
graph
,
rlib
,
ctx
)
# set parameter (upload params to the remote device. This may take a while)
module
.
set_input
(
**
params
)
# set input data
module
.
set_input
(
'data'
,
tvm
.
nd
.
array
(
x
.
astype
(
'float32'
)))
# run
module
.
run
()
# get output
out
=
module
.
get_output
(
0
)
# get top1 result
top1
=
np
.
argmax
(
out
.
asnumpy
())
print
(
'TVM prediction top-1: {}'
.
format
(
synset
[
top1
]))
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment