Partager via


Guide de l’entraînement avec des GPU distribués (SDK v2)

APPLIES TO : 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 :

  • 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.

PyTorch

Azure Machine Learning prend en charge l’exécution de travaux distribués à l’aide des fonctionnalités d’entraînement distribuée 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 de toute formation distribuée est un groupe de processus qui se connaissent et peuvent communiquer entre eux à l’aide d’un back-end. Pour PyTorch, vous créez le groupe de processus 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 courants sont mpi, ncclet gloo. Pour l’entraînement basé sur GPU, utilisez-le nccl pour obtenir les meilleures performances.

Le init_method paramètre spécifie comment chaque processus découvre les autres processus et comment ils initialisent et vérifient le groupe de processus à l’aide du back-end de communication. Par défaut, si vous ne spécifiez init_methodpas, PyTorch utilise la méthode d’initialisation des variables d’environnement (env://). Utilisez-le init_method dans votre code d’entraînement pour exécuter 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 0
  • MASTER_PORT : port libre sur la machine qui héberge le processus avec le rang 0
  • WORLD_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 seule fois par nœud, généralement sur 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é :

  1. Spécifiez le script et les arguments d’entraînement.
  2. Créez une command, et spécifiez le type PyTorch et process_count_per_instance dans le paramètre distribution. 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. Si vous ne spécifiez process_count_per_instancepas, Azure Machine Learning lance un processus par nœud par défaut.

Azure Machine Learning définit les variables d’environnement MASTER_ADDR, MASTER_PORT, WORLD_SIZE et NODE_RANK sur chaque nœud. Il définit les variables de processus RANK et LOCAL_RANK d’environnement.

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.8-cuda12.6@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_NC4AS_T4_V3", instance_count=2
)  # Serverless compute resources

Exemple PyTorch

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

Vous pouvez activer DeepSpeed à l’aide de la distribution PyTorch ou de MPI pour exécuter 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, tel que l’API de tf.distribute.Strategy TensorFlow 2.x, vous pouvez lancer le travail distribué via Azure Machine Learning à l’aide distribution de paramètres ou de 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.16-cuda12@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 l’exemple précédent, vous spécifiez "parameter_server_count" : 1 et "worker_count": 2.

TF_CONFIG

Dans TensorFlow, vous avez besoin de la variable d’environnement pour effectuer l’apprentissage TF_CONFIG sur plusieurs machines. Pour les travaux TensorFlow, Azure Machine Learning définit la TF_CONFIG variable correctement 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

Accélération de l’entraînement de GPU distribué avec InfiniBand

Lorsque vous augmentez le nombre de machines virtuelles qui entraînent un modèle, le temps nécessaire à l’apprentissage de ce modèle doit diminuer. La diminution du temps doit être proportionnelle linéairement au nombre de machines virtuelles d’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 prendre 50 secondes. L’entraînement du modèle sur quatre machines virtuelles doit prendre 25 secondes, et ainsi de suite.

InfiniBand peut vous aider à atteindre 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 de formation 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 machine virtuelle avec un « r » dans leur nom contiennent le matériel InfiniBand requis, et ceux sans « r » ne le sont généralement pas. (« r » est une référence à RDMA, qui représente l’accès direct à la mémoire directe à distance.) Par exemple, la référence SKU Standard_NC24rs_v3 de machine virtuelle est Compatible InfiniBand, mais la référence SKU Standard_NC24s_v3 n’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. Les deux ont 24 cœurs, 448 Go de RAM, 4 GPU de la même référence SKU, et ainsi de suite. 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