Introduction

Tulip Vision est une solution sans code Vision par ordinateur pour lesopérations en atelier. Elle permet de créer Tulip Apps qui utilise Vision par ordinateur pour piloter et surveiller les opérations. Tulip La vision peut être utilisée pour détecter l'activité sur le poste de travail, suivre les objets et les personnes. Les signaux de vision peuvent être utilisés pour contrôler la sécurité, les opérations d'assemblage manuel, le kitting et le picking, et bien d'autres applications qui augmentent la fiabilité et réduisent le nombre d'erreurs. Au centre de Vision for the shop-floor se trouvent les algorithmes 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 est souvent un modeste PC fonctionnant sous Windows. Afin d'apporter l'IA la plus récente aux ordinateurs sous-puissants des ateliers, nous utilisons la clé de calcul neuronalIntel Neural Compute Stick version 2 (NCS v2), alias Movidius Vision Processing Unit (VPU). Il s'agit d'un dispositif USB doté d'un matériel de calcul conçu pour l'exécution de réseaux neuronaux profonds, qui supprime le travail arithmétique du CPU ou du GPU de l'ordinateur. 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 trouvé que le NCS Intel était un processeur très performant pour nos besoins à Tulip Vision. Nous nous concentrons sur la détection des humains et de leurs opérations sur la ligne, il est donc important de pouvoir détecter les mains et les personnes dans un flux de caméras entrant. Les modèles de détection humaine les plus récents utilisent des réseaux neuronaux profonds et des modèles lourds, qui mettent le NCS au défi en termes de performances.

