Dear NXP,
I'm trying to run a segmentation network on the i.mx8m's npu. The problem is that not matter what I'm trying to do, the model is not running on the npu only, and will fallback on the cpu or is rejected.
I post are some details and my logs so hopefully someone can tell me what I'm doing wrong here.
For testing purposes I created three different sequential models just to demonstrate the errors I'm running into.
Model architectures:
Model 1 contains three convolutional layers.
Input -> Conv1 -> Conv2 -> Conv3 -> Output
Model 2 contains three convolutional layers, a maxpool layer and an upsampling layer
Input -> Conv1 -> Maxpooling -> Conv2 -> Upsampling2D -> Conv3 -> Output
Model 3 contains three convolutional layers, a maxpool layer and a transpose convolution layer
Input -> Conv1 -> Maxpooling -> Conv2 -> TransConv -> Conv3 -> Output
These models are trained to have the identity output, again nothing special just to demonstrate the case.
I tried four different solutions to archive my goal (get a segmentation network running on the npu):
- through a tflite model and a python script using tflite runtime.
- through a tflite model and a python script using pyarmnn
- through a onnx model and a c++ script using onnx runtime
- through a onnx model and a python script using pyarmnn
Models trained with Tensorflow:
Creation of a tflite model. I converted my models using the tensorflow recepie (https://www.tensorflow.org/lite/performance/post_training_integer_quant) and the in 'i.MX Machine Learning User's Guide' chapter 3.6 given instructions:
converter = tf.lite.TFLiteConverter.from_saved_model(model_path)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.representative_dataset = representative_data_gen
converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8]
# Set to False to use TOCO
#converter.experimental_new_converter = False
converter.target_spec.supported_types = [tf.int8]
converter.inference_input_type = tf.int8
converter.inference_output_type = tf.int8
tflite_quant_model = converter.convert()
I used both Tensorflow v2.4 and v2.3 to convert my models.
Here are the logs I got, when running the model on the i.mx8m plus:
Model 1, TF v2.4 using TFLite runtime:
- see log_file.txt Line 1-11
Model 1, TF v2.3 using TFLite runtime:
- see log_file.txt Line 13- 24
No Problems here, but no upsampling or transpose convolution layer.
Model 1 TF v.2.4 using pyarmnn setting VsiNpu as only backend:
- see log_file.txt Line 26-40
- input data type QAsymmS8 and output data type QAsymmS8 not supported
Model 1 TF v.2.3 using pyarmnn setting VsiNpu as only backend:
- see log_file.txt Line 47-63
- input data type QAsymmS8 and output data type QAsymmS8 not supported
Model 2, TF v2.4 using TFLite runtime:
- see log_file.txt Line 65-76 (esp. Line 70)
- Failed to apply NNAPI delegate
Model 2, TF v2.3 using TFLite runtime:
- see log_file.txt Line 80-92
- NNAPI does not support half_pixel_centers == true
Model 2 TF v.2.4 using pyarmnn setting VsiNpu as only backend:
- see log_file.txt Line 95-111
- input data type QAsymmS8 and output data type QAsymmS8 not supported
Model 2 TF v.2.3 using pyarmnn setting VsiNpu as only backend:
- see log_file.txt Line 114-130
- input data type QAsymmS8 and output data type QAsymmS8 not supported
Model 3, TF v2.4 using TFLite runtime:
- see log_file.txt Line 133-143 (esp. Line 137)
- Failed to apply NNAPI delegate.
Model 3, TF v2.3 using TFLite runtime:
- see log_file.txt Line 146-157
- Operator TRANSPOSE_CONV (v3) refused by NNAPI delegate: OP Version different from 1
Model 3 TF v.2.4 using pyarmnn with VsiNpu as the only backend:
- see log_file.txt Line 160-171
- expected armnn does not support transpose convolution
Model 3 TF v.2.3 using pyarmnn with VsiNpu as only backend:
- see log_file.txt Line 174-190
- expected armnn does not support transpose convolution
Models trained with Pytorch:
Same model architecture as before. I used Pytorch to train the model, instead of Tensorflow. Models are saved in onnx format using op version 10, 11 and 12. In the next step all models are converted to int8 models using the instructions given in https://www.onnxruntime.ai/docs/how-to/quantization.html and executed on the i.mx8m plus using the instruction given in 'i.MX Machine Learning User's Guide' chapter 6.2 with an adapted version of the C_Api_Sample.cpp
Python code for model quantization:
from onnxruntime.quantization import quantize_dynamic, QuantType
model_fp32 = 'model path to fp model'
model_quant = 'path to new model.onnx'
quantized_model = quantize_dynamic(model_fp32, model_quant, weight_type=QuantType.QInt8, activation_type=QuantType.QInt8)
Model 1 Pytorch v1.8 using onnx runtime:
- op v10 see log_file.txt Line 193-331
- op v11 see log_file.txt Line 334-473
- op v12 see log_file.txt Line 476-615
- lots of unsupported node messages
Model 2 Pytorch v1.8 using onnx runtime:
- skipped since Model 1 is not working
Model 3 Pytorch v1.8 using onnx runtime:
- skipped since Model 1 is not working
Model 1 Pytorch v1.8 using pyarmnn:
- op v11 see log_file.txt Line 618-629
- op v12 see log_file.txt Line 632-643
- op v13 see log_file.txt Line 646-657
- only support for float, int32, int64 -> not working on the NPU
Model 2 Pytorch v1.8 using pyarmnn:
- skipped since Model 1 is not working
Model 1 Pytorch v1.8 using pyarmnn:
- skipped since Model 1 is not working
The big question is now, what do I have to do in order to get my models working on the NPU or does the i.mx8m NPU not support modern (upsampling) neural networks?
Thanks in advance
Peter Woltersdorf