Aprendizagem Distribuída com Apache MXNet e Horovod

A tradução do artigo foi preparada na véspera do início do curso "ML Industrial em Big Data"

O treinamento distribuído em múltiplas instâncias de computação de alto desempenho pode reduzir o tempo de treinamento de redes neurais profundas modernas em grandes quantidades de dados de semanas para horas ou até minutos, tornando essa técnica de treinamento predominante em aplicações práticas de aprendizado profundo. Os usuários devem compreender como compartilhar e sincronizar dados entre múltiplas instâncias, o que, por sua vez, tem um grande impacto na eficiência do escalonamento. Além disso, os usuários também devem saber como implantar um script de treinamento executado em uma única instância para várias instâncias.

Neste artigo falaremos sobre uma maneira rápida e fácil de distribuir o aprendizado usando a biblioteca aberta de aprendizado profundo Apache MXNet e a estrutura de aprendizado distribuído Horovod. Demonstraremos claramente os benefícios de desempenho da estrutura Horovod e demonstraremos como escrever um script de treinamento MXNet para que funcione de maneira distribuída com o Horovod.

O que é Apache MXNet

Apache MX Net é uma estrutura de aprendizado profundo de código aberto usada para criar, treinar e implantar redes neurais profundas. MXNet abstrai as complexidades associadas à implementação de redes neurais, tem alto desempenho e escalabilidade e oferece APIs para linguagens de programação populares, como Python, C + +, Clojure, Java, Julia, R, Scala e outros.

Treinamento distribuído em MXNet com servidor de parâmetros

Módulo de aprendizagem distribuída padrão no MXNet usa uma abordagem de servidor de parâmetros. Ele usa um conjunto de servidores de parâmetros para coletar gradientes de cada trabalhador, realizar agregação e enviar gradientes atualizados de volta aos trabalhadores para a próxima iteração de otimização. Determinar a proporção correta de servidores para trabalhadores é a chave para um dimensionamento eficaz. Se houver apenas um servidor de parâmetros, pode ser um gargalo nos cálculos. Por outro lado, se forem usados ​​muitos servidores, a comunicação muitos-para-muitos poderá obstruir todas as conexões de rede.

O que é Horovod

Horovod é uma estrutura de aprendizagem profunda distribuída aberta desenvolvida na Uber. Ele aproveita tecnologias eficientes entre GPUs e nós, como NVIDIA Collective Communications Library (NCCL) e Message Passing Interface (MPI) para distribuir e agregar parâmetros de modelo entre vorrecs. Ele otimiza o uso da largura de banda da rede e é bem dimensionado ao trabalhar com modelos de redes neurais profundas. Atualmente suporta vários frameworks populares de aprendizado de máquina, nomeadamente MXNet, Tensorflow, Keras e PyTorch.

Integração MXNet e Horovod

MXNet se integra ao Horovod por meio das APIs de aprendizagem distribuída definidas no Horovod. APIs de comunicação Horovod horovod.broadcast(), horovod.allgather() и horovod.allreduce() implementado usando retornos de chamada assíncronos do mecanismo MXNet, como parte de seu gráfico de tarefas. Dessa forma, as dependências de dados entre comunicação e computação são facilmente tratadas pelo mecanismo MXNet para evitar perdas de desempenho devido à sincronização. Objeto otimizador distribuído definido em Horovod horovod.DistributedOptimizer expande Optimizer no MXNet para que ele chame as APIs Horovod correspondentes para atualizações de parâmetros distribuídas. Todos esses detalhes de implementação são transparentes para os usuários finais.

Início rápido

Você pode começar rapidamente a treinar uma pequena rede neural convolucional no conjunto de dados MNIST usando MXNet e Horovod em seu MacBook.
Primeiro, instale o mxnet e o horovod do PyPI:

pip install mxnet
pip install horovod

