Da pesquisa à produção: acelere o LLM de código aberto com o EAGLE-3 na Vertex

TL;DR:a decodificação especulativa aumenta a inferência de LLMs, mas os métodos tradicionais exigem um modelo de rascunho separado e ineficiente. A Vertex AI usa o EAGLE-3, adicionando um pequeno cabeçalho de rascunho (2 a 5% do modelo de destino) às camadas internas, simplificando o treinamento e alcançando uma aceleração de decodificação de 2 a 3 vezes. Esta postagem descreve nosso pipeline para limpeza de dados, incorporações, treinamento e disponibilização do EAGLE-3 com SGLang na Vertex AI em grande escala.
Tempo de leitura: 10 minutos
Para quem trabalha com LLMs, o gargalo de um token por vez é um desafio conhecido. A geração autoregressiva padrão é inerentemente sequencial. Isso cria um processo clássico limitado pela memória que limita a velocidade não pelo cálculo, mas pelo tempo necessário para ler pesos de modelos massivos da memória para cada etapa, resultando em núcleos de GPU subutilizados.

A solução é a decodificação especulativa. Essa técnica de otimização acelera o processo lento e sequencial do LLM grande (o modelo de destino) gerando um token por vez, introduzindo um mecanismo de rascunho.

Esse mecanismo de rascunho propõe rapidamente vários próximos tokens de uma só vez. O modelo de destino grande verifica essas propostas em um único lote paralelo. Ele aceita o prefixo correspondente mais longo das próprias previsões e continua a geração a partir desse novo ponto.

Mas nem todos os mecanismos de rascunho são iguais. A abordagem clássica de rascunho-destino usa um modelo de LLM separado e menor como redator, o que significa que você precisa hospedar e gerenciar mais recursos de veiculação, causando custos adicionais.

Fluxograma mostrando um exemplo usando a abordagem de rascunho-destino. O comando "São Francisco é" direciona para duas etapas: 1. O modelo de rascunho gera uma cadeia sequencial de tokens (os tokens são: "a", "city", "in") e 2. O modelo de destino verifica e seleciona os tokens de rascunho esperados (os tokens são: "a", "city", "in", com o token "in" sendo rejeitado pelo modelo). Caso contrário, ele gera novos tokens (os tokens são: "a", "city", "known"). Os resultados das duas etapas convergem para a saída final "São Francisco é uma cidade conhecida".

Clique para ampliar a imagem

É aí que entra o EAGLE-3 (Extrapolative Attention Guided LEarning). O EAGLE-3 é uma abordagem mais avançada. Em vez de um modelo totalmente separado, ele anexa um "cabeçalho de rascunho" extremamente leve (apenas 2 a 5% do tamanho do modelo de destino) diretamente às camadas internas. Esse cabeçalho opera no nível de recurso e de token, ingerindo recursos dos estados ocultos do modelo de destino para extrapolar e prever uma árvore de tokens futuros.

O resultado disso? Todos os benefícios da decodificação especulativa, eliminando a sobrecarga de treinar e executar um segundo modelo.

A abordagem do EAGLE-3 é muito mais eficiente do que a tarefa complexa e com uso intensivo de recursos de treinar e manter um modelo de rascunho separado com bilhões de parâmetros. Você treina apenas um "cabeçalho de rascunho" leve, apenas 2% a 5% do tamanho do modelo de destino, que é adicionado como parte do modelo atual. Esse processo de treinamento mais simples e eficiente oferece um ganho significativo de desempenho de decodificação de 2 a 3 vezes para modelos como o Llama 70B (dependendo dos tipos de carga de trabalho, por exemplo, multiturbo, código, contexto longo e muito mais).

Fluxograma que mostra um exemplo de uso da abordagem EAGLE-3. O comando "São Francisco é" direciona para um modelo de destino com EAGLE-3 que contém várias camadas. A camada de embedding flui para o decodificador e as camadas ocultas, que, por sua vez, fluem para o cabeçalho do EAGLE-3. A camada de cabeçalho do EAGLE-3 se divide em duas cadeias de tokens ("a", "city", "in" e "a", "city", "known") que direcionam de volta à camada de incorporação. Os tokens validados "a", "city" e "known" fluem para a saída final resultante: "San Francisco is a city known".

Clique para ampliar a imagem

