Menor laténcia e maior taxa de transferäncia com implantação DeepSeek multi-nó

Implantação multi-GPU aumenta desempenho de modelo MoE simultaneamente em velocidade e escala

AutoresPerplexity Research

Na maioria dos sistemas, a latência e a taxa de transferência (throughput) são, frequentemente, objetivos conflitantes que exigem concessões durante o projeto e a implantação. Por exemplo, em modelos de linguagem grandes e densos, aumentar o tamanho do lote (batch size) pode melhorar a taxa de transferência, mas também aumenta a laténcia; aumentar o paralelismo de tensores dentro de uma ónica máquina pode reduzir a laténcia, mas diminui o número de réplicas, levando a uma taxa de transferäncia menor.

Modelos de Mistura de Especialistas (MoE), como o DeepSeek-V3/R1, demonstraram recentemente capacidades de modelo e eficiéncia operacional excelentes. Por exemplo, o modelo DeepSeek-V3/R1 possui 671B de parâmetros no total, mas cada token utiliza apenas 37B de parâmetros durante a inferéncia. Esta arquitetura de modelo apresenta desafios e oportunidades para sistemas de inferéncia.

Este artigo demonstra que, contrariamente aos sistemas convencionais, modelos MoE como o DeepSeek-V3/R1 podem alcançar simultaneamente uma taxa de transferäncia maior e uma laténcia menor ao utilizar mais GPUs em implantações multi-nó na maioria dos cenários.

Arquiteturas de Implantação

Implantação em nó único via NVLink, com atenção e computação de especialistas distribuídas entre GPUs.
Implantação multinó via InfiniBand, com grupos de GPUs conectados dentro dos nós e entre eles.

Devido ao grande número de pequenos especialistas que o modelo possui, as implantações devem ser distribuídas por vários dispositivos. Consideramos tanto implantações de nó ónico em um ónico nó com GPUs 8xH200 quanto implantações multi-nó em GPUs 8xH100.

Ambas as arquiteturas de implantação aproveitam o Paralelismo de Dados, orquestrado através do nosso agendador de solicitações interno. A implementação do paralelismo de dados envolve o lançamento de várias instâncias do mecanismo de inferéncia, cada uma operando independentemente para atender e manter solicitações. O agendador de solicitações, que interage com o mecanismo através de GRPC, é responsável por distribuir as solicitações o mais uniformemente possível, facilitando também a reutilização de KV, enviando solicitações com prefixo parcial correspondente aos servidores que contém o cache. As instâncias do mecanismo não abrangem móltiplos nós. Elas podem, opcionalmente, usar paralelismo de tensores para fragmentar a atenção entre móltiplos dispositivos. As instâncias são interconectadas via NVLink no caso de nó ónico ou InfiniBand para o caso multi-nó, despachando e coletando especialistas.

A configuração de implantação de nó ónico oferece uma laténcia superior com tamanhos de lote pequenos; no entanto, o desempenho degrada rapidamente sob condições de carga aumentada.

Para implantar o mecanismo de serviço, lançamos um pod por nó hospedando várias instâncias do mecanismo. O PyTorch é responsável por configurar a comunicação distribuída e negociar a inicialização do NVSHMEM. Para comunicação, baseamo-nos em kernels CUDA personalizados descritos em uma postagem de blog anterior. A implementação das duas implantações é praticamente idéntica, com o modelo escolhendo os kernels corretos a serem usados com base no tecido que implementa o paralelismo de especialistas.

Técnicas de paralelização

Antes de mergulhar em nossas comparações de desempenho, é essencial entender as principais estratégias de paralelização que tornam possível a implantação de modelos MoE massivos como o DeepSeek-V3/R1.

Paralelismo de Tensores

Na inferéncia LLM, o Paralelismo de Tensores (TP) é normalmente usado para reduzir o uso de memória e o cálculo por GPU, reduzindo assim a laténcia. Normalmente, podemos fragmentar Projeções Lineares em Camadas de Atenção e MLP ao longo das dimensões de linha ou coluna, e fragmentar operações de Atenção ao longo da dimensão da cabeça de atenção.

