• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# PyArmNN
2
3PyArmNN is a python extension for [Arm NN SDK](https://developer.arm.com/ip-products/processors/machine-learning/arm-nn).
4PyArmNN provides interface similar to Arm NN C++ Api.
5Before you proceed with the project setup, you will need to checkout and build a corresponding Arm NN version.
6
7PyArmNN is built around public headers from the armnn/include folder of Arm NN. PyArmNN does not implement any computation kernels itself, all operations are
8delegated to the Arm NN library.
9
10The [SWIG](http://www.swig.org/) project is used to generate the Arm NN python shadow classes and C wrapper.
11
12The following diagram shows the conceptual architecture of this library:
13![PyArmNN](../../docs/pyarmnn.png)
14
15# Setup development environment
16
17Before, proceeding to the next steps, make sure that:
18
191. You have Python 3.6+ installed system-side. The package is not compatible with older Python versions.
202. You have python3.6-dev installed system-side. This contains header files needed to build PyArmNN extension module.
213. In case you build Python from sources manually, make sure that the following libraries are installed and available in you system:
22``python3.6-dev build-essential checkinstall libreadline-gplv2-dev libncursesw5-dev libssl-dev libsqlite3-dev tk-dev libgdbm-dev libc6-dev libbz2-dev``
234. Install SWIG 4.x. Only 3.x version is typically available in Linux package managers, so you will have to build it and install it from sources. It can be downloaded from the [SWIG project website](http://www.swig.org/download.html) or from [SWIG GitHub](https://github.com/swig/swig). To install it follow the guide on [SWIG GitHub](https://github.com/swig/swig/wiki/Getting-Started).
24
25## Setup virtual environment
26
27Now you can proceed with setting up workspace. It is recommended to create a python virtual environment, so you do not pollute your working folder:
28```bash
29python -m venv env
30source env/bin/activate
31```
32
33You may run into missing python modules such as *wheel*. Make sure to install those using pip:
34```bash
35pip install wheel
36```
37
38## Build python distr
39
40Python supports source and binary distribution packages.
41
42Source distr contains setup.py script that is executed on the users machine during package installation.
43When preparing binary distr (wheel), setup.py is executed on the build machine and the resulting package contains only the result
44of the build (generated files and resources, test results etc).
45
46In our case, PyArmNN depends on Arm NN installation. Thus, binary distr will be linked with
47the local build machine libraries and runtime.
48
49The recommended way to build the python packages is by CMake.
50
51### CMake build
52
53The recommended approach is to build PyArmNN together with Arm NN by adding the following options to your CMake command:
54```
55-DBUILD_PYTHON_SRC=1
56```
57This will build the source package. Current project headers and build libraries will be used, so there is no need to provide them.
58
59SWIG is required to generate the wrappers. If CMake did not find the executable during the configure step or it has found an older version, you may provide it manually:
60```
61-DSWIG_EXECUTABLE=<path_to_swig_executable>
62```
63
64After the build finishes, you will find the python packages in `<build_folder>/python/pyarmnn/dist`.
65
66# PyArmNN installation
67
68PyArmNN can be distributed as a source package or a binary package (wheel).
69
70Binary package is platform dependent, the name of the package will indicate the platform it was built for, e.g.:
71
72* Linux x86 64bit machine: pyarmnn-32.0.0-cp36-cp36m-*linux_x86_64*.whl
73* Linux Aarch 64 bit machine: pyarmnn-32.0.0-cp36-cp36m-*linux_aarch64*.whl
74
75The source package is platform independent but installation involves compilation of Arm NN python extension. You will need to have g++ compatible with C++ 14 standard and a python development library installed on the build machine.
76
77Both of them, source and binary package, require the Arm NN library to be present on the target/build machine.
78
79It is strongly suggested to work within a python virtual environment. The further steps assume that the virtual environment was created and activated before running PyArmNN installation commands.
80
81PyArmNN also depends on the NumPy python library. It will be automatically downloaded and installed alongside PyArmNN. If your machine does not have access to Python pip repositories you might need to install NumPy in advance by following public instructions: https://scipy.org/install.html
82
83## Installing from source package
84
85Installing from source is the most reliable way.
86
87While installing from sources, you have the freedom of choosing Arm NN libraries location. Set environment variables *ARMNN_LIB* and *ARMNN_INCLUDE* to point to Arm NN libraries and headers.
88If you want to use system default locations, just set *ARMNN_INCLUDE* to point to Arm NN headers.
89Additionally, *LD_LIBRARY_PATH* may need to be updated to the Arm NN libraries location due to dependencies of the same shared library files being 'not found'.
90
91```bash
92$ export  ARMNN_LIB=/path/to/libs
93$ export  LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/libs
94$ export  ARMNN_INCLUDE=/full/path/to/armnn/include:/full/path/to/armnn/profiling/common/include
95```
96
97Install PyArmNN as follows:
98```bash
99$ pip install /path/to/armnn/python/pyarmnn
100```
101
102If PyArmNN installation script fails to find Arm NN libraries it will raise an error like this
103
104`RuntimeError: ArmNN library was not found in ('/usr/lib/gcc/aarch64-linux-gnu/8/', <...> ,'/lib/', '/usr/lib/'). Please install ArmNN to one of the standard locations or set correct ARMNN_INCLUDE and ARMNN_LIB env variables.`
105
106You can now verify that PyArmNN library is installed and check PyArmNN version using:
107```bash
108$ pip show pyarmnn
109```
110You can also verify it by running the following and getting output similar to below:
111```bash
112$ python -c "import pyarmnn as ann;print(ann.GetVersion())"
113'32.0.0'
114```
115
116
117## Installing PyArmNN while using ArmNN prebuilt binaries
118
119If you wish to use ArmNN prebuilt binaries from our release page, you will need to generate the PyArmNN SWIG wrappers.
120
121Again setup your environmental variables along with a virtual environment:
122
123```bash
124$ python -m venv env
125$ source env/bin/activate
126
127$ export  ARMNN_LIB=/path/to/libs
128$ export  LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/libs
129$ export  ARMNN_INCLUDE=/full/path/to/armnn/include:/full/path/to/armnn/profiling/common/include
130```
131
132Then generate the SWIG wrappers:
133```bash
134$ cd armnn/python/pyarmnn/
135$ python swig_generate.py -v
136```
137
138Then install PyArmNN:
139```bash
140# From directory armnn/python/pyarmnn/
141$ pip install .
142```
143
144As above, you can verify that PyArmNN library is installed and check PyArmNN version using:
145```bash
146$ pip show pyarmnn
147```
148You can also verify it by running the following and getting output similar to below:
149```bash
150$ python -c "import pyarmnn as ann;print(ann.GetVersion())"
151'32.0.0'
152```
153
154# PyArmNN API overview
155
156#### Getting started
157The easiest way to begin using PyArmNN is by using the Parsers. We will demonstrate how to use them below:
158
159Create a parser object and load your model file.
160```python
161import pyarmnn as ann
162import imageio
163
164# An ONNX parser also exists.
165parser = ann.ITfLiteParser()
166network = parser.CreateNetworkFromBinaryFile('./model.tflite')
167```
168
169Get the input binding information by using the name of the input layer.
170```python
171input_binding_info = parser.GetNetworkInputBindingInfo(0, 'model/input')
172
173# Create a runtime object that will perform inference.
174options = ann.CreationOptions()
175runtime = ann.IRuntime(options)
176```
177Choose preferred backends for execution and optimize the network.
178```python
179# Backend choices earlier in the list have higher preference.
180preferredBackends = [ann.BackendId('CpuAcc'), ann.BackendId('CpuRef')]
181opt_network, messages = ann.Optimize(network, preferredBackends, runtime.GetDeviceSpec(), ann.OptimizerOptions())
182
183# Load the optimized network into the runtime.
184net_id, _ = runtime.LoadNetwork(opt_network)
185```
186Make workload tensors using input and output binding information.
187```python
188# Load an image and create an inputTensor for inference.
189img = imageio.imread('./image.png')
190input_tensors = ann.make_input_tensors([input_binding_info], [img])
191
192# Get output binding information for an output layer by using the layer name.
193output_binding_info = parser.GetNetworkOutputBindingInfo(0, 'model/output')
194output_tensors = ann.make_output_tensors([output_binding_info])
195```
196
197Perform inference and get the results back into a numpy array.
198```python
199runtime.EnqueueWorkload(0, input_tensors, output_tensors)
200
201results = ann.workload_tensors_to_ndarray(output_tensors)
202print(results)
203```
204
205#### Examples
206
207To further explore PyArmNN API there are several examples provided in the `/examples` folder for you to explore.
208
209##### Image Classification
210
211This sample application performs image classification on an image and outputs the <i>Top N</i> results, listing the classes and probabilities associated with the classified image. All resources are downloaded during execution, so if you do not have access to the internet, you may need to download these manually.
212
213Sample scripts are provided for performing image classification with TFLite and ONNX models with `tflite_mobilenetv1_quantized.py` and `onnx_mobilenetv2.py`.
214
215##### Object Detection
216
217This sample application guides the user and shows how to perform object detection using PyArmNN API. By taking a model and video file or camera feed as input, and running inference on each frame, we are able to interpret the output to draw bounding boxes around detected objects and overlay the corresponding labels and confidence scores.
218
219Sample scripts are provided for performing object detection from video file and video stream with `run_video_file.py` and `run_video_stream.py`.
220
221
222## Tox for automation
223
224To make things easier *tox* is available for automating individual tasks or running multiple commands at once such as generating wrappers, running unit tests using multiple python versions or generating documentation. To run it use:
225
226```bash
227$ tox <task_name>
228```
229
230See *tox.ini* for the list of tasks. You may also modify it for your own purposes. To dive deeper into tox read through https://tox.readthedocs.io/en/latest/
231
232## Running unit-tests
233
234Download resources required to run unit tests by executing the script in the scripts folder:
235
236```
237$ python ./scripts/download_test_resources.py
238```
239
240The script will download an archive from the Linaro server and extract it. A folder `test/testdata/shared` will be created. Execute `pytest` from the project root dir:
241```bash
242$ python -m pytest test/ -v
243```
244or run tox which will do both:
245```bash
246$ tox
247```
248