Horovod : Framework d'apprentissage profond distribué
Introduction
Horovod est un framework open source d'entraînement distribué pour l'apprentissage profond, développé par Uber. Son objectif est de rendre l'entraînement distribué de l'apprentissage profond plus simple, plus rapide et plus facile à utiliser. Horovod prend en charge les frameworks d'apprentissage profond populaires tels que TensorFlow, Keras, PyTorch et Apache MXNet.
Caractéristiques principales
- Facilité d'utilisation : Horovod fournit une API simple qui permet de convertir facilement le code d'entraînement sur une seule machine en code d'entraînement distribué.
- Haute performance : Horovod utilise des mécanismes de communication efficaces (par exemple, MPI et NCCL) pour obtenir un entraînement distribué rapide.
- Extensibilité : Horovod peut s'étendre à des centaines de nœuds GPU ou CPU pour traiter des modèles et des ensembles de données d'apprentissage profond à grande échelle.
- Flexibilité : Horovod prend en charge plusieurs frameworks d'apprentissage profond et peut être intégré à diverses plateformes matérielles.
- Open source : Horovod est un projet open source avec un support communautaire actif.
Principaux avantages
- Vitesse d'entraînement plus rapide : En entraînant des modèles en parallèle sur plusieurs nœuds GPU ou CPU, Horovod peut réduire considérablement le temps d'entraînement.
- Capacité de modèle plus importante : Horovod permet d'entraîner des modèles plus grands que dans un environnement à machine unique, car le modèle peut être distribué dans la mémoire de plusieurs nœuds.
- Débit de données plus élevé : Horovod peut traiter des ensembles de données plus volumineux, car il peut charger et traiter les données en parallèle sur plusieurs nœuds.
- Meilleure utilisation des ressources : Horovod peut utiliser plus efficacement les ressources de calcul, car il peut répartir la charge de travail sur plusieurs nœuds.
Frameworks pris en charge
Horovod prend principalement en charge les frameworks d'apprentissage profond suivants :
- TensorFlow : Framework d'apprentissage profond populaire développé par Google.
- Keras : Une API de réseau neuronal de haut niveau qui peut fonctionner sur TensorFlow, Theano et CNTK.
- PyTorch : Un autre framework d'apprentissage profond populaire développé par Facebook.
- Apache MXNet : Framework d'apprentissage profond flexible et efficace développé par la Fondation Apache.
Mécanismes de communication
Horovod prend en charge les mécanismes de communication suivants :
- MPI (Message Passing Interface) : Un protocole standard pour la communication entre plusieurs nœuds. Horovod utilise MPI pour coordonner le processus d'entraînement distribué.
- NCCL (NVIDIA Collective Communications Library) : Une bibliothèque développée par NVIDIA pour la communication haute performance entre les GPU. Horovod utilise NCCL pour accélérer l'entraînement distribué sur les GPU.
- gloo : Bibliothèque de communication collective développée par Facebook, prenant en charge diverses plateformes matérielles.
- TCP/IP : Horovod peut également utiliser TCP/IP pour la communication, mais les performances sont généralement inférieures à celles de MPI ou NCCL.
Installation
Le processus d'installation de Horovod dépend du framework d'apprentissage profond et du mécanisme de communication que vous utilisez. Généralement, vous devez d'abord installer MPI ou NCCL, puis installer Horovod à l'aide de pip.
Par exemple, pour installer Horovod à l'aide de pip et prendre en charge TensorFlow et NCCL, vous pouvez exécuter la commande suivante :
pip install horovod[tensorflow,gpu]
Veuillez consulter la documentation officielle de Horovod pour obtenir des instructions d'installation plus détaillées : https://github.com/horovod/horovod
Utilisation
L'utilisation de Horovod pour l'entraînement distribué implique généralement les étapes suivantes :
- Initialiser Horovod : Au début du script d'entraînement, appelez
horovod.init()
pour initialiser Horovod.
- Fixer le GPU (facultatif) : Pour améliorer les performances, vous pouvez fixer chaque processus à un GPU spécifique.
- Mettre à l'échelle le taux d'apprentissage : Étant donné que plusieurs nœuds sont utilisés pour l'entraînement, vous devez ajuster le taux d'apprentissage en fonction du nombre de nœuds.
- Utiliser
DistributedOptimizer
: Utilisez le DistributedOptimizer
fourni par Horovod pour encapsuler l'optimiseur d'origine.
- Diffuser l'état initial : Diffusez l'état initial du modèle du rang 0 à tous les autres rangs.
- Enregistrer les points de contrôle (uniquement sur le rang 0) : Pour éviter les enregistrements en double, il est généralement préférable d'enregistrer les points de contrôle du modèle uniquement sur le rang 0.
Voici un exemple simple d'utilisation de Horovod pour l'entraînement distribué TensorFlow :
import tensorflow as tf
import horovod.tensorflow as hvd
# 1. Initialiser Horovod
hvd.init()
# 2. Fixer le GPU
gpus = tf.config.experimental.list_physical_devices('GPU')
for gpu in gpus:
tf.config.experimental.set_memory_growth(gpu, True)
if gpus:
tf.config.experimental.set_visible_devices(gpus[hvd.local_rank()], 'GPU')
# 3. Charger l'ensemble de données
(mnist_images, mnist_labels), _ = tf.keras.datasets.mnist.load_data()
dataset = tf.data.Dataset.from_tensor_slices(
(tf.cast(mnist_images[..., None] / 255.0, tf.float32),
tf.cast(mnist_labels, tf.int64)))
dataset = dataset.repeat().shuffle(10000).batch(128)
# 4. Construire le modèle
model = tf.keras.models.Sequential([
tf.keras.layers.Conv2D(32, [3, 3], activation='relu'),
tf.keras.layers.Conv2D(64, [3, 3], activation='relu'),
tf.keras.layers.MaxPooling2D(pool_size=(2, 2)),
tf.keras.layers.Dropout(0.25),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dropout(0.5),
tf.keras.layers.Dense(10, activation='softmax')
])
# 5. Définir l'optimiseur
opt = tf.keras.optimizers.Adam(0.001 * hvd.size()) # Mettre à l'échelle le taux d'apprentissage
# 6. Utiliser DistributedOptimizer
opt = hvd.DistributedOptimizer(opt)
# 7. Définir la fonction de perte et les métriques
loss_fn = tf.keras.losses.SparseCategoricalCrossentropy()
metric = tf.keras.metrics.SparseCategoricalAccuracy()
# 8. Définir l'étape d'entraînement
@tf.function
def train_step(images, labels):
with tf.GradientTape() as tape:
probs = model(images, training=True)
loss = loss_fn(labels, probs)
tape = hvd.DistributedGradientTape(tape)
gradients = tape.gradient(loss, model.trainable_variables)
opt.apply_gradients(zip(gradients, model.trainable_variables))
metric.update_state(labels, probs)
return loss
# 9. Diffuser les variables initiales
@tf.function
def initialize_vars():
if hvd.rank() == 0:
model(tf.zeros((1, 28, 28, 1)))
hvd.broadcast_variables(model.variables, root_rank=0)
hvd.broadcast_variables(opt.variables(), root_rank=0)
initialize_vars()
# 10. Boucle d'entraînement
for batch, (images, labels) in enumerate(dataset.take(10000 // hvd.size())):
loss = train_step(images, labels)
if batch % 10 == 0 and hvd.rank() == 0:
print('batch: %d, loss: %.4f, accuracy: %.2f' % (batch, loss, metric.result()))
Bonnes pratiques
- Choisir le mécanisme de communication approprié : Choisissez le mécanisme de communication approprié (MPI, NCCL, Gloo) en fonction de votre plateforme matérielle et de votre environnement réseau.
- Ajuster le taux d'apprentissage : Ajustez le taux d'apprentissage en fonction du nombre de nœuds pour obtenir les meilleurs résultats d'entraînement.
- Surveiller le processus d'entraînement : Utilisez TensorBoard ou d'autres outils pour surveiller le processus d'entraînement afin de détecter et de résoudre les problèmes.
- Utiliser le parallélisme des données : Horovod est principalement utilisé pour le parallélisme des données, qui consiste à diviser l'ensemble de données en plusieurs parties et à entraîner des copies du modèle sur différents nœuds.
- Éviter le déséquilibre des données : Assurez-vous que l'ensemble de données est réparti uniformément entre les nœuds afin d'éviter que le déséquilibre des données ne réduise l'efficacité de l'entraînement.
Conclusion
Horovod est un framework d'apprentissage profond distribué puissant qui peut vous aider à entraîner plus facilement et plus rapidement des modèles d'apprentissage profond à grande échelle. En utilisant plusieurs nœuds GPU ou CPU, Horovod peut réduire considérablement le temps d'entraînement et améliorer la précision du modèle.
Ressources
Toutes les informations détaillées sont disponibles sur le site officiel (https://github.com/horovod/horovod)