Utiliser des processeurs graphiques (GPU) pour exécuter vos modèles de machine learning (ML) peut considérablement améliorer les performances de votre modèle et l'expérience utilisateur de vos applications compatibles avec le ML. LiteRT permet d'utiliser des GPU et d'autres processeurs spécialisés via un pilote matériel appelé délégués. Permettre l'utilisation de GPU avec LiteRT ML applications peuvent offrir les avantages suivants:
- Rapidité : les GPU sont conçus pour un débit élevé sur des charges de travail massivement parallèles. charges de travail. Cette conception convient parfaitement aux réseaux de neurones profonds, se composent d'un très grand nombre d'opérateurs, chacun travaillant sur des Tensors d'entrée peuvent être traités en parallèle, ce qui réduit généralement la latence. Dans Dans le meilleur des cas, l'exécution de votre modèle sur un GPU peut s'exécuter assez rapidement des applications en temps réel qui n'étaient pas possibles auparavant.
- Efficacité énergétique : les GPU effectuent des calculs de ML de manière très efficace de manière optimisée, généralement moins gourmandes en énergie que la même tâche exécutée sur les CPU.
Ce document présente la prise en charge des GPU dans LiteRT, ainsi que et les utilisations avancées des processeurs GPU. Pour en savoir plus sur sur la prise en charge des GPU sur des plates-formes spécifiques, consultez les guides suivants:
Compatibilité avec les opérations GPU ML
Les opérations (ops) de TensorFlow ML sont limitées. accéléré par le délégué de GPU LiteRT. Le délégué prend en charge Opérations suivantes en précision à virgule flottante 16 et 32 bits:
ADD
AVERAGE_POOL_2D
CONCATENATION
CONV_2D
DEPTHWISE_CONV_2D v1-2
EXP
FULLY_CONNECTED
LOGICAL_AND
LOGISTIC
LSTM v2 (Basic LSTM only)
MAX_POOL_2D
MAXIMUM
MINIMUM
MUL
PAD
PRELU
RELU
RELU6
RESHAPE
RESIZE_BILINEAR v1-3
SOFTMAX
STRIDED_SLICE
SUB
TRANSPOSE_CONV
Par défaut, toutes les opérations ne sont compatibles qu'avec la version 1. Activer la quantification support active les versions appropriées, par exemple, AJOUTER version 2.
Résoudre les problèmes liés aux GPU
Si certaines opérations ne sont pas prises en charge par le délégué GPU, le framework qu'une partie du graphique est exécutée sur le GPU et la partie restante sur le CPU. Date limite au coût élevé de la synchronisation CPU/GPU, un mode d'exécution fractionné comme celui-ci entraîne souvent des performances plus lentes que lorsque l'ensemble du réseau est exécuté sur le processeur seul. Dans ce cas, l'application génère un avertissement, par exemple:
WARNING: op code #42 cannot be handled by this delegate.
Il n'y a pas de rappel pour les échecs de ce type, car il ne s'agit pas d'une erreur réelle lors d'une défaillance au moment de l'exécution. Lorsque vous testez l'exécution de votre modèle avec le délégué de GPU, vous devez être attentif à ces avertissements. Un nombre élevé de ces avertissements peut indiquer que votre modèle n'est pas adapté à l'accélération du GPU ; et peut nécessiter une refactorisation du modèle.
Exemples de modèles
Les exemples de modèles suivants sont conçus pour exploiter l'accélération du GPU avec LiteRT et sont fournis à titre de référence et de test:
- Image MobileNet v1 (224 x 224)
classification
<ph type="x-smartling-placeholder">
- </ph>
- Un modèle de classification d'images conçu pour les mobiles et les modèles embarqués des applications de vision. (modèle)
- Segmentation DeepLab
(257x257)
<ph type="x-smartling-placeholder">
- </ph>
- qui attribue des étiquettes sémantiques (par exemple, un chien, "cat" ou "car", à chaque pixel de l'image d'entrée. (modèle)
- Objet SSD MobileNet
la détection
<ph type="x-smartling-placeholder">
- </ph>
- Un modèle de classification d'images qui détecte plusieurs objets avec cadres de délimitation. (modèle)
- PoseNet pour la pose
estimation
<ph type="x-smartling-placeholder">
- </ph>
- Un modèle de vision qui estime la posture des personnes dans une image ou vidéo. (modèle)
Optimiser pour les GPU
Les techniques suivantes peuvent vous aider à obtenir de meilleures performances lorsque vous exécutez des modèles sur le matériel GPU à l'aide du délégué de GPU LiteRT:
Opérations de remodelage : certaines opérations rapides sur un processeur peuvent avoir un coût élevé pour le GPU sur les appareils mobiles. Les opérations de remodelage sont particulièrement coûteux, dont
BATCH_TO_SPACE
,SPACE_TO_BATCH
,SPACE_TO_DEPTH
, etc. Vous devez examiner de près l'utilisation de reshape des opérations, et tenez compte de ce qui a pu être appliqué uniquement à l'exploration de données ou pour les premières itérations de votre modèle. Leur suppression peut considérablement améliorer les performances.Canaux de données d'image : sur un GPU, les données de Tensor sont réparties en quatre canaux. Un calcul sur un Tensor ayant la forme
[B,H,W,5]
est donc effectué identique sur un Tensor de forme[B,H,W,8]
, mais nettement moins bien[B,H,W,4]
Si le matériel de l'appareil photo que vous utilisez prend en charge les images Le RVBA, qui transmet cette entrée à quatre canaux, est beaucoup plus rapide, car il évite une copie de mémoire de RVB 3 canaux vers RGBX 4 canaux.Modèles optimisés pour les mobiles : pour bénéficier de performances optimales, de réentraîner votre classificateur avec une architecture réseau optimisée pour les mobiles. L'optimisation de l'inférence sur les appareils peut réduire considérablement la latence et grâce aux fonctionnalités matérielles mobiles.
Compatibilité avancée avec les GPU
Vous pouvez utiliser d'autres techniques avancées avec le traitement GPU pour activer de meilleures performances pour vos modèles, y compris la quantification et la sérialisation. Les sections suivantes décrivent ces techniques plus en détail.
Utiliser des modèles quantifiés
Cette section explique comment le délégué de GPU accélère les modèles quantifiés 8 bits, notamment:
- Modèles entraînés avec l'entraînement basé sur la quantification
- Quantification de plage dynamique post-entraînement
- Quantification entière post-entraînement
Pour optimiser les performances, utilisez des modèles dotés à la fois d'une entrée à virgule flottante et Tensors de sortie.
Comment ça marche ?
Étant donné que le backend GPU n'accepte que l'exécution à virgule flottante, nous exécutons une requête quantifiée en lui offrant une "vue à virgule flottante" du modèle d'origine. Au de manière générale, cela implique les étapes suivantes:
Les Tensors constants (tels que les pondérations/biais) sont dé-quantifiés une fois dans le mémoire GPU. Cette opération se produit lorsque le délégué est activé pour LiteRT.
Les entrées et sorties du programme GPU, si quantifiées sur 8 bits, sont dé-quantifiée et quantifiée (respectivement) pour chaque inférence. Cette opération se fait sur le CPU à l'aide des noyaux optimisés de LiteRT.
Des simulateurs de quantification sont insérés entre les opérations pour imiter l'activité quantifiée. comportemental. Cette approche est nécessaire pour les modèles dans lesquels les opérations attendent des activations. pour suivre les limites apprises lors de la quantification.
Pour en savoir plus sur l'activation de cette fonctionnalité avec le délégué de GPU, consultez la suivantes:
- Utiliser des modèles quantifiés avec GPU sur Android
- Utiliser des modèles quantifiés avec GPU sur iOS
Réduire le temps d'initialisation grâce à la sérialisation
La fonctionnalité de délégation de GPU vous permet de charger à partir du code du noyau précompilé et données de modèle sérialisées et enregistrées sur le disque lors des exécutions précédentes. Cette approche évite recompilation et peut réduire le temps de démarrage jusqu'à 90%. Cette amélioration est en échangeant de l'espace disque pour des gains de temps. Vous pouvez activer cette fonctionnalité avec quelques options de configuration, comme illustré dans les exemples de code suivants:
C++
TfLiteGpuDelegateOptionsV2 options = TfLiteGpuDelegateOptionsV2Default(); options.experimental_flags |= TFLITE_GPU_EXPERIMENTAL_FLAGS_ENABLE_SERIALIZATION; options.serialization_dir = kTmpDir; options.model_token = kModelToken; auto* delegate = TfLiteGpuDelegateV2Create(options); if (interpreter->ModifyGraphWithDelegate(delegate) != kTfLiteOk) return false;
Java
GpuDelegate delegate = new GpuDelegate( new GpuDelegate.Options().setSerializationParams( /* serializationDir= */ serializationDir, /* modelToken= */ modelToken)); Interpreter.Options options = (new Interpreter.Options()).addDelegate(delegate);
Lorsque vous utilisez la fonctionnalité de sérialisation, assurez-vous que votre code respecte ces règles d'implémentation:
- Stockez les données de sérialisation dans un répertoire auquel les autres
applications. Sur les appareils Android, utilisez
getCodeCacheDir()
qui pointe vers un emplacement privé pour l'application actuelle. - Le jeton de modèle doit être unique à l'appareil pour le modèle spécifique. Vous pouvez
calculer un jeton de modèle en générant une empreinte à partir des données du modèle à l'aide de
des bibliothèques telles que
farmhash::Fingerprint64