분산 GPU 학습 가이드(SDK v2)

적용 대상: Python SDK azure-ai-ml v2(현재)

Azure Machine Learning에서 분산 GPU 학습 코드를 사용하는 방법에 대해 자세히 알아봅니다. 이 문서는 기존 분산 학습 코드를 실행하는 데 도움이 되며 각 프레임워크에 대해 따라야 할 팁과 예제를 제공합니다.

  • MPI(메시지 전달 인터페이스)
    • Horovod
    • Open MPI의 환경 변수
  • PyTorch
  • TensorFlow
  • InfiniBand를 통해 GPU 학습 가속화

필수 조건

데이터 병렬 처리, 분산 데이터 병렬 처리, 모델 병렬 처리분산 GPU 학습의 기본 개념을 검토합니다.

사용할 병렬 처리의 유형을 모르는 경우, 90% 이상 분산 데이터 병렬 처리를 사용해야 합니다.

MPI

Azure Machine Learning은 MPI 작업을 제공하여 각 노드에서 지정된 수의 프로세스를 실행합니다. Azure Machine Learning은 배후에서 전체 MPI 시작 명령(mpirun)을 구성합니다. mpirun 또는 DeepSpeed launcher 같은 사용자 고유의 전체 헤드 노드 시작 관리자 명령을 제공할 수 없습니다.

Azure Machine Learning MPI 작업에서 사용되는 기본 Docker 이미지에는 MPI 라이브러리가 설치되어 있어야 합니다. 개방형 MPI는 모든 Azure Machine Learning GPU 기본 이미지에 포함되어 있습니다. 사용자 지정 Docker 이미지를 사용하는 경우, 이미지에 MPI 라이브러리가 포함되어 있는지 확인해야 합니다. 개방형 MPI를 사용하는 것이 좋지만, Intel MPI와 같은 다른 MPI 구현을 사용할 수도 있습니다. 또한 Azure Machine Learning은 널리 사용되는 프레임워크를 위한 큐레이팅된 환경을 제공합니다.

MPI를 사용하여 분산 학습을 실행하려면 다음 단계를 수행합니다.

  1. 기본 딥 러닝 프레임워크 및 MPI와 함께 Azure Machine Learning 환경을 사용합니다. Azure Machine Learning은 널리 사용되는 프레임워크를 위한 큐레이팅된 환경을 제공합니다. 또는 기본 설정하는 딥 러닝 프레임워크와 MPI를 사용하여 사용자 지정 환경을 만듭니다.
  2. commandinstance_count로 정의합니다. instance_count는 프로세스별 시작의 경우 노드당 GPU 수와 같아야 하고, 사용자 스크립트로 노드별 프로세스를 시작해야 하는 경우 노드별 시작에 대해 1(기본값)로 설정해야 합니다.
  3. commanddistribution 매개 변수를 사용하여 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

딥 러닝 프레임워크를 사용하는 분산 학습에 Horovod를 이용하는 경우 MPI 작업 구성을 사용합니다.

코드가 다음 팁을 따르는지 확인합니다.

  • 학습 코드는 Azure Machine Learning 파트를 추가하기 전에 Horovod로 올바르게 계측됩니다.
  • Azure Machine Learning 환경에는 Horovod 및 MPI가 포함되어 있습니다. PyTorch 및 TensorFlow 큐레이팅된 GPU 환경은 Horovod와 해당 종속성을 사용하여 미리 구성됩니다.
  • 원하는 배포로 command를 만듭니다.

Horovod 예제

Open MPI의 환경 변수

Open MPI 이미지로 MPI 작업을 실행할 때 시작된 각 프로세스에 대해 다음 환경 변수를 사용할 수 있습니다.

  1. OMPI_COMM_WORLD_RANK: 프로세스의 순위
  2. OMPI_COMM_WORLD_SIZE: 세계 크기
  3. AZ_BATCH_MASTER_NODE: MASTER_ADDR:MASTER_PORT 포트가 있는 기본 주소
  4. OMPI_COMM_WORLD_LOCAL_RANK: 노드에 있는 프로세스의 로컬 순위
  5. OMPI_COMM_WORLD_LOCAL_SIZE: 노드의 프로세스 수

이름과 다르게 환경 변수 OMPI_COMM_WORLD_NODE_RANKNODE_RANK에 해당하지 않습니다. 노드별 시작 관리자를 사용하려면 process_count_per_node=1을 설정하고 OMPI_COMM_WORLD_RANKNODE_RANK로 사용합니다.

PyTorch

Azure Machine Learning은 PyTorch의 네이티브 분산 학습 기능(torch.distributed)을 사용하여 분산 작업 실행을 지원합니다.

