Les délégués permettent l'accélération matérielle des modèles LiteRT en exploitant les accélérateurs sur l'appareil tels que le GPU et le processeur de signal numérique (DSP).
Par défaut, LiteRT utilise des noyaux de processeur optimisés pour le jeu d'instructions ARM Neon. Toutefois, 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 de machine learning (par exemple, les calculs matriciels impliqués dans les couches de convolution et denses).
En revanche, la plupart des téléphones mobiles modernes contiennent des puces plus performantes pour gérer ces opérations lourdes. Leur utilisation pour les opérations de réseaux neuronaux offre d'énormes avantages en termes de latence et d'efficacité énergétique. Par exemple, les GPU peuvent multiplier par cinq la vitesse de latence.
Chacun de ces accélérateurs est associé à des API qui permettent des calculs personnalisés, tels qu'OpenCL ou OpenGL ES pour le GPU mobile. En règle générale, vous devez écrire beaucoup de code personnalisé pour exécuter un réseau de neurones via ces interfaces. Les choses se compliquent encore plus lorsque l'on considère que chaque accélérateur a ses avantages et ses inconvénients, et qu'il ne peut pas exécuter toutes les opérations d'un réseau de neurones. L'API Delegate de TensorFlow Lite résout ce problème en servant de pont entre le runtime TFLite et ces API de niveau inférieur.

Choisir un délégué
LiteRT est compatible avec plusieurs délégués, chacun étant optimisé pour certaines plates-formes et certains types de modèles. En général, plusieurs délégués s'appliquent à 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 plate-forme
Multiplate-forme (Android et iOS)
- Délégué GPU : le délégué GPU peut être utilisé sur Android et iOS. Il est optimisé pour exécuter des modèles basés sur des nombres à virgule flottante de 32 et 16 bits lorsqu'un GPU est disponible. Il est également compatible avec les modèles quantifiés 8 bits et offre des performances de GPU équivalentes à celles de leurs versions flottantes. Pour en savoir plus sur le délégué GPU, consultez LiteRT sur GPU.
iOS
- Délégué Core ML pour les nouveaux iPhones et iPads : pour les nouveaux iPhones et iPads sur lesquels le moteur 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 de 32 ou 16 bits. Neural Engine est disponible sur les appareils mobiles Apple équipés d'un SoC A12 ou version ultérieure. Pour obtenir une présentation du délégué Core ML et des instructions détaillées, consultez Délégué LiteRT Core ML.
Délégués par type de modèle
Chaque accélérateur est conçu pour une certaine largeur de bits de données. Si vous fournissez un modèle à virgule flottante à un délégué qui ne prend en charge que les opérations quantifiées sur 8 bits, il rejettera toutes ses opérations et le modèle s'exécutera entièrement sur le processeur. Pour éviter de telles surprises, le tableau ci-dessous présente une vue d'ensemble de la compatibilité des délégués en fonction du type de modèle :
| Type de modèle | GPU | CoreML |
|---|---|---|
| Virgule flottante (32 bits) | Oui | Oui |
| Quantification float16 post-entraînement | Oui | Oui |
| Quantification de la plage dynamique post-entraînement | Oui | Non |
| Quantification par nombres entiers post-entraînement | Oui | Non |
| Entraînement tenant compte de la quantification | Oui | Non |
Valider les performances
Les informations de cette section servent de guide approximatif pour présélectionner les délégués susceptibles d'améliorer votre application. Toutefois, 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 qu'il peut se comporter différemment selon le modèle et l'appareil. Par conséquent, il est généralement recommandé d'effectuer des tests comparatifs pour évaluer l'utilité d'un délégué pour vos besoins. Cela permet également de justifier l'augmentation de la taille du binaire associée à l'association d'un délégué au runtime LiteRT.
LiteRT dispose d'outils complets d'évaluation des performances et de la précision qui permettent aux développeurs d'utiliser les délégués en toute confiance dans leur application. Ces outils sont décrits dans la section suivante.
Outils d'évaluation
Latence et espace mémoire
L'outil de benchmarking de LiteRT 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 est compatible avec plusieurs indicateurs pour déterminer la meilleure configuration de délégué 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 de délégué acceptés est définie dans la documentation détaillée.
Voici un exemple d'exécution 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écompilée de cet outil pour Android, architecture ARM 64 bits, sur cette page (plus d'informations).
Précision et exactitude
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, l'utilisation d'un délégué pour l'accélération matérielle entraîne un compromis (généralement mineur) en termes de précision. Notez que cela n'est pas toujours vrai. Par exemple, comme le GPU utilise une précision à virgule flottante pour exécuter les modèles quantifiés, il peut y avoir une légère amélioration de la précision (par exemple, Amélioration de moins de 1 % du Top 5 dans la classification d'images ILSVRC.
LiteRT propose deux types d'outils pour mesurer la précision du comportement d'un délégué pour un modèle donné : Task-Based et Task-Agnostic. Tous les outils décrits dans cette section sont compatibles avec les paramètres de délégation avancée utilisés par l'outil de benchmarking 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é est-il aussi performant que le processeur ?) plutôt que sur l'évaluation du modèle (le modèle lui-même est-il adapté à la tâche ?).
Évaluation basée sur les tâches
LiteRT propose des outils pour évaluer l'exactitude de deux tâches basées sur des images :
ILSVRC 2012 (classification d'images) avec précision top-K
Détection d'objets COCO (avec des cadres de sélection) avec précision moyenne (mAP)
Vous trouverez les binaires prédéfinis de ces outils (architecture Android ARM 64 bits) ainsi que la documentation ici :
L'exemple ci-dessous illustre l'évaluation de la classification d'images avec GPU 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_gpu=true
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 agnostique aux tâches
Pour les tâches pour lesquelles il n'existe pas d'outil d'évaluation sur l'appareil établi ou si vous expérimentez avec des modèles personnalisés, LiteRT propose l'outil Inference Diff. (Android, architecture binaire ARM 64 bits ici)
Inference Diff compare l'exécution de LiteRT (en termes de latence et d'écart de valeur de sortie) dans deux paramètres :
- Inférence du processeur monothread
- 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 à deux interprètes TFLite : l'un exécutant des kernels 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 Tensors de sortie de chaque Interpreter, élément par élément.
Pour un modèle avec un seul Tensor de sortie, le résultat peut 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 Tensor de sortie à l'index 0, les éléments de la sortie du processeur diffèrent de la sortie du délégué 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 la signification de chaque Tensor de sortie. S'il s'agit d'une régression simple qui détermine un score ou un embedding, la différence doit être faible (sinon, il s'agit d'une erreur avec le délégué). Toutefois, les sorties telles que la "classe de détection" des modèles SSD sont un peu plus difficiles à interpréter. Par exemple, il peut afficher une différence à l'aide de cet outil, mais cela ne signifie pas nécessairement qu'il y a un problème avec le délégué. Prenons l'exemple de deux classes (fictives) : "TV (ID : 10)", "Écran (ID : 20)". Si un délégué est légèrement différent de la vérité absolue et affiche un écran au lieu d'un téléviseur, la différence de sortie pour ce Tensor peut atteindre 20-10 = 10.