[!NOTE] Tradução automática Este artigo foi traduzido automaticamente a partir da versão original em inglês.

Escalonamento de Modelos de Língua Grande: Estratégias Multi-GPU e Multi-Nó que Funcionam na Prática

As cargas de trabalho com modelos grandes ultrapassam o limite de um único GPU por diferentes motivos. Um job de treino pode esgotar a memória devido ao estado do otimizador, outro devido às ativações de sequências longas, e mesmo um modelo que se encaixa nos requisitos pode ainda não atingir o seu objetivo de taxa de processamento. Cada problema exige um padrão de particionamento e comunicação distinto.

Trata‑se de uma explicação prática das principais estratégias de paralelismo e dos constrangimentos que as regem, baseada nas informações fornecidas por Hugging Face’s Manual de Operações em Escala Ultra-Alta. O objetivo é demonstrar o que cada divisão traz de benefícios, o que ela comunica e quando se tornam necessárias combinações entre elas.

TL;DR. O paralelismo de dados replicado aumenta a taxa de treino sempre que cabe uma réplica. O paralelismo de dados totalmente shardizado divide o estado do modelo, mas acarreta operações adicionais de coleta de parâmetros e dispersão/redução de gradientes. Já o paralelismo de tensores, pipeline, contexto e especialistas divide as operações matemáticas das camadas, a profundidade, as sequências e os especialistas MoE. Devem ser combinados apenas após identificar as restrições de memória ou comunicação envolvidas.

Este guia pressupõe que você já tenha familiaridade com a retropropagação, as camadas Transformer e um ciclo de treino padrão PyTorch.

Comece com dois orçamentos de memória

O treino e a inferência não apresentam o mesmo impacto em termos de recursos.

training peak ≈ parameters
              + gradients
              + optimizer state
              + saved activations
              + temporary buffers
              + communication buffers
              + allocator headroom

inference peak ≈ resident weights
               + KV cache
               + runtime workspace
               + communication buffers
               + allocator headroom

Um modelo com 70 mil milhões de parâmetros exige um limite inferior de 140 GB em formato decimal apenas para os pesos de BF16. Esse valor revela pouca informação sobre o processo de treino, no qual gradientes, estado do otimizador, pesos mestre e ativações podem ter um papel preponderante. Além disso, ele não reflete as dimensões necessárias para serving, onde políticas de cache, comprimento das sequências, concorrência entre lotes e quantização são fatores cruciais.

Analise em detalhe a arquitetura exata, a precisão, o comprimento da sequência, o tamanho dos micro-lotes, o otimizador, a política de criação de pontos de controle e runtime. Registe a memória máxima alocada e reservada, os tokens por segundo, o tempo gasto nos kernels e o tempo de execução dentro dos collectives.

A escalabilidade distribuída começa com a identificação de um gargalo mensurável.

Cada dimensão paralela implica um compromisso

A pergunta relevante não é “Qual técnica é a melhor?”, mas sim “Qual dimensão do tensor é dividida, qual estado é replicado e qual estrutura coletiva entra no caminho crítico?”

EstratégiaDivisõesAlívio primárioComunicação estabelecida
Paralelismo de dados replicadolotelargura de banda de treinoredução global por gradiente
Paralelismo de dados totalmente shardadoparâmetros, gradientes e estado do otimizador em todo um grupo de DPmemória de estado do modeloparâmetro all-gather, redução de gradiente por scatter
Paralelismo de tensoresdimensões da matriz ou de atenção dentro das camadaspesos e ativações de camadacoletivos dentro de blocos Transformer
Pipeline paralelismogrupos de camadasprofundidade do modelo e estado por faseativações ponto-a-ponto associadas a bolhas de agendamento
Paralelismo de contextodimensão da sequênciamemória de ativação para sequências longastroca de chave/valor ou de atenção entre os grupos de sequências
Paralelismo especializadoMoE especialistas e tokens roteadoscapacidade de especialista por níveldisparo e combinação de tokens, geralmente no formato all-to-all

O alívio de memória não é um multiplicador fixo. Depende do grau de fragmentação, do que permanece replicado, do estado temporário não fragmentado, da política de ativação, do preenchimento, do desequilíbrio e dos buffers.

Paralelismo de dados replicado: largura de banda sem limitações de capacidade

Treino em paralelo com dados replicados

O paralelismo de dados distribuído mantém uma réplica completa do treino em cada nó da rede. Cada nó lida com um micro-lote diferente, e os gradientes são sincronizados antes da atualização realizada pelo otimizador.

Utilize-o quando o estado completo de treino cabe com margem de segurança suficiente, e quando é possível aumentar o lote global ou ajustar a acumulação de gradientes. As suas principais vantagens residem na semântica simples e na integração eficaz entre o cálculo retroativo e a redução de gradientes por blocos.