Nota: Se você encontrar um erro durante pip instalar horovodtalvez você precise adicionar uma variável MACOSX_DEPLOYMENT_TARGET=10.vvOnde vv – esta é a versão da sua versão MacOS, por exemplo, para MacOSX Sierra você precisará escrever MACOSX_DEPLOYMENT_TARGET=10.12 pip instalar horovod

Em seguida, instale o OpenMPI por isso.

Ao final, baixe o script de teste mxnet_mnist.py por isso e execute os seguintes comandos no terminal MacBook no diretório de trabalho:

mpirun -np 2 -H localhost:2 -bind-to none -map-by slot python mxnet_mnist.py

Isso executará o treinamento em dois núcleos do seu processador. A saída será a seguinte:

INFO:root:Epoch[0] Batch [0-50] Speed: 2248.71 samples/sec      accuracy=0.583640
INFO:root:Epoch[0] Batch [50-100] Speed: 2273.89 samples/sec      accuracy=0.882812
INFO:root:Epoch[0] Batch [50-100] Speed: 2273.39 samples/sec      accuracy=0.870000

Demonstração de desempenho

Ao treinar um modelo ResNet50-v1 em um conjunto de dados ImageNet em 64 GPUs com oito instâncias p3.16xgrande EC2, cada um contendo 8 GPUs NVIDIA Tesla V100 na nuvem AWS, alcançamos uma taxa de transferência de treinamento de 45000 imagens/s (ou seja, o número de amostras treinadas por segundo). Treinamento concluído em 44 minutos após 90 épocas com melhor precisão de 75.7%.

Comparamos isso com a abordagem de treinamento distribuído da MXNet de usar servidores de parâmetros em 8, 16, 32 e 64 GPUs com um único servidor de parâmetros e uma proporção de servidor para trabalhador de 1 para 1 e 2 para 1, respectivamente. Você pode ver o resultado na Figura 1 abaixo. No eixo y à esquerda, as barras representam o número de imagens a serem treinadas por segundo, as linhas refletem a eficiência de dimensionamento (ou seja, a proporção entre a taxa de transferência real e ideal) no eixo y à direita. Como você pode ver, a escolha do número de servidores afeta a eficiência do dimensionamento. Se houver apenas um servidor de parâmetros, a eficiência de escalonamento cai para 38% em 64 GPUs. Para obter a mesma eficiência de escalonamento do Horovod, é necessário duplicar o número de servidores em relação ao número de trabalhadores.

Aprendizagem Distribuída com Apache MXNet e Horovod
Figura 1. Comparação de aprendizagem distribuída usando MXNet com Horovod e com servidor de parâmetros

Na Tabela 1 abaixo, comparamos o custo final por instância ao executar experimentos em 64 GPUs. Usar MXNet com Horovod fornece o melhor rendimento com o menor custo.

Aprendizagem Distribuída com Apache MXNet e Horovod
Tabela 1. Comparação de custos entre Horovod e Parameter Server com uma proporção de servidor para trabalhador de 2 para 1.

Passos para reproduzir

Nas próximas etapas mostraremos como reproduzir o resultado do treinamento distribuído usando MXNet e Horovod. Para saber mais sobre aprendizagem distribuída com MXNet, leia esta postagem.

Passo 1

Crie um cluster de instâncias homogêneas com MXNet versão 1.4.0 ou superior e Horovod versão 0.16.0 ou superior para usar o aprendizado distribuído. Você também precisará instalar bibliotecas para treinamento de GPU. Para nossas instâncias, escolhemos Ubuntu 16.04 Linux, com GPU Driver 396.44, CUDA 9.2, biblioteca cuDNN 7.2.1, comunicador NCCL 2.2.13 e OpenMPI 3.1.1. Você também pode usar AMI de aprendizado profundo da Amazon, onde essas bibliotecas já estão pré-instaladas.

Passo 2

