HorovodRunner: aprendizagem profunda distribuída com Horovod

Aprenda a realizar o treinamento distribuído da versão do machine learning usando o HorovodRunner para iniciar Job de treinamento do Horovod como Spark Job no Databricks.

O que é HorovodRunner?

O HorovodRunner é uma API geral para execução de cargas de trabalho de aprendizagem profunda distribuídas em Databricks usando a estrutura Horovod . Ao integrar o Horovod com o modo de barreira do Spark, o Databricks é capaz de fornecer maior estabilidade para Job treinamento profundo de aprendizagem de longa duração no Spark. HorovodRunner usa um método Python que contém código de treinamento de aprendizagem profunda com ganchos Horovod. HorovodRunner seleciona o método no driver e o distribui para worker Spark . Um Horovod MPI Job é incorporado como um Spark Job 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 aciona um Horovod Job usando mpirun. Cada processo Python MPI carrega o programa de usuário em conserva, desserializa-o e executa-o.

HorovodRunner

Treinamento distribuído com HorovodRunner

HorovodRunner permite que você inicie Job de treinamento Horovod como Spark Job. A API HorovodRunner oferece suporte aos métodos mostrados na tabela. Para obter detalhes, consulte a documentação da API do HorovodRunner.

Método e assinatura

Descrição

init(self, np)

Crie uma instância de HorovodRunner.

run(self, main, **kwargs)

execução de um Job 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 clusters worker.

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

  1. Crie uma instância HorovodRunner inicializada com o número de nós.

  2. Defina um método de treinamento Horovod de acordo com os métodos descritos em Uso de Horovod, certificando-se de adicionar quaisquer declarações de importação dentro do método.

  3. Passe o método de treinamento para a instância HorovodRunner .

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ê poderá escolher n até 4. Para obter detalhes sobre o parâmetro np, consulte a documentação da API HorovodRunner. Para obter detalhes sobre como pin uma GPU por subprocesso, consulte o guia de uso do Horovod.

Um erro comum é que os objetos do TensorFlow não podem ser encontrados ou decapados. 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 qualquer outra função definida pelo usuário chamada no método de treinamento Horovod.

Grave o treinamento de Horovod com a linha do tempo de Horovod

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

Importante

Horovod Timeline tem um impacto significativo no desempenho. Inception3 A taxa de download pode diminuir em ~40% quando o Horovod Timeline está habilitado. Para acelerar o HorovodRunner Job, não use o Horovod Timeline.

Você não pode view a linha do tempo Horovod enquanto o treinamento está em andamento.

Para gravar uma linha do tempo Horovod, defina a variável de ambiente HOROVOD_TIMELINE para o local onde deseja salvar o arquivo da linha do tempo. Databricks recomenda usar 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 como 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 o código específico da linha do tempo ao início e ao final da função de treinamento. O Notebook de exemplo a seguir inclui código de exemplo que você pode usar como uma solução alternativa para view o progresso do treinamento.

Notebook de exemplo da linha do tempo Horovod

Abra o bloco de anotações em outra guia

Para fazer o download do arquivo de linha do tempo, use a CLI do Databricks ou o FileStore e, em seguida, use o recurso chrome://tracing do navegador Chrome para view. Por exemplo:

Linha do tempo Horovod

Desenvolvimento fluxo de trabalho

Estes são os passos gerais na migração do código profundo de aprendizado de nó único para o treinamento distribuído. Os Exemplos: Migrar para aprendizagem distribuída profunda com HorovodRunner nesta seção ilustram esses passos.

  1. Prepare o código de nó único: prepare e teste o código de nó único com TensorFlow, Keras ou PyTorch.

  2. Migrar para Horovod: Siga as instruções de uso do Horovod para migrar o código com o Horovod e testá-lo no driver:

    1. Adicione hvd.init() para inicializar Horovod.

    2. pin uma GPU de servidor para ser usada por este processo usando config.gpu_options.visible_device_list. Com a configuração típica de uma GPU por processo, isso pode ser definido como classificação local. Nesse caso, o primeiro processo no servidor será alocado para a primeira GPU, o segundo processo será alocado para a segunda GPU e assim por diante.

    3. Inclua um fragmento do dataset. Esse operador dataset é muito útil ao executar treinamento distribuído, pois permite que cada worker leia um subconjunto exclusivo.

    4. escalar a taxa de aprendizagem por número de worker. O tamanho efetivo dos lotes no treinamento distribuído síncrono é dimensionado pelo número de worker. O aumento da taxa de aprendizado compensa o aumento do tamanho dos lotes.

    5. Envolva o otimizador em hvd.DistributedOptimizer. O otimizador distribuído delega a computação de gradiente ao otimizador original, calcula a média dos gradientes usando allreduce ou allgather e, em seguida, aplica os gradientes médios.

    6. Adicione hvd.BroadcastGlobalVariablesHook(0) para transmitir estados variáveis iniciais da classificação 0 para todos os outros processos. Isso é necessário para garantir a inicialização consistente de todos worker quando o treinamento é iniciado com pesos aleatórios ou restaurado a partir de um ponto de verificação. Como alternativa, se você não estiver usando MonitoredTrainingSession, poderá executar as operações hvd.broadcast_global_variables depois que as variáveis globais forem inicializadas.

    7. Modifique seu código para salvar pontos de verificação apenas no worker 0 para evitar que outro worker os corrompa.

  3. Migrar para HorovodRunner: HorovodRunner executa o Job de treinamento Horovod invocando uma função Python. Você deve agrupar o procedimento de treinamento principal em uma única função Python. Então você pode testar o HorovodRunner no modo local e no modo distribuído.

Atualize as bibliotecas de aprendizagem profunda

Observação

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

Se você fizer upgrade ou downgrade do TensorFlow, Keras ou PyTorch, deverá reinstalar o Horovod para que ele seja compilado na biblioteca recém-instalada. Por exemplo, se você deseja atualizar o TensorFlow, o Databricks recomenda usar o init script das instruções de instalação do TensorFlow e anexar o seguinte código de instalação Horovod específico do TensorFlow ao final dele. Consulte as instruções de instalação do Horovod para trabalhar com diferentes combinações, como atualizar ou rebaixar o PyTorch e 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 distribuída profunda com HorovodRunner

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

Limitações

  • Ao trabalhar com arquivos workspace , o HorovodRunner não funcionará se np for definido como maior que 1 e o Notebook importar de outros arquivos relativos. Considere usar Horovod.spark em vez de HorovodRunner.