Guide de l’entraînement avec des GPU distribués (SDK v2)
S’APPLIQUE À : Kit de développement logiciel (SDK) Python azure-ai-mlv2 (préversion)
Apprenez-en plus sur l’utilisation du code d’entraînement GPU distribué dans Azure Machine Learning. Cet article vous aide à exécuter votre code d’entraînement distribué existant et propose des conseils et des exemples à suivre pour chaque infrastructure :
- Interface de passage de messages (MPI)
- Horovod
- Variables d’environnement à partir d’Open MPI
- PyTorch
- TensorFlow
- Entraînement de GPU accéléré avec InfiniBand
Prérequis
Passez en revue les concepts de base de l’entraînement de GPU distribué, comme le parallélisme des données, le parallélisme des données distribuées et le parallélisme des modèles.
Conseil
Si vous ne connaissez pas le type de parallélisme à utiliser, plus de 90 % du temps, vous devez utiliser le parallélisme des données distribuées.
MPI
Azure Machine Learning fournit un travail MPI qui permet de lancer un nombre donné de processus dans chaque nœud. Azure Machine Learning construit la commande de lancement MPI complète (mpirun
) en arrière-plan. Vous ne pouvez pas fournir vos propres commandes de lanceur de nœud principal complètes, telles que mpirun
ou DeepSpeed launcher
.
Conseil
Une bibliothèque MPI doit être installée sur l’image Docker de base utilisée par un travail MPI Azure Machine Learning. Open MPI est inclus dans toutes les images de base de GPU Azure Machine Learning. Quand vous utilisez une image Docker personnalisée, vous devez vous assurer que l’image comprend une bibliothèque MPI. Open MPI est recommandé, mais vous pouvez également utiliser une autre implémentation MPI telle qu’Intel MPI. Azure Machine Learning fournit également des environnements organisés pour les frameworks populaires.
Pour exécuter un entraînement distribué avec MPI, procédez comme suit :
- Utilisez un environnement Azure Machine Learning avec le framework de Deep Learning par défaut et MPI. Azure Machine Learning fournit également des environnements organisés pour les infrastructures populaires. Ou créez un environnement personnalisé avec l’infrastructure de Deep Learning préférée et la MPI.
- Définissez une
command
avecinstance_count
.instance_count
doit être égal au nombre de GPU par nœud pour le lancement par processus, ou défini sur 1 (valeur par défaut) pour le lancement par nœud si le script utilisateur est chargé de lancer les processus par nœud. - Utilisez le paramètre
distribution
decommand
pour spécifier des paramètres pourMpiDistribution
.
from azure.ai.ml import command, MpiDistribution
job = command(
code="./src", # local path where the code is stored
command="python train.py --epochs ${{inputs.epochs}}",
inputs={"epochs": 1},
environment="AzureML-tensorflow-2.12-cuda11@latest",
compute="gpu-cluster",
instance_count=2,
distribution=MpiDistribution(process_count_per_instance=2),
display_name="tensorflow-mnist-distributed-horovod-example"
# experiment_name: tensorflow-mnist-distributed-horovod-example
# description: Train a basic neural network with TensorFlow on the MNIST dataset, distributed via Horovod.
)
Horovod
Utilisez la configuration du travail MPI quand vous utilisez Horovod pour un entraînement distribué avec le framework de Deep Learning.
Assurez-vous que votre code suit ces conseils :
- Le code d’entraînement est correctement instrumenté avec Horovod avant l’ajout des parties Azure Machine Learning.
- Votre environnement Azure Machine Learning contient Horovod et MPI. Les environnements de GPU organisés PyTorch et TensorFlow sont préconfigurés avec Horovod et ses dépendances.
- Créez une
command
avec la distribution souhaitée.
Exemple Horovod
- Pour que le notebook complet exécute l’exemple d’Horovod, consultez azureml-examples : Entraîner un réseau neuronal de base avec MPI distribué sur le jeu de données MNIST en utilisant Horovod.
Variables d’environnement à partir d’Open MPI
Lors de l’exécution des tâches MPI avec des images Open MPI, vous pouvez utiliser les variables d’environnement suivantes pour chaque processus lancé :
OMPI_COMM_WORLD_RANK
: rang du processusOMPI_COMM_WORLD_SIZE
: nombre total de processus (WORLD_SIZE)AZ_BATCH_MASTER_NODE
: adresse principale avec port,MASTER_ADDR:MASTER_PORT
OMPI_COMM_WORLD_LOCAL_RANK
: rang local du processus sur le nœudOMPI_COMM_WORLD_LOCAL_SIZE
: nombre de processus sur le nœud
Conseil
Malgré son nom, la variable d’environnement OMPI_COMM_WORLD_NODE_RANK
ne correspond pas à NODE_RANK
. Pour utiliser le lanceur par nœud, définissez process_count_per_node=1
et utilisez OMPI_COMM_WORLD_RANK
comme NODE_RANK
.
PyTorch
Azure Machine Learning prend en charge l’exécution de travaux distribués avec des fonctionnalités d’entraînement distribué natives de PyTorch (torch.distributed
).
Conseil
Pour le parallélisme des données, l’aide officielle de PyTorch stipule d’utiliser DistributedDataParallel (DDP) plutôt que DataParallel pour l’entraînement distribué mononœud et multinœud. De plus, PyTorch recommande d’utiliser DistributedDataParallel plutôt que le package de multitraitement. La documentation et les exemples Azure Machine Learning se concentrent donc sur l’entraînement DistributedDataParallel.
Initialisation du groupe de processus
L’épine dorsale d’un entraînement distribué repose sur un groupe de processus qui se connaissent entre eux et peuvent communiquer entre eux avec un back-end. Pour PyTorch, le groupe de processus est créé en appelant torch.distributed.init_process_group dans tous les processus distribués pour former collectivement un groupe de processus.
torch.distributed.init_process_group(backend='nccl', init_method='env://', ...)
Les back-ends de communication les plus couramment utilisés sont mpi
, nccl
et gloo
. Pour l’entraînement basé sur le GPU, nccl
est recommandé pour des performances optimales et doit être utilisé chaque fois que cela est possible.
init_method
indique comment chaque processus peut découvrir les autres processus et comment ils initialisent et vérifient le groupe de processus en utilisant le back-end de communication. Par défaut, si init_method
n’est pas spécifié, PyTorch utilise la méthode d’initialisation par variable d’environnement (env://
). init_method
est la méthode d’initialisation recommandée à utiliser dans votre code d’entraînement pour exécuter un travail PyTorch distribué sur Azure Machine Learning. PyTorch recherche les variables d’environnement suivantes pour l’initialisation :
MASTER_ADDR
: adresse IP de la machine qui héberge le processus avec le rang 0MASTER_PORT
: port libre sur la machine qui héberge le processus avec le rang 0WORLD_SIZE
: nombre total de processus. Doit être égal au nombre total d’appareils (GPU) utilisés pour l’entraînement distribuéRANK
: rang (mondial) du processus en cours. Les valeurs possibles sont comprises entre 0 et (le nombre total de processus - 1)
Pour plus d’informations sur l’initialisation du groupe de processus, consultez la documentation PyTorch.
De nombreuses applications ont également besoin des variables d’environnement suivantes :
LOCAL_RANK
: rang local (relatif) du processus dans le nœud. Les valeurs possibles sont comprises entre 0 et (le nombre de processus sur le nœud - 1). Ces informations sont utiles, car de nombreuses opérations, telles que la préparation des données, doivent être effectuées une fois par nœud, généralement avec local_rank = 0.NODE_RANK
: rang du nœud dans l’entraînement sur plusieurs nœuds. Les valeurs possibles sont comprises entre 0 et (le nombre total de nœuds - 1).
Vous n’avez pas besoin de recourir à un utilitaire de lancement comme torch.distributed.launch
. Pour exécuter un travail PyTorch distribué :
- Spécifiez le script et les arguments d’entraînement.
- Créez une
command
, et spécifiez le typePyTorch
etprocess_count_per_instance
dans le paramètredistribution
.process_count_per_instance
correspond au nombre total de processus que vous souhaitez exécuter pour votre travail.process_count_per_instance
doit généralement être égal à# of GPUs per node
. Siprocess_count_per_instance
n’est pas spécifié, Azure Machine Learning lance par défaut un processus par nœud.
Azure Machine Learning définit les variables d’environnement MASTER_ADDR
, MASTER_PORT
, WORLD_SIZE
et NODE_RANK
sur chaque nœud et définit les variables d’environnement RANK
et LOCAL_RANK
de niveau processus.
from azure.ai.ml import command
from azure.ai.ml.entities import Data
from azure.ai.ml import Input
from azure.ai.ml import Output
from azure.ai.ml.constants import AssetTypes
# === Note on path ===
# can be can be a local path or a cloud path. AzureML supports https://`, `abfss://`, `wasbs://` and `azureml://` URIs.
# Local paths are automatically uploaded to the default datastore in the cloud.
# More details on supported paths: https://docs.microsoft.com/azure/machine-learning/how-to-read-write-data-v2#supported-paths
inputs = {
"cifar": Input(
type=AssetTypes.URI_FOLDER, path=returned_job.outputs.cifar.path
), # path="azureml:azureml_stoic_cartoon_wgb3lgvgky_output_data_cifar:1"), #path="azureml://datastores/workspaceblobstore/paths/azureml/stoic_cartoon_wgb3lgvgky/cifar/"),
"epoch": 10,
"batchsize": 64,
"workers": 2,
"lr": 0.01,
"momen": 0.9,
"prtfreq": 200,
"output": "./outputs",
}
from azure.ai.ml.entities import ResourceConfiguration
job = command(
code="./src", # local path where the code is stored
command="python train.py --data-dir ${{inputs.cifar}} --epochs ${{inputs.epoch}} --batch-size ${{inputs.batchsize}} --workers ${{inputs.workers}} --learning-rate ${{inputs.lr}} --momentum ${{inputs.momen}} --print-freq ${{inputs.prtfreq}} --model-dir ${{inputs.output}}",
inputs=inputs,
environment="azureml:AzureML-acpt-pytorch-2.2-cuda12.1@latest",
instance_count=2, # In this, only 2 node cluster was created.
distribution={
"type": "PyTorch",
# set process count to the number of gpus per node
# NC6s_v3 has only 1 GPU
"process_count_per_instance": 1,
},
)
job.resources = ResourceConfiguration(
instance_type="Standard_NC6s_v3", instance_count=2
) # Serverless compute resources
Exemple Pytorch
- Pour que le notebook complet exécute l’exemple de Pytorch, consultez azureml-examples : Entraînement distribué avec PyTorch sur CIFAR-10.
DeepSpeed
Azure Machine Learning prend en charge DeepSpeed en tant que citoyen de première classe pour exécuter des travaux distribués avec une scalabilité quasi linéaire en termes de :
- Augmentation de la taille de modèle
- Augmentation du nombre de GPU
DeepSpeed peut être activé à l’aide de la distribution Pytorch ou de MPI pour l’exécution de l’entraînement distribué. Azure Machine Learning prend en charge le lanceur DeepSpeed pour lancer l’entraînement distribué ainsi que le réglage automatique pour obtenir une configuration ds
optimale.
Vous pouvez utiliser un environnement organisé pour un environnement prêt à l’emploi avec les dernières technologies de pointe, notamment DeepSpeed, ORT, MSSCCL et Pytorch pour vos travaux d’entraînement DeepSpeed.
Exemple DeepSpeed
- Pour obtenir des exemples d’entraînement et de réglage automatique DeepSpeed, consultez ces dossiers.
TensorFlow
Si vous utilisez TensorFlow distribué natif dans votre code d’entraînement, comme l’API tf.distribute.Strategy
de TensorFlow 2.x, vous pouvez lancer le travail distribué via Azure Machine Learning en utilisant les paramètres de distribution
ou l’objet TensorFlowDistribution
.
# create the command
job = command(
code="./src", # local path where the code is stored
command="python main.py --epochs ${{inputs.epochs}} --model-dir ${{inputs.model_dir}}",
inputs={"epochs": 1, "model_dir": "outputs/keras-model"},
environment="AzureML-tensorflow-2.12-cuda11@latest",
compute="cpu-cluster",
instance_count=2,
# distribution = {"type": "mpi", "process_count_per_instance": 1},
# distribution={
# "type": "tensorflow",
# "parameter_server_count": 1, # for legacy TensorFlow 1.x
# "worker_count": 2,
# "added_property": 7,
# },
# distribution = {
# "type": "pytorch",
# "process_count_per_instance": 4,
# "additional_prop": {"nested_prop": 3},
# },
display_name="tensorflow-mnist-distributed-example"
# experiment_name: tensorflow-mnist-distributed-example
# description: Train a basic neural network with TensorFlow on the MNIST dataset, distributed via TensorFlow.
)
# can also set the distribution in a separate step and using the typed objects instead of a dict
job.distribution = TensorFlowDistribution(worker_count=2)
Si votre script d’entraînement utilise la stratégie de serveur de paramètres pour l’entraînement distribué, comme pour la version de TensorFlow 1.x héritée, vous devez aussi spécifier le nombre de serveurs de paramètres à utiliser dans le travail, dans le paramètre de distribution
de la command
. Dans ce qui précède, par exemple, "parameter_server_count" : 1
et "worker_count": 2
.
TF_CONFIG
Dans TensorFlow, la variable d’environnement TF_CONFIG
est requise pour l’entraînement sur plusieurs machines. Pour les travaux TensorFlow, Azure Machine Learning configure et définit la variable TF_CONFIG
de manière appropriée pour chaque Worker avant d’exécuter votre script d’entraînement.
Si nécessaire, vous pouvez accéder à TF_CONFIG
à partir de votre script d’entraînement : os.environ['TF_CONFIG']
.
Exemple TF_CONFIG
défini sur un nœud Worker principal :
TF_CONFIG='{
"cluster": {
"worker": ["host0:2222", "host1:2222"]
},
"task": {"type": "worker", "index": 0},
"environment": "cloud"
}'
Exemple TensorFlow
- Pour que le notebook complet exécute l’exemple de TensorFlow, consultez azureml-examples : Entraîner un réseau neuronal de base avec MPI distribué sur le jeu de données MNIST en utilisant TensorFlow avec Horovod.
Accélération de l’entraînement de GPU distribué avec InfiniBand
Le temps nécessaire à l’entraînement d’un modèle doit diminuer à mesure que le nombre de machines virtuelles utilisées à cet effet augmente. Idéalement, cette durée doit diminuer de façon linéaire proportionnellement au nombre de machines virtuelles participant à l’entraînement. Par exemple, si l’entraînement d’un modèle sur une machine virtuelle prend 100 secondes, l’entraînement du même modèle sur deux machines virtuelles doit dans l’idéal prendre 50 secondes. L’entraînement du modèle sur quatre machines virtuelles doit prendre 25 secondes, et ainsi de suite.
InfiniBand peut être un facteur important pour parvenir à cette mise à l’échelle linéaire. InfiniBand autorise une communication à faible latence, de GPU à GPU, entre les nœuds d’un cluster. InfiniBand nécessite un matériel spécialisé pour fonctionner. Certaines séries de machines virtuelles Azure, en particulier les séries NC, ND et H, offrent désormais des machines virtuelles compatibles RDMA avec prise en charge de SR-IOV et d’InfiniBand. Ces machines virtuelles communiquent via le réseau InfiniBand à faible latence et à large bande passante, qui est beaucoup plus performant que la connectivité Ethernet. SR-IOV pour InfiniBand offre des performances quasi-complètes pour toute bibliothèque MPI (MPI est utilisée par de nombreuses infrastructures et outils d’entraînement distribué, y compris le logiciel NCCL de NVIDIA). Ces références SKU sont destinées à répondre aux besoins des charges de travail de Machine Learning gourmandes en ressources et avec accélération GPU. Pour plus d’informations, consultez Accélération de l’entraînement distribué dans Azure Machine Learning avec SR-IOV.
En règle générale, les références SKU de machines virtuelles dont le nom contient « r » intègrent le matériel InfiniBand nécessaire, ce qui n’est généralement pas le cas de celles qui ne contiennent pas « r ». (« r » fait référence à RDMA, qui signifie accès direct à la mémoire à distance.) Par exemple, la référence SKU de machine virtuelle Standard_NC24rs_v3
est compatible avec InfiniBand, mais la référence SKU Standard_NC24s_v3
ne l’est pas. En dehors des capacités d’InfiniBand, les spécifications entre ces deux références SKU sont en grande partie les mêmes. Elles disposent toutes deux de 24 cœurs, de 448 Go de RAM, de 4 GPU de la même référence SKU, etc. Découvrez plus en détail les références SKU de machines compatibles RDMA et InfiniBand.
Avertissement
La référence SKU de machine d’ancienne génération Standard_NC24r
est compatible RDMA, mais elle n’intègre pas le matériel SR-IOV nécessaire à InfiniBand.
Si vous créez un cluster AmlCompute
avec l’une de ces tailles compatibles InfiniBand et prenant en charge RDMA, l’image du système d’exploitation est fournie avec le pilote Mellanox OFED nécessaire pour activer InfiniBand préinstallé et préconfiguré.
Étapes suivantes
Commentaires
https://aka.ms/ContentUserFeedback.
Bientôt disponible : pendant toute l’année 2024, nous allons éliminer progressivement Problèmes GitHub comme mécanisme de commentaires pour le contenu et le remplacer par un nouveau système de commentaires. Pour plus d’informations, voir :Soumettre et afficher des commentaires pour