Phase 10 - Lesson 19
Paralelismo DualPipe
O DeepSeek-V3 foi treinado em 2.048 GPUs H800 com especialistas de MoE distribuídos entre nós. A comunicação all-to-all de especialistas entre nós custava 1 hora de GPU de comunicação para cada 1 hora de GPU de computação. As GPUs ficavam ociosas metade do tempo. O DualPipe (DeepSeek, Dez 2024) é um pipeline bidirecional que sobrepõe a computação forward e backward com as comunicações all-to-all que elas disparam. As bolhas diminuem, o throughput aumenta, e manter duas cópias dos parâmetros do modelo (o "dual" que dá nome ao método) é barato quando o Paralelismo de Especialistas (Expert Parallelism) já está distribuindo os especialistas entre os ranks de qualquer forma. Esta lição é um passo a passo do tipo Learn sobre o que o DualPipe realmente faz e por que o refinamento DualPipeV do Sea AI Lab elimina o custo de 2x parâmetros em troca de uma bolha ligeiramente maior.
Tipo: Learn Idiomas: Python (stdlib, simulador de cronograma) Pré-requisitos: Phase 10 · 05 (treinamento distribuído, FSDP, DeepSpeed), Phase 10 · 14 (arquiteturas de modelos abertos e MoE) Tempo: ~60 minutos
Objetivos de Aprendizado
- Nomear os quatro componentes de um chunk forward-backward do DualPipe e por que cada um tem sua própria janela de sobreposição.
- Explicar o problema da bolha de pipeline em escala e o que "livre de bolhas" significa na prática versus no marketing.
- Rastrear manualmente um cronograma DualPipe para 8 ranks de PP e 16 micro-batches e confirmar que os fluxos forward e reverso preenchem os espaços ociosos uns dos outros.
- Apresentar a compensação (tradeoff) que o DualPipeV (Sea AI Lab, 2025) faz: elimina a replicação de parâmetros de 2x à custa de uma bolha ligeiramente maior quando o Paralelismo de Especialistas está inativo.
O Problema
Treinar um modelo MoE de 671B em 2k GPUs H800 esbarra em três gargalos cumulativos:
- Pressão de memória. Cada GPU mantém uma fatia do modelo. A memória de ativação com sequência de 8k em 61 camadas e 128 heads é enorme.
- Bolhas de pipeline. O paralelismo de pipeline tradicional (GPipe, 1F1B) deixa as GPUs ociosas enquanto esperam pela entrada ou pelo gradiente de sua etapa. Com 8 estágios, cerca de 12% do tempo de GPU pode ser perdido em bolhas, mesmo com o agendamento 1F1B.
- All-to-all entre nós (cross-node). MoE com paralelismo de especialistas distribui os especialistas entre nós. Cada passagem forward dispara uma comunicação all-to-all para enviar (dispatch) tokens para seus especialistas, e outra para combiná-los (combine). Em 2k GPUs, isso facilmente se torna uma proporção de 1:1 entre computação e comunicação.
Cada um desses problemas tem soluções separadas: checkpointing de gradiente para memória, Zero Bubble (Sea AI Lab, 2023) para bolhas de pipeline e kernels de comunicação específicos para paralelismo de especialistas para all-to-all. O que o DualPipe faz é integrá-los. O cronograma sobrepõe computação e comunicação dentro de um único chunk forward-backward, injeta micro-batches de ambas as extremidades do pipeline simultaneamente e usa o cronograma resultante para ocultar o all-to-all dentro das janelas de computação.
Resultado relatado: quase eliminação das bolhas de pipeline, com mais de 95% de utilização de GPU na execução de treinamento de 14,8T tokens do DeepSeek-V3.
O Conceito
Recapitulação do paralelismo de pipeline
Divida um modelo de N camadas em P dispositivos. O dispositivo i mantém as camadas i * N/P .. (i+1) * N/P - 1. Um micro-batch flui no sentido forward pelos dispositivos 0 a P-1 e, em seguida, no sentido backward de P-1 a 0. Cada dispositivo só pode iniciar sua etapa forward quando o dispositivo anterior envia sua saída, e só pode iniciar o backward quando o dispositivo downstream envia o gradiente upstream.
O GPipe (Huang et al., 2019) agenda um micro-batch de cada vez, o que desperdiça a maior parte do tempo de GPU. O 1F1B (Narayanan et al., 2021) intercala as passagens forward e backward para múltiplos micro-batches. O Zero Bubble (Qi et al., 2023) divide a passagem backward em duas partes — backward para entrada (B) e backward para pesos (W) — e as agenda para preencher a bolha. Após o Zero Bubble, o pipeline fica quase totalmente otimizado.
O DualPipe é o próximo passo. Ele adiciona duas ideias principais:
Ideia 1: decomposição em chunks
Cada chunk forward é dividido em quatro componentes:
- Attention. Projeções Q/K/V, atenção, projeção de saída.
- All-to-all dispatch. Comunicação entre nós que envia tokens para seus especialistas.
- MLP. A computação dos especialistas do MoE.
- All-to-all combine. Comunicação entre nós que traz de volta as saídas dos especialistas.
Um chunk backward adiciona as versões de gradiente de cada um desses componentes. O DualPipe os agenda de forma que o all-to-all dispatch ocorra em paralelo com a computação de atenção (attention compute) do próximo chunk, e o all-to-all combine ocorra em paralelo com a computação do MLP (MLP compute) do chunk seguinte.
Ideia 2: agendamento bidirecional
A maioria dos cronogramas de pipeline injeta micro-batches a partir do estágio 0, fluindo em direção ao estágio P-1. O DualPipe injeta micro-batches a partir de AMBAS as extremidades. O estágio 0 vê micro-batches forward originando-se ali; o estágio P-1 também vê micro-batches forward originando-se ali. Os dois fluxos se encontram no meio.
Para que isso funcione, o dispositivo i deve conter TANTO a camada inicial do pipeline i QUANTO a camada final do pipeline P - 1 - i. Essa é a parte "dual" do DualPipe: cada dispositivo mantém duas cópias das camadas do modelo que precisa processar (uma para cada direção). Na escala do DeepSeek-V3, isso gera um custo de replicação de parâmetros de 2x. Isso é viável porque o Paralelismo de Especialistas já distribui os especialistas de MoE de forma tão pulverizada que duplicar as camadas que não são de especialistas é um custo insignificante.
Crucialmente, o fluxo forward em uma direção e o fluxo backward na outra direção se sobrepõem exatamente onde estariam as bolhas em um cronograma unidirecional. As bolhas desaparecem.
Rastreamento manual do cronograma
Considere P = 4 ranks, 8 micro-batches, divididos em 4 forward / 4 reversos. O tempo se move da esquerda para a direita; as linhas representam os ranks dos dispositivos.
Time →
rank 0: F1 F2 F3 F4 F5R F6R F7R F8R B1 B2 B3 B4 ...
rank 1: F1 F2 F3 F4/F5R F6R F7R B1 B2 ...
rank 2: F1 F2 F3/F5R F4/F6R B1 ...
rank 3: F1 F2/F5R F3/F6R ...
Lendo a notação "F4/F5R": o rank 1 está executando o forward do micro-batch 4 (indo da esquerda para a direita no pipeline) E o forward do micro-batch 5 (indo da direita para a esquerda) no mesmo intervalo de tempo. É isso que "bidirecional" significa operacionalmente.
No rank 2, os fluxos cruzados se sobrepõem mais cedo; nos ranks 0 e P-1, a sobreposição ocorre por último. Na fase intermediária estável do cronograma, cada rank executa o forward da direção X sobreposto ao backward da direção Y. A computação está ocupada. Os envios all-to-all (all-to-all dispatches) para a passagem forward ficam ocultos dentro da computação backward. As combinações all-to-all (all-to-all combines) ficam ocultas dentro da computação forward. As bolhas são eliminadas.
Contabilidade de bolhas
Bolha de pipeline padrão no 1F1B (tempo desperdiçado por rank):
bubble_1F1B = (P - 1) * forward_chunk_time
O refinamento Zero Bubble reduz esse valor, mas não a zero. O DualPipe, na fase estável, tem bolha zero se a contagem de micro-batches for divisível por 2 vezes a profundidade do pipeline. Fora da fase estável (warmup e cooldown), existe alguma bolha, mas ela não cresce com o número de micro-batches — uma propriedade fundamental que o artigo destaca.
Em termos de marketing: "livre de bolhas" (bubble-free). Em termos técnicos: as bolhas não crescem com a contagem de micro-batches. A análise subsequente do Sea AI Lab (DualPipeV / Cut-in-half) mostra a ausência total de bolhas (zero-bubble) apenas quando o Paralelismo de Especialistas não é o gargalo; com all-to-all orientado por EP, algum comprometimento no agendamento sempre se faz presente.
DualPipeV — o refinamento
O Sea AI Lab (2025) observou que a replicação de parâmetros de 2x é desnecessária quando a sobreposição de comunicação de EP não é o objetivo principal. Seu cronograma DualPipeV dobra a injeção bidirecional em um formato de "V" que roda em uma única cópia dos parâmetros. A bolha é ligeiramente maior que a do DualPipe, mas a economia de memória é substancial. A DeepSeek adotou o DualPipeV em sua implementação open-source do DualPipe como um modo "EP-off" (sem EP).
O tradeoff:
| Recurso | DualPipe | DualPipeV | 1F1B | Zero Bubble |
|---|---|---|---|---|
| Cópias de parâmetros por dispositivo | 2 | 1 | 1 | 1 |
| Bolha vs micro-batches | constante | pequeno crescimento | cresce | cresce |
| Sobreposição computação-comunicação | total | parcial | mínima | parcial |
| Usar quando | MoE com muito EP | denso ou pouco EP | linha de base | qualquer pipeline |
O que isso significa para uma execução de 14.8T de tokens
O pré-treinamento do DeepSeek-V3 consumiu 14,8T de tokens em 2.048 GPUs H800 em aproximadamente 2,8M de horas-GPU. Com o 1F1B básico, eles teriam perdido de 12% a 15% disso com bolhas de pipeline — de 340k a 420k horas-GPU, o suficiente para treinar um modelo completo de 70B. O DualPipe recuperou a maior parte disso. Quantificar diretamente essa contribuição é difícil sem os logs internos, mas a afirmação no artigo é de mais de 95% de utilização média das GPUs durante o treinamento.
Para execuções menores (menos de 1k GPUs), o DualPipe é excessivo (overkill) — as bolhas de pipeline são menores em relação ao custo total, e o treinamento de modelos densos raramente atinge o gargalo de all-to-all. Para o treinamento de MoE de ponta em escala de milhares de GPUs, ele é efetivamente obrigatório.
Onde ele se situa no stack
- Complementar ao FSDP (Phase 10 · 05). O FSDP divide os parâmetros do modelo entre os ranks; o DualPipe agenda a computação entre os ranks. Eles se combinam.
- Compatível com o sharding de gradientes do ZeRO-3. A contabilidade para a replicação de duas cópias precisa cooperar com os gradientes sharded do ZeRO.
- Requer kernels customizados de all-to-all sintonizados para a topologia específica do cluster. Os kernels open-source da DeepSeek são a implementação de referência.
Use It
O arquivo code/main.py é um simulador de cronograma de pipeline. Ele recebe (P, n_micro_batches, schedule) e imprime a utilização na fase estável para cada um dos métodos: 1F1B, Zero Bubble, DualPipe e DualPipeV. É uma ferramenta didática — os números correspondem às afirmações qualitativas nos artigos, não sendo uma garantia de aceleração medida em produção.
O valor do simulador: execute-o com diferentes valores de P e contagens de micro-batches e observe como a fração de bolha cresce para o 1F1B, mas não para o DualPipe.
Considerações de integração para uma execução de treinamento real:
- Escolha uma profundidade paralela de pipeline que divida perfeitamente a sua contagem de micro-batches.
- Garanta que sua malha paralela de especialistas (expert-parallel mesh) suporte all-to-all bidirecional. Os kernels da DeepSeek são a referência.
- Espere gastar uma semana depurando o cronograma na primeira vez. O controle de estados (bookkeeping) é complexo.
- Monitore a utilização de GPU por rank, não apenas a agregada. O benefício do DualPipe vem do ajuste dos ranks mais lentos (stragglers).
Ship It
Esta lição produz o arquivo outputs/skill-dualpipe-planner.md. Dada uma especificação de cluster de treinamento (quantidade de GPUs, topologia, interconexão, formato do modelo), ele recomenda uma estratégia de paralelismo de pipeline, o algoritmo de agendamento a ser usado e a fração de bolha esperada na escala desejada.
Exercícios
Execute
code/main.pycom(P=8, micro_batches=16, schedule=dualpipe)e(P=8, micro_batches=16, schedule=1f1b). Calcule a diferença de utilização de GPU e expresse-a como horas-GPU recuperadas por milhão de tokens de treinamento.Desenhe à mão a tabela de cronograma para
(P=4, micro_batches=8, schedule=dualpipe). Marque cada intervalo de tempo com o ID do micro-batch e a direção. Identifique o primeiro intervalo de tempo onde não há bolhas.Leia a Figura 5 do relatório técnico do DeepSeek-V3 (arXiv:2412.19437). Identifique a janela de sobreposição para all-to-all dispatch dentro de um chunk forward do DualPipe. Explique como o cronograma de computação a oculta.
Calcule o overhead de 2x parâmetros do DualPipe para um modelo denso de 70B com P=8 estágios de pipeline e um modelo MoE de 671B com P=16 estágios de pipeline. Mostre por que o overhead no caso do MoE é proporcionalmente menor (a maioria dos parâmetros são especialistas, divididos em um grande grupo de EP).
Compare o DualPipe ao Chimera (um agendador bidirecional concorrente de 2021). Identifique as duas propriedades específicas que o DualPipe adicionou e que o Chimera não possuía, usando a Seção 3.4 do artigo como referência.
Termos-Chave
| Termo | O que dizem | O que realmente significa |
|---|---|---|
| Bolha de pipeline (Pipeline bubble) | "Tempo ocioso por rank" | Ciclos de GPU desperdiçados porque uma etapa de pipeline está esperando por sua entrada ou gradiente |
| 1F1B | "Cronograma padrão de pipeline" | Agendamento intercalado de um forward / um backward; a linha de base que o DualPipe supera |
| Zero Bubble | "Sea AI Lab 2023" | Divide o backward em B (gradiente de entrada) e W (gradiente de peso); quase otimiza o pipeline por completo |
| DualPipe | "Cronograma do DeepSeek-V3" | Pipeline bidirecional + sobreposição computação-comunicação; as bolhas não crescem com a contagem de micro-batches |
| DualPipeV | "Cut-in-half" | Refinamento em formato de V que elimina a replicação de parâmetros de 2x à custa de bolhas ligeiramente maiores |
| Chunk | "Unidade de trabalho do pipeline" | Uma passagem forward ou backward de um micro-batch por um estágio de pipeline |
| All-to-all dispatch | "Enviar tokens para os especialistas" | Comunicação entre nós que roteia tokens para seus especialistas MoE atribuídos |
| All-to-all combine | "Trazer de volta as saídas dos especialistas" | Comunicação entre nós que reúne as saídas dos especialistas após o MLP |
| Paralelismo de Especialistas (EP) | "Especialistas entre GPUs" | Divide os especialistas MoE entre os ranks para que diferentes GPUs guardem diferentes especialistas |
| Paralelismo de Pipeline (PP) | "Camadas entre GPUs" | Divide as camadas do modelo entre os ranks; a dimensão que o DualPipe agenda |
| Fração de bolha | "Tempo de GPU desperdiçado" | (tempo_de_bolha / tempo_total); a fração que o DualPipe reduz a quase zero |
Leituras Adicionais
- DeepSeek-AI — DeepSeek-V3 Technical Report (arXiv:2412.19437), Section 3.3.2 and Figure 5 — a referência principal do DualPipe
- DeepSeek — DualPipe GitHub repository — a implementação de referência de código aberto, incluindo o modo DualPipeV (Cut-in-half)
- Qi et al. — Zero Bubble Pipeline Parallelism (arXiv:2401.10241, Sea AI Lab 2023) — o predecessor do Zero Bubble
- Sea AI Lab — DualPipe could be better without the Dual — a análise do DualPipeV que informou o modo EP-off da DeepSeek
- Narayanan et al. — PipeDream / 1F1B (arXiv:1806.03377, 2018-2021) — o cronograma 1F1B com o qual o DualPipe se compara
- Huang et al. — GPipe (arXiv:1811.06965, 2018) — o artigo original sobre paralelismo de pipeline e o problema das bolhas