Adicionar rankings pode ser prejudicial se o lote local se tornar demasiado pequeno, se a rede não conseguir ocultar o processo de all-reduce, se houver atrasos na entrega das entradas, ou se o lote de otimização desejado não for escalável.

Paralelismo de dados totalmente shardizado: memória de estado para coletivos

Execução paralela de dados totalmente shardada

O paralelismo de dados totalmente shardizado armazena os shards de parâmetros, gradientes e otimizadores em todo um grupo. Os parâmetros de uma camada são reunidos para efeitos de cálculo e podem ser re-shardizados posteriormente; os gradientes, por sua vez, são dispersados de forma reduzida de volta aos seus respectivos proprietários.

A documentação atual PyTorch diferencia as funcionalidades do FSDP2 fully_shard API proveniente das versões mais antigas FullyShardedDataParallel envoltório. O FSDP2 agrupa a comunicação de acordo com os módulos aos quais fully_shard É aplicado e recomenda uma abordagem bottom-up, de modo que os grupos de camadas possam sobrepor a comunicação e o processamento.

from torch.distributed.fsdp import fully_shard


# Apply bottom-up: each block becomes a communication group.
for block in model.transformer.blocks:
    fully_shard(block)

# Shard remaining root parameters such as embeddings and output projection.
fully_shard(model)

# Construct the optimizer after parameters have become sharded DTensors.
optimizer = AdamW(model.parameters(), lr=learning_rate)

Trata‑se de um esboço estrutural, e não de um lançador completo. As malhas de dispositivos, a precisão mista, o salvamento de pontos de verificação, a inicialização, o estado do otimizador e os processos distribuídos checkpoints devem ser compatíveis com a pilha de treino.

O sharding torna-se atraente quando o estado do modelo representa a restrição determinante e o processamento em camadas consegue ocultar uma parte suficiente do tráfego coletivo. No entanto, pode ser uma escolha pouco vantajosa para modelos pequenos, ligações lentas, camadas reduzidas ou estruturas cujo grupo de shards atravessa limites topológicos inadequados.

Paralelismo de tensores: matemática da particionamento de camadas

Partição da camada paralela de tensores

O paralelismo de tensores divide as operações de álgebra linear dentro de uma camada — como, por exemplo, as projeções colunar e horizontalmente paralelas. Os resultados parciais exigem operações coletivas nos blocos de transformador, pelo que a latência e a largura de banda são fatores cruciais em todas as etapas dos passos forward e backward.

Utilize-o quando uma camada ou as suas ativações não se encaixam, ou quando os produtos matriciais são suficientemente grandes para que kernels particionados apresentem um desempenho superior face a um único rank. Associe o grupo de tensores paralelos ao domínio de comunicação mais rápido disponível e, em seguida, efetue as medições. Um grau elevado pode reduzir cada matriz local até que a eficiência do kernel diminua, ao mesmo tempo que o overhead coletivo aumenta.

O paralelismo de sequências é frequentemente combinado com o paralelismo de tensores para evitar a repetição de algumas operações de ativação; ele difere do paralelismo de contexto, que abrange toda a sequência de entrada do modelo.

Pipeline paralelismo: profundidade de particionamento e tempo de agendamento

Pipeline fases paralelas e micro-lotes

Pipeline O paralelismo distribui diferentes grupos de camadas por fases distintas, enviando ativações entre elas. Os micro-lotes permitem que as fases operem em simultâneo.

Alivia o estado do modelo em cada fase e consegue reduzir o volume de comunicação que atravessa uma fronteira mais lenta, em comparação com os métodos de coleta de tensores por camada. Os seus custos incluem “bolhas” de dados, transferências de ativações, desequilíbrio entre fases, agendamento mais complexo, bem como recuperação e criação de pontos de verificação mais difíceis.

Para um agendamento simples e equilibrado no estilo GPipe com p estágios e m micro-lotes, a fração idealizada da bolha de avanço é aproximadamente:

(p - 1) / (m + p - 1)

Os cronogramas reais podem utilizar variantes como one-forward/one-backward, interleaving ou zero-bubble, e os custos de camada desiguais podem dominar a fórmula de cálculo. Escolham os limites entre fases com base no tempo e na memória efetivamente medidos, e não no número igual de camadas.

Paralelismo de contexto: particionamento de ativações de sequências longas

Intercâmbio de atenção paralela no contexto

