Partilhar via


HorovodRunner: aprendizagem profunda distribuída com o Horovod

Saiba como executar treinamento distribuído de modelos de aprendizado de máquina usando o HorovodRunner para iniciar trabalhos de treinamento do Horovod como trabalhos do Spark no Azure Databricks.

Qual é HorovodRunner?

O HorovodRunner é uma API geral para executar cargas de trabalho distribuídas de aprendizagem profunda no Azure Databricks usando a estrutura Horovod . Ao integrar o Horovod com o modo de barreira do Spark, o Azure Databricks é capaz de fornecer maior estabilidade para trabalhos de treinamento de aprendizagem profunda de longa duração no Spark. HorovodRunner usa um método Python que contém código de treinamento de aprendizado profundo com ganchos Horovod. O HorovodRunner pica o método no motorista e o distribui aos trabalhadores da Spark. Um trabalho Horovod MPI é incorporado como um trabalho do Spark usando o modo de execução de barreira. O primeiro executor coleta os endereços IP de todos os executores de tarefas usando BarrierTaskContext e dispara um trabalho Horovod usando mpirun. Cada processo Python MPI carrega o programa de usuário em pickled, desserializa-o e executa-o.

HorovodRunner

Treinamento distribuído com HorovodRunner

HorovodRunner permite que você inicie trabalhos de treinamento Horovod como trabalhos Spark. A API HorovodRunner suporta os métodos mostrados na tabela. Para obter detalhes, consulte a documentação da API HorovodRunner.

Método e assinatura Description
init(self, np) Crie uma instância de HorovodRunner.
run(self, main, **kwargs) Execute um trabalho de treinamento Horovod invocando main(**kwargs). A função principal e os argumentos de palavra-chave são serializados usando cloudpickle e distribuídos para trabalhadores de cluster.

A abordagem geral para desenvolver um programa de treinamento distribuído usando HorovodRunner é:

  1. Crie uma HorovodRunner instância inicializada com o número de nós.
  2. Defina um método de treinamento Horovod de acordo com os métodos descritos no uso do Horovod, certificando-se de adicionar quaisquer instruções de importação dentro do método.
  3. Passe o método de treinamento para a HorovodRunner instância.

Por exemplo:

hr = HorovodRunner(np=2)

def train():
  import tensorflow as tf
  hvd.init()

hr.run(train)

Para executar HorovodRunner no driver apenas com n subprocessos, use hr = HorovodRunner(np=-n). Por exemplo, se houver 4 GPUs no nó do driver, você pode escolher n até 4. Para obter detalhes sobre o parâmetro np, consulte a documentação da API HorovodRunner. Para obter detalhes sobre como fixar uma GPU por subprocesso, consulte o guia de uso do Horovod.

Um erro comum é que os objetos TensorFlow não podem ser encontrados ou capturados. Isso acontece quando as instruções de importação da biblioteca não são distribuídas para outros executores. Para evitar esse problema, inclua todas as instruções de importação (por exemplo, import tensorflow as tf) na parte superior do método de treinamento Horovod e dentro de quaisquer outras funções definidas pelo usuário chamadas no método de treinamento Horovod.

Gravar treinamento Horovod com Horovod Timeline

Horovod tem a capacidade de gravar a linha do tempo de sua atividade, chamada Horovod Timeline.

Importante

Horovod Timeline tem um impacto significativo no desempenho. A taxa de transferência do Inception3 pode diminuir em ~40% quando a Linha do tempo do Horovod está ativada. Para acelerar os trabalhos do HorovodRunner, não use o Horovod Timeline.

Não é possível visualizar a Linha do Tempo do Horovod enquanto o treinamento estiver em andamento.

Para gravar uma linha do tempo do Horovod, defina a HOROVOD_TIMELINE variável de ambiente para o local onde deseja salvar o arquivo da linha do tempo. O Databricks recomenda o uso de um local no armazenamento compartilhado para que o arquivo de linha do tempo possa ser facilmente recuperado. Por exemplo, você pode usar APIs de arquivo local DBFS conforme mostrado:

timeline_dir = "/dbfs/ml/horovod-timeline/%s" % uuid.uuid4()
os.makedirs(timeline_dir)
os.environ['HOROVOD_TIMELINE'] = timeline_dir + "/horovod_timeline.json"
hr = HorovodRunner(np=4)
hr.run(run_training_horovod, params=params)

Em seguida, adicione código específico da linha do tempo ao início e ao fim da função de treinamento. O bloco de anotações de exemplo a seguir inclui código de exemplo que você pode usar como uma solução alternativa para exibir o progresso do treinamento.

