Skip to main content
  • Place orders quickly and easily
  • View orders and track your shipping status
  • Enjoy members-only rewards and discounts
  • Create and access a list of your products

Techniques d’optimisation pour la formation CheXNet sur le serveur Dell C4140, avec les processeurs graphiques NVIDIA V100

Summary: Pratiques d’excellence pour obtenir des performances maximales sur la formation scale-out distribuée de CheXNet à l’aide des processeurs graphiques Nvidia V100 SXM2 dans les serveurs Dell EMC C4140. ...

This article applies to This article does not apply to This article is not tied to any specific product. Not all product versions are identified in this article.

Symptoms

L’article a été écrit par Rakshith Vasudev et John Lockman, HPC AI Innovation Lab, en octobre 2019

Cause

  -

Resolution

Comme présenté précédemment, CheXNet est un modèle d’assistant radiologiste basé sur l’IA qui utilise DenseNet pour identifier jusqu’à 14 pathologies à partir d’une image de rayons X donnée. Plusieurs approches ont été explorées pour faire évoluer la formation d’un modèle capable d’atteindre des performances aussi bonnes ou meilleures que le modèle CheXNet-121 d’origine avec ResNet-50, ce qui est prometteur sur le plan de l’évolutivité et de l’amélioration de la précision de la formation (AUROC positif). Les auteurs ont fait preuve d’évolutivité sur les systèmes dotés de processeur, mais nous sommes intéressés par l’exploitation du parallélisme des processeurs graphiques pour accélérer le processus de formation. Dans cet article, nous décrivons les pratiques d’excellence pour obtenir des performances maximales sur la formation scale-out distribuée de CheXNet à l’aide des processeurs graphiques Nvidia V100 SXM2 dans les serveurs Dell EMC C4140. Le système Dell EMC PowerEdge C4140 offre à la fois densité et performances avec quatre processeurs graphiques Nvidia V100 dans une configuration SXM2.


 

Configuration matérielle : Configuration du logiciel :
  • 4 PowerEdge C4140
  • 4 NVIDIA V100 32 Go SXM2
  • 2 processeurs 20 cœurs Intel(R) Xeon(R) Gold 6148 à 2,40 GHz
  • 384 Go de RAM, DDR4 à 2 666 MHz
  • 1 adaptateur HCA Mellanox EDR
  • Système de fichiers Lustre
  • Cadre Deep Learning : tensorflow-gpu
  • Version cadre : 1.12.0
  • Version Horovod : 0.16.4
  • Version de MPI : 4.0.0 avec prise en charge de cuda et ucx
  • Version de CUDA : 10.1.105
  • Version de CUDNN : 7.6.0
  • Version de NCCL : 2.4.7
  • Version Python : 3.6.8
  • Système d’exploitation et version : RHEL 7,4


 


Le pipeline de données est essentiel pour tirer le meilleur parti de vos accélérateurs :



 

Que sont les données tf et pourquoi devriez-vous vous efforcer de les utiliser ?

 

Comme les nouveaux appareils informatiques (tels que les processeurs graphiques et les TPU) permettent de former des réseaux neuronaux à un rythme de plus en plus rapide, le traitement du processeur est susceptible de devenir le goulot d’étranglement. L’API tf.data fournit aux utilisateurs des blocs de construction pour concevoir des pipelines d’entrée qui utilisent efficacement le processeur, optimisant chaque étape du processus ETL.

 

Pour effectuer une étape de formation, vous devez d’abord extraire et transformer les données de formation, puis les envoyer à un modèle exécuté sur un accélérateur. Toutefois, dans une implémentation synchrone naïve, l’accélérateur est inactif lorsque le processeur prépare les données. À l’inverse, lorsque l’accélérateur forme le modèle, le processeur est inactif. Le temps d’étape de formation correspond donc à la somme du temps de prétraitement du processeur et du temps de formation de l’accélérateur

 

Le pipelining englobe le prétraitement et l’exécution du modèle d’une étape de formation. Pendant que l’accélérateur effectue l’étape de formation N, le processeur prépare les données pour l’étape N+1. Cela réduit le temps d’étape au maximum (par opposition à la somme) de la formation et le temps nécessaire à l’extraction et à la transformation des données.

 

Sans pipelining, le processeur et le processeur graphique/TPU restent inactifs la plupart du temps :

SLN318898_en_US__1Sequantial execution
Fig. 1 : Avec l’exécution séquentielle, le processeur graphique est souvent inactif

 

Avec le pipelining, le temps d’inactivité diminue considérablement :

SLN318898_en_US__2Pipelining overlaps
Fig. 2 : Le pipelining englobe l’utilisation du processeur et du processeur graphique, optimisant ainsi l’utilisation du processeur graphique

 

L’API tf.data fournit un mécanisme de pipelining logiciel via la transformation tf.data.Dataset.prefetch, qui peut être utilisée pour dissocier l’heure à laquelle les données sont produites à partir du moment où elles sont consommées. Plus précisément, la transformation utilise un thread d’arrière-plan et une mémoire tampon interne pour prérécupérer des éléments du jeu de données d’entrée à l’avance, au moment où ils sont demandés.

 

Plus d’informations ici : https://www.tensorflow.org/guide/performance/datasets

 

En suivant les instructions fournies par tensorflow, il est possible d’obtenir un pipeline de données qui ressemble à ceci (ancienne approche) :
https://github.com/dellemc-hpc-ai/code-examples/blob/master/cheXNet-snippets/old_approach.py

 

