xref: /aosp_15_r20/external/armnn/python/pyarmnn/README.md (revision 89c4ff92f2867872bb9e2354d150bf0c8c502810)
1*89c4ff92SAndroid Build Coastguard Worker# PyArmNN
2*89c4ff92SAndroid Build Coastguard Worker
3*89c4ff92SAndroid Build Coastguard WorkerPyArmNN is a python extension for [Arm NN SDK](https://developer.arm.com/ip-products/processors/machine-learning/arm-nn).
4*89c4ff92SAndroid Build Coastguard WorkerPyArmNN provides interface similar to Arm NN C++ Api.
5*89c4ff92SAndroid Build Coastguard WorkerBefore you proceed with the project setup, you will need to checkout and build a corresponding Arm NN version.
6*89c4ff92SAndroid Build Coastguard Worker
7*89c4ff92SAndroid Build Coastguard WorkerPyArmNN is built around public headers from the armnn/include folder of Arm NN. PyArmNN does not implement any computation kernels itself, all operations are
8*89c4ff92SAndroid Build Coastguard Workerdelegated to the Arm NN library.
9*89c4ff92SAndroid Build Coastguard Worker
10*89c4ff92SAndroid Build Coastguard WorkerThe [SWIG](http://www.swig.org/) project is used to generate the Arm NN python shadow classes and C wrapper.
11*89c4ff92SAndroid Build Coastguard Worker
12*89c4ff92SAndroid Build Coastguard WorkerThe following diagram shows the conceptual architecture of this library:
13*89c4ff92SAndroid Build Coastguard Worker![PyArmNN](../../docs/pyarmnn.png)
14*89c4ff92SAndroid Build Coastguard Worker
15*89c4ff92SAndroid Build Coastguard Worker# Setup development environment
16*89c4ff92SAndroid Build Coastguard Worker
17*89c4ff92SAndroid Build Coastguard WorkerBefore, proceeding to the next steps, make sure that:
18*89c4ff92SAndroid Build Coastguard Worker
19*89c4ff92SAndroid Build Coastguard Worker1. You have Python 3.6+ installed system-side. The package is not compatible with older Python versions.
20*89c4ff92SAndroid Build Coastguard Worker2. You have python3.6-dev installed system-side. This contains header files needed to build PyArmNN extension module.
21*89c4ff92SAndroid Build Coastguard Worker3. In case you build Python from sources manually, make sure that the following libraries are installed and available in you system:
22*89c4ff92SAndroid Build Coastguard Worker``python3.6-dev build-essential checkinstall libreadline-gplv2-dev libncursesw5-dev libssl-dev libsqlite3-dev tk-dev libgdbm-dev libc6-dev libbz2-dev``
23*89c4ff92SAndroid Build Coastguard Worker4. 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*89c4ff92SAndroid Build Coastguard Worker
25*89c4ff92SAndroid Build Coastguard Worker## Setup virtual environment
26*89c4ff92SAndroid Build Coastguard Worker
27*89c4ff92SAndroid Build Coastguard WorkerNow 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*89c4ff92SAndroid Build Coastguard Worker```bash
29*89c4ff92SAndroid Build Coastguard Workerpython -m venv env
30*89c4ff92SAndroid Build Coastguard Workersource env/bin/activate
31*89c4ff92SAndroid Build Coastguard Worker```
32*89c4ff92SAndroid Build Coastguard Worker
33*89c4ff92SAndroid Build Coastguard WorkerYou may run into missing python modules such as *wheel*. Make sure to install those using pip:
34*89c4ff92SAndroid Build Coastguard Worker```bash
35*89c4ff92SAndroid Build Coastguard Workerpip install wheel
36*89c4ff92SAndroid Build Coastguard Worker```
37*89c4ff92SAndroid Build Coastguard Worker
38*89c4ff92SAndroid Build Coastguard Worker## Build python distr
39*89c4ff92SAndroid Build Coastguard Worker
40*89c4ff92SAndroid Build Coastguard WorkerPython supports source and binary distribution packages.
41*89c4ff92SAndroid Build Coastguard Worker
42*89c4ff92SAndroid Build Coastguard WorkerSource distr contains setup.py script that is executed on the users machine during package installation.
43*89c4ff92SAndroid Build Coastguard WorkerWhen preparing binary distr (wheel), setup.py is executed on the build machine and the resulting package contains only the result
44*89c4ff92SAndroid Build Coastguard Workerof the build (generated files and resources, test results etc).
45*89c4ff92SAndroid Build Coastguard Worker
46*89c4ff92SAndroid Build Coastguard WorkerIn our case, PyArmNN depends on Arm NN installation. Thus, binary distr will be linked with
47*89c4ff92SAndroid Build Coastguard Workerthe local build machine libraries and runtime.
48*89c4ff92SAndroid Build Coastguard Worker
49*89c4ff92SAndroid Build Coastguard WorkerThe recommended way to build the python packages is by CMake.
50*89c4ff92SAndroid Build Coastguard Worker
51*89c4ff92SAndroid Build Coastguard Worker### CMake build
52*89c4ff92SAndroid Build Coastguard Worker
53*89c4ff92SAndroid Build Coastguard WorkerThe recommended approach is to build PyArmNN together with Arm NN by adding the following options to your CMake command:
54*89c4ff92SAndroid Build Coastguard Worker```
55*89c4ff92SAndroid Build Coastguard Worker-DBUILD_PYTHON_SRC=1
56*89c4ff92SAndroid Build Coastguard Worker```
57*89c4ff92SAndroid Build Coastguard WorkerThis will build the source package. Current project headers and build libraries will be used, so there is no need to provide them.
58*89c4ff92SAndroid Build Coastguard Worker
59*89c4ff92SAndroid Build Coastguard WorkerSWIG 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*89c4ff92SAndroid Build Coastguard Worker```
61*89c4ff92SAndroid Build Coastguard Worker-DSWIG_EXECUTABLE=<path_to_swig_executable>
62*89c4ff92SAndroid Build Coastguard Worker```
63*89c4ff92SAndroid Build Coastguard Worker
64*89c4ff92SAndroid Build Coastguard WorkerAfter the build finishes, you will find the python packages in `<build_folder>/python/pyarmnn/dist`.
65*89c4ff92SAndroid Build Coastguard Worker
66*89c4ff92SAndroid Build Coastguard Worker# PyArmNN installation
67*89c4ff92SAndroid Build Coastguard Worker
68*89c4ff92SAndroid Build Coastguard WorkerPyArmNN can be distributed as a source package or a binary package (wheel).
69*89c4ff92SAndroid Build Coastguard Worker
70*89c4ff92SAndroid Build Coastguard WorkerBinary package is platform dependent, the name of the package will indicate the platform it was built for, e.g.:
71*89c4ff92SAndroid Build Coastguard Worker
72*89c4ff92SAndroid Build Coastguard Worker* Linux x86 64bit machine: pyarmnn-32.0.0-cp36-cp36m-*linux_x86_64*.whl
73*89c4ff92SAndroid Build Coastguard Worker* Linux Aarch 64 bit machine: pyarmnn-32.0.0-cp36-cp36m-*linux_aarch64*.whl
74*89c4ff92SAndroid Build Coastguard Worker
75*89c4ff92SAndroid Build Coastguard WorkerThe 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*89c4ff92SAndroid Build Coastguard Worker
77*89c4ff92SAndroid Build Coastguard WorkerBoth of them, source and binary package, require the Arm NN library to be present on the target/build machine.
78*89c4ff92SAndroid Build Coastguard Worker
79*89c4ff92SAndroid Build Coastguard WorkerIt 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*89c4ff92SAndroid Build Coastguard Worker
81*89c4ff92SAndroid Build Coastguard WorkerPyArmNN 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*89c4ff92SAndroid Build Coastguard Worker
83*89c4ff92SAndroid Build Coastguard Worker## Installing from source package
84*89c4ff92SAndroid Build Coastguard Worker
85*89c4ff92SAndroid Build Coastguard WorkerInstalling from source is the most reliable way.
86*89c4ff92SAndroid Build Coastguard Worker
87*89c4ff92SAndroid Build Coastguard WorkerWhile 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.
88*89c4ff92SAndroid Build Coastguard WorkerIf you want to use system default locations, just set *ARMNN_INCLUDE* to point to Arm NN headers.
89*89c4ff92SAndroid Build Coastguard WorkerAdditionally, *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*89c4ff92SAndroid Build Coastguard Worker
91*89c4ff92SAndroid Build Coastguard Worker```bash
92*89c4ff92SAndroid Build Coastguard Worker$ export  ARMNN_LIB=/path/to/libs
93*89c4ff92SAndroid Build Coastguard Worker$ export  LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/libs
94*89c4ff92SAndroid Build Coastguard Worker$ export  ARMNN_INCLUDE=/full/path/to/armnn/include:/full/path/to/armnn/profiling/common/include
95*89c4ff92SAndroid Build Coastguard Worker```
96*89c4ff92SAndroid Build Coastguard Worker
97*89c4ff92SAndroid Build Coastguard WorkerInstall PyArmNN as follows:
98*89c4ff92SAndroid Build Coastguard Worker```bash
99*89c4ff92SAndroid Build Coastguard Worker$ pip install /path/to/armnn/python/pyarmnn
100*89c4ff92SAndroid Build Coastguard Worker```
101*89c4ff92SAndroid Build Coastguard Worker
102*89c4ff92SAndroid Build Coastguard WorkerIf PyArmNN installation script fails to find Arm NN libraries it will raise an error like this
103*89c4ff92SAndroid Build Coastguard Worker
104*89c4ff92SAndroid Build Coastguard Worker`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*89c4ff92SAndroid Build Coastguard Worker
106*89c4ff92SAndroid Build Coastguard WorkerYou can now verify that PyArmNN library is installed and check PyArmNN version using:
107*89c4ff92SAndroid Build Coastguard Worker```bash
108*89c4ff92SAndroid Build Coastguard Worker$ pip show pyarmnn
109*89c4ff92SAndroid Build Coastguard Worker```
110*89c4ff92SAndroid Build Coastguard WorkerYou can also verify it by running the following and getting output similar to below:
111*89c4ff92SAndroid Build Coastguard Worker```bash
112*89c4ff92SAndroid Build Coastguard Worker$ python -c "import pyarmnn as ann;print(ann.GetVersion())"
113*89c4ff92SAndroid Build Coastguard Worker'32.0.0'
114*89c4ff92SAndroid Build Coastguard Worker```
115*89c4ff92SAndroid Build Coastguard Worker
116*89c4ff92SAndroid Build Coastguard Worker
117*89c4ff92SAndroid Build Coastguard Worker## Installing PyArmNN while using ArmNN prebuilt binaries
118*89c4ff92SAndroid Build Coastguard Worker
119*89c4ff92SAndroid Build Coastguard WorkerIf you wish to use ArmNN prebuilt binaries from our release page, you will need to generate the PyArmNN SWIG wrappers.
120*89c4ff92SAndroid Build Coastguard Worker
121*89c4ff92SAndroid Build Coastguard WorkerAgain setup your environmental variables along with a virtual environment:
122*89c4ff92SAndroid Build Coastguard Worker
123*89c4ff92SAndroid Build Coastguard Worker```bash
124*89c4ff92SAndroid Build Coastguard Worker$ python -m venv env
125*89c4ff92SAndroid Build Coastguard Worker$ source env/bin/activate
126*89c4ff92SAndroid Build Coastguard Worker
127*89c4ff92SAndroid Build Coastguard Worker$ export  ARMNN_LIB=/path/to/libs
128*89c4ff92SAndroid Build Coastguard Worker$ export  LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/libs
129*89c4ff92SAndroid Build Coastguard Worker$ export  ARMNN_INCLUDE=/full/path/to/armnn/include:/full/path/to/armnn/profiling/common/include
130*89c4ff92SAndroid Build Coastguard Worker```
131*89c4ff92SAndroid Build Coastguard Worker
132*89c4ff92SAndroid Build Coastguard WorkerThen generate the SWIG wrappers:
133*89c4ff92SAndroid Build Coastguard Worker```bash
134*89c4ff92SAndroid Build Coastguard Worker$ cd armnn/python/pyarmnn/
135*89c4ff92SAndroid Build Coastguard Worker$ python swig_generate.py -v
136*89c4ff92SAndroid Build Coastguard Worker```
137*89c4ff92SAndroid Build Coastguard Worker
138*89c4ff92SAndroid Build Coastguard WorkerThen install PyArmNN:
139*89c4ff92SAndroid Build Coastguard Worker```bash
140*89c4ff92SAndroid Build Coastguard Worker# From directory armnn/python/pyarmnn/
141*89c4ff92SAndroid Build Coastguard Worker$ pip install .
142*89c4ff92SAndroid Build Coastguard Worker```
143*89c4ff92SAndroid Build Coastguard Worker
144*89c4ff92SAndroid Build Coastguard WorkerAs above, you can verify that PyArmNN library is installed and check PyArmNN version using:
145*89c4ff92SAndroid Build Coastguard Worker```bash
146*89c4ff92SAndroid Build Coastguard Worker$ pip show pyarmnn
147*89c4ff92SAndroid Build Coastguard Worker```
148*89c4ff92SAndroid Build Coastguard WorkerYou can also verify it by running the following and getting output similar to below:
149*89c4ff92SAndroid Build Coastguard Worker```bash
150*89c4ff92SAndroid Build Coastguard Worker$ python -c "import pyarmnn as ann;print(ann.GetVersion())"
151*89c4ff92SAndroid Build Coastguard Worker'32.0.0'
152*89c4ff92SAndroid Build Coastguard Worker```
153*89c4ff92SAndroid Build Coastguard Worker
154*89c4ff92SAndroid Build Coastguard Worker# PyArmNN API overview
155*89c4ff92SAndroid Build Coastguard Worker
156*89c4ff92SAndroid Build Coastguard Worker#### Getting started
157*89c4ff92SAndroid Build Coastguard WorkerThe easiest way to begin using PyArmNN is by using the Parsers. We will demonstrate how to use them below:
158*89c4ff92SAndroid Build Coastguard Worker
159*89c4ff92SAndroid Build Coastguard WorkerCreate a parser object and load your model file.
160*89c4ff92SAndroid Build Coastguard Worker```python
161*89c4ff92SAndroid Build Coastguard Workerimport pyarmnn as ann
162*89c4ff92SAndroid Build Coastguard Workerimport imageio
163*89c4ff92SAndroid Build Coastguard Worker
164*89c4ff92SAndroid Build Coastguard Worker# An ONNX parser also exists.
165*89c4ff92SAndroid Build Coastguard Workerparser = ann.ITfLiteParser()
166*89c4ff92SAndroid Build Coastguard Workernetwork = parser.CreateNetworkFromBinaryFile('./model.tflite')
167*89c4ff92SAndroid Build Coastguard Worker```
168*89c4ff92SAndroid Build Coastguard Worker
169*89c4ff92SAndroid Build Coastguard WorkerGet the input binding information by using the name of the input layer.
170*89c4ff92SAndroid Build Coastguard Worker```python
171*89c4ff92SAndroid Build Coastguard Workerinput_binding_info = parser.GetNetworkInputBindingInfo(0, 'model/input')
172*89c4ff92SAndroid Build Coastguard Worker
173*89c4ff92SAndroid Build Coastguard Worker# Create a runtime object that will perform inference.
174*89c4ff92SAndroid Build Coastguard Workeroptions = ann.CreationOptions()
175*89c4ff92SAndroid Build Coastguard Workerruntime = ann.IRuntime(options)
176*89c4ff92SAndroid Build Coastguard Worker```
177*89c4ff92SAndroid Build Coastguard WorkerChoose preferred backends for execution and optimize the network.
178*89c4ff92SAndroid Build Coastguard Worker```python
179*89c4ff92SAndroid Build Coastguard Worker# Backend choices earlier in the list have higher preference.
180*89c4ff92SAndroid Build Coastguard WorkerpreferredBackends = [ann.BackendId('CpuAcc'), ann.BackendId('CpuRef')]
181*89c4ff92SAndroid Build Coastguard Workeropt_network, messages = ann.Optimize(network, preferredBackends, runtime.GetDeviceSpec(), ann.OptimizerOptions())
182*89c4ff92SAndroid Build Coastguard Worker
183*89c4ff92SAndroid Build Coastguard Worker# Load the optimized network into the runtime.
184*89c4ff92SAndroid Build Coastguard Workernet_id, _ = runtime.LoadNetwork(opt_network)
185*89c4ff92SAndroid Build Coastguard Worker```
186*89c4ff92SAndroid Build Coastguard WorkerMake workload tensors using input and output binding information.
187*89c4ff92SAndroid Build Coastguard Worker```python
188*89c4ff92SAndroid Build Coastguard Worker# Load an image and create an inputTensor for inference.
189*89c4ff92SAndroid Build Coastguard Workerimg = imageio.imread('./image.png')
190*89c4ff92SAndroid Build Coastguard Workerinput_tensors = ann.make_input_tensors([input_binding_info], [img])
191*89c4ff92SAndroid Build Coastguard Worker
192*89c4ff92SAndroid Build Coastguard Worker# Get output binding information for an output layer by using the layer name.
193*89c4ff92SAndroid Build Coastguard Workeroutput_binding_info = parser.GetNetworkOutputBindingInfo(0, 'model/output')
194*89c4ff92SAndroid Build Coastguard Workeroutput_tensors = ann.make_output_tensors([output_binding_info])
195*89c4ff92SAndroid Build Coastguard Worker```
196*89c4ff92SAndroid Build Coastguard Worker
197*89c4ff92SAndroid Build Coastguard WorkerPerform inference and get the results back into a numpy array.
198*89c4ff92SAndroid Build Coastguard Worker```python
199*89c4ff92SAndroid Build Coastguard Workerruntime.EnqueueWorkload(0, input_tensors, output_tensors)
200*89c4ff92SAndroid Build Coastguard Worker
201*89c4ff92SAndroid Build Coastguard Workerresults = ann.workload_tensors_to_ndarray(output_tensors)
202*89c4ff92SAndroid Build Coastguard Workerprint(results)
203*89c4ff92SAndroid Build Coastguard Worker```
204*89c4ff92SAndroid Build Coastguard Worker
205*89c4ff92SAndroid Build Coastguard Worker#### Examples
206*89c4ff92SAndroid Build Coastguard Worker
207*89c4ff92SAndroid Build Coastguard WorkerTo further explore PyArmNN API there are several examples provided in the `/examples` folder for you to explore.
208*89c4ff92SAndroid Build Coastguard Worker
209*89c4ff92SAndroid Build Coastguard Worker##### Image Classification
210*89c4ff92SAndroid Build Coastguard Worker
211*89c4ff92SAndroid Build Coastguard WorkerThis 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*89c4ff92SAndroid Build Coastguard Worker
213*89c4ff92SAndroid Build Coastguard WorkerSample scripts are provided for performing image classification with TFLite and ONNX models with `tflite_mobilenetv1_quantized.py` and `onnx_mobilenetv2.py`.
214*89c4ff92SAndroid Build Coastguard Worker
215*89c4ff92SAndroid Build Coastguard Worker##### Object Detection
216*89c4ff92SAndroid Build Coastguard Worker
217*89c4ff92SAndroid Build Coastguard WorkerThis 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*89c4ff92SAndroid Build Coastguard Worker
219*89c4ff92SAndroid Build Coastguard WorkerSample scripts are provided for performing object detection from video file and video stream with `run_video_file.py` and `run_video_stream.py`.
220*89c4ff92SAndroid Build Coastguard Worker
221*89c4ff92SAndroid Build Coastguard Worker
222*89c4ff92SAndroid Build Coastguard Worker## Tox for automation
223*89c4ff92SAndroid Build Coastguard Worker
224*89c4ff92SAndroid Build Coastguard WorkerTo 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*89c4ff92SAndroid Build Coastguard Worker
226*89c4ff92SAndroid Build Coastguard Worker```bash
227*89c4ff92SAndroid Build Coastguard Worker$ tox <task_name>
228*89c4ff92SAndroid Build Coastguard Worker```
229*89c4ff92SAndroid Build Coastguard Worker
230*89c4ff92SAndroid Build Coastguard WorkerSee *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*89c4ff92SAndroid Build Coastguard Worker
232*89c4ff92SAndroid Build Coastguard Worker## Running unit-tests
233*89c4ff92SAndroid Build Coastguard Worker
234*89c4ff92SAndroid Build Coastguard WorkerDownload resources required to run unit tests by executing the script in the scripts folder:
235*89c4ff92SAndroid Build Coastguard Worker
236*89c4ff92SAndroid Build Coastguard Worker```
237*89c4ff92SAndroid Build Coastguard Worker$ python ./scripts/download_test_resources.py
238*89c4ff92SAndroid Build Coastguard Worker```
239*89c4ff92SAndroid Build Coastguard Worker
240*89c4ff92SAndroid Build Coastguard WorkerThe 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*89c4ff92SAndroid Build Coastguard Worker```bash
242*89c4ff92SAndroid Build Coastguard Worker$ python -m pytest test/ -v
243*89c4ff92SAndroid Build Coastguard Worker```
244*89c4ff92SAndroid Build Coastguard Workeror run tox which will do both:
245*89c4ff92SAndroid Build Coastguard Worker```bash
246*89c4ff92SAndroid Build Coastguard Worker$ tox
247*89c4ff92SAndroid Build Coastguard Worker```
248