Utbildningsguide för distribuerad GPU (SDK v2)

GÄLLER FÖR: Python SDK azure-ai-ml v2 (aktuell)

Läs mer om hur du använder distribuerad GPU-träningskod i Azure Machine Learning. Den här artikeln hjälper dig att köra din befintliga distribuerade träningskod och ger tips och exempel som du kan följa för varje ramverk:

  • MPI (Message Passing Interface)
    • Horovod
    • Miljövariabler från Open MPI
  • PyTorch
  • TensorFlow
  • Påskynda GPU-träningen med InfiniBand

Förutsättningar

Granska de grundläggande begreppen för distribuerad GPU-utbildning, till exempel dataparallellitet, distribuerad dataparallellitet och modellparallellitet.

Dricks

Om du inte vet vilken typ av parallellitet du ska använda bör du använda distribuerad dataparallellitet mer än 90 % av tiden.

MPI

Azure Machine Learning erbjuder ett MPI-jobb för att starta ett visst antal processer i varje nod. Azure Machine Learning konstruerar det fullständiga MPI-startkommandot (mpirun) i bakgrunden. Du kan inte ange dina egna fullständiga head-node-launcher-kommandon som mpirun eller DeepSpeed launcher.

Dricks

Den grundläggande Docker-avbildningen som används av ett Azure Machine Learning MPI-jobb måste ha ett MPI-bibliotek installerat. Open MPI ingår i alla Azure Machine Learning GPU-basavbildningar. När du använder en anpassad Docker-avbildning ansvarar du för att se till att avbildningen innehåller ett MPI-bibliotek. Öppna MPI rekommenderas, men du kan också använda en annan MPI-implementering, till exempel Intel MPI. Azure Machine Learning tillhandahåller även utvalda miljöer för populära ramverk.

Följ dessa steg för att köra distribuerad träning med MPI:

  1. Använd en Azure Machine Learning-miljö med önskat ramverk för djupinlärning och MPI. Azure Machine Learning tillhandahåller utvalda miljöer för populära ramverk. Eller skapa en anpassad miljö med önskat djupinlärningsramverk och MPI.
  2. Definiera en command med instance_count. instance_count ska vara lika med antalet GPU:er per nod för per processstart eller vara inställt på 1 (standardvärdet) för start per nod om användarskriptet ansvarar för att starta processerna per nod.
  3. Använd parametern distribution för för command att ange inställningar för MpiDistribution.
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.7-ubuntu20.04-py38-cuda11-gpu@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

Använd MPI-jobbkonfigurationen när du använder Horovod för distribuerad träning med ramverket för djupinlärning.

Se till att koden följer dessa tips:

  • Träningskoden instrumenteras korrekt med Horovod innan du lägger till Azure Machine Learning-delarna.
  • Din Azure Machine Learning-miljö innehåller Horovod och MPI. PyTorch- och TensorFlow-kurerade GPU-miljöer är förkonfigurerade med Horovod och dess beroenden.
  • Skapa en command med önskad distribution.

Horovod-exempel

Miljövariabler från Open MPI

När du kör MPI-jobb med Öppna MPI-avbildningar kan du använda följande miljövariabler för varje process som startas:

  1. OMPI_COMM_WORLD_RANK: Processens rangordning
  2. OMPI_COMM_WORLD_SIZE: Världens storlek
  3. AZ_BATCH_MASTER_NODE: Den primära adressen med port, MASTER_ADDR:MASTER_PORT
  4. OMPI_COMM_WORLD_LOCAL_RANK: Den lokala rangordningen för processen på noden
  5. OMPI_COMM_WORLD_LOCAL_SIZE: Antalet processer på noden

Dricks

Trots namnet motsvarar NODE_RANKmiljövariabeln OMPI_COMM_WORLD_NODE_RANK inte . Om du vill använda startprogrammet per nod anger process_count_per_node=1 du och använder OMPI_COMM_WORLD_RANK som NODE_RANK.

PyTorch

Azure Machine Learning stöder körning av distribuerade jobb med pyTorchs inbyggda distribuerade träningsfunktioner (torch.distributed).

Dricks