O paralelismo de contexto distribui a dimensão da sequência. Cada nó possui um fragmento de sequência, enquanto o mecanismo de atenção troca as informações necessárias para preservar a semântica de contexto completo. As implementações podem recorrer a estruturas em anel ponto-a-ponto, operações all-gather, all-to-all ou combinações hierárquicas.

Reduz a memória de ativação necessária para o treino com contexto longo, mas replica os pesos em todo o grupo de contexto e introduz mecanismos de comunicação por atenção. O benefício depende do tipo de atenção utilizado, do mascaramento causal, do comprimento da sequência, da recálculo dos valores e da forma como os grupos de contexto se combinam com grupos paralelos baseados em tensores e dados.

Não o selecione com base num limiar universal de 8K, 32K ou 100K. Utilize a memória de ativação de perfil e a comunicação de atenção adequadas à arquitetura específica.

Paralelismo especializado: apenas para uma arquitetura MoE

Roteamento de tokens em paralelo por especialistas

O paralelismo especializado distribui os especialistas nas camadas de mistura de especialistas. O router envia representações de tokens para os especialistas selecionados e combina os seus resultados. Apenas os especialistas escolhidos realizam o cálculo para cada token, mas os pesos totais dos especialistas continuam a exigir armazenamento e localização em serving.

Trata‑se de um elemento que faz parte da arquitetura MoE e não de um interruptor de otimização para modelos densos. Ele permite gerir o equilíbrio de carga, a capacidade, a comunicação token‑a‑token, os tokens descartados ou preenchidos, as perdas auxiliares e a assimetria em caso de falha. É possível monitorizar os tokens por especialista, a entropia de roteamento, o transbordamento de capacidade, o tempo de comunicação e a qualidade de acordo com cada rota.

Compor um layout a partir da topologia

Os sistemas de treino de grande escala combinam diferentes dimensões. O tamanho total do mundo geralmente segue uma estrutura de produto, como:

world size = DP × TP × PP × CP

O paralelismo avançado pode partilhar ou dobrar dimensões de forma diferente; portanto, verifique a malha suportada pelo framework em vez de multiplicar os valores de forma indiscriminada.

Construa o layout nesta ordem:

  1. Desenhar os domínios de comunicação: ligações GPU-para-GPU, comutadores, limites NUMA, estrutura de nodos, sobrescrição e caminho de armazenamento.
  2. Colocar os conjuntos sensíveis à latência, geralmente TP, no domínio mais rápido e adequado.
  3. Selecionar FSDP ou grupos DP replicados a partir da capacidade e largura de banda restantes.
  4. Adicionar PP sempre que haja benefícios na colocação em profundidade ou no tráfego entre domínios, equilibrando o tempo de processamento medido com o uso de memória.
  5. Adicionar CP apenas devido à restrição de sequência, e EP apenas para a topologia especializada do modelo.
  6. Verificar se as dimensões dos cabeçalhos, dimensões ocultas, camadas, especialistas, lotes e sequências são divisíveis para a malha candidata.
  7. Benchmark existem várias malhas válidas; heurísticas sensíveis à topologia selecionam os candidatos, e não necessariamente os melhores.

Dois clusters com o mesmo número de GPU podem optar por layouts diferentes, uma vez que a largura de banda das ligações, a hierarquia dos switches, a conexão CPU e a concorrência na rede variam entre eles.

O treinamento e o serving exigem decisões separadas

A inferência geralmente não transporta gradientes nem o estado do otimizador, pelo que os esquemas de treino no estilo FSDP não são transferidos automaticamente.

Para serving, pergunte:

Benchmark o servidor completo, que inclui o agendador, mecanismos de quantização, sistema de distribuição de contexto, política de agrupamento de solicitações e modelagem da carga de tráfego. O número de tokens processados por segundo não consegue prever o serving tempo necessário até a geração do primeiro token, nem a latência entre eles.

Medir com precisão o layout de escalonamento

Para cada candidato, registe:

Compare deliberadamente a escala fraca e a escala forte. A escala fraca aumenta o trabalho total à medida que o número de ranks aumenta; a escala forte mantém o trabalho total constante. Uma percentagem rotulada como “eficiência de escala” não tem sentido sem esse denominador e sem um valor de referência.

Conclusão

O paralelismo consiste numa mapeamento de um gargalo identificado para uma dimensão do tensor e um padrão de comunicação. A replicação, o shardização, a partição por camadas, o estágio intermediário, a partição por sequência e o encaminhamento especializado atuam cada uma para aliviar uma restrição distinta e gerar um modo de falha diferente.

Inventariar a carga de trabalho, desenhar a topologia, gerar malhas válidas e criar os seus perfis. O layout vencedor é aquele que se adapta ao espaço disponível e minimiza as comunicações expostas para a tarefa que efetivamente se executa.

Referências