Guia de treinamento de GPU distribuída (SDK v2)
APLICA-SE A: Python SDK azure-ai-ml v2 (atual)
Saiba mais sobre como usar o código de treinamento de GPU distribuída no Aprendizado de Máquina do Azure. Este artigo ajuda você a executar seu código de treinamento distribuído existente e oferece dicas e exemplos a serem seguidos para cada estrutura:
- Interface de Passagem de Mensagens (MPI)
- Horovod
- Variáveis de ambiente do Open MPI
- PyTorch
- TensorFlow
- Acelere o treinamento de GPU com a InfiniBand
Pré-requisitos
Analise os conceitos básicos do treinamento de GPU distribuída, como paralelismo de dados, paralelismo de dados distribuídos e paralelismo de modelo.
Gorjeta
Se você não sabe que tipo de paralelismo usar, mais de 90% do tempo você deve usar paralelismo de dados distribuídos.
IPM
O Azure Machine Learning oferece um trabalho MPI para iniciar um determinado número de processos em cada nó. O Azure Machine Learning constrói o comando de inicialização MPI completo (mpirun
) nos bastidores. Você não pode fornecer seus próprios comandos completos head-node-launcher como mpirun
ou DeepSpeed launcher
.
Gorjeta
A imagem base do Docker usada por um trabalho MPI do Azure Machine Learning precisa ter uma biblioteca MPI instalada. O Open MPI está incluído em todas as imagens base da GPU do Azure Machine Learning. Ao usar uma imagem personalizada do Docker, você é responsável por garantir que a imagem inclua uma biblioteca MPI. Recomenda-se abrir o MPI, mas você também pode usar uma implementação MPI diferente, como o Intel MPI. O Azure Machine Learning também fornece ambientes com curadoria para estruturas populares.
Para executar o treinamento distribuído usando o MPI, siga estas etapas:
- Use um ambiente do Azure Machine Learning com a estrutura de aprendizado profundo e MPI preferida. O Azure Machine Learning fornece ambientes com curadoria para estruturas populares. Ou crie um ambiente personalizado com a estrutura de aprendizagem profunda preferida e o MPI.
- Defina um
command
cominstance_count
.instance_count
deve ser igual ao número de GPUs por nó para inicialização por processo ou definido como 1 (o padrão) para inicialização por nó se o script de usuário for responsável por iniciar os processos por nó. - Use o
distribution
parâmetro do para especificar configurações paracommand
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
Use a configuração de trabalho MPI ao usar o Horovod para treinamento distribuído com a estrutura de aprendizado profundo.
Certifique-se de que seu código siga estas dicas:
- O código de treinamento é instrumentado corretamente com o Horovod antes de adicionar as partes do Aprendizado de Máquina do Azure.
- Seu ambiente do Azure Machine Learning contém Horovod e MPI. Os ambientes de GPU com curadoria PyTorch e TensorFlow vêm pré-configurados com o Horovod e suas dependências.
- Crie um
command
com a distribuição desejada.
Exemplo de Horovod
- Para obter o bloco de anotações completo para executar o exemplo de Horovod, consulte azureml-examples: Train a basic neural network with distributed MPI on the MNIST dataset using Horovod.
Variáveis de ambiente do Open MPI
Ao executar trabalhos MPI com imagens Open MPI, você pode usar as seguintes variáveis de ambiente para cada processo iniciado:
OMPI_COMM_WORLD_RANK
: A classificação do processoOMPI_COMM_WORLD_SIZE
: O tamanho do mundoAZ_BATCH_MASTER_NODE
: O endereço principal com porta,MASTER_ADDR:MASTER_PORT
OMPI_COMM_WORLD_LOCAL_RANK
: A classificação local do processo no nóOMPI_COMM_WORLD_LOCAL_SIZE
: O número de processos no nó
Gorjeta
Apesar do nome, a variável OMPI_COMM_WORLD_NODE_RANK
de ambiente não corresponde ao NODE_RANK
. Para usar o iniciador por nó, defina process_count_per_node=1
e use OMPI_COMM_WORLD_RANK
como o NODE_RANK
.
PyTorch
O Azure Machine Learning dá suporte à execução de trabalhos distribuídos usando os recursos de treinamento distribuído nativos do PyTorch (torch.distributed
).
Gorjeta
Para paralelismo de dados, a orientação oficial do PyTorch é usar DistributedDataParallel (DDP) sobre DataParallel para treinamento distribuído de nó único e multinó. PyTorch também recomenda o uso de DistributedDataParallel sobre o pacote de multiprocessamento. Portanto, a documentação e os exemplos do Azure Machine Learning se concentram no treinamento DistributedDataParallel.
Inicialização do grupo de processos
A espinha dorsal de qualquer treinamento distribuído é baseada em um grupo de processos que se conhecem e podem se comunicar uns com os outros usando um back-end. Para o PyTorch, o grupo de processos é criado chamando torch.distributed.init_process_group em todos os processos distribuídos para formar coletivamente um grupo de processos.
torch.distributed.init_process_group(backend='nccl', init_method='env://', ...)
Os back-ends de comunicação mais comuns usados são mpi
, nccl
e gloo
. Para treinamento baseado em GPU, nccl
é recomendado para melhor desempenho e deve ser usado sempre que possível.
init_method
Informa como cada processo pode descobrir um ao outro, como eles inicializam e verificam o grupo de processos usando o back-end de comunicação. Por padrão, se init_method
não for especificado, o PyTorch usa o método de inicialização da variável de ambiente (env://
). init_method
é o método de inicialização recomendado a ser usado em seu código de treinamento para executar o PyTorch distribuído no Aprendizado de Máquina do Azure. O PyTorch procura as seguintes variáveis de ambiente para inicialização:
MASTER_ADDR
: Endereço IP da máquina que hospeda o processo com classificação 0MASTER_PORT
: Uma porta livre na máquina que hospeda o processo com classificação 0WORLD_SIZE
: O número total de processos. Deve ser igual ao número total de dispositivos (GPU) usados para treinamento distribuídoRANK
: A classificação (global) do processo atual. Os valores possíveis são 0 a (tamanho do mundo - 1)
Para obter mais informações sobre a inicialização do grupo de processos, consulte a documentação do PyTorch.
Muitos aplicativos também precisam das seguintes variáveis de ambiente:
LOCAL_RANK
: A classificação local (relativa) do processo dentro do nó. Os valores possíveis são 0 a (# de processos no nó - 1). Essas informações são úteis porque muitas operações, como a preparação de dados, devem ser executadas apenas uma vez por nó, geralmente em local_rank = 0.NODE_RANK
: A classificação do nó para treinamento de vários nós. Os valores possíveis são 0 a (total # de nós - 1).
Você não precisa usar um utilitário lançador como torch.distributed.launch
o . Para executar um trabalho distribuído do PyTorch:
- Especifique o script de treinamento e os argumentos.
- Crie um
command
e especifique o tipo comoPyTorch
e oprocess_count_per_instance
nodistribution
parâmetro. Oprocess_count_per_instance
corresponde ao número total de processos que você deseja executar para o seu trabalho.process_count_per_instance
deve normalmente ser igual a# of GPUs per node
. Seprocess_count_per_instance
não for especificado, o Azure Machine Learning iniciará, por padrão, um processo por nó.
O Azure Machine Learning define as MASTER_ADDR
variáveis , MASTER_PORT
, WORLD_SIZE
e NODE_RANK
de ambiente em cada nó e define as variáveis de nível RANK
de processo e LOCAL_RANK
de ambiente.
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
Exemplo de Pytorch
- Para obter o bloco de anotações completo para executar o exemplo do Pytorch, consulte azureml-examples: Distributed training with PyTorch on CIFAR-10.
DeepSpeed
O Azure Machine Learning suporta o DeepSpeed como um cidadão de primeira classe para executar trabalhos distribuídos com escalabilidade quase linear em termos de:
- Aumento do tamanho do modelo
- Aumento no número de GPUs
O DeepSpeed pode ser ativado usando a distribuição Pytorch ou MPI para executar treinamento distribuído. O Azure Machine Learning suporta o iniciador DeepSpeed para iniciar formação distribuída, bem como o ajuste automático para obter a configuração ideal ds
.
Você pode usar um ambiente com curadoria para um ambiente pronto para uso com as mais recentes tecnologias de ponta, incluindo DeepSpeed, ORT, MSSCCL e Pytorch para seus trabalhos de treinamento DeepSpeed.
Exemplo de DeepSpeed
- Para obter exemplos de treinamento e ajuste automático do DeepSpeed, consulte estas pastas.
TensorFlow
Se você usar o TensorFlow distribuído nativo em seu código de treinamento, como a API do tf.distribute.Strategy
TensorFlow 2.x, poderá iniciar o trabalho distribuído por meio do Aprendizado de Máquina do Azure usando distribution
parâmetros ou o TensorFlowDistribution
objeto.
# 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)
Se o script de treinamento usa a estratégia de servidor de parâmetros para treinamento distribuído, como para o TensorFlow 1.x herdado, você também precisa especificar o número de servidores de parâmetros a serem usados no trabalho, dentro do distribution
command
parâmetro do . No acima, por exemplo, "parameter_server_count" : 1
e "worker_count": 2
.
TF_CONFIG
No TensorFlow, a variável de ambiente é necessária para treinamento TF_CONFIG
em várias máquinas. Para trabalhos do TensorFlow, o Aprendizado de Máquina do Azure configura e define a TF_CONFIG
variável apropriadamente para cada trabalhador antes de executar seu script de treinamento.
Você pode acessar TF_CONFIG
a partir do seu script de treinamento se precisar: os.environ['TF_CONFIG']
.
Exemplo TF_CONFIG
definido em um nó de trabalhador principal:
TF_CONFIG='{
"cluster": {
"worker": ["host0:2222", "host1:2222"]
},
"task": {"type": "worker", "index": 0},
"environment": "cloud"
}'
Exemplo do TensorFlow
- Para obter o bloco de anotações completo para executar o exemplo do TensorFlow, consulte azureml-examples: Train a basic neural network with distributed MPI on the MNIST dataset using Tensorflow with Horovod.
Acelerando o treinamento distribuído de GPU com o InfiniBand
À medida que o número de VMs treinando um modelo aumenta, o tempo necessário para treinar esse modelo deve diminuir. A diminuição do tempo, idealmente, deve ser linearmente proporcional ao número de VMs de treinamento. Por exemplo, se o treinamento de um modelo em uma VM leva 100 segundos, o treinamento do mesmo modelo em duas VMs deve, idealmente, levar 50 segundos. O treinamento do modelo em quatro VMs deve levar 25 segundos, e assim por diante.
InfiniBand pode ser um fator importante na obtenção deste escalonamento linear. A InfiniBand permite a comunicação GPU-a-GPU de baixa latência entre nós em um cluster. InfiniBand requer hardware especializado para operar. Algumas séries de VMs do Azure, especificamente as séries NC, ND e H, agora têm VMs compatíveis com RDMA com suporte a SR-IOV e InfiniBand. Essas VMs se comunicam pela rede InfiniBand de baixa latência e alta largura de banda, que é muito mais eficiente do que a conectividade baseada em Ethernet. O SR-IOV para InfiniBand permite um desempenho quase bare-metal para qualquer biblioteca MPI (o MPI é usado por muitas estruturas de treinamento distribuídas e ferramentas, incluindo o software NCCL da NVIDIA.) Esses SKUs destinam-se a atender às necessidades de cargas de trabalho de aprendizado de máquina aceleradas por GPU e com uso intensivo de computação. Para obter mais informações, consulte Acelerando o treinamento distribuído no Azure Machine Learning com SR-IOV.
Normalmente, as SKUs de VM com um "r" em seu nome contêm o hardware InfiniBand necessário, e aquelas sem um "r" normalmente não. ("r" é uma referência a RDMA, que significa acesso remoto direto à memória.) Por exemplo, o SKU Standard_NC24rs_v3
da VM é habilitado para InfiniBand, mas o SKU Standard_NC24s_v3
não. Além dos recursos da InfiniBand, as especificações entre esses dois SKUs são basicamente as mesmas. Ambos têm 24 núcleos, 448 GB de RAM, 4 GPUs do mesmo SKU, etc. Saiba mais sobre SKUs de máquinas habilitadas para RDMA e InfiniBand.
Aviso
O SKU Standard_NC24r
da máquina de geração mais antiga é habilitado para RDMA, mas não contém hardware SR-IOV necessário para o InfiniBand.
Se você criar um AmlCompute
cluster de um desses tamanhos habilitados para RDMA e habilitados para InfiniBand, a imagem do sistema operacional será fornecida com o driver Mellanox OFED necessário para habilitar o InfiniBand pré-instalado e pré-configurado.