Introduction
Les délégués permettent l'accélération matérielle des modèles TensorFlow Lite en tirant parti des accélérateurs intégrés à l'appareil tels que le GPU et le processeur de signal numérique (DSP) .
Par défaut, TensorFlow Lite utilise des noyaux de processeur optimisés pour le jeu d'instructions ARM Neon . Cependant, le processeur est un processeur polyvalent qui n'est pas nécessairement optimisé pour l'arithmétique lourde que l'on trouve généralement dans les modèles d'apprentissage automatique (par exemple, les mathématiques matricielles impliquées dans la convolution et les couches denses).
D'autre part, la plupart des téléphones portables modernes contiennent des puces qui permettent de mieux gérer ces opérations lourdes. Leur utilisation pour les opérations de réseau neuronal offre d'énormes avantages en termes de latence et d'efficacité énergétique. Par exemple, les GPU peuvent fournir jusqu'à 5 fois plus de temps de latence, tandis que le DSP Qualcomm® Hexagon a montré qu'il réduisait la consommation d'énergie jusqu'à 75 % dans nos expériences.
Chacun de ces accélérateurs est associé à des API qui permettent des calculs personnalisés, comme OpenCL ou OpenGL ES pour les GPU mobiles et le SDK Qualcomm® Hexagon pour DSP. En règle générale, vous devrez écrire beaucoup de code personnalisé pour exécuter un réseau de neurones via ces interfaces. Les choses deviennent encore plus compliquées lorsque vous considérez que chaque accélérateur a ses avantages et ses inconvénients et ne peut pas exécuter toutes les opérations dans un réseau de neurones. L'API Delegate de TensorFlow Lite résout ce problème en agissant comme un pont entre l'environnement d'exécution TFLite et ces API de niveau inférieur.
Choisir un délégué
TensorFlow Lite prend en charge plusieurs délégués, chacun étant optimisé pour certaines plates-formes et certains types de modèles. Habituellement, il y aura plusieurs délégués applicables à votre cas d'utilisation, en fonction de deux critères majeurs : la plate -forme (Android ou iOS ?) que vous ciblez et le type de modèle (virgule flottante ou quantifié ?) que vous essayez d'accélérer. .
Délégués par plateforme
Multiplateforme (Android et iOS)
- Délégué GPU - Le délégué GPU peut être utilisé à la fois sur Android et iOS. Il est optimisé pour exécuter des modèles flottants 32 bits et 16 bits lorsqu'un GPU est disponible. Il prend également en charge les modèles quantifiés 8 bits et fournit des performances GPU comparables à leurs versions flottantes. Pour plus de détails sur le délégué GPU, consultez TensorFlow Lite sur GPU . Pour obtenir des didacticiels détaillés sur l'utilisation du délégué GPU avec Android et iOS, consultez Tutoriel sur le délégué GPU TensorFlow Lite .
Android
- Délégué NNAPI pour les nouveaux appareils Android - Le délégué NNAPI peut être utilisé pour accélérer les modèles sur les appareils Android avec GPU, DSP et/ou NPU disponibles. Il est disponible sous Android 8.1 (API 27+) ou supérieur. Pour obtenir une vue d'ensemble du délégué NNAPI, des instructions détaillées et des bonnes pratiques, consultez Délégué NNAPI TensorFlow Lite .
- Délégué Hexagon pour les appareils Android plus anciens - Le délégué Hexagon peut être utilisé pour accélérer les modèles sur les appareils Android avec Qualcomm Hexagon DSP. Il peut être utilisé sur des appareils exécutant des versions antérieures d'Android qui ne prennent pas en charge NNAPI. Voir délégué TensorFlow Lite Hexagon pour plus de détails.
iOS
- Délégué Core ML pour les iPhones et iPads plus récents - Pour les iPhones et iPads plus récents où Neural Engine est disponible, vous pouvez utiliser le délégué Core ML pour accélérer l'inférence pour les modèles à virgule flottante 32 bits ou 16 bits. Neural Engine est disponible sur les appareils mobiles Apple avec SoC A12 ou supérieur. Pour obtenir une vue d'ensemble du délégué Core ML et des instructions pas à pas, consultez Délégué TensorFlow Lite Core ML .
Délégués par type de modèle
Chaque accélérateur est conçu avec une certaine largeur de bits de données à l'esprit. Si vous fournissez un modèle à virgule flottante à un délégué qui ne prend en charge que les opérations quantifiées 8 bits (comme le délégué Hexagon ), il rejettera toutes ses opérations et le modèle s'exécutera entièrement sur le CPU. Pour éviter de telles surprises, le tableau ci-dessous donne un aperçu de la prise en charge des délégués en fonction du type de modèle :
Type de modèle | GPU | NNAPI | Hexagone | CoreML |
---|---|---|---|---|
Virgule flottante (32 bits) | Oui | Oui | Non | Oui |
Quantification float16 post-entraînement | Oui | Non | Non | Oui |
Quantification de plage dynamique post-entraînement | Oui | Oui | Non | Non |
Quantification entière post-formation | Oui | Oui | Oui | Non |
Formation sensible à la quantification | Oui | Oui | Oui | Non |
Validation des performances
Les informations contenues dans cette section servent de lignes directrices approximatives pour la présélection des délégués qui pourraient améliorer votre candidature. Cependant, il est important de noter que chaque délégué dispose d'un ensemble prédéfini d'opérations qu'il prend en charge et peut effectuer différemment selon le modèle et l'appareil ; par exemple, le délégué NNAPI peut choisir d'utiliser Edge-TPU de Google sur un téléphone Pixel tout en utilisant un DSP sur un autre appareil. Par conséquent, il est généralement recommandé d'effectuer une analyse comparative pour évaluer l'utilité d'un délégué pour vos besoins. Cela permet également de justifier l'augmentation de la taille binaire associée à l'attachement d'un délégué au runtime TensorFlow Lite.
TensorFlow Lite dispose de nombreux outils d'évaluation des performances et de la précision qui permettent aux développeurs d'utiliser en toute confiance des délégués dans leur application. Ces outils sont abordés dans la section suivante.
Outils d'évaluation
Latence et empreinte mémoire
L' outil de référence de TensorFlow Lite peut être utilisé avec des paramètres appropriés pour estimer les performances du modèle, y compris la latence d'inférence moyenne, la surcharge d'initialisation, l'empreinte mémoire, etc. Cet outil prend en charge plusieurs indicateurs pour déterminer la meilleure configuration déléguée pour votre modèle. Par exemple, --gpu_backend=gl
peut être spécifié avec --use_gpu
pour mesurer l'exécution du GPU avec OpenGL. La liste complète des paramètres délégués pris en charge est définie dans la documentation détaillée .
Voici un exemple exécuté pour un modèle quantifié avec GPU via adb
:
adb shell /data/local/tmp/benchmark_model \
--graph=/data/local/tmp/mobilenet_v1_224_quant.tflite \
--use_gpu=true
Vous pouvez télécharger la version pré-construite de cet outil pour Android, architecture ARM 64 bits ici ( plus de détails ).
Exactitude et justesse
Les délégués effectuent généralement des calculs avec une précision différente de celle de leurs homologues CPU. Par conséquent, il existe un compromis de précision (généralement mineur) associé à l'utilisation d'un délégué pour l'accélération matérielle. Notez que ce n'est pas toujours vrai; par exemple, étant donné que le GPU utilise une précision en virgule flottante pour exécuter des modèles quantifiés, il peut y avoir une légère amélioration de la précision (par exemple, <1 % d'amélioration du Top-5 dans la classification des images ILSVRC).
TensorFlow Lite dispose de deux types d'outils pour mesurer la précision avec laquelle un délégué se comporte pour un modèle donné : basé sur les tâches et indépendant des tâches . Tous les outils décrits dans cette section prennent en charge les paramètres de délégation avancés utilisés par l'outil d'analyse comparative de la section précédente. Notez que les sous-sections ci-dessous se concentrent sur l' évaluation du délégué (le délégué effectue-t-il la même chose que le processeur ?) plutôt que sur l'évaluation du modèle (le modèle lui-même est-il bon pour la tâche ?).
Évaluation basée sur les tâches
TensorFlow Lite dispose d'outils permettant d'évaluer l'exactitude de deux tâches basées sur des images :
ILSVRC 2012 (Classification des images) avec une précision top-K
Détection d'objets COCO (avec cadres de délimitation) avec précision moyenne moyenne (mAP)
Les binaires prédéfinis de ces outils (Android, architecture ARM 64 bits), ainsi que la documentation peuvent être trouvés ici :
L'exemple ci-dessous illustre l'évaluation de la classification des images avec NNAPI à l'aide du Edge-TPU de Google sur un Pixel 4 :
adb shell /data/local/tmp/run_eval \
--model_file=/data/local/tmp/mobilenet_quant_v1_224.tflite \
--ground_truth_images_path=/data/local/tmp/ilsvrc_images \
--ground_truth_labels=/data/local/tmp/ilsvrc_validation_labels.txt \
--model_output_labels=/data/local/tmp/model_output_labels.txt \
--output_file_path=/data/local/tmp/accuracy_output.txt \
--num_images=0 # Run on all images. \
--use_nnapi=true \
--nnapi_accelerator_name=google-edgetpu
Le résultat attendu est une liste de métriques Top-K de 1 à 10 :
Top-1 Accuracy: 0.733333
Top-2 Accuracy: 0.826667
Top-3 Accuracy: 0.856667
Top-4 Accuracy: 0.87
Top-5 Accuracy: 0.89
Top-6 Accuracy: 0.903333
Top-7 Accuracy: 0.906667
Top-8 Accuracy: 0.913333
Top-9 Accuracy: 0.92
Top-10 Accuracy: 0.923333
Évaluation indépendante des tâches
Pour les tâches où il n'y a pas d'outil d'évaluation sur l'appareil établi, ou si vous expérimentez avec des modèles personnalisés, TensorFlow Lite dispose de l'outil Inference Diff . (Android, binaire d'architecture binaire ARM 64 bits ici )
Inference Diff compare l'exécution de TensorFlow Lite (en termes de latence et d'écart de la valeur de sortie) dans deux paramètres :
- Inférence CPU à thread unique
- Inférence définie par l'utilisateur - définie par ces paramètres
Pour ce faire, l'outil génère des données gaussiennes aléatoires et les transmet à travers deux interpréteurs TFLite - l'un exécutant des noyaux CPU monothread et l'autre paramétré par les arguments de l'utilisateur.
Il mesure la latence des deux, ainsi que la différence absolue entre les tenseurs de sortie de chaque interpréteur, élément par élément.
Pour un modèle avec un seul tenseur de sortie, la sortie pourrait ressembler à ceci :
Num evaluation runs: 50
Reference run latency: avg=84364.2(us), std_dev=12525(us)
Test run latency: avg=7281.64(us), std_dev=2089(us)
OutputDiff[0]: avg_error=1.96277e-05, std_dev=6.95767e-06
Cela signifie que pour le tenseur de sortie à l'indice 0
, les éléments de la sortie CPU diffèrent de la sortie déléguée d'une moyenne de 1.96e-05
.
Notez que l'interprétation de ces chiffres nécessite une connaissance plus approfondie du modèle et de ce que signifie chaque tenseur de sortie. S'il s'agit d'une simple régression qui détermine une sorte de score ou d'intégration, la différence doit être faible (sinon c'est une erreur avec le délégué). Cependant, les sorties comme celle de « classe de détection » des modèles SSD sont un peu plus difficiles à interpréter. Par exemple, cela peut montrer une différence en utilisant cet outil, mais cela ne signifie pas vraiment quelque chose qui ne va pas avec le délégué : considérez deux (fausses) classes : "TV (ID : 10)", "Monitor (ID : 20)" - Si un délégué est légèrement en dehors de la vérité dorée et montre moniteur au lieu de TV, le diff de sortie pour ce tenseur peut être quelque chose d'aussi élevé que 20-10 = 10.