La traduction de l'article a été préparée à la veille du début du cours
La formation distribuée sur plusieurs instances de calcul haute performance peut réduire le temps de formation des réseaux neuronaux profonds modernes sur de grandes quantités de données de plusieurs semaines à quelques heures, voire quelques minutes, ce qui rend cette technique de formation répandue dans les applications pratiques de l'apprentissage profond. Les utilisateurs doivent comprendre comment partager et synchroniser les données sur plusieurs instances, ce qui a un impact majeur sur l'efficacité de la mise à l'échelle. En outre, les utilisateurs doivent également savoir comment déployer un script de formation qui s'exécute sur une seule instance vers plusieurs instances.
Dans cet article, nous parlerons d'un moyen rapide et simple de distribuer l'apprentissage à l'aide de la bibliothèque ouverte d'apprentissage en profondeur Apache MXNet et du cadre d'apprentissage distribué Horovod. Nous démontrerons clairement les avantages en termes de performances du framework Horovod et montrerons comment écrire un script de formation MXNet afin qu'il fonctionne de manière distribuée avec Horovod.
Qu'est-ce qu'Apache MXNet
Formation distribuée en MXNet avec serveur de paramètres
Qu'est-ce que Horovod
Intégration MXNet et Horovod
MXNet s'intègre à Horovod via les API d'apprentissage distribué définies dans Horovod. API de communication Horovod horovod.broadcast(), horovod.allgather() и horovod.allreduce() implémenté à l'aide de rappels asynchrones du moteur MXNet, dans le cadre de son graphe de tâches. De cette manière, les dépendances de données entre la communication et le calcul sont facilement gérées par le moteur MXNet pour éviter les pertes de performances dues à la synchronisation. Objet optimiseur distribué défini dans Horovod horovod.DistributedOptimizer se développe Optimizer dans MXNet afin qu'il appelle les API Horovod correspondantes pour les mises à jour distribuées des paramètres. Tous ces détails de mise en œuvre sont transparents pour les utilisateurs finaux.
Départ rapide
Vous pouvez rapidement commencer à former un petit réseau neuronal convolutionnel sur l'ensemble de données MNIST à l'aide de MXNet et Horovod sur votre MacBook.
Tout d’abord, installez mxnet et horovod depuis PyPI :
pip install mxnet
pip install horovod
Remarque : Si vous rencontrez une erreur lors pip installer horovodpeut-être que tu dois ajouter une variable MACOSX_DEPLOYMENT_TARGET=10.vvOù vv – c’est la version de votre version MacOS, par exemple, pour MacOSX Sierra vous devrez écrire MACOSX_DEPLOYMENT_TARGET=10.12 pip installation horovod
Ensuite installez OpenMPI
A la fin, téléchargez le script de test mxnet_mnist.py
mpirun -np 2 -H localhost:2 -bind-to none -map-by slot python mxnet_mnist.py
Cela exécutera une formation sur deux cœurs de votre processeur. Le résultat sera le suivant :
INFO:root:Epoch[0] Batch [0-50] Speed: 2248.71 samples/sec accuracy=0.583640
INFO:root:Epoch[0] Batch [50-100] Speed: 2273.89 samples/sec accuracy=0.882812
INFO:root:Epoch[0] Batch [50-100] Speed: 2273.39 samples/sec accuracy=0.870000
Démo de performances
Lors de la formation d'un modèle ResNet50-v1 sur un ensemble de données ImageNet sur 64 GPU avec huit instances p3.16xlarge EC2, contenant chacun 8 GPU NVIDIA Tesla V100 sur le cloud AWS, nous avons atteint un débit d'entraînement de 45000 44 images/s (c'est-à-dire le nombre d'échantillons entraînés par seconde). Formation terminée en 90 minutes après 75.7 époques avec une meilleure précision de XNUMX %.
Nous avons comparé cela à l'approche de formation distribuée de MXNet consistant à utiliser des serveurs de paramètres sur 8, 16, 32 et 64 GPU avec un seul serveur de paramètres et un ratio serveur/travailleur de 1 pour 1 et 2 pour 1, respectivement. Vous pouvez voir le résultat dans la figure 1 ci-dessous. Sur l'axe des y à gauche, les barres représentent le nombre d'images à entraîner par seconde, les lignes reflètent l'efficacité de mise à l'échelle (c'est-à-dire le rapport entre le débit réel et le débit idéal) sur l'axe des y à droite. Comme vous pouvez le constater, le choix du nombre de serveurs affecte l’efficacité de la mise à l’échelle. S'il n'y a qu'un seul serveur de paramètres, l'efficacité de mise à l'échelle tombe à 38 % sur 64 GPU. Pour obtenir la même efficacité de mise à l'échelle qu'avec Horovod, vous devez doubler le nombre de serveurs par rapport au nombre de travailleurs.
Figure 1. Comparaison de l'apprentissage distribué utilisant MXNet avec Horovod et avec le serveur de paramètres
Dans le tableau 1 ci-dessous, nous comparons le coût final par instance lors de l'exécution d'expériences sur 64 GPU. L'utilisation de MXNet avec Horovod offre le meilleur débit au moindre coût.
Tableau 1. Comparaison des coûts entre Horovod et Parameter Server avec un ratio serveur/travailleur de 2 pour 1.
Étapes pour reproduire
Dans les prochaines étapes, nous vous montrerons comment reproduire le résultat d'une formation distribuée à l'aide de MXNet et Horovod. Pour en savoir plus sur l'apprentissage distribué avec MXNet, lisez
Étape 1
Créez un cluster d'instances homogènes avec MXNet version 1.4.0 ou supérieure et Horovod version 0.16.0 ou supérieure pour utiliser l'apprentissage distribué. Vous devrez également installer des bibliothèques pour la formation GPU. Pour nos instances, nous avons choisi Ubuntu 16.04 Linux, avec le pilote GPU 396.44, CUDA 9.2, la bibliothèque cuDNN 7.2.1, le communicateur NCCL 2.2.13 et OpenMPI 3.1.1. Vous pouvez également utiliser
Étape 2
Ajoutez la possibilité de travailler avec l'API Horovod à votre script de formation MXNet. Le script ci-dessous basé sur l'API MXNet Gluon peut être utilisé comme modèle simple. Les lignes en gras sont nécessaires si vous disposez déjà d’un script de formation correspondant. Voici quelques changements essentiels que vous devez apporter pour apprendre avec Horovod :
- Définissez le contexte en fonction du rang Horovod local (ligne 8) pour comprendre que la formation est effectuée sur le bon noyau graphique.
- Transmettez les paramètres initiaux d’un travailleur à tous (ligne 18) pour garantir que tous les travailleurs démarrent avec les mêmes paramètres initiaux.
- Créer un Horovod Optimiseur distribué (ligne 25) pour mettre à jour les paramètres de manière distribuée.
Pour obtenir le script complet, veuillez vous référer aux exemples Horovod-MXNet
1 import mxnet as mx
2 import horovod.mxnet as hvd
3
4 # Horovod: initialize Horovod
5 hvd.init()
6
7 # Horovod: pin a GPU to be used to local rank
8 context = mx.gpu(hvd.local_rank())
9
10 # Build model
11 model = ...
12
13 # Initialize parameters
14 model.initialize(initializer, ctx=context)
15 params = model.collect_params()
16
17 # Horovod: broadcast parameters
18 hvd.broadcast_parameters(params, root_rank=0)
19
20 # Create optimizer
21 optimizer_params = ...
22 opt = mx.optimizer.create('sgd', **optimizer_params)
23
24 # Horovod: wrap optimizer with DistributedOptimizer
25 opt = hvd.DistributedOptimizer(opt)
26
27 # Create trainer and loss function
28 trainer = mx.gluon.Trainer(params, opt, kvstore=None)
29 loss_fn = ...
30
31 # Train model
32 for epoch in range(num_epoch):
33 ...
Étape 3
Connectez-vous à l'un des travailleurs pour démarrer une formation distribuée à l'aide de la directive MPI. Dans cet exemple, la formation distribuée s'exécute sur quatre instances avec 4 GPU chacune et un total de 16 GPU dans le cluster. L'optimiseur de descente de gradient stochastique (SGD) sera utilisé avec les hyperparamètres suivants :
- taille du mini-lot : 256
- taux d'apprentissage : 0.1
- élan : 0.9
- perte de poids : 0.0001
Au fur et à mesure que nous sommes passés d'un GPU à 64 GPU, nous avons augmenté linéairement le taux de formation en fonction du nombre de GPU (de 0,1 pour 1 GPU à 6,4 pour 64 GPU), tout en gardant le nombre d'images par GPU à 256 (à partir d'un lot de 256 images pour 1 GPU à 16 384 pour 64 GPU). Les paramètres de perte de poids et d’élan ont changé à mesure que le nombre de GPU augmentait. Nous avons utilisé un entraînement de précision mixte avec le type de données float16 pour la passe avant et float32 pour les gradients afin d'accélérer les calculs float16 pris en charge par les GPU NVIDIA Tesla.
$ mpirun -np 16
-H server1:4,server2:4,server3:4,server4:4
-bind-to none -map-by slot
-mca pml ob1 -mca btl ^openib
python mxnet_imagenet_resnet50.py
Conclusion
Dans cet article, nous avons examiné une approche évolutive de la formation de modèles distribués à l'aide d'Apache MXNet et Horovod. Nous avons démontré l'efficacité de la mise à l'échelle et la rentabilité par rapport à l'approche du serveur de paramètres sur l'ensemble de données ImageNet sur lequel le modèle ResNet50-v1 a été formé. Nous avons également inclus des étapes que vous pouvez utiliser pour modifier un script existant afin d'exécuter une formation multi-instance à l'aide d'Horovod.
Si vous débutez avec MXNet et le deep learning, accédez à la page d'installation
Si vous avez déjà travaillé avec MXNet et souhaitez essayer l'apprentissage distribué avec Horovod, jetez un œil à
*le coût est calculé en fonction
En savoir plus sur le cours
Source: habr.com