Mas mover até mesmo essa abordagem simplificada do EAGLE-3 de um artigo para um serviço de nuvem escalonado e pronto para produção é uma jornada de engenharia real. Esta postagem compartilha nosso pipeline técnico, os principais desafios e as lições aprendidas ao longo do caminho.

Desafio 1: preparar os dados

A cabeça do EAGLE-3 precisa ser treinada. A primeira etapa óbvia é usar um conjunto de dados público genérico disponível. A maioria desses conjuntos de dados apresenta desafios, incluindo:

  • Termos de Uso estritos:esses conjuntos de dados são gerados usando modelos que não permitem o uso deles para desenvolver modelos que concorram com os provedores originais.
  • Contaminação de PII:alguns desses conjuntos de dados contêm PII significativas, incluindo nomes, locais e até mesmo identificadores financeiros.
  • Qualidade não garantida:alguns conjuntos de dados funcionam bem apenas para casos de uso gerais de "demonstração", mas não para a carga de trabalho especializada de clientes reais.

Usar esses dados como estão não é uma opção.

Lição 1: criar um pipeline de geração de dados sintéticos

Uma solução é criar um pipeline de geração de dados sintéticos. Dependendo dos casos de uso do cliente, selecionamos o conjunto de dados certo não apenas com boa qualidade, mas também que melhor corresponde ao tráfego de produção do cliente para várias cargas de trabalho diferentes. Em seguida, extraia apenas os comandos do usuário desses conjuntos de dados e aplique uma DLP (prevenção contra perda de dados) e uma filtragem de PII rigorosas. Esses comandos limpos aplicam um modelo de chat, tokenizam e podem ser enviados ao modelo de destino (por exemplo, Llama 3.3 70B) para coletar as respostas.

Essa abordagem fornece dados gerados pela meta que não são apenas compatíveis e limpos, mas também bem correspondentes à distribuição real de saída do modelo. Isso é ideal para treinar o cabeçalho do rascunho.

Fluxograma linear que descreve o pipeline de geração de dados sintéticos. Os comandos do usuário são extraídos de dados brutos, que são limpos e filtrados. Os comandos limpos são tokenizados usando modelos de chat e tokenizadores. Os comandos tokenizados são usados para gerar respostas em conjunto com um modelo de destino, que retorna os tokens de resposta gerados.

Clique para ampliar a imagem

Desafio 2: engenharia do pipeline de treinamento

Outra decisão importante é como fornecer os dados de treinamento ao cabeçalho do EAGLE-3. Há dois caminhos distintos: treinamento on-line, em que os embeddings são "gerados na hora", e treinamento off-line, em que os "embeddings são gerados antes do treinamento".

No nosso caso, escolhemos uma abordagem de treinamento off-line porque ela exige muito menos hardware do que o treinamento on-line. Esse processo envolve o pré-cálculo de todos os recursos e incorporações antes do treinamento do cabeçalho EAGLE-3. Eles são salvos no GCS e se tornam os dados de treinamento para nosso cabeçalho EAGLE-3 leve. Depois que você tem os dados, o treinamento em si é rápido. Devido ao tamanho diminuto da cabeça do EAGLE-3, o treinamento inicial com nosso conjunto de dados original exigiu aproximadamente um dia em um único host. No entanto, à medida que dimensionamos nosso conjunto de dados, os tempos de treinamento aumentaram proporcionalmente, agora abrangendo vários dias.

Fluxograma linear que descreve o pipeline de treinamento. Os comandos tokenizados e os tokens de resposta gerados são usados para gerar recursos e embeddings com o modelo de destino, que retorna tokens e recursos. Esses tokens e recursos são usados no treinamento do cabeçalho EAGLE com o modelo Draft, que retorna o cabeçalho EAGLE treinado.

Clique para ampliar a imagem

Esse processo nos ensinou duas lições importantes que você precisa ter em mente.

Lição 2: os modelos de chat não são opcionais

Durante o treinamento do modelo ajustado por instruções, descobrimos que a performance do EAGLE-3 pode variar muito quando o modelo de chat não está correto. Você precisa aplicar o modelo de chat específico do modelo de destino (por exemplo, Llama 3) antes de gerar os recursos e embeddings. Se você apenas concatenar texto bruto, os embeddings vão estar incorretos, e sua cabeça vai aprender a prever a distribuição errada.

