Introduction

Tulip est une Vision par ordinateur sans code destinéeaux opérations en atelier. Elle permet de créerApps Tulip Apps utilisent Vision par ordinateur piloter et surveiller les opérations. Tulip peut être utilisée pour détecter l'activité sur le poste de travail, ainsi que pour suivre des objets et des personnes. Les signaux de vision peuvent être configurés pour surveiller la sécurité, les opérations d'assemblage manuel, la préparation de kits et la préparation de commandes, ainsi que de nombreuses autres applications qui améliorent la fiabilité et réduisent les erreurs. Au cœur de la vision industrielle en atelier se trouvent Vision par ordinateur basés sur des réseaux neuronaux profonds. Ces algorithmes sont conçus pour fonctionner sur le matériel existant dans les ateliers, qui consiste souvent en un simple PC équipé de Windows. Afin d’apporter les toutes dernières technologies d’IA aux ordinateurs peu puissants des ateliers, nous utilisons Intel Compute Stick version 2 (NCS v2), également connu sous le nom de Movidius Vision Processing Unit (VPU). Il s'agit d'un périphérique USB doté d'un matériel de calcul conçu pour exécuter des réseaux neuronaux profonds, qui décharge le processeur (CPU) ou le processeur graphique (GPU) du PC des tâches arithmétiques. Le NCS est une solution à faible coût et à faible consommation d'énergie pour l'IA en périphérie, qui est également prête à l'emploi.

Pourquoi l'optimisation est-elle nécessaire ?

Nous avons constaté que le processeur Intel répondait parfaitement à nos besoins chez Tulip . Notre activité consiste principalement à détecter les personnes et leurs actions sur la chaîne de production ; il est donc essentiel de pouvoir repérer les mains et les personnes dans le flux vidéo en temps réel. Les modèles de détection humaine les plus récents font appel à des réseaux neuronaux profonds et à des modèles très lourds, ce qui représente un défi pour le NCS en termes de performances.

Avec une exécution standard d’un modèle de détection des mains, nous avons atteint une vitesse de 14 images par seconde (FPS) pour l’inférence. Certaines optimisations sont nécessaires pour atteindre nos objectifs de détection des gestes humains en temps réel (ce que l’on considère généralement comme étant 30 FPS et plus, soit la vitesse de fonctionnement habituelle de la plupart des caméras). Nous cherchions également à tirer le meilleur parti du matériel NCS, dont le coût est payé d’avance. Les spécifications du NCS indiquent une vitesse de traitement théorique de 100 GFLOP/s (giga-opérations en virgule flottante par seconde), alors qu’au départ, nous ne parvenions qu’à atteindre 20 à 25 GFLOP/s (avec un réseau de 1,5 GFLOP à 14 FPS), avec une latence considérable.

Dans cet article, nous abordons les techniques d'optimisation que nous avons explorées, ainsi que celle qui a réellement fait la différence pour nous et nous a permis d'atteindre les performances requises pour l'inférence en temps réel. Intel a Intel publié un guide utile sur l'optimisation des réseaux pour le NCSv2, que nous avons utilisé dans le cadre de nos travaux.

Conversion d'un modèle pour qu'il fonctionne sur le NCS

Pour commencer, nous avons obtenu le graphe et les poids d'un réseau de détection des mains. Nous entraînons nos propres modèles de détection des mains, optimisés pour les scènes en atelier, mais il existe en ligne des modèles librement accessibles qui fonctionnent étonnamment bien. Voici un exemple de modèle sur GitHub que nous avons utilisé pour les tests et les comparaisons de référence. Avec un modèle pré-entraîné, on peut souhaiter l'ajuster en fonction de ses besoins et de ses données. Nous avons utilisé une suite d'outils de TensorFlow de Google pour tester les techniques d'ajustement et d'apprentissage par transfert.

Pour qu'un modèle puisse fonctionner sur le NCS, il doit être converti au format approprié. Intel utilise OpenVINO pour le développement sur le NCS. Il s'agit d'une boîte à outils très complète qui permet d'exécuter des modèles dans des environnements hétérogènes (par exemple, CPU, GPU, VPU), de les convertir à partir de nombreuses architectures sources telles que TensorFlow, ONYX, PyTorch, etc., et d'optimiser les modèles de diverses manières.

Pour convertir un modèle, celui-ci doit d'abord être dans un état de graphe figé. Cela signifie que seules les parties du réseau neuronal nécessaires à l'inférence sont conservées, tandis que tout le reste est supprimé ; il faut également s'assurer que tous les poids du graphe sont finalisés. Plusieurs données accompagnent les graphes d'exécution des réseaux neuronaux et sont liées à leur apprentissage ; elles ne sont pas nécessaires à l'inférence et peuvent même causer des problèmes lors de la conversion. Pour amener notre modèle de détection de mains à un état de graphe gelé, nous utilisons le script suivant :