För dataparallellitet är den officiella PyTorch-vägledningen att använda DistributedDataParallel (DDP) över DataParallel för både distribuerad träning med en nod och flera noder. PyTorch rekommenderar också att du använder DistributedDataParallel via multiprocesspaketet. Dokumentationen och exemplen i Azure Machine Learning fokuserar därför på DistributedDataParallel-utbildning.

Initiering av processgrupp

Ryggraden i en distribuerad träning baseras på en grupp processer som känner varandra och kan kommunicera med varandra med hjälp av en serverdel. För PyTorch skapas processgruppen genom att anropa torch.distributed.init_process_group i alla distribuerade processer för att tillsammans bilda en processgrupp.

torch.distributed.init_process_group(backend='nccl', init_method='env://', ...)

De vanligaste kommunikationsserverdelarna som används är mpi, nccloch gloo. För GPU-baserad träning nccl rekommenderas för bästa prestanda och bör användas när det är möjligt.

init_method anger hur varje process kan identifiera varandra, hur de initierar och verifierar processgruppen med hjälp av kommunikationsserverdelen. Om inte anges använder PyTorch som standard init_method initieringsmetoden för miljövariabeln (env://). init_method är den rekommenderade initieringsmetoden som ska användas i träningskoden för att köra distribuerade PyTorch på Azure Machine Learning. PyTorch söker efter följande miljövariabler för initiering:

  • MASTER_ADDR: IP-adress för den dator som är värd för processen med rangordning 0
  • MASTER_PORT: En kostnadsfri port på datorn som är värd för processen med rangordning 0
  • WORLD_SIZE: Det totala antalet processer. Ska vara lika med det totala antalet enheter (GPU) som används för distribuerad träning
  • RANK: Rangordningen (globalt) för den aktuella processen. Möjliga värden är 0 till (världsstorlek - 1)

Mer information om initiering av processgrupper finns i PyTorch-dokumentationen.

Många program behöver också följande miljövariabler:

  • LOCAL_RANK: Den lokala (relativa) rangordningen för processen inom noden. Möjliga värden är 0 till (antal processer på noden - 1). Den här informationen är användbar eftersom många åtgärder, till exempel förberedelse av data, bara ska utföras en gång per nod, vanligtvis på local_rank = 0.
  • NODE_RANK: Nodens rangordning för träning med flera noder. Möjliga värden är 0 till (totalt antal noder - 1).

Du behöver inte använda ett startverktyg som torch.distributed.launch. Så här kör du ett distribuerat PyTorch-jobb:

  1. Ange träningsskriptet och argumenten.
  2. Skapa en command och ange typen som PyTorch och process_count_per_instance i parametern distribution . process_count_per_instance Motsvarar det totala antalet processer som du vill köra för jobbet. process_count_per_instance ska vanligtvis vara lika med # of GPUs per node. Om process_count_per_instance inte anges startar Azure Machine Learning som standard en process per nod.

Azure Machine Learning anger MASTER_ADDRmiljövariablerna , MASTER_PORT, WORLD_SIZEoch NODE_RANK på varje nod och anger processnivå RANK - och LOCAL_RANK miljövariablerna.

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-acpt-pytorch-2.0-cuda11.7:26",
    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

Pytorch-exempel

DeepSpeed

Azure Machine Learning har stöd för DeepSpeed som förstklassig medborgare för att köra distribuerade jobb med nästan linjär skalbarhet när det gäller:

  • Öka modellstorleken
  • Ökning av antalet GPU:er

DeepSpeed kan aktiveras med antingen Pytorch-distribution eller MPI för att köra distribuerad träning. Azure Machine Learning stöder DeepSpeed-startprogrammet för att starta distribuerad träning samt automatisk tunning för att få optimal ds konfiguration.

Du kan använda en kuraterad miljö för en out-of-the-box-miljö med den senaste tekniken, inklusive DeepSpeed, ORT, MSSCCL och Pytorch för dina DeepSpeed-träningsjobb.

DeepSpeed-exempel

  • För DeepSpeed-tränings- och autotuningexempel, se dessa mappar.

TensorFlow

Om du använder inbyggt distribuerat TensorFlow i träningskoden, till exempel TensorFlow 2.xs tf.distribute.Strategy API, kan du starta det distribuerade jobbet via Azure Machine Learning med hjälp av distribution parametrar eller TensorFlowDistribution objektet.

# 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.4-ubuntu18.04-py37-cuda11-gpu@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)

Om ditt träningsskript använder parameterserverstrategin för distribuerad träning, till exempel för äldre TensorFlow 1.x, måste du också ange antalet parameterservrar som ska användas i jobbet, i parametern distribution i command. I ovanstående, till exempel, "parameter_server_count" : 1 och "worker_count": 2.

TF_CONFIG

I TensorFlow TF_CONFIG krävs miljövariabeln för träning på flera datorer. För TensorFlow-jobb konfigurerar och ställer Azure Machine Learning in variabeln TF_CONFIG på rätt sätt för varje arbetare innan du kör träningsskriptet.

Du kan komma åt TF_CONFIG från ditt träningsskript om du behöver: os.environ['TF_CONFIG'].

Exempeluppsättning TF_CONFIG på en chefsarbetsnod:

TF_CONFIG='{
    "cluster": {
        "worker": ["host0:2222", "host1:2222"]
    },
    "task": {"type": "worker", "index": 0},
    "environment": "cloud"
}'

