Transformers documentation

Métodos de paralelismo

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v5.22.1).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Métodos de paralelismo

Configurações multi-GPU são eficazes para acelerar o treinamento e para caber em memória modelos grandes que, de outra forma, não caberiam em uma única GPU. Elas dependem da paralelização da carga de trabalho entre as GPUs. Existem vários tipos de paralelismo, como paralelismo de dados, paralelismo de tensor, paralelismo de pipeline e paralelismo de modelo. Cada tipo de paralelismo divide a carga de trabalho de maneira diferente, seja os dados ou o modelo.

Este guia discutirá os diversos métodos de paralelismo, sua combinação e a escolha de uma estratégia adequada para o seu ambiente. Para mais detalhes sobre treinamento distribuído, consulte a documentação do Accelerate.

Para um guia abrangente sobre o dimensionamento de grandes modelos de linguagem, consulte o Ultrascale Playbook, que fornece estratégias detalhadas e melhores práticas para treinamento em larga escala.

Estratégia de escalabilidade

Use a Model Memory Calculator para calcular a quantidade de memória necessária por um modelo. Em seguida, consulte a tabela abaixo para selecionar uma estratégia com base na sua configuração.

setupcenárioestratégia
nó único/multi-GPUcabe em uma única GPUDistributedDataParallel ou ZeRO
não cabe em uma única GPUPipelineParallel, ZeRO ou TensorParallel
a maior camada do modelo não cabeTensorParallel ou ZeRO
multi-nó/multi-GPUconectividade rápida entre nós (NVLink ou NVSwitch)ZeRO ou paralelismo 3D (PipelineParallel, TensorParallel, DataParallel)
conectividade lenta entre nósZeRO ou paralelismo 3D (PipelineParallel, TensorParallel, DataParallel)

Paralelismo de dados

O paralelismo de dados distribui uniformemente os dados entre várias GPUs. Cada GPU mantém uma cópia do modelo e processa, de forma concorrente, sua parte dos dados. Ao final, os resultados de cada GPU são sincronizados e combinados.

O paralelismo de dados reduz significativamente o tempo de treinamento ao processar os dados em paralelo e é escalável para o número de GPUs disponíveis. No entanto, a sincronização dos resultados de cada GPU pode adicionar sobrecarga.

Existem dois tipos de paralelismo de dados: DataParallel (DP) e DistributedDataParallel (DDP).

DataParallel

DataParallel suporta treinamento distribuído em uma máquina única com múltiplas GPUs.

  1. A GPU padrão, GPU 0, lê um lote de dados e envia um mini lote para as outras GPUs.
  2. Um modelo atualizado é replicado da GPU 0 para as outras GPUs.
  3. Uma passagem forward é executada em cada GPU e suas saídas são enviadas para a GPU 0 para calcular a perda.
  4. A perda é distribuída da GPU 0 para as outras GPUs para a passagem de backward.
  5. Os gradientes de cada GPU são enviados de volta para a GPU 0 e em seguida calcula-se a média.

DistributedDataParallel

DistributedDataParallel suporta treinamento distribuído em múltiplas máquinas com várias GPUs.

  1. O processo principal replica o modelo da GPU padrão, GPU 0, para cada GPU.
  2. Cada GPU processa diretamente um mini lote de dados.
  3. Os gradientes locais são média entre todas as GPUs durante a passagem backward.

DDP é recomendado porque reduz a sobrecarga de comunicação entre GPUs, utiliza cada GPU de forma eficiente e escala para mais de uma máquina.

Paralelismo de dados ZeRO

O Zero Redundancy Optimizer é um tipo de paralelismo de dados mais eficiente em termos de memória. Ele melhora significativamente a eficiência de memória ao particionar parâmetros, gradientes e estados do otimizador entre processos de paralelismo de dados, reduzindo assim o uso de memória. Existem três estágios do ZeRO:

  • A Etapa 1 particiona os estados do otimizador
  • A Etapa 2 particiona os estados do otimizador e dos gradientes
  • A Etapa 3 particiona o otimizador, os gradientes e os parâmetros

Paralelismo de modelo