python3 /content/models/research/object_detection/export_inference_graph.py \
 --input_type=image_tensor \ 
 --pipeline_config_path=/chemin/vers/pipeline.config \
 --output_directory=/chemin/vers/répertoire_de_sortie \
 --trained_checkpoint_prefix=/chemin/vers/model.ckpt-xyz # Remplacez xyz par la valeur de l'étape du point de contrôle.

Figure 1. Script d'exportation du graphe d'inférence pour les modèles entraînés avec l'API de détection d'objets de TensorFlow

Pour la conversion, nous utilisons le DL (Deep Learning) Workbench d'OpenVINO. Il s'installe facilement sur tous les principaux systèmes d'exploitation et fonctionne soit comme une application graphique autonome (GUI), soit via la ligne de commande. Nous nous concentrons ici sur l'utilisation de l'interface graphique pour visualiser nos opérations. OpenVINO propose un excellent guide de « mise en route » pour le DL Workbench. Dans le DL Workbench, nous chargeons le modèle et spécifions les formes des tenseurs d'entrée et de sortie.

Optimisation du Neural Compute Stick pour l'inférence de modèles de vision en périphérie
Optimisation du Neural Compute Stick pour l'inférence de modèles de vision en périphérie

Figure 2. Configuration du modèle dans Intel Learning Workbench

L'environnement de travail propose également des outils très utiles pour évaluer l'exécution et les performances du modèle, ainsi que des tests permettant de vérifier que le modèle est compatible avec le NCS en ce qui concerne les couches de réseaux neuronaux mises en œuvre.

Optimisation du Neural Compute Stick pour l'inférence de modèles de vision en périphérie

Figure 3. Évaluation comparative du modèle sur des données de test (non annotées) à l'aide d'un processeur Intel

Enfin, l'environnement de travail permet de convertir très facilement le modèle au format requis par le NCS :

Optimisation du Neural Compute Stick pour l'inférence de modèles de vision en périphérie

Figure 4. Téléchargement du modèle OpenVINO converti

Optimisation du modèle pour une inférence rapide

Pour commencer, nous avons utilisé le code d'exemple fourni par OpenVINO pour la détection d'objets. Celui-ci utilise une API synchrone simple qui envoie une requête d’inférence (IR) au NCS et attend (bloque le thread) qu’elle aboutisse, en partant du principe que l’exécution du modèle prend simplement un certain temps. Cela nous a donné notre résultat initial décevant d’environ 14 images par seconde. En analysant les chiffres, nous avons constaté que ce résultat était bien en deçà des capacités du NCS.

Nous avons émis l'hypothèse que le modèle était trop volumineux, ce qui expliquerait ses mauvaises performances. Nous avons donc d'abord essayé de réduire la taille de l'image d'entrée fournie au modèle. L'hypothèse avancée était que les grandes couches convolutives initiales, appliquées à des images d'entrée de grande taille avant le pooling, représentaient une part importante de la charge de calcul. Nous avons modifié la taille de l'entrée pour la ramener à 64x64 et 128x128, contre 224x224 à l'origine. Mais cela a également entraîné une baisse considérable de la précision, ce que nous ne pouvons pas accepter.

FPS vs. Graphique de modèle

Figure 5. Diagramme à barres illustrant le FPS en fonction de la taille d'entrée du modèle. Tous les modèles sont des modèles SSDLite basés sur Mobilenetv2. Pour Mobilenetv2 xy-abc, xy = multiplicateur de profondeur, abc = taille d'entrée.

Nous avons également testé différentes architectures de réseaux de base et de détecteurs, telles que MobileNet V3 et EfficientDet, disponibles dans la bibliothèque de modèles OpenVINO. Nous avons toutefois conclu que le compromis entre vitesse et précision lors de l'inférence sur NCS n'était pas satisfaisant pour notre cas d'utilisation.

FPS vs. Graphique de modèle

Figure 6. Structure et architecture du modèle en fonction du nombre d'images par seconde (FPS). Toutes les structures Mobilenet utilisent SSDLite comme détecteurs de boîtes.