TensorFlow-exempel

Påskynda distribuerad GPU-träning med InfiniBand

När antalet virtuella datorer som tränar en modell ökar bör den tid som krävs för att träna modellen minska. Den minskade tiden bör helst vara linjärt proportionell mot antalet virtuella träningsdatorer. Om det till exempel tar 100 sekunder att träna en modell på en virtuell dator bör det ta 50 sekunder att träna samma modell på två virtuella datorer. Det bör ta 25 sekunder att träna modellen på fyra virtuella datorer och så vidare.

InfiniBand kan vara en viktig faktor för att uppnå den här linjära skalningen. InfiniBand möjliggör GPU-till-GPU-kommunikation med låg svarstid mellan noder i ett kluster. InfiniBand kräver särskild maskinvara för att fungera. Vissa azure VM-serier, särskilt NC-, ND- och H-serien, har nu RDMA-kompatibla virtuella datorer med stöd för SR-IOV och InfiniBand. Dessa virtuella datorer kommunicerar via infiniBand-nätverket med låg svarstid och hög bandbredd, vilket är mycket mer högpresterande än Ethernet-baserad anslutning. SR-IOV för InfiniBand möjliggör nästan bare metal-prestanda för alla MPI-bibliotek (MPI används av många distribuerade träningsramverk och verktyg, inklusive NVIDIA:s NCCL-programvara.) Dessa SKU:er är avsedda att uppfylla behoven hos beräkningsintensiva, GPU-accelererade maskininlärningsarbetsbelastningar. Mer information finns i Accelerera distribuerad utbildning i Azure Machine Learning med SR-IOV.

Vanligtvis innehåller VM-SKU:er med ett "r" i namnet nödvändig InfiniBand-maskinvara, och de som saknar "r" gör vanligtvis inte det. ("r" är en referens till RDMA, som står för fjärråtkomst till direkt minne.) Den virtuella datorns SKU Standard_NC24rs_v3 är till exempel InfiniBand-aktiverad, men SKU Standard_NC24s_v3 :n är inte det. Förutom InfiniBand-funktionerna är specifikationerna mellan dessa två SKU:er i stort sett desamma. Båda har 24 kärnor, 448 GB RAM-minne, 4 GPU:er av samma SKU osv. Läs mer om RDMA- och InfiniBand-aktiverade dator-SKU:er.

Varning

Den äldre generationens SKU Standard_NC24r är RDMA-aktiverad, men den innehåller inte den SR-IOV-maskinvara som krävs för InfiniBand.

Om du skapar ett AmlCompute kluster med någon av dessa RDMA-kompatibla, InfiniBand-aktiverade storlekar levereras OS-avbildningen med mellanox OFED-drivrutinen som krävs för att aktivera InfiniBand förinstallerat och förkonfigurerat.

Nästa steg