Com TP, a arquitetura Llama-3 não tem computação duplicada para Projeção Linear e operações de Atenção entre GPUs, o que é um método de fragmentação ideal. No entanto, nos modelos DeepSeek-V3/R1, o TP não pode alcançar isso.

Os modelos DeepSeek-V3/R1 usam Multi-Latent Attention (MLA). Uma Camada MLA usa primeiro uma Projeção Linear kv_a_proj para calcular o vetor latente, depois usa outra Projeção Linear kv_b_proj para transformá-lo no espaço de cada cabeça de atenção. Como todas as cabeças de atenção compartilham o mesmo vetor latente, o TP não pode fragmentar o vetor latente, portanto, todos os Ranks de TP precisam replicar os parâmetros e o cálculo de kv_a_proj e kv_b_proj. Da mesma forma, como o MLA armazena o vetor latente no Cache KV, cada Rank de TP armazena uma cópia idéntica do Cache KV.

Apesar de alguma duplicação no MLA, o Paralelismo de Tensores ainda fornece redução parcial nas demandas de computação, tornando-o valioso para cenários que exigem altas velocidades de saída.

Paralelismo de Especialistas

Os modelos DeepSeek-V3/R1 substituem as Camadas MLP por Camadas MoE. Uma Camada MoE tem 256 especialistas roteados e um especialista compartilhado. Cada token é despachado para 8 especialistas roteados diferentes para cálculo, e os resultados são somados ponderadamente. Cada token também calcula no especialista compartilhado, e o resultado é adicionado ao resultado dos especialistas roteados.

O Paralelismo de Especialistas (EP) serve como a abordagem típica de fragmentação para Camadas MoE, com cada GPU gerenciando 256 / EP especialistas roteados enquanto mantém uma cópia do especialista compartilhado. Comparado ao TP, a vantagem do EP é que ele pode distribuir a computação entre mais GPUs, reduzindo o uso de computação e memória por GPU.

Antes de realizar a computação especializada, todas as GPUs precisam realizar uma comunicação AllToAll para despachar tokens para as GPUs onde os especialistas correspondentes estão localizados; após a computação especializada, outra comunicação AllToAll é necessária para coletar resultados de computação de várias GPUs e realizar a soma ponderada. Implementamos uma versão otimizada desses dois Kernels de comunicação AllToAll, Dispatch e Combine, usando NVSHMEM. Em nossa postagem de blog anterior, detalhamos a implementação, e nossos kernels foram de código aberto no GitHub.

Paralelismo de Dados

Com o EP, podemos distribuir a computação MoE entre 128 ou até mais GPUs. No entanto, o cálculo de MLA não pode ser particionado com EP. Nesse ponto, podemos introduzir o Paralelismo de Dados (DP). Cada Grupo DP tem uma cópia completa da Camada MLA. Cada Grupo DP aceita entradas diferentes e realiza o cálculo da Camada MLA independentemente.

O DP e o TP da camada MLA podem ser combinados, com um Grupo DP sendo dividido em móltiplos Ranks de TP. O EP da camada MoE pode ser combinado com o DP/TP da Camada MLA. EP = DP * TP. Por exemplo, em 16 máquinas, EP128 DP32 TP4 significa distribuir especialistas roteados entre 128 GPUs, com cada 4 GPUs formando um Grupo DP, para um total de 32 Grupos DP independentes.

Nó Ónico vs. Multi-Nó

Os 671B de parâmetros do DeepSeek excedem a capacidade de memória de uma ónica máquina H100 de 8 GPUs (80 GB * 8), mas uma ónica máquina H200 de 8 GPUs pode acomodar totalmente todo o modelo (141 GB * 8). Usando a configuração EP8 DP8 TP1, o modelo usa cerca de 100 GB de memória por GPU, deixando aproximadamente 40 GB para o Cache KV e outros resultados intermediários. Um token ocupa 70.272 bytes de Cache KV. Supondo que cada solicitação tenha 5.000 tokens, cada GPU pode acomodar cerca de 100 solicitações.