Exemplo de bloco de anotações de linha do tempo Horovod

Obter o bloco de notas

Para transferir o ficheiro da linha cronológica, utilize a CLI do Databricks chrome://tracing e, em seguida, utilize a funcionalidade do navegador Chrome para o visualizar. Por exemplo:

Linha do tempo de Horovod

Fluxo de trabalho de desenvolvimento

Estas são as etapas gerais na migração de código de aprendizado profundo de nó único para treinamento distribuído. Os exemplos: migrar para o aprendizado profundo distribuído com o HorovodRunner nesta seção ilustram essas etapas.

  1. Preparar código de nó único: Prepare e teste o código de nó único com TensorFlow, Keras ou PyTorch.
  2. Migrar para o Horovod: Siga as instruções do uso do Horovod para migrar o código com o Horovod e testá-lo no driver:
    1. Adicionar hvd.init() para inicializar o Horovod.
    2. Fixe uma GPU de servidor a ser usada por esse processo usando config.gpu_options.visible_device_listo . Com a configuração típica de uma GPU por processo, isso pode ser definido para a classificação local. Nesse caso, o primeiro processo no servidor será alocado a primeira GPU, o segundo processo será alocado a segunda GPU e assim por diante.
    3. Inclua um fragmento do conjunto de dados. Este operador de conjunto de dados é muito útil ao executar treinamento distribuído, pois permite que cada trabalhador leia um subconjunto exclusivo.
    4. Dimensione a taxa de aprendizagem pelo número de trabalhadores. O tamanho efetivo do lote no treinamento distribuído síncrono é dimensionado pelo número de trabalhadores. O aumento da taxa de aprendizagem compensa o aumento do tamanho do lote.
    5. Envolva o otimizador em hvd.DistributedOptimizer. O otimizador distribuído delega a computação de gradiente ao otimizador original, calcula médias de gradientes usando allreduce ou allgather e, em seguida, aplica os gradientes médios.
    6. Adicione hvd.BroadcastGlobalVariablesHook(0) à transmissão estados variáveis iniciais da classificação 0 para todos os outros processos. Isso é necessário para garantir a inicialização consistente de todos os trabalhadores quando o treinamento é iniciado com pesos aleatórios ou restaurado a partir de um ponto de controle. Como alternativa, se você não estiver usando MonitoredTrainingSessiono , poderá executar a operação após as hvd.broadcast_global_variables variáveis globais terem sido inicializadas.
    7. Modifique seu código para salvar pontos de verificação somente no trabalhador 0 para evitar que outros trabalhadores os corrompam.
  3. Migrar para o HorovodRunner: o HorovodRunner executa o trabalho de treinamento do Horovod invocando uma função Python. Você deve envolver o procedimento de treinamento principal em uma única função Python. Em seguida, você pode testar o HorovodRunner no modo local e no modo distribuído.

Atualizar as bibliotecas de aprendizagem profunda

Nota

Este artigo contém referências ao termo slave, um termo que o Azure Databricks não usa. Quando o termo for removido do software, iremos removê-lo deste artigo.

Se você atualizar ou fazer downgrade do TensorFlow, Keras ou PyTorch, deverá reinstalar o Horovod para que ele seja compilado na biblioteca recém-instalada. Por exemplo, se você quiser atualizar o TensorFlow, o Databricks recomenda usar o script init das instruções de instalação do TensorFlow e anexar o seguinte código de instalação específico do TensorFlow Horovod ao final dele. Consulte as instruções de instalação do Horovod para trabalhar com diferentes combinações, como atualizar ou fazer downgrade do PyTorch e de outras bibliotecas.

add-apt-repository -y ppa:ubuntu-toolchain-r/test
apt update
# Using the same compiler that TensorFlow was built to compile Horovod
apt install g++-7 -y
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 60 --slave /usr/bin/g++ g++ /usr/bin/g++-7

HOROVOD_GPU_ALLREDUCE=NCCL HOROVOD_CUDA_HOME=/usr/local/cuda pip install horovod==0.18.1 --force-reinstall --no-deps --no-cache-dir

Exemplos: Migrar para aprendizagem profunda distribuída com o HorovodRunner

Os exemplos a seguir, baseados no conjunto de dados MNIST , demonstram como migrar um programa de aprendizado profundo de nó único para aprendizado profundo distribuído com o HorovodRunner.

Limitações

  • Ao trabalhar com arquivos de espaço de trabalho, o HorovodRunner não funcionará se np estiver definido como maior que 1 e o bloco de anotações importar de outros arquivos relativos. Considere usar horovod.spark em vez de HorovodRunner.