Adicione a capacidade de trabalhar com a API Horovod ao seu script de treinamento MXNet. O script abaixo baseado na API MXNet Gluon pode ser usado como um modelo simples. As linhas em negrito são necessárias caso você já possua um roteiro de treinamento correspondente. Aqui estão algumas mudanças críticas que você precisa fazer para aprender com o Horovod:

  • Defina o contexto de acordo com a classificação Horovod local (linha 8) para entender que o treinamento é realizado no núcleo gráfico correto.
  • Passe os parâmetros iniciais de um trabalhador para todos (linha 18) para garantir que todos os trabalhadores comecem com os mesmos parâmetros iniciais.
  • Crie um Horovod DistribuídoOptimizer (linha 25) para atualizar os parâmetros de forma distribuída.

Para obter o script completo, consulte os exemplos do Horovod-MXNet MNIST и IMAGEnet.

1  import mxnet as mx
2  import horovod.mxnet as hvd
3
4  # Horovod: initialize Horovod
5  hvd.init()
6
7  # Horovod: pin a GPU to be used to local rank
8  context = mx.gpu(hvd.local_rank())
9
10 # Build model
11 model = ...
12
13 # Initialize parameters
14 model.initialize(initializer, ctx=context)
15 params = model.collect_params()
16
17 # Horovod: broadcast parameters
18 hvd.broadcast_parameters(params, root_rank=0)
19
20 # Create optimizer
21 optimizer_params = ...
22 opt = mx.optimizer.create('sgd', **optimizer_params)
23
24 # Horovod: wrap optimizer with DistributedOptimizer
25 opt = hvd.DistributedOptimizer(opt)
26
27 # Create trainer and loss function
28 trainer = mx.gluon.Trainer(params, opt, kvstore=None)
29 loss_fn = ...
30
31 # Train model
32 for epoch in range(num_epoch):
33    ...

Passo 3

Faça login em um dos trabalhadores para iniciar o treinamento distribuído usando a diretiva MPI. Neste exemplo, o treinamento distribuído é executado em quatro instâncias com 4 GPUs cada e um total de 16 GPUs no cluster. O otimizador Stochastic Gradient Descent (SGD) será usado com os seguintes hiperparâmetros:

  • tamanho do minilote: 256
  • taxa de aprendizagem: 0.1
  • impulso: 0.9
  • redução de peso: 0.0001

À medida que aumentamos de uma GPU para 64 GPUs, aumentamos linearmente a taxa de treinamento de acordo com o número de GPUs (de 0,1 para 1 GPU a 6,4 para 64 GPUs), mantendo o número de imagens por GPU em 256 (de um lote de 256 imagens para 1 GPU a 16 para 384 GPUs). Os parâmetros de redução de peso e impulso mudaram conforme o número de GPUs aumentou. Usamos treinamento de precisão mista com o tipo de dados float64 para passagem direta e float16 para gradientes para acelerar os cálculos float32 suportados pelas GPUs NVIDIA Tesla.

$ mpirun -np 16 
    -H server1:4,server2:4,server3:4,server4:4 
    -bind-to none -map-by slot 
    -mca pml ob1 -mca btl ^openib 
    python mxnet_imagenet_resnet50.py

Conclusão

Neste artigo, analisamos uma abordagem escalonável para treinamento de modelo distribuído usando Apache MXNet e Horovod. Demonstramos a eficiência de dimensionamento e a relação custo-benefício em comparação com a abordagem do servidor de parâmetros no conjunto de dados ImageNet no qual o modelo ResNet50-v1 foi treinado. Também incluímos etapas que você pode usar para modificar um script existente para executar treinamento em várias instâncias usando o Horovod.

Se você está apenas começando com MXNet e aprendizado profundo, vá para a página de instalação MXNepara primeiro construir o MXNet. Também recomendamos fortemente a leitura do artigo MXNet em 60 minutospara começar.

Se você já trabalhou com MXNet e deseja experimentar o aprendizado distribuído com Horovod, dê uma olhada em Página de instalação do Horovod, construa-o a partir do MXNet e siga o exemplo MNIST ou IMAGEnet.

*o custo é calculado com base em taxas horárias AWS para instâncias EC2

Saiba mais sobre o curso "ML Industrial em Big Data"

Fonte: habr.com

Adicionar um comentário