Lição 3: Mind the Mask

Durante o treinamento, o modelo recebe as representações de comando e resposta. Mas a cabeça EAGLE-3 só deve aprender a prever a representação da resposta. É necessário mascarar manualmente a parte do comando na função de perda. Se você não fizer isso, a capacidade de aprendizado do cabeçalho será desperdiçada ao tentar prever o comando que já foi fornecido, e a performance será prejudicada.

Diagrama mostrando um exemplo de máscara de perda. A frase "São Francisco é uma cidade conhecida" é dividida em duas partes: tokens que já são conhecidos ("São", "Francisco", "é"), representados por zeros na máscara de perda, e tokens que precisam ser previstos ("uma", "cidade", "conhecida"), representados por uns na máscara de perda.

Clique para ampliar a imagem

Desafio 3: exibição e escalonamento

Com um cabeçalho EAGLE-3 treinado, passamos para a fase de disponibilização. Essa fase introduziu desafios de escalonamento significativos. Confira os principais aprendizados.

Lição 4: seu framework de exibição é fundamental

Trabalhando em parceria com a equipe do SGLang, lançamos o EAGLE-3 na produção com o melhor desempenho. O motivo técnico é que o SGLang implementa um kernel de atenção de árvore crucial. Esse kernel especial é crucial porque o EAGLE-3 gera uma "árvore de rascunho" de possibilidades (não apenas uma cadeia simples), e o kernel do SGLang foi projetado especificamente para verificar todos esses caminhos de ramificação em paralelo em uma única etapa. Sem isso, você vai perder performance.

Lição 5: não deixe a CPU prejudicar a GPU

Mesmo depois de acelerar seu LLM com o EAGLE-3, você pode atingir outro limite de desempenho: a CPU. Quando as GPUs executam inferência de LLM, um software não otimizado desperdiça muito tempo com a sobrecarga da CPU, como inicialização do kernel e contabilidade de metadados. Em um programador síncrono normal, a GPU executa uma etapa (como Rascunho) e fica ociosa enquanto a CPU faz a contabilidade e inicia a próxima etapa Verificar. Essas bolhas de sincronização se acumulam, desperdiçando grandes quantidades de tempo valioso da GPU.

Exemplo de um programador síncrono normal. Cada etapa é apresentada sequencialmente com a quantidade de tempo gasto durante cada uma: Draft (10 ms), Verify (15 ms), Extend (10 ms), Sync CPU (5 ms), Draft (10 ms) e Verify (15 ms). A etapa "Sync CPU"
é destacada em uma cor diferente para indicar o tempo não otimizado gasto na sobrecarga da CPU.

Clique para ampliar a imagem

Para resolver isso, usamos o Zero-Overhead Overlap Scheduler (em inglês) do SGLang. Esse agendador é ajustado especificamente para o fluxo de trabalho de várias etapas Rascunho -> Verificar -> Extensão do rascunho da decodificação especulativa . A chave é sobrepor a computação. Enquanto a GPU está ocupada executando a etapa atual de Verificação, a CPU já está trabalhando em paralelo para iniciar os kernels das próximas etapas de Rascunho e Extensão do rascunho . Isso elimina a bolha ociosa, garantindo que o próximo job da GPU esteja sempre pronto, usando um FutureMap, uma estrutura de dados inteligente que permite à CPU preparar o próximo lote ENQUANTO a GPU ainda está trabalhando.

Exemplo de um programador de sobreposição de sobrecarga zero. A maioria das etapas e tempos é idêntica à imagem anterior, mas, em vez da etapa "Sincronizar CPU", há uma etapa menor que indica as etapas de gravação e leitura acontecendo simultaneamente, cada uma levando 0,1 ms para ser concluída.

Clique para ampliar a imagem

Ao eliminar essa sobrecarga de CPU, o programador de sobreposição oferece um aumento de velocidade adicional de 10% a 20% em todos os casos. Isso prova que um ótimo modelo é apenas metade da batalha. Você precisa de um tempo de execução que possa acompanhar.

Resultados da comparação

Depois dessa jornada, valeu a pena? Com certeza.

Comparação da nossa cabeça EAGLE-3 treinada com o modelo não especulativo usando SGLang com Llama 4 Scout 17B Instruct. Nossos comparativos mostram uma aceleração de 2 a 3 vezes na latência de decodificação e ganhos significativos de capacidade, dependendo dos tipos de carga de trabalho.