데이터 병렬 처리 시 공식 PyTorch 지침은 단일 노드 및 다중 노드 분산 학습에 모두 DataParallel을 통해 DDP(DistributedDataParallel)를 사용하는 것입니다. 또한 PyTorch에서는 다중 처리 패키지에 대해 DistributedDataParallel을 사용하는 것이 좋습니다. 따라서 Azure Machine Learning 설명서와 예제는 DistributedDataParallel 학습에 초점을 맞춥니다.

프로세스 그룹 초기화

분산 학습의 백본은 서로를 알고, 백 엔드를 사용해 서로 통신할 수 있는 프로세스 그룹을 기반으로 합니다. PyTorch의 경우 프로세스 그룹이 모든 분산 프로세스에서 torch.distributed.init_process_group을 호출하여 만들어져 총칭하여 프로세스 그룹을 형성합니다.

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

사용되는 가장 일반적인 통신 백 엔드는 mpi, nccl, gloo입니다. GPU 기반 학습의 경우 nccl은 최고의 성능을 발휘하려는 경우에 권장되며, 가능할 때마다 사용해야 합니다.

init_method는 각 프로세스가 서로를 검색하는 방법, 통신 백 엔드를 사용하여 프로세스 그룹을 초기화하고 확인하는 방법을 알려 줍니다. 기본적으로 init_method가 지정되어 있지 않으면 PyTorch에서는 환경 변수 초기화 메서드(env://)를 사용합니다. init_method는 Azure Machine Learning에서 분산 PyTorch를 실행하기 위해 학습 코드에서 사용하는 권장 초기화 방법입니다. PyTorch는 초기화를 위해 다음의 환경 변수를 찾습니다.

  • MASTER_ADDR: 0순위의 프로세스를 호스팅할 컴퓨터의 IP 주소입니다.
  • MASTER_PORT: 0순위의 프로세스를 호스트하는 컴퓨터에서 사용 가능한 포트입니다.
  • WORLD_SIZE: 프로세스의 총수입니다. 분산 학습에 사용되는 총 디바이스(GPU) 수와 같아야 합니다.
  • RANK: 현재 프로세스의 순위(전체)입니다. 가능한 값은 0~(세계 크기 - 1)입니다.

프로세스 그룹 초기화에 대한 자세한 내용은 PyTorch 설명서를 참조하세요.

또한 많은 애플리케이션에는 다음과 같은 환경 변수가 필요합니다.

  • LOCAL_RANK: 노드 내 프로세스의 로컬 순위(상대)입니다. 가능한 값은 0~(노드의 프로세스 수 - 1)입니다. 데이터 준비와 같은 많은 작업이 노드별로 한 번만 수행되어야 하기 때문에(일반적으로 local_rank = 0) 이 정보는 유용합니다.
  • NODE_RANK: 다중 노드 학습을 위한 노드의 순위입니다. 가능한 값은 0~(총 노드 수 - 1)입니다.

torch.distributed.launch 같은 시작 관리자 유틸리티를 사용할 필요가 없습니다. 분산 PyTorch 작업을 실행하려면 다음을 수행합니다.

  1. 학습 스크립트 및 인수를 지정합니다.
  2. command를 만들고 형식을 PyTorch로 지정하고 distribution 매개 변수에서 process_count_per_instance를 지정합니다. process_count_per_instance는 작업에 대해 실행하려는 총 프로세스 수에 해당합니다. process_count_per_instance는 일반적으로 # of GPUs per node와 동일해야 합니다. process_count_per_instance가 지정되지 않은 경우 Azure Machine Learning은 기본적으로 노드당 하나의 프로세스를 시작합니다.

Azure Machine Learning은 각 노드에서 MASTER_ADDR, MASTER_PORT, WORLD_SIZENODE_RANK 환경 변수를 설정하고 프로세스 수준 RANKLOCAL_RANK 환경 변수를 설정합니다.

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 예

DeepSpeed

Azure Machine Learning은 다음과 같은 측면에서 선형에 가까운 확장성으로 분산 작업을 실행할 수 있도록 DeepSpeed를 최고의 개체로 지원합니다.

  • 모델 크기 증가
  • GPU 수 증가

DeepSpeed는 분산 학습을 실행하기 위해 Pytorch 배포 또는 MPI를 사용하여 사용하도록 설정할 수 있습니다. Azure Machine Learning은 DeepSpeed 실행 프로그램을 지원하여 분산 학습을 시작하고 최적의 ds 구성을 가져오기 위한 자동 튜닝을 시작합니다.

DeepSpeed 학습 작업을 위해 DeepSpeed, ORT, MSSCCL 및 Pytorch를 비롯한 최신 기술이 적용된 즉시 사용 가능한 환경을 위한 큐레이션된 환경을 사용할 수 있습니다.

DeepSpeed 예제

  • DeepSpeed 학습 및 자동 튜닝 예는 이 폴더를 참조하세요.

TensorFlow

TensorFlow 2.x의 tf.distribute.Strategy API와 같은 학습 코드에서 네이티브 분산 TensorFlow를 사용하는 경우 distribution 매개 변수 또는 TensorFlowDistribution 개체를 사용하여 Azure Machine Learning을 통해 분산 작업을 시작할 수 있습니다.

# 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)

학습 스크립트가 분산 학습에 매개 변수 서버 전략(예: 레거시 TensorFlow 1.x)을 사용하는 경우, commanddistribution 매개 변수 내에서 작업에 사용할 매개 변수 서버의 수도 지정해야 합니다. 예를 들어, 위에서는 "parameter_server_count" : 1"worker_count": 2입니다.

TF_CONFIG

TensorFlow에서 TF_CONFIG 환경 변수는 여러 머신에서 학습하는 데 필요합니다. TensorFlow작업의 경우 Azure Machine Learning은 학습 스크립트를 실행하기 전에 각 작업자에 맞게 TF_CONFIG 변수를 구성하고 설정합니다.

필요한 경우 학습 스크립트에서 TF_CONFIG에 액세스할 수 있습니다(os.environ['TF_CONFIG']).

주 작업자 노드에 설정된 TF_CONFIG 예:

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

TensorFlow 예제

InfiniBand를 통해 분산된 GPU 학습 가속화

모델을 학습하는 VM 수가 늘어남에 따라 모델 학습에 필요한 시간이 줄어듭니다. 시간 감소는 학습 VM 수에 따라 선형적으로 비례합니다. 예를 들어 1개의 VM에서 모델을 학습하는 데 100초가 걸릴 경우 2개의 VM으로 동일한 모델을 학습하면 이상적으로 50초가 걸립니다. 4개의 VM에서 모델을 학습하려면 25초가 걸립니다.

InfiniBand는 이러한 선형적 확장을 유지하는 데 있어서 중요한 요소일 수 있습니다. InfiniBand는 클러스터에서 노드 간에 지연 시간이 낮은 GPU 간 통신을 가능하게 해줍니다. InfiniBand를 사용하려면 특별한 하드웨어가 필요합니다. 특정 Azure VM 시리즈, 특히 NC, ND, H 시리즈에는 현재 SR-IOV 및 InfiniBand를 지원하는 RDMA 지원 VM이 있습니다. 이러한 VM은 대기 시간이 짧은 고대역폭 InfiniBand 네트워크를 통해 통신하는데, 이는 이더넷 기반 연결보다 훨씬 더 성능이 뛰어납니다. InfiniBand용 SR-IOV는 모든 MPI 라이브러리에 대해 거의 베어 메탈 성능을 구현합니다(MPI는 NVIDIA의 NCCL 소프트웨어를 비롯한 많은 분산 학습 프레임워크 및 도구에서 사용됨). 이러한 SKU는 컴퓨팅 집약적인 GPU 가속 기계 학습 워크로드의 요구 사항을 충족하기 위한 것입니다. 자세한 내용은 SR-IOV를 사용하여 Azure Machine Learning에서 분산 학습 가속화를 참조하세요.

일반적으로 이름에 “r”이 있는 VM SKU에는 필요한 InfiniBand 하드웨어가 있고 “r”이 없는 VM SKU에는 없습니다. (“r”은 원격 직접 메모리 액세스를 나타내는 RDMA에 대한 참조입니다.) 예를 들어 VM SKU Standard_NC24rs_v3는 InfiniBand를 지원하지만 SKU Standard_NC24s_v3는 그렇지 않습니다. InfiniBand 기능을 제외하면 이 두 SKU 간의 사양은 거의 동일합니다. 둘 다에 24개 코어, 448GB RAM, 동일한 SKU의 4개 GPU 등이 있습니다. RDMA 및 InfiniBand를 지원하는 컴퓨터 SKU에 대해 자세히 알아보세요.

Warning

이전 세대 컴퓨터 SKU Standard_NC24r은 RDMA를 지원하지만 InfiniBand에 필요한 SR-IOV 하드웨어를 포함하지 않습니다.

이러한 RDMA 지원, InfiniBand 지원 크기 중 하나의 AmlCompute 클러스터를 만드는 경우 OS 이미지는 InfiniBand가 미리 설치/구성되도록 설정하는 데 필요한 Mellanox OFED 드라이버와 함께 제공됩니다.

다음 단계