Déconcertés par ces résultats, nous avons essayé d'alléger le modèle. L'allègement consiste à supprimer les parties du modèle qui ne contribuent pas beaucoup à ses performances, en privilégiant la précision au détriment de la vitesse. Nous avons essayé l'élagage intelligent de modèles proposé par TensorFlow, qui repose sur la recherche de « couches légères ». Actuellement, TensorFlow ne prend en charge l'élagage de modèles que pour les modèles séquentiels basés sur Keras et ne prend pas en charge les modèles entraînés à l'aide de l'API de détection d'objets de TensorFlow. Cela a encore compliqué nos efforts pour créer un modèle allégé et élagué.

La quantification constitue un autre axe d'optimisation. Dans le cadre de la quantification, on modifie la précision numérique de certaines couches du réseau pour adopter un type plus léger et plus rapide. Cela repose sur l'hypothèse que les matériels d'exécution moins puissants, tels que les téléphones mobiles, sont plus lents à exécuter des opérations arithmétiques en virgule flottante (par exemple, virgule flottante 32 bits, FLOAT32) que des opérations sur des entiers (par exemple, entier 8 bits, INT8). Il s'agit là d'une des meilleures astuces pour l'optimisation des réseaux neuronaux. Cependant, là encore, le NCS ne prend pas en charge les opérations INT8, ce qui nous ramène à la case départ.

Exécution asynchrone

Enfin, après avoir testé de nombreuses techniques d'optimisation, nous avons constaté qu'il suffisait de ne pas attendre la fin de la requête d'inférence pour en lancer une autre en parallèle à l'aide de l'API asynchrone d'OpenVINO (comme décrit dans le guide). Nous pouvons recevoir une nouvelle requête d'inférence pendant que les autres sont encore en cours d'exécution, et la transmettre à une autre image pour détection. Étant donné que nous capturons les images en temps réel à partir de la caméra, cela introduit un léger décalage dans la sortie, mais un gain de vitesse considérable. Le diagramme suivant illustre l'avantage du flux IR asynchrone :

Optimisation du Neural Compute Stick pour l'inférence de modèles de vision en périphérie

En pratique, nous gérons un pool de 4 requêtes d'inférence simultanées. La taille de ce pool est déterminée par le dispositif d'inférence, c'est-à-dire le NCS. Un processeur (CPU) disposera d'un plus grand nombre de requêtes d'inférence (IR) que le NCS, et un processeur graphique (GPU) puissant peut en avoir encore davantage. Quoi qu'il en soit, si un modèle est volumineux et donc lent, et que le traitement de la requête prend beaucoup de temps, il est possible que nous épuisions le pool de requêtes d'inférence et que nous constations malgré tout une baisse du taux de rafraîchissement.

Évaluation et résultats de performance

Nos principaux indicateurs pour l'évaluation des performances sont le nombre d'images par seconde (FPS) et la latence. Nous souhaitons un nombre d'images par seconde plus élevé et une latence plus faible ; cependant, avec l'approche par API asynchrone, ces deux paramètres sont en contradiction. L'exécution d'un plus grand nombre d'IR simultanés implique une période de préchauffage plus longue et une latence plus élevée, mais permet d'obtenir un temps de traitement globalement plus rapide.

Pour mesurer les performances, nous disposons d'outils internes, mais nous avons également utilisé l'outil de benchmark C++ proposé par OpenVINO. Celui-ci permet d'exécuter les modèles sur le NCS et fournit des statistiques très utiles. Bien qu'il ne s'agisse pas d'une véritable simulation de l'inférence de modèles dans Tulip , cet outil nous a fourni d'excellentes données sans que nous ayons besoin d'exécuter le modèle dans notre framework.

FPS vs. Graphique de modèle

Figure 7. Performances du modèle SSDLite MobilenetV2 avec les API asynchrones et synchrones.

Conclusion

Nous avons trouvé que Intel et la boîte à outils OpenVINO répondaient parfaitement à nos besoins. Au-delà de sa fonction de plateforme hétérogène permettant d'exécuter des modèles et de fonctionner de manière fluide avec la VPU NCS, elle offre également une prise en charge très complète pour la conversion et les tests de performance, ainsi que des outils utiles pour l'optimisation. Nous avons essayé de nombreuses solutions avant de découvrir l’option d’inférence asynchrone, et nous avons beaucoup appris au cours de ce processus. C’est ainsi que nous offrons à nos clients des performances de premier ordre grâce à Tulip , à un coût très faible. L’API asynchrone d’OpenVINO a permis d’obtenir la meilleure amélioration de performances par rapport à de nombreuses autres approches traditionnelles en matière d’optimisation de l’inférence de modèles, mais ces dernières pourraient encore s’avérer utiles à mesure que nous déployons davantage de modèles profonds dans la production Vision.