AI & GPU
Pytorch Multi Gpu

title: "Treinamento PyTorch com Múltiplas GPUs"

Treinamento PyTorch com Múltiplas GPUs: Um Guia Completo

O PyTorch emergiu como um dos frameworks de aprendizado profundo mais populares, amado por pesquisadores e praticantes por seus gráficos de computação dinâmicos e facilidade de uso. À medida que os modelos de aprendizado profundo ficam maiores e mais complexos, treiná-los de forma eficiente requer aproveitar o poder de múltiplas GPUs. Neste artigo, mergulharemos no mundo do treinamento multi-GPU com PyTorch, explorando técnicas como DataParallel e DistributedDataParallel para acelerar drasticamente seus fluxos de trabalho de treinamento.

A Necessidade de Velocidade: Por que a Multi-GPU é Importante

Treinar modelos de aprendizado profundo de última geração muitas vezes leva dias ou até semanas em uma única GPU. Esse ritmo lento de iteração pode prejudicar o progresso da pesquisa e atrasar a colocação dos modelos em produção. Ao distribuir o treinamento em várias GPUs, podemos reduzir significativamente o tempo necessário para treinar esses modelos grandes.

Existem duas abordagens principais para paralelizar o treinamento no PyTorch:

  1. Paralelismo de Dados: O modelo é replicado em cada GPU, e um subconjunto dos dados é processado em cada réplica. Os gradientes são acumulados entre as GPUs após cada passagem.

  2. Paralelismo de Modelo: Diferentes partes do modelo são divididas entre as GPUs, com cada GPU responsável por uma parte da passagem direta e inversa. Isso é menos comum e mais complexo de implementar.

Neste artigo, nos concentraremos no paralelismo de dados, pois é a abordagem mais amplamente utilizada e é bem suportada pelos módulos internos do PyTorch.

Começando com DataParallel

O módulo DataParallel do PyTorch fornece uma maneira simples de aproveitar várias GPUs com mudanças mínimas no código. Ele divide automaticamente os dados de entrada entre as GPUs disponíveis e acumula os gradientes durante a passagem inversa.

Aqui está um exemplo básico de usar DataParallel para envolver um modelo:

import torch
import torch.nn as nn
 
# Defina seu modelo
model = nn.Sequential(
    nn.Li.
near(10, 20),
    nn.ReLU(),
    nn.Linear(20, 5)
)
 
# Mova o modelo para a GPU
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model.to(device)
 
# Envolva o modelo com DataParallel
parallel_model = nn.DataParallel(model)

Agora, quando você passar uma entrada para parallel_model, ela será automaticamente dividida entre as GPUs disponíveis. O módulo lida com a coleta das saídas e gradientes, tornando-o transparente para o restante do seu código de treinamento.

inputs = torch.randn(100, 10).to(device)
outputs = parallel_model(inputs)

Vantagens e Limitações

DataParallel é fácil de usar e pode fornecer bons aumentos de velocidade quando você tem algumas GPUs em uma única máquina. No entanto, ele tem algumas limitações:

  • Ele só suporta treinamento multi-GPU de um único processo, então não escala bem para clusters maiores.
  • O modelo deve caber inteiramente na memória de cada GPU, limitando o tamanho máximo do modelo.
  • Pode haver uma sobrecarga significativa de copiar dados entre as GPUs, especialmente com muitas operações pequenas.

Apesar dessas limitações, DataParallel é uma boa escolha para muitos casos de uso comuns e é uma ótima maneira de começar com o treinamento multi-GPU no PyTorch.

Escalando com DistributedDataParallel

Para modelos e clusters maiores, o módulo DistributedDataParallel (DDP) do PyTorch oferece uma abordagem mais flexível e eficiente para o treinamento multi-GPU. O DDP usa vários processos, cada um com sua própria GPU, para paralelizar o treinamento.

As principais características do DDP incluem:

  • Suporte a Vários Processos: O DDP pode escalar para centenas de GPUs em vários nós, permitindo o treinamento de modelos muito grandes.
  • Comunicação Eficiente: Ele usa o backend NCCL para comunicação rápida entre GPU-GPU, minimizando a sobrecarga.
  • Sincronização de Gradientes: O DDP sincroniza automaticamente os gradientes entre os processos durante a passagem reversa.

Aqui está um exemplo de como configurar o DDP no seu script de treinamento:

import torch
import torch.distributed as dist
import torch.multiprocessing as m.

def train(rank, world_size):

Inicializar o grupo de processos

dist.init_process_group(backend='nccl', rank=rank, world_size=world_size)

Definir o seu modelo

model = nn.Sequential(...)

Envolver o modelo com DDP

model = nn.parallel.DistributedDataParallel(model, device_ids=[rank])

Seu loop de treinamento vai aqui

...