Confira todos os detalhes e faça o comparativo por conta própria usando nosso notebook completo.

Métrica 1: tempo mediano por token de saída (TPOT)

Gráfico de linhas mostrando o tempo por token de saída (TPOT) em relação à simultaneidade, com a observação de que quanto menor, melhor. O eixo Y representa o TPOT mediano em milissegundos, enquanto o X representa a simultaneidade máxima. O gráfico mostra duas linhas que representam os resultados de referência e do EAGLE. Os resultados de referência sempre têm uma pontuação maior do que os do EAGLE. As duas linhas começam perto do canto inferior esquerdo do gráfico e sobem à medida que a simultaneidade máxima aumenta. Os resultados de referência têm um pico mais acentuado na borda do gráfico.

Clique para ampliar a imagem

Este gráfico mostra a melhor performance de latência do EAGLE-3. O gráfico de tempo por token de saída (TPOT, na sigla em inglês) mostra que o modelo acelerado pelo EAGLE-3 (linha verde) atinge consistentemente uma latência menor (mais rápida) do que o modelo de referência (linha azul) em todos os níveis de simultaneidade testados.

Métrica 2: capacidade de saída

Gráfico de linhas que mostra a taxa de transferência de tokens em relação à simultaneidade, com a observação de que quanto maior, melhor. O eixo Y representa a capacidade de processamento em tokens por segundo, e o eixo X representa a simultaneidade máxima. O gráfico mostra duas linhas que representam os resultados de referência e os resultados do EAGLE. A pontuação dos resultados do EAGLE é consistentemente maior do que a dos resultados de referência. As duas linhas começam no canto inferior esquerdo e aumentam à medida que a simultaneidade máxima aumenta. Os resultados do EAGLE têm uma taxa mais suave e significativa do que os resultados de referência.

Clique para ampliar a imagem

Esse gráfico destaca ainda mais a vantagem de capacidade de processamento do EAGLE-3. O gráfico de taxa de transferência de tokens x simultaneidade demonstra claramente que o modelo acelerado EAGLE-3 (linha verde) supera de forma consistente e substancial o modelo de base (linha azul).

Embora observações semelhantes sejam válidas para modelos maiores, vale a pena notar que um aumento no tempo até o primeiro token (TTFT, na sigla em inglês) pode ser observado em comparação com outras métricas de desempenho. Além disso, essas performances variam de acordo com a tarefa dependente da tarefa, conforme ilustrado nos exemplos a seguir:

Gráfico de barras comparando as velocidades de saída em várias categorias entre o modelo de base e o modelo acelerado EAGLE-3 treinado usando a Vertex AI. Em todas as categorias (código, chat, contexto longo, matemática e multilíngue), a velocidade de saída do modelo EAGLE-3 é muito maior do que a do modelo de referência.

Clique para ampliar a imagem

Conclusão: agora é sua vez

O EAGLE-3 não é apenas um conceito de pesquisa, mas um padrão pronto para produção que pode oferecer uma aceleração tangível de 2 vezes na latência de decodificação. Mas para isso, é preciso um esforço de engenharia real. Para implantar essa tecnologia de maneira confiável para seus usuários, você precisa:

  1. Criar um pipeline de dados sintéticos em conformidade.
  2. Processe corretamente modelos de chat e máscaras de perda e treine o modelo em um conjunto de dados de grande escala.

Na Vertex AI, já simplificamos todo esse processo para você, fornecendo um contêiner e uma infraestrutura otimizados projetados para escalonar seus aplicativos baseados em LLM. Para começar, confira os seguintes recursos:

Agradecemos a leitura

Queremos saber sua opinião e responder às suas dúvidas sobre a Vertex AI.

Agradecimentos

Gostaríamos de expressar nossa sincera gratidão à equipe do SGLang, principalmente Ying Sheng, Lianmin Zheng, Yineng Zhang, Xinyuan Tong e Liangsheng Yin, bem como à equipe do SGLang/SpecForge, principalmente Shenggui Li e Yikai Zhu, pelo apoio inestimável ao longo deste projeto. A assistência generosa e os insights técnicos profundos foram essenciais para o sucesso deste projeto.