Dans cette approche également appelée « ancienne approche », le pipeline de données tf effectue les opérations suivantes (en supposant que le jeu de données du rayon x est une séquence de TFRecords) :

 

  1. Obtient la liste absolue des noms de fichier.
  2. Crée un jeu de données à partir de la liste des noms de fichiers à l’aide de TFRecordDataset()
  3. Crée un nouveau jeu de données qui charge et formate des images en les prétraitant.
  4. Fragmente le jeu de données.
  5. Lit de manière aléatoire le jeu de données lors de la formation.
  6. Répète le jeu de données.
  7. Traite par lots le jeu de données.
  8. Prérécupère le jeu de données pour batch_size.


 

Toutefois, il ne s’agit pas du code le plus performant. Il provoque des blocages et de fréquentes utilisations à 0 % du processeur graphique. En fait, il n’utilise pas efficacement les accélérateurs.

Pour configurer correctement le pipeline de données tf, nous suivons l’approche adoptée par les modèles officiels tensorflow, en particulier, celui de ResNet.  La différence entre les ancienne et nouvelle approches est la façon dont le pipeline de données est configuré avant de l’alimenter vers le modèle.

 

Voici à quoi ressemble la nouvelle approche :
https://github.com/dellemc-hpc-ai/code-examples/blob/master/cheXNet-snippets/new_approach.py

 

L’approche officielle des modèles TensorFlow, également appelée nouvelle approche, est la suivante :

 

  1. Obtient la liste absolue des noms de fichier.
  2. Crée un jeu de données à partir de la liste des noms de fichiers à l’aide de from_tensor_slices()
  3. La fragmentation est effectuée à l’avance.
  4. Le jeu de données est lu de manière aléatoire pendant la formation.
  5. Le jeu de données est ensuite entrelacé en parallèle, ce qui permet d’entrelacer et de traiter plusieurs fichiers (définis par cycle_length) afin de les transformer pour créer un jeu de données TFRecord.
  6. Le jeu de données est ensuite prérécupéré. Buffer_size définit le nombre d’enregistrements qui sont prérécupérés, qui est généralement le mini batch_size de la tâche.
  7. Le jeu de données est à nouveau lu de manière aléatoire. Les détails de la lecture aléatoire sont contrôlés par buffer_size.
  8. Le jeu de données est répété.  Il répète le jeu de données jusqu’à ce que num_epochs soit formé.
  9. Le jeu de données est soumis à des map_and_batch() simultanés qui analysent les fichiers d’enregistrement tf, ce qui, à son tour, prétraite l’image et les regroupe.
  10. L’image prétraitée est prête en tant que jeu de données et est à nouveau prérécupérée.


 

Voici une comparaison des performances des anciennes et nouvelles approches, à l’aide des modèles officiels de TF.

SLN318898_en_US__3image(12053)
Fig. 3 : Avec la nouvelle approche, on peut s’attendre à une mise à l’échelle quasi linéaire.

 

Comme on peut le voir, il y a un impact significatif sur les performances et il n’y a pas de mise à l’échelle avec l’ancienne approche. Les processeurs graphiques n’ont souvent que peu d’utilisation, voire aucune utilisation, ce qui entraîne une stagnation des performances. Rendre le calcul plus efficace sur un processeur graphique se traduit par un calcul plus efficace sur plusieurs processeurs graphiques sur plusieurs nœuds, si la communication est bien gérée.
Le fait que les CPU effectuent le prétraitement en parallèle, que les données traitées soient prérécupérées en mémoire et que les processeurs graphiques se chargent de la multiplication des matrices avec une communication rapide est un autre aspect qui rend cette nouvelle approche plus intéressante pour plusieurs nœuds.


 


Autres techniques à étudier pour obtenir des performances optimales :



 

Il est important de disposer de l’environnement approprié :

 

L’environnement qui exécute vos tâches est aussi important que vos tâches. Il est en effet essentiel d’avoir les bons modules/bibliothèques car ils auront un impact sur les performances de la formation. En outre, le fait de disposer des dernières bibliothèques associées à CUDA peut vous aider à améliorer les performances.

Suivez ce didacticiel pour l’installation, si vous n’avez pas de configuration d’environnement de travail.



 

Utilisation des paramètres de liaison corrects pour MPI :

 

MPI est une bibliothèque de communication qui aide horovod à distribuer les tâches. Différentes options de paramètres de liaison et de mappage ont été explorées et les meilleurs paramètres pour le C4140 étaient le mappage par socket. Le paramètre recommandé est le suivant :
mpirun --map-by socket -np x python pyfile.py --pyoptions



 

Assurez-vous qu’un seul processus agit sur un processeur graphique :

 

Si plusieurs processus travaillent sur un processeur graphique, ils risquent de devoir lutter pour les ressources de ce processeur graphique, de consommer sa mémoire et de ne pas pouvoir adapter plus d’images par lot, ce qui entraîne une baisse des performances du processeur graphique. Tensorflow 1.13.1 a été exploré, mais il semblait qu’il avait un bug à l’époque. Il lançait plusieurs processus par processeur graphique.


 

En résumé :

  • Il est essentiel de configurer correctement le pipeline de données pour obtenir des gains de performances.
  • La configuration de l’environnement approprié contribue à l’amélioration des performances.
  • L’utilisation de paramètres de liaison corrects pour MPI permet d’améliorer les performances.
  • Profilez et corrigez les goulots d’étranglement lorsque les processeurs graphiques ne sont pas entièrement utilisés.


 


Affected Products

High Performance Computing Solution Resources, Poweredge C4140
Article Properties
Article Number: 000124384
Article Type: Solution
Last Modified: 17 Sep 2021
Version:  5
Find answers to your questions from other Dell users
Support Services
Check if your device is covered by Support Services.