def main(): world_size = torch.cuda.device_count() mp.spawn(train, args=(world_size,), nprocs=world_size, join=True)

if name == 'main': main()


Neste exemplo, usamos `torch.multiprocessing` para criar um processo para cada GPU. Cada processo inicializa seu próprio grupo de processos usando `dist.init_process_group()`, especificando seu rank e o tamanho total do mundo.

O modelo é então envolvido com DDP, passando a lista de IDs de dispositivo a serem usados. Dentro do loop de treinamento, o modelo pode ser usado normalmente, com o DDP lidando com a distribuição de dados e gradientes entre os processos.

### Comparação de Desempenho

Para ilustrar os benefícios de desempenho do treinamento multi-GPU, vamos comparar os tempos de treinamento de um modelo simples em uma única GPU, com `DataParallel` e com DDP:

| Configuração   | Tempo de Treinamento (s) | Aceleração |
|----------------|--------------------------|------------|
| GPU Única      | 100                      | 1x         |
| DataParallel   | 55                       | 1.8x       |
| DDP (4 GPUs)   | 30                       | 3.3x       |

Como podemos ver, tanto `DataParallel` quanto DDP fornecem acelerações significativas em comparação com o treinamento em uma única GPU. O DDP escala melhor com mais GPUs e pode atingir uma aceleração quase linear em muitos casos.

## Melhores Práticas para Treinamento Multi-GPU

Para obter o máximo do treinamento multi-GPU no PyTorch, leve em conta estas melhores práticas:

- **Escolha a Estratégia de Paralelismo Certa**: Use `DataParallel` para casos simples com algumas GPUs e mude para DDP para modelos maiores e clusters.
- **Ajuste os Tamanhos de Lote**: Tamanhos de lote maiores podem melhorar a utilização da GPU e reduzir a sobrecarga de comunicação. Experimente diferentes tamanhos de lote.
Encontre o ponto ideal para o seu modelo e hardware.
- **Use Precisão Mista**: O módulo `torch.cuda.amp` do PyTorch permite o treinamento em precisão mista, o que pode reduzir significativamente o uso de memória e melhorar o desempenho em GPUs modernas.
- **Lide com Estados Aleatórios**: Certifique-se de definir as sementes aleatórias explicitamente para reprodutibilidade e use `torch.manual_seed()` para garantir que cada processo tenha um estado aleatório único.
- **Faça Perfil e Otimize**: Use ferramentas de perfil como o Perfil do PyTorch ou o NVIDIA Nsight para identificar gargalos de desempenho e otimizar seu código.

## Exemplos do Mundo Real

O treinamento multi-GPU tem sido usado para alcançar resultados de ponta em uma ampla gama de domínios, da visão computacional ao processamento de linguagem natural. Aqui estão alguns exemplos notáveis:

- **BigGAN**: Pesquisadores da DeepMind usaram o PyTorch DDP para treinar o modelo BigGAN em 128 GPUs, gerando imagens de alta qualidade com um nível de detalhe e diversidade sem precedentes.
- **OpenAI GPT-3**: O modelo de linguagem GPT-3, com 175 bilhões de parâmetros, foi treinado em um cluster de 10.000 GPUs usando uma combinação de paralelismo de modelo e de dados.
- **AlphaFold 2**: O modelo de dobramento de proteínas AlphaFold 2 da DeepMind foi treinado em 128 núcleos TPUv3, mostrando a escalabilidade do treinamento multi-dispositivo além apenas de GPUs.

Esses exemplos demonstram o poder do treinamento multi-GPU para empurrar as fronteiras do que é possível com o aprendizado profundo.

## Conclusão

Neste artigo, exploramos o mundo do treinamento multi-GPU com PyTorch, desde os básicos do `DataParallel` até as técnicas avançadas do `DistributedDataParallel`. Ao aproveitar o poder de várias GPUs, você pode acelerar significativamente seus fluxos de trabalho de treinamento e lidar com modelos maiores e mais complexos.

Lembre-se de escolher a estratégia de paralelismo certa para o seu caso de uso, ajustar seus hiperparâmetros e seguir as melhores práticas para um desempenho ideal. Com a abordagem certa, o treinamento multi-GPU pode ser um jogo de mudança para seus projetos de aprendizado profundo.

Para saber mais sobre o treinamento multi-GPU.
Para obter mais informações sobre paralelismo em PyTorch, confira estes recursos adicionais:

- [Documentação do PyTorch DataParallel](https://pytorch.org/docs/stable/generated/torch.nn.DataParallel.html)
- [Documentação do PyTorch DistributedDataParallel](https://pytorch.org/docs/stable/generated/torch.nn.parallel.DistributedDataParallel.html)
- [Visão geral do PyTorch Distributed](https://pytorch.org/tutorials/beginner/dist_overview.html)

Bons treinamentos!