Queríamos entender as diferenças de desempenho entre implantações de nó ónico e multi-nó sob diferentes configurações. Usamos uma máquina H200 para implantação de nó ónico e até 16 máquinas H100 para implantações multi-nó. Para cada ambiente de implantação, usamos combinações de TP 1, 2, 4, 8, e tamanhos de lote por GPU de 1, 2, 4, 8, 16, 32, 64, 128. Assumimos que cada solicitação tinha um comprimento de Cache KV de 5.000 tokens. Também assumimos que a Multi-Token Prediction (MTP) prevê 1 token adicional (ou seja, o comprimento da consulta de cada solicitação é 2), e assumimos conservadoramente uma taxa de aceitação de 60%. A figura abaixo mostra a taxa de transferäncia e a velocidade de saída para diferentes configurações.

Frentes de Pareto de latência versus throughput para diferentes configurações de paralelismo de especialistas.

O eixo horizontal representa a velocidade de saída por solicitação em tokens/s. O eixo vertical usa uma escala logarítmica para mostrar a taxa de transferäncia por máquina em tokens/s. Marcamos a Fronteira de Pareto para cada configuração de EP com linhas coloridas diferentes.

Em cenários com requisitos de velocidade de saída extremamente altos, usar EP8 DP1 TP8 de nó ónico com um tamanho de lote de 1 pode alcançar uma velocidade de saída superior a 100 tokens/s, mas a taxa de transferäncia é extremamente baixa, equivalente à velocidade de saída. Neste cenário, todo o lote tem apenas 2 tokens, que podem ser despachados para no máximo 2*8=16 especialistas, ativando um total de no máximo 57B de parâmetros.

Na faixa de velocidade de saída de 80-40 tokens/s, à medida que a taxa de transferäncia aumenta, a velocidade de saída diminui significativamente. Em contraste, o EP128 tem uma taxa de transferäncia cerca de 5x maior do que a implantação de nó ónico na mesma velocidade de saída.

Este fenômeno pode ser explicado examinando como as implantações de nó ónico se comportam: aumentar o tamanho do lote correlaciona-se diretamente com um aumento nos especialistas ativados. Quando o tamanho do lote é 1, o número médio de especialistas ativados por GPU é 2 * 8 / 8 = 2. Quando o lote é grande o suficiente, todos os especialistas são ativados, o que significa que cada GPU ativa 256 / 8 = 32 especialistas. Ativar mais especialistas significa que a GPU precisa ler mais parâmetros da memória, aumentando significativamente a pressão da largura de banda da memória. Como a fase de decodificação de modelos de linguagem grandes já está limitada pela largura de banda da memória em vez do desempenho de computação, aumentar o tamanho do lote na implantação de nó ónico reduz significativamente a velocidade de saída.

A comparação das quatro configurações de implantação multi-nó (EP16, EP32, EP64 e EP128) revela que valores de EP mais altos deslocam a Fronteira de Pareto em direção a melhorias simultâneas na taxa de transferäncia e na velocidade de saída.

Usar um número de EP mais alto significa que cada GPU recebe menos especialistas. Por exemplo, EP128 significa que cada GPU é responsável por 256 / 128 = 2 especialistas, portanto, a pressão da largura de banda da memória é reduzida significativamente. Em outras palavras, ao usar um número de EP maior, ganhamos efetivamente mais largura de banda de memória. Quando o tamanho do lote por GPU é inferior a 64, aumentar o tamanho do lote não afeta significativamente a velocidade de computação especializada, porque aumentar o número de entradas não aumenta significativamente a pressão da largura de banda da memória. Portanto, observamos que, ao usar EP128, aumentar o tamanho do lote não afeta a velocidade de saída tão significativamente.

Curiosamente, em tamanhos de lote maiores (64 solicitações por GPU), observamos um novo fenômeno: a taxa de transferäncia da implantação de nó ónico é ligeiramente maior do que a da implantação multi-nó. Parte da razão é que o NVLink intra-nó tem largura de banda maior que o InfiniBand inter-nó. Outra parte deve-se a limitações em nossa implementação. Analisaremos esse fenômeno com mais detalhes posteriormente.

Devido a limitações de capacidade de memória, a configuração EP8 DP8 TP1 não pode atingir um tamanho de lote de 128 por GPU, portanto, a implantação multi-nó ainda é uma escolha melhor em cenários que buscam maior taxa de transferäncia.

Sobreposição de Computação e Comunicação

Como brevemente apresentado acima sobre o Paralelismo de Especialistas, as GPUs ficam ociosas durante a comunicação da Camada MoE. Para reduzir o desperdício e diminuir a laténcia, precisamos encontrar tarefas de computação independentes de dados para preencher esse tempo ocioso.

Cronogramas de computação e comunicação sem sobreposição, com sobreposição de despacho e um pipeline de cinco estágios.

A parte superior da figura acima mostra o fluxo de computação de uma camada. O cálculo de MoE depende do Dispatch, e o cálculo da próxima camada depende do resultado do Combine.

Colocamos o especialista compartilhado em cada GPU. Dessa forma, o cálculo do especialista compartilhado não requer comunicação AllToAll. Portanto, podemos realizar o cálculo do especialista compartilhado imediatamente após o envio de Dispatch, depois aguardar a conclusão do recebimento de Dispatch. Chamamos esse esquema de sobreposição de "Dispatch Overlap".

O Dispatch Overlap oferece implementação direta e ampla aplicabilidade. Essa técnica oculta o tempo de cálculo do especialista compartilhado em todos os tamanhos de EP e tamanhos de lote.

Para aumentar ainda mais a sobreposição de computação e comunicação, usamos micro batching mencionado no relatório técnico do DeepSeek para quebrar a dependéncia de dados. Como mostrado na parte inferior da figura, dividimos o cálculo de uma Camada Transformer em 5 estágios:

Estágio 1: InputNorm, QKVProj, AppendKV, BMM

Estágio 2: BMM, Attn, OProj, PostNorm, Gate

Estágio 3: Envio de Dispatch, Especialista Compartilhado

Estágio 4: Recebimento de Dispatch, MoE, Envio de Combine

Estágio 5: Recebimento de Combine

Nas primeiras 3 Camadas Transformer Densas, usamos o lote inteiro. Nas 58 Camadas Transformer MoE seguintes, dividimos uniformemente o lote em dois micro lotes. Os dois micro lotes são executados alternadamente, compensados por 3 estágios. Como não há dependéncia de dados entre esses dois micro lotes, podemos mudar para o cálculo de outro micro lote após o envio de Dispatch e após o envio de Combine.

Análise de Laténcia

Em seguida, comparamos os efeitos da sobreposição por meio de um experimento, bem como comparamos as diferenças de desempenho entre a implantação de nó ónico EP8 e a implantação multi-nó EP128. Para facilitar a comparação, usamos GPUs H100 para o seguinte experimento. Usamos TP1, um tamanho de lote de 128 por GPU, um comprimento de consulta de 2 por solicitação e um comprimento de Cache KV de 5000.

Latência por camada, por kernel, nas configurações comparadas de paralelismo de especialistas e sobreposição.

A figura acima mostra o tempo total gasto em uma Camada Transformer MoE e a proporção de laténcia de diferentes tipos de kernels. Exceto por Dispatch, Combine e GroupGEMM, o tempo de execução de outros kernels deve ser igual nas séries EP8, EP128 NoOverlap e EP128 DispatchOverlap porque o tamanho do lote é o mesmo.

Sobreposição

Vamos primeiro comparar os efeitos dos trés métodos de sobreposição. NoOverlap levou 2667µs no total, DispatchOverlap levou 2651µs, economizando 16µs ou apenas 0,6%. O MicroBatch mostrou uma melhoria muito significativa, levando 1896µs, uma aceleração de 29%. Tanto o tempo de Dispatch quanto o de Combine foram significativamente reduzidos. O Dispatch diminuiu de 593µs para 367µs, e o Combine de 1012µs para 237µs.

Observe que, para kernels de computação, dividir um lote de tamanho 128 em dois lotes de tamanho 64 aumenta o tempo total de execução. Portanto, embora o tempo gasto na comunicação tenha sido reduzido em 1001µs, o tempo total reduziu apenas 771µs. Explicaremos a razão usando o modelo Roofline na seção a seguir.

Por esse motivo, o microbatching nem sempre melhora o desempenho.

Mudanças na velocidade de saída e no throughput por nó com micro-batching, plotadas em função do tamanho do lote por GPU.

A figura acima mostra a melhoria de desempenho do Microbatch em comparação com o DispatchOverlap para tamanhos de lote de 4-128. Quando o tamanho do lote é inferior a 32, o Microbatch diminui o desempenho em 5%-40%. Quando o tamanho do lote é maior ou igual a 32, o Microbatch pode melhorar o desempenho em 10%-35%.

EP8 vs. EP128

Vamos retornar à figura anterior e comparar o Microbatch EP8 e EP128. O EP8 levou 1802µs no total, ligeiramente menos que os 1896µs do EP128. Além do aumento do tempo de execução do kernel trazido pelo Microbatch mencionado acima, as principais diferenças estão no GroupGEMM usado para cálculo MoE, e nos dois kernels de comunicação, Dispatch e Combine.

O GroupGEMM do EP8 levou 555µs, enquanto o GroupGEMM do EP128 levou 270µs, reduzindo pela metade. Esta é a vantagem principal da implantação multi-nó.

Infelizmente, o tempo gasto na comunicação aumentou em 213µs, o que compensou muito a vantagem do GroupGEMM. Em testes de desempenho separados de nossos kernels de comunicação, descobrimos que eles só conseguem atingir metade da largura de banda da Infiniband. Continuaremos a otimizar nossos kernels de comunicação.

Outro kernel que fica significativamente atrás é o GEMM. O Microbatch aumentou o GEMM em 95µs. Analisaremos o GEMM mais profundamente na seção Roofline abaixo. Acreditamos que a implementação atual do GEMM ainda não alcançou o desempenho ideal.

Roofline

O Modelo Roofline é uma boa ferramenta para analisar o desempenho do kernel. Seu eixo horizontal é a Intensidade Aritmética, a razão de FLOP para bytes de E/S de memória. O valor do eixo horizontal pode ser calculado diretamente a partir da semântica do kernel. O eixo vertical representa o desempenho alcançado, calculado dividindo FLOP pela laténcia de benchmark.

O limite superior teórico do desempenho do kernel é determinado diretamente pelas especificações da GPU. O desempenho de pico FP8 do H100 é 1979 TFLOP/s, representado como uma linha horizontal no modelo Roofline. A largura de banda de memória do H100 é 3,35 TB/s, representada como a inclinação de uma linha que passa pela origem. As duas linhas fornecem os limites de desempenho para kernels limitados por computação e limitados por memória, respectivamente.

Abaixo, discutimos o desempenho dos kernels GroupGEMM e GEMM.

GroupGEMM

O kernel GroupGEMM em MoE realiza o seguinte cálculo: Há g grupos no total, o i-ésimo grupo tem m_i tokens, realizando uma multiplicação de matriz de [m_i, k] x [k, n] -> [m_i, n]. Nos testes de desempenho, assumimos que o número de tokens em cada grupo é o mesmo, denotado como m_i = m. Então, a contagem de FLOP para GroupGEMM é 2 * g * m * k * n, e os bytes de E/S de memória são g * (m * k + n * k + m * n).

No modelo DeepSeek-V3/R1, existem 256 especialistas, e cada token é despachado para 8 especialistas para computação. Supondo um tamanho de lote de 128, comprimento de consulta de 2, usando a configuração EP128 DP128, o número médio de tokens recebidos por cada especialista (ou seja, m) é 128 * 2 * 8 * 128 / 256 = 1024. Da mesma forma, podemos calcular m para outras configurações e tamanhos de lote.

Usamos a implementação GroupGEMM do DeepGEMM para testes de desempenho. Os pontos de teste cobriram combinações das configurações EP8, EP16, EP32, EP64, EP128 com TP1 e tamanhos de lote 1-128.

Desempenho do GroupGEMM em relação às linhas de base ideais de computação e de largura de banda de memória.

A figura acima mostra o modelo Roofline para GroupGEMM sob diferentes configurações de EP. EP diferente corresponde a números diferentes de grupos. A figura ilustra linhas de desempenho quase sobrepostas, indicando que o desempenho do GroupGEMM é predominantemente determinado pela contagem total de tokens (representada como g * m).

As estrelas marcam os pontos de dados correspondentes a um tamanho de lote de 128 por GPU para cada configuração de EP. Comparando esses pontos de dados com estrela, podemos ver que à medida que o EP aumenta (e o DP aumenta de forma síncrona), o número de tokens por especialista m também aumenta. No EP8, m=128, enquanto no EP128, m=2048.

Como m aumenta, a Intensidade Aritmética também aumenta. Na maioria das configurações, o GroupGEMM é limitado pela largura de banda da memória, portanto, aumentar m melhora o desempenho.

GEMM

O kernel GEMM corresponde a Projeções Lineares no modelo, como Projeção Q/K/V/O. Para uma multiplicação de matriz de [m, k] x [k, n] -> [m, n], a contagem de FLOP é 2 * m * k * n, e os bytes de E/S de memória são m * k + n * k + m * n. Também podemos testar a laténcia para tamanhos de lote 1-128.

Desempenho do GEMM em relação às linhas de base ideais de computação e de largura de banda de memória.

A figura acima mostra o modelo Roofline para GEMM sob diferentes configurações de EP. Podemos ver que o desempenho do GEMM é limitado pela largura de banda da memória. À medida que o tamanho do lote aumenta, a Intensidade Aritmética também aumenta, melhorando assim o desempenho.

Microbatch

Ao usar microbatching, dividimos o lote uniformemente em duas partes. A partir das duas figuras acima, podemos ver que quando m se torna m/2, a eficiéncia da multiplicação de matriz diminui. Portanto, executar duas multiplicações de matriz de tamanho m/2 leva mais tempo do que executar uma multiplicação de matriz de tamanho m.

Previsão de Tokens Móltiplos

Ao longo deste artigo, assumimos o uso de Previsão de Tokens Móltiplos (MTP) para decodificação especulativa. O MTP altera o comprimento da consulta por solicitação de 1 para 2. Para multiplicação de matriz, isso é equivalente a alterar m para m * 2, aumentando assim a eficiéncia da multiplicação de matriz. Por outro lado, se desenharmos o modelo Roofline para MLA, descobriríamos que aumentar o comprimento da consulta aumenta significativamente a eficiéncia do kernel MLA.

Portanto, o uso de MTP desempenha um papel importante na eficiéncia do modelo.

Implementação e otimizações

Nesta seção, apresentaremos alguns detalhes de implementação e otimização para nosso modelo DeepSeek-V3/R1.

Quantização

O DeepSeek-V3/R1 foi treinado nativamente em FP8 usando um esquema de quantização por bloco, com pesos quantizados estaticamente e ativações quantizadas on-the-fly. Em vez de calcular um fator de escala por canal ou por matriz estaticamente, os fatores de escala são calculados em vetores de 128 elementos para ativações e blocos de 128x128 elementos para matrizes, limitando a degradação da precisão devido à quantização.

Na Perplexity, contamos com uma mistura de kernels CUDA e Triton para dar suporte à inferéncia, com CUDA sendo usado para os kernels mais sensíveis ao desempenho e menos modificados (como atenção e GEMM), com Triton implementando uma ampla gama de kernels de ativação, normalização e utilitários. O Triton nos permitiu adaptar rapidamente os kernels ao esquema de quantização por bloco.

Para camadas lineares e MoE, misturamos os kernels Deep GEMM com nossos próprios kernels Triton GEMM, pois notamos que para certas dimensões de matriz e tamanhos de lote baixos, o Split-K oferece menor laténcia. Se a camada não quantizada realiza uma multiplicação de (M, K) x (K, N), ela precisa de fator de escala (M x ceil_div(K, 128)) x (ceil_div(K, 128), ceil_div(N, 128)) para quantização por bloco. Para quantização por bloco, os fatores de escala para ativações são calculados on-the-fly, em vez de serem pré-calibrados. Como os fatores de escala de ativação são agregados apenas ao longo da dimensão K e não ao longo da dimensão M, os kernels requerem apenas pequenas alterações para dar suporte ao esquema.

Computação de SiLU e multiplicação em lote, mostrando tensores de entrada dos especialistas, tensores de saída e fatores de escala.

A função de ativação SiLU usada pelo DeepSeek-V3/R1 exigiu alterações substanciais para dar suporte a grafos CUDA, quantização por bloco e contagens de tokens roteadas dinamicamente. A quantização por bloco pode ser problemática, pois introduz reduções horizontais, no entanto, o kernel já fragmentava as ativações ao longo de sua dimensão oculta em blocos de 1024 elementos. Dentro de um bloco, o tensor a ser quantizado foi ainda mais fragmentado em blocos de 128 para calcular o maior valor absoluto, com Triton gerando reduções máximas cross-warp eficientes, adicionando sobrecarga mínima.

Para suportar o roteamento MoE sob grafos CUDA, os kernels devem estar cientes das informações de roteamento indicando o número de tokens por especialista, em vez de agendar o trabalho com base no tamanho dos buffers que foram alocados para manter o limite superior das contagens de tokens. Não podemos dividir o problema com base nas dimensões do tensor de entrada, então lançamos um número fixo de kernels persistentes que leem as informações de roteamento para determinar quantos tokens estão populados e dividir o trabalho de processar as ativações entre eles dinamicamente.

Já enviamos alguns de nossos kernels para o projeto FlashInfer e, no futuro, estaremos disponibilizando mais de nosso código como código aberto.

Camada MLA

Usamos FlashInfer para o cálculo de MLA. O FlashInfer suporta configurações de Tabela de Páginas flexíveis e desempenho extremamente alto.

Fundimos q_a_proj e kv_a_proj em uma ónica qkv_a_proj. A laténcia diminuiu de 15,4 µs + 14,8 µs = 30,2 µs para 16,7 µs.

Decompusemos kv_b_proj em duas matrizes, k_b_proj e v_b_proj. Escrevemos um kernel BMM Quantizado por Bloco FP8 para cálculos relacionados a essas duas matrizes.

Grafo Cuda

O Grafo Cuda pode reduzir significativamente a sobrecarga de lançamento de kernel, o que é crucial para o desempenho. Criamos um Grafo Cuda para cada tamanho de lote.

Antes de desenvolver nosso Kernel AllToAll, usamos torch.all_to_all_single() para comunicação AllToAll. Esta operação requer que todas as GPUs usem o mesmo tamanho de lote. No entanto, diferentes Grupos DP podem executar tamanhos de lote diferentes.

Para garantir que all_to_all_single() seja compatível com diferentes Grupos DP usando tamanhos de lote diferentes, usamos primeiro uma operação allreduce() antes de cada execução de modelo para obter o tamanho máximo de lote entre todos os Grupos DP. Então, fizemos com que todos os Grupos DP usassem esse tamanho de lote para executar.

Embora essa abordagem garanta que possamos usar o Grafo Cuda, ela tem trés desvantagens. Primeiro, requer uma operação allreduce() adicional. Segundo, Grupos DP com tamanhos de lote menores são forçados a fazer preenchimento (padding). Terceiro, torna o código de nossa implementação complexo.

Após implementar nosso próprio Kernel AllToAll, não exigimos mais que todas as GPUs usem o mesmo tamanho de lote. Portanto, não precisamos mais realizar operações allreduce() adicionais ou preencher tamanhos de lote.

Roteador MoE

O roteador MoE é implementado em Triton, contando com uma classificação modificada derivada da biblioteca padrão, que também rastreia os índices dos elementos classificados. A implementação é compartilhada entre todos os modelos MoE, pois o roteamento Mixtral é um caso especial das rotas DeepSeek onde o grupo Top-K é o mesmo que o grupo de todos os especialistas. Os kernels esparsos consomem os índices e pontuações Top-K diretamente, enquanto os esquemas densos de despacho/combinação que dependem de all-to-all requerem que as informações de roteamento sejam agregadas por especialista em vez de uma base por token.

Trabalho Futuro

No trabalho futuro, planejamos otimizar ainda mais o desempenho do modelo DeepSeek.

A próxima otimização mais importante é a Desagregação de Prefill. A fase de Prefill e a fase de Decodificação do modelo DeepSeek-V3/R1 tém características computacionais muito diferentes. Ambas podem usar diferentes estratégias de otimização e esquemas de implantação.

Para a Camada MLA, na fase de Decodificação, usamos Absorção de Matriz para reduzir a contagem de FLOP do cálculo MLA. Na fase de Prefill, projetar primeiro o vetor latente no espaço K/V e depois calcular na forma de Multi-Head Attention (MHA) teria um desempenho melhor.

Se Prefill e Decodificação forem executados na mesma GPU, para reduzir o impacto de Prefill na velocidade de saída da Decodificação, usamos normalmente prefill fragmentado para dividir a consulta em móltiplos fragmentos para Prefill. Como o Cache KV armazena o vetor latente, torna-se difícil converter MLA na forma MHA.

Para a Camada MoE, na fase de Decodificação, usamos EP e DP o maior possível para aumentar o número de tokens de entrada por especialista, melhorando assim o desempenho do GroupGEMM. Na fase de Prefill, como o número de tokens já é grande o suficiente, o GroupGEMM já está limitado pela computação. Portanto, para Prefill, podemos usar EP e DP menores.

Se Prefill e Decodificação forem executados na mesma GPU, contanto que qualquer Grupo DP esteja realizando Prefill, a laténcia das Camadas MoE em todas as GPUs aumentará, afetando significativamente a velocidade de saída da Decodificação.

Além da Desagregação de Prefill, também planejamos otimizar os seguintes aspectos:

Desempenho AllToAll: Nosso kernel AllToAll atualmente só consegue atingir 1/3 da largura de banda da Infiniband. Continuaremos a otimizar este kernel.

Decodificação especulativa estilo EAGLE: Nos dados acima, assumimos o uso de decodificação especulativa para prever 1 token. O EAGLE pode usar uma estrutura de árvore para prever vários tokens, melhorando o comprimento de aceitação, o que pode aumentar significativamente a velocidade de saída.

Kernel GEMM: No Modelo Roofline mostrado anteriormente, podemos constatar que a eficiéncia do kernel GEMM ainda está longe do limite teórico. Continuaremos a otimizar este kernel.

GB200 NVL72: Na mais recente solução GB200 NVL72 da NVIDIA, 72 GPUs Blackwell são interconectadas via NVLink de alta velocidade. Para modelos de arquitetura MoE, esta é uma grande oportunidade e desafio.

Conclusão

A implantação multi-nó de modelos DeepSeek MoE alcança o que é tipicamente impossível com LLMs densos: melhorar simultaneamente a taxa de transferäncia e a laténcia. Ao distribuir especialistas entre mais GPUs, reduzimos a pressão da largura de banda da memória por dispositivo, permitindo um processamento mais rápido e maior taxa de transferäncia do sistema. Nossos experimentos mostram que as configuração EP128 alcançam uma taxa de transferäncia até 5x maior em velocidades de saída equivalentes em comparação com implantações de nó ónico.

Técnicas de sobreposição de computação-comunicação como micro-batching reduzem significativamente a sobrecarga de comunicação multi-nó, com nossa implementação mostrando uma aceleração de até 40%. Nossos kernels de comunicação AllToAll personalizados e implementações de kernel otimizadas permitiram a implantação eficiente do modelo de 671B de parâmetros.

Como as arquiteturas MoE ganham popularidade por sua capacidade, essas estratégias de implantação fornecem insights valiosos para escalar tais modelos eficientemente.

Referéncias

Relatório Técnico DeepSeek-V3

Visão Geral do Sistema de Inferéncia DeepSeek-V3/R1

Megatron-LM: Treinando Modelos de Linguagem de Bilhões de Parâmetros Usando Paralelismo de Modelo

EAGLE: Amostragem Especulativa Requer Repensar a Incerteza do Recurso

Citação

BibTeX
@online{perplexity2025LowerLatencyAndHigherThroughputWithMultiNodeDeepseekDeployment,
  author = {{Perplexity} and Lequn Chen and Nandor Licker and Erin McKnight},
  title = {{Lower latency and higher throughput with multi-node DeepSeek deployment}},
  date = {2025-04-18},
  url = {https://perplexity.coolkeypoint.com/hub/blog/lower-latency-and-higher-throughput-with-multi-node-deepseek-deployment}
}