O paralelismo de modelo distribui um modelo entre várias GPUs. Existem várias maneiras de dividir um modelo, mas o método típico distribui as camadas do modelo entre as GPUs. Na passagem forward, a primeira GPU processa um lote de dados e o passa para o próximo grupo de camadas na GPU seguinte. Para a passagem backward, os dados são enviados de volta da camada final para a primeira camada.

O paralelismo de modelos é uma estratégia útil para treinar modelos que são grandes demais para caber na memória de uma única GPU. No entanto, a utilização das GPUs é desequilibrada, pois apenas uma GPU está ativa de cada vez. A passagem de resultados entre GPUs também adiciona sobrecarga de comunicação e pode se tornar um gargalo.

Paralelismo de pipeline

O paralelismo de pipeline é conceitualmente muito semelhante ao paralelismo de modelo, mas é mais eficiente porque reduz a quantidade de tempo ocioso da GPU. Em vez de aguardar que cada GPU termine o processamento de um lote de dados, o paralelismo de pipeline cria micro-lotes de dados. Assim que um micro-lote é finalizado, ele é passado para a próxima GPU. Dessa forma, cada GPU pode processar parte dos dados de forma concorrente, sem precisar esperar que a outra GPU termine completamente o processamento de um mini-lote de dados.

O paralelismo de pipeline compartilha as mesmas vantagens do paralelismo de modelo, mas otimiza a utilização da GPU e reduz o tempo ocioso. No entanto, o paralelismo de pipeline pode ser mais complexo, pois os modelos podem precisar ser reescritos como uma sequência de módulos nn.Sequential, e também não é possível reduzir completamente o tempo ocioso, pois a última passagem de forward também deve aguardar o término da passagem de backward.

Paralelismo de tensor

O paralelismo de tensores distribui o cálculo de tensores grandes entre várias GPUs. Os tensores são fatiados horizontalmente ou verticalmente e cada fatia é processada por uma GPU separada. Cada GPU executa seus cálculos em sua fatia de tensor e os resultados são sincronizados no final para reconstruir o resultado final.

O paralelismo de tensor é eficaz para treinar modelos grandes que não cabem na memória de uma única GPU. Ele também é mais rápido e eficiente, pois cada GPU pode processar sua fatia de tensor em paralelo, e pode ser combinado com outros métodos de paralelismo. No entanto, como outros métodos de paralelismo, o paralelismo de tensor adiciona sobrecarga de comunicação entre as GPUs.

Consulte o guia de Paralelismo de tensor para aprender a usá-lo para inferência.

Paralelismo híbrido

Os métodos de paralelismo podem ser combinados para alcançar economias de memória ainda maiores e treinar modelos com bilhões de parâmetros de forma mais eficiente.

Paralelismo de dados e paralelismo de pipeline

O paralelismo de dados e de pipeline distribui os dados entre as GPUs e divide cada mini lote de dados em microlotes para alcançar o paralelismo de pipeline.

Cada rank de paralelismo de dados trata o processo como se houvesse apenas uma GPU em vez de duas, mas as GPUs 0 e 1 podem transferir micro-lotes de dados para as GPUs 2 e 3 e reduzir o tempo ocioso.

Essa abordagem otimiza o processamento paralelo de dados, reduzindo a ociosidade dos GPUs.

Paralelismo de dados ZeRO, paralelismo de pipeline e paralelismo de modelo (paralelismo 3D)

O paralelismo de dados, de pipeline e de modelo se combinam para formar o paralelismo 3D, otimizando a eficiência de memória e de computação.

A eficiência de memória é alcançada dividindo o modelo entre as GPUs e também separando-o em estágios para criar um pipeline. Isso permite que as GPUs trabalhem em paralelo em micro-lotes de dados, reduzindo o uso de memória do modelo, do otimizador e das ativações.

A eficiência de computação é habilitada pela paralelização de dados ZeRO, na qual cada GPU armazena apenas uma fatia do modelo, do otimizador e das ativações. Isso permite uma maior largura de banda de comunicação entre os nós de paralelismo de dados, pois a comunicação pode ocorrer de forma independente ou em paralelo com as outras etapas do pipeline.

Essa abordagem é escalável para modelos extremamente grandes com trilhões de parâmetros.

Update on GitHub