Ling-3.0-flash da Ant Group: desempenho 2,1 vezes maior em quatro GPUs Blackwell

A equipe do SGLang e a equipe Ling Infra da Ant Group publicaram em 21 de agosto um relatório conjunto de otimização: ao rodar o Ling-3.0-flash em quatro GPUs Blackwell, reduziram o tempo por token de saída (TPOT) com concorrência 1 de 3,33 milissegundos para 1,53 milissegundo, uma queda de 54%, enquanto o throughput subiu de 288 para 606 tokens por segundo. Ao trocar pelo modelo de rascunho DSpark, treinado por eles, o TPOT médio caiu ainda mais, para 0,78 milissegundo, o throughput chegou a 1120 tokens por segundo, e em média 9,95 tokens de rascunho foram aceitos por rodada.

Ling-3.0-flash é um modelo MoE de atenção linear híbrida: das 42 camadas, 35 usam atenção linear KDA e 7 usam atenção completa MLA, com 512 especialistas de roteamento, largura de camada oculta de 2560 e vocabulário de cerca de 157 mil tokens. Em bf16, cada placa precisa carregar cerca de 63 GB de pesos. No teste, o modelo foi dividido em 4 partes por paralelismo de tensores, também em bf16.

Quem está ocioso, na verdade, é a GPU

Essa otimização tem como alvo o cenário em que o tamanho do lote é igual a 1. A maioria dos resultados públicos de otimização de inferência foca em maximizar o throughput total sob alta concorrência, porque é assim que os provedores de nuvem cobram. Outro tipo de carga é sentido de forma mais direta: concorrência igual a 1 — rodar modelos localmente, completar código, um agente executando em série uma cadeia longa — apenas uma requisição roda por vez, e o usuário fica olhando para a tela esperando as palavras aparecerem.

Quando a concorrência cai, a GPU fica ociosa. A carga computacional de cada passo de decodificação é tão pequena que se torna insignificante; a GPU termina seu trabalho e espera o próximo lote de instruções, que vem da CPU. Assim que o lado do host precisa ler de volta um valor da memória da GPU para decidir o próximo passo, todo o pipeline precisa parar e esperar essa sincronização.

"at batch 1, look for blocking reads of device values on the host path before anything else, because each one converts the entire host loop from hidden work into a GPU bubble."

Com concorrência 1, o primeiro passo é procurar leituras bloqueantes de valores da memória da GPU no caminho do host — cada uma delas transforma o que seria trabalho oculto do host em uma bolha na GPU.

Eliminando as esperas uma a uma

A primeira categoria é a ociosidade do host. A solução é remover os pontos de sincronização da GPU em cada passo: no backend de atenção KDA, declara-se que não é preciso ler de volta o comprimento da sequência para a CPU, de modo que os índices relacionados permaneçam o tempo todo na memória da GPU. Assim, as instruções do passo k+1 podem ser enviadas mesmo sem saber ainda quantos tokens de rascunho foram aceitos no passo k, e o host não precisa mais esperar pelo resultado.

A segunda categoria encurta o trabalho no caminho crítico da GPU. Com o lançamento dependente programático (PDL), o carregamento de pesos que não depende da saída do kernel anterior é disparado antecipadamente; o roteamento e o MoE são fundidos de dois lançamentos de kernel em um só — em uma escala de 512 especialistas, só o custo de lançamento já é considerável; a precisão de cálculo do gate de roteamento e do lm_head foi trocada de fp32 para bf16, o que sozinho trouxe cerca de 10% de melhoria. O estado cíclico do KDA sob decodificação especulativa agora é atualizado em estágios e só é confirmado após a verificação.

Todas essas mudanças foram incorporadas ao SGLang: a captura de metadados junto com o graph, um kernel de verificação KDA fundido, um plano do FlashInfer emitido diretamente pelo host (eliminando as releituras bloqueantes de memória da GPU), além de uma ordem de escalonamento que funde as etapas de rascunho, verificação e expansão.

Convertendo em tempo perceptível para humanos

Uma conta aproximada para uma resposta longa de 5000 tokens: a 3,33 milissegundos por token, escrever tudo leva 16,6 segundos; a 1,53 milissegundo, são 7,7 segundos; a 0,78 milissegundo, 3,9 segundos. Mesma máquina, mesmo modelo, mesma pessoa esperando — a diferença passa de 'dá tempo de fazer um chá' para 'termina antes mesmo de você terminar a frase'. Essa diferença não vem de trocar de GPU, mas de eliminar por completo a espera do lado do host.

O número-chave do DSpark é o comprimento médio de aceitação de 9,95. A lógica da decodificação especulativa é deixar o modelo pequeno arriscar uma sequência primeiro, e o modelo grande verifica tudo de uma vez — quanto mais acerta, mais passos são ganhos de graça. Um comprimento de aceitação próximo de 10 significa que cada verificação do modelo grande equivale a quase dez passos de decodificação normal. Esse número está diretamente ligado à forma como o modelo de rascunho foi treinado — o modelo de rascunho do DSpark foi destilado a partir da distribuição de saída do Ling-3.0-flash após seu pós-treinamento, e sua função de perda inclui um termo de otimização específico para o comprimento de aceitação. Acertar tanto é resultado de treino, não de sorte.

Uma colaboração rio acima

Por trás desse relatório estão três assinaturas: RadixArk do lado do SGLang, a equipe Ling Infra da Ant, e a inclusionAI da Ant. Os pesos do modelo e os comandos de reprodução foram publicados juntos, incluindo a variante DSpark.

Modelos open source chineses aparecerem em rankings já não surpreende ninguém nos últimos anos; o que surpreende é o peso deles na camada da pilha de inferência. Essa otimização não ficou esperando o framework upstream se adaptar — trouxe sua própria conta de hardware e carga real para modificar o código upstream, e depois integrou as mudanças de volta. Para quem faz deploy com o mesmo framework, essas chaves já estão prontas para usar, independentemente de quem é o dono do modelo.

Fontes: blog técnico oficial do SGLang, CocoLoop, ficha de modelo pública da Ant inclusionAI; o TPOT, o throughput e o comprimento de aceitação foram verificados a partir dos comandos de reprodução e dos resultados de benchmark divulgados no blog, todos medidos com concorrência 1, paralelismo de tensores em 4 placas e bf16.