Avec l'exécution de la vanille d'un modèle de détection de la main, nous avons pu atteindre une vitesse de 14 images par seconde (FPS) pour l'inférence. Une certaine optimisation est nécessaire pour atteindre nos objectifs de détection d'opérations humaines en temps réel (familièrement considéré comme 30 FPS et plus, 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 prévoient un taux de traitement théorique de 100 GFLOP/s (Giga opérations en virgule flottante par seconde), alors qu'au départ nous n'avons pu obtenir que 20 à 25 GFLOP/s (avec un réseau de 1,5 GFLOP à 14 FPS) avec un temps de latence considérable.

Dans cet article, nous discutons des techniques d'optimisation que nous avons explorées, et de celle qui a réellement fait la différence pour nous et nous a permis de nous situer dans le domaine de l'inférence en temps réel. Intel a déjà fourni un guide utile sur l'optimisation des réseaux pour le NCSv2, que nous avons utilisé dans le cadre de notre travail.

Conversion d'un modèle en vue de son exécution sur le SOC

Pour commencer, nous avons obtenu le graphe et les poids d'un réseau de détection des mains. Nous formons nos propres modèles de détection des mains, adaptés aux performances des scènes d'atelier, mais il existe des modèles gratuits en ligne 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é, vous pouvez l'adapter à votre objectif et à vos données. Nous avons utilisé une suite d'outils de Google TensorFlow pour tester le réglage fin et les techniques d'apprentissage par transfert.

Pour qu'un modèle donné puisse fonctionner sur le SOC, il doit être converti dans le bon format. Intel Le SOC utilise OpenVINO pour développer des modèles pour le SOC. 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 convertir 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 se trouver dans un état de graphe gelé. Cela signifie que seules les parties du réseau neuronal nécessaires à l'inférence sont conservées, tandis que toutes les autres sont éliminées, et que tous les poids du graphe doivent être finalisés. Plusieurs données accompagnant les graphes d'exécution des réseaux neuronaux, liées à la formation, ne sont pas nécessaires à l'inférence et peuvent même poser des problèmes lors de la conversion. Pour amener notre modèle de détection des mains à un état de graphe gelé, nous utilisons le script suivant :

python3 /content/models/research/object_detection/export_inference_graph.py \N- --input_type=image_tensor \N- --input_type=image_tensor
 --input_type=image_tensor \N- --pipeline_config_path=/path/to/pipeline.config 
 --pipeline_config_path=/path/to/pipeline.config \N- -output_directory=pipeline_config_path=path/to/pipeline.config
 --output_directory=/path/to/output_directory \N- --pipeline_config_path=path/to/pipeline.config
 --trained_checkpoint_prefix=/path/to/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 formés avec l'API de détection d'objets de Tensorflow

Pour la conversion, nous utilisons l'atelier DL (Deep Learning) d'OpenVINO. Il est facile à installer sur tous les principaux systèmes d'exploitation et fonctionne comme une application graphique autonome (GUI), ou peut être utilisé à partir de la ligne de commande. Nous nous concentrerons ici sur l'utilisation de l'interface graphique pour la visualisation de nos opérations. OpenVINO fournit un excellent guide de démarrage pour l'atelier DL. Dans l'atelier DL, nous chargeons le modèle et spécifions les formes des tenseurs d'entrée et de sortie.

Optimisation du bâton de calcul neuronal pour l'inférence de modèles de vision en périphérie
Optimisation du bâton de calcul neuronal pour l'inférence de modèles de vision en périphérie

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

L'atelier dispose également d'outils très utiles pour évaluer l'exécution et les performances du modèle, ainsi que de tests permettant de s'assurer que le modèle est exploitable sur le SOC en termes de couches NN implémentées.

Optimisation du bâton de calcul neuronal pour l'inférence de modèles de vision en périphérie

Figure 3. Analyse comparative du modèle sur des données de test (non annotées) à l'aide de l'unité centrale Intel i7-8700T

Enfin, l'atelier permet de convertir très facilement le modèle au format requis par le SOC :

Optimisation du bâton de calcul neuronal pour l'inférence de modèles de vision en périphérie

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

Optimiser le modèle pour une inférence rapide

Pour commencer, nous avons utilisé le code d'exemple d'OpenVINO pour la détection d'objets. Il utilise une API synchrone simple qui envoie une demande d'inférence (IR) au SOC et attend (bloque le thread) qu'elle se termine, en supposant que l'exécution du modèle prend simplement un certain temps pour se terminer. Cela nous a permis d'obtenir notre point de performance initial peu satisfaisant d'environ 14 FPS. En calculant les chiffres, nous nous sommes aperçus que cette performance était très inférieure à celle dont le SOC est capable.

Nous avons supposé que le modèle était trop grand et que c'était la raison de la mauvaise performance. Nous avons donc d'abord essayé de réduire la taille de l'image d'entrée du modèle. La théorie de base était que les grandes couches convolutives initiales sur les grandes tailles d'entrée avant la mise en commun supportent une grande partie du poids de calcul. Nous avons donc modifié la forme de l'image d'entrée en la ramenant à 64x64 et 128x128, contre 224x224 à l'origine. Mais cela a également réduit la précision par une marge importante, ce que nous ne pouvons pas accepter.

Graphique FPS vs. 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 essayé différentes architectures de backbones et de détecteurs, par exemple MobileNet V3, EfficientDet, qui sont disponibles dans le cadre du zoo modèle OpenVINO. Mais nous avons conclu que le compromis vitesse/précision lors de l'inférence sur le SOC n'est pas favorable pour notre site cas d'utilisation.

Graphique FPS vs. modèle

Figure 6. Modèle de réseau fédérateur et d'architecture en fonction du taux de réussite. Tous les backbones Mobilenet utilisent SSDLite comme détecteurs de boîtes.

Stupéfaits par ces résultats, nous avons essayé d'élaguer le modèle. Lors de l'élagage, nous supprimons les parties du modèle qui ne contribuent pas beaucoup à ses performances, en sacrifiant la vitesse à la précision. Nous avons essayé l'élagage de modèle intelligent de Tensorflow, basé sur la recherche de "couches légères". Actuellement, Tensorflow ne supporte l'élagage de modèle que pour les modèles séquentiels basés sur Keras et ne supporte pas les modèles formés à l'aide de l'API de détection d'objets de Tensorflow. Cela a contrarié nos efforts pour créer un modèle élagué léger.

La quantification est un autre moyen d'optimisation. La quantification permet de modifier la précision numérique de certaines couches du réseau en un type plus léger et plus rapide. Cela suppose que le matériel d'exécution plus faible, tel que les téléphones mobiles, est plus lent à exécuter des opérations arithmétiques à virgule flottante (par exemple, virgule flottante 32 bits, FLOAT32) que des opérations entières (par exemple, entier 8 bits, INT8). Il s'agit de l'une des meilleures astuces pour l'optimisation du NN. Cependant, le SOC ne prend pas en charge les opérations INT8 et nous sommes revenus à la case départ.

Exécution asynchrone

Enfin, après de nombreux essais de techniques d'optimisation, nous avons découvert que nous pouvions simplement ne pas attendre la fin de la requête d'inférence et en exécuter une autre en parallèle en utilisant l'API asynchrone d'OpenVINO (comme décrit dans le guide). Nous pouvons obtenir une autre requête d'inférence pendant que les autres sont encore en cours d'exécution, et la transmettre à une autre image pour la détection. Puisque nous avons une capture d'image en temps réel de la caméra, cela introduit un petit décalage dans la sortie mais un très grand gain de vitesse. Le diagramme suivant illustre les avantages d'un flux IR asynchrone :

Optimisation du bâton de calcul neuronal pour l'inférence de modèles de vision en périphérie

Dans la pratique, nous utilisons un pool de 4 demandes d'inférence simultanées. La taille du pool est déterminée par le dispositif d'inférence, c'est-à-dire le SOC. Un CPU aura plus d'IRs que le NCS, et un puissant GPU peut en avoir encore beaucoup plus. Quoi qu'il en soit, si un modèle est gros et donc lent, prenant beaucoup de temps pour compléter la requête, nous pouvons épuiser le pool d'IRs et avoir encore une réduction du framerate.

Évaluation et résultats des performances

Nos principales mesures pour l'évaluation des performances sont le nombre de secondes par seconde et la latence. Nous voulons un taux de FPS plus élevé et une latence plus faible, mais avec l'approche asynchrone de l'API, ces deux éléments font l'objet d'un compromis. L'exécution d'un plus grand nombre de RI simultanées implique une période d'échauffement et une latence plus longues, mais elle permet d'obtenir un délai d'exécution globalement plus rapide.

Pour mesurer les performances, nous disposons d'outils internes, mais nous avons également utilisé l'outil de benchmarking C++ disponible auprès d'OpenVINO. Il est capable 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 d'un modèle dans Tulip Vision, il nous a fourni de très bonnes données sans qu'il soit nécessaire d'exécuter le modèle dans notre cadre.

Graphique FPS vs. modèle

Figure 7. Performances du modèle pour SSDLite MobilenetV2 en utilisant l'API asynchrone et synchrone.

Conclusion

Nous avons trouvé le site Intel NCSv2 et la boîte à outils OpenVINO très utiles pour nos besoins. En plus d'être une plateforme hétérogène pour l'exécution de modèles, fonctionnant sans problème avec le VPU NCS, il dispose également d'un support assez étendu pour la conversion et le benchmarking, ainsi que d'outils utiles pour l'optimisation. Nous avons essayé beaucoup de choses avant de trouver l'option d'inférence asynchrone, et nous avons beaucoup appris au cours du processus. C'est ainsi que nous offrons à nos clients des performances de premier ordre en utilisant Tulip Vision à un coût très bas. L'API asynchrone d'OpenVINO a permis la meilleure augmentation des performances par rapport à de nombreuses autres approches traditionnelles dans les astuces d'optimisation de l'inférence des modèles, mais celles-ci peuvent encore s'avérer utiles à mesure que nous déployons des modèles plus profonds dans la production de Vision.