Phase 17 - Lesson 06

SGLang e RadixAttention para Cargas de Trabalho Intensivas em Prefixos

O SGLang trata o KV cache como um recurso reutilizável de primeira classe armazenado em uma árvore radix (radix tree). Enquanto o vLLM agenda requisições com base em FCFS (first-come, first-served), o agendador baseado em cache (cache-aware scheduler) do SGLang prioriza requisições com prefixos compartilhados mais longos — efetivamente uma travessia radix de busca em profundidade (depth-first radix traversal) para que os ramos quentes (hot branches) permaneçam residentes na HBM. No Llama 3.1 8B com prompts de 1K semelhantes ao ShareGPT, o SGLang atinge ~16.200 tok/s versus ~12.500 do vLLM, uma vantagem de ~29%. Em cargas de trabalho de RAG intensivas em prefixos, a vantagem chega a 6,4x. Em cargas de trabalho de clonagem de voz, a taxa de acerto do cache superou 86%. Implementado em mais de 400.000 GPUs em 2026 nas empresas xAI, LinkedIn, Cursor, Oracle, GCP, Azure e AWS. O detalhe é que o fator de 6,4x desaparece quando a ordenação do prefixo não é consistente — a ordenação representa a alavanca do engenheiro.

Tipo: Aprender Linguagens: Python (stdlib, simulador simplificado de cache em árvore radix + agendador baseado em cache) Pré-requisitos: Phase 17 · 04 (vLLM Serving Internals), Phase 14 (Agentic RAG) Tempo: ~75 minutos

Objetivos de Aprendizagem

  • Diagramar o RadixAttention: como os prefixos são armazenados em uma árvore radix e como os blocos de KV são compartilhados entre sequências enraizadas no mesmo ramo.
  • Explicar o agendamento baseado em cache e por que o FCFS está errado para tráfego intensivo em prefixos.
  • Calcular a aceleração esperada para uma carga de trabalho dada a taxa de acerto do cache de prefixo e a distribuição de comprimento dos prompts.
  • Nomear a disciplina de ordenação de prompts que torna real a aceleração de 6,4x em vez de um benefício desperdiçado.

O Problema

O serviço clássico de inferência trata o prompt de cada requisição como opaco. Mesmo quando 5.000 requisições de RAG começam com o mesmo prompt de sistema de 2.000 tokens e o mesmo preâmbulo de recuperação, o vLLM realiza o prefill desse prefixo de 2.000 tokens 5.000 vezes. A GPU realiza o mesmo trabalho repetidamente.

A observação: prompts em cargas de trabalho agenticas e de RAG compartilham prefixos longos quase sempre. Prompt de sistema, esquemas de ferramentas, exemplos de poucas demonstrações (few-shot), cabeçalhos de recuperação, histórico de conversação — tudo se repete entre as requisições. Se você armazenasse o KV cache desse prefixo uma vez e o reutilizasse, não precisaria fazer o prefill dele novamente.

O RadixAttention faz exatamente isso. Os tokens são indexados em uma árvore radix; cada nó possui blocos de KV para a sequência de tokens em seu caminho a partir da raiz. Uma nova requisição percorre a árvore: qualquer nó cujo token corresponda reutiliza os blocos de KV desse nó. O custo do prefill torna-se proporcional ao sufixo "novo", e não ao prompt completo.

O desafio está no agendamento. Se duas requisições compartilham um prefixo de 2.000 tokens e uma terceira compartilha apenas 200 tokens do mesmo prefixo, você deseja atender as duas requisições com maior compartilhamento juntas para que o prefixo longo permaneça na HBM. O FCFS faz o oposto — atende a quem chegou primeiro, potencialmente despejando o ramo quente antes que a próxima requisição com o prefixo longo chegue.

O Conceito

A árvore radix como um índice de KV

Uma árvore radix (trie compacta) armazena sequências de tokens. Cada nó possui uma faixa de tokens e os blocos de KV computados para essa faixa. Os nós filhos estendem a sequência em um ou mais tokens.

root
 |- "You are a helpful assistant..."  (2.000 tokens, 124 blocos de KV)
      |- "Context: <doc A>..."        (500 tokens, 31 blocos)
           |- "Question: Alice..."    (80 tokens, 5 blocos)
           |- "Question: Bob..."      (95 tokens, 6 blocos)
      |- "Context: <doc B>..."        (520 tokens, 33 blocos)

Uma nova requisição chega com prompt de sistema + "Context: " + "Question: Carol". O agendador percorre a árvore: o prefixo do sistema corresponde (124 blocos reutilizados), o ramo do doc-A corresponde (31 blocos reutilizados) e, em seguida, aloca blocos novos apenas para "Question: Carol" (4 blocos). Custo do prefill: 4 blocos de novos tokens. Sem a árvore: 160 blocos. Economia de ~40x no prefill.

Agendamento baseado em cache (cache-aware)

A reutilização baseada em árvore radix não tem sentido se o cache sofrer desgaste contínuo (thrashing). Duas políticas fundamentais:

  1. Despacho em profundidade (depth-first dispatch). Ao escolher a próxima requisição da fila, dê preferência a requisições enraizadas no mesmo ramo do conjunto em execução atual. Isso mantém o ramo quente fixado.
  2. LRU no nível do ramo, não do bloco. Despeje ramos inteiros (começando pelas folhas menos utilizadas recentemente) em vez de blocos individuais, para que o formato do cache corresponda ao formato radix.

O FCFS viola ambas as políticas. Uma requisição que compartilha 2.000 tokens fica atrás de uma requisição que compartilha 50 tokens, e então o ramo de 2.000 tokens é despejado para admitir a requisição de 50 tokens.

Números de benchmark que você deve memorizar

  • Llama 3.1 8B, H100, prompts de 1K do ShareGPT: SGLang ~16.200 tok/s vs vLLM ~12.500 (vantagem de ~29%).
  • RAG intensivo em prefixos (mesmo sistema + mesmo documento, alterando apenas a pergunta): aceleração de até 6,4x no SGLang.
  • Cargas de trabalho de clonagem de voz: taxa de acerto do cache de prefixo de 86,4%.
  • Taxas de acerto em produção em clientes do SGLang: 50% a 99% dependendo da disciplina de prompts.
  • Implementado em mais de 400.000 GPUs em 2026.

A armadilha da ordenação

A aceleração de 6,4x depende de uma ordenação consistente dos templates de prompts. Se o cliente constrói prompts como [sistema, ferramentas, contexto, histórico, pergunta] em algumas requisições e como [sistema, contexto, ferramentas, histórico, pergunta] em outras, a árvore não conseguirá encontrar o prefixo compartilhado. O que parece ser um prefixo compartilhado para um humano representa duas sequências distintas para a árvore radix.

Alavanca do engenheiro: o template de seu prompt é uma chave de cache. Fixe a ordem. Coloque tudo o que for imutável (sistema, ferramentas, esquemas) primeiro. Coloque o contexto de recuperação em seguida. Coloque a pergunta do usuário por último. Não intercale conteúdo dinâmico no meio do prefixo.

Caso real de pesquisa: mover o conteúdo dinâmico para fora do prefixo cacheável elevou a taxa de acerto do cache de um deploy de 7% para 74% com apenas uma alteração.

Onde o RadixAttention vence e perde

Vence:

  • RAG (mesmo preâmbulo de recuperação, pergunta variável).
  • Agentes (mesmos esquemas de ferramentas, consulta variável).
  • Chat com prompts de sistema longos.
  • Cargas de trabalho de voz/visão com preâmbulos repetidos.

Perde (retorna ao nível de rendimento do vLLM):

  • Geração de etapa única (single-shot) com prompts exclusivos (autocompletar código, chat livre sem prompt de sistema).
  • Prompts dinâmicos em que cada requisição intercala conteúdo exclusivo no meio do prefixo.

Por que esse é um problema de agendamento, e não apenas de kernel

Você pode implementar a reutilização de KV como um truque de kernel. A percepção do SGLang é que a reutilização só compensa se o agendador mantiver o ramo quente residente. Uma política ingênua de "reutilizar se disponível" causará desgaste do cache sob carga mista. O agendador indexado por árvore radix é o que transforma o truque do kernel em uma vantagem de produção de 29%.

Relação com o vLLM

Os dois sistemas não são concorrentes rígidos. Em 2026, o vLLM adicionou o cache de prefixos (--enable-prefix-caching) e um roteador baseado em cache (vLLM Router escrito em Rust). A diferença diminuiu, mas não desapareceu totalmente — a pilha completa do SGLang é baseada em radix primeiro; o vLLM adicionou isso como extensão. Para cargas de trabalho dominadas pela reutilização de prefixos, o SGLang permanece como o padrão. Para serviços de uso geral sem fortes padrões de prefixos, o vLLM permanece igual ou superior.

Use It

O arquivo code/main.py implementa um KV cache simplificado em árvore radix mais um agendador com duas políticas: FCFS e baseado em cache. Executa a mesma carga de trabalho em ambos, relatando a taxa de acerto do cache de prefixo e a diferença de rendimento. Em seguida, executa uma carga de trabalho com "ordem misturada" para demonstrar a perda da aceleração de 6,4x.

Ship It

Esta lição produz outputs/skill-radix-scheduler-advisor.md. Dada uma descrição de carga de trabalho (formato do template de prompt, padrão de recuperação, número de locatários simultâneos), ela produz uma recomendação de ordenação de prompts e uma decisão de adoção ou não do SGLang.

Exercises

  1. Execute code/main.py. Compare o FCFS e o agendador baseado em cache na mesma carga de trabalho. De onde vem a diferença — economia de prefill, economia de decodificação ou atraso na fila?
  2. Modifique a carga de trabalho para que os prompts permutem aleatoriamente os blocos [sistema, ferramentas, contexto]. Execute novamente. O que acontece com a taxa de acerto? Por quê?
  3. Calcule o custo de HBM de manter um prompt de sistema de 2.000 tokens residente como um ramo radix no Llama 3.1 8B. Compare com o custo de um lote de 16 sequências sem reutilização de prefixos.
  4. Leia o artigo do SGLang RadixAttention. Explique em três frases por que a política de despejo LRU baseada em árvore supera a política LRU baseada em blocos sob tráfego intensivo em prefixos.
  5. Um cliente relata apenas 8% de taxa de acerto no cache. Nomeie três causas prováveis e o diagnóstico que você executaria para cada uma.

Key Terms

Term What people say What it actually means
RadixAttention "o negócio do SGLang" KV cache indexado como uma árvore radix para que prefixos compartilhados reutilizem blocos
Radix tree "trie compacta" Árvore onde cada nó possui uma faixa de tokens e seus respectivos blocos de KV
Cache-aware scheduler "ramo-quente-primeiro" Agendador que prioriza requisições que compartilham o ramo residente
Prefix-cache hit rate "quanto do seu prompt saiu de graça" Fração de tokens de prompt atendidos a partir de blocos de KV reutilizados
FCFS "primeiro a chegar, primeiro a ser atendido" Agendamento padrão que desfaz a localidade do prefixo
Branch-level LRU "despejar a folha" Política de despejo de cache ajustada ao formato da árvore radix
Prompt template ordering "a chave do cache" A ordem dos componentes do prompt define o que a árvore pode compartilhar
System prompt pinning "prefixo residente" Manter a parte imutável do sistema fixada para evitar desgaste de despejo (eviction thrash)

Further Reading

0 lifetime access. Curriculum based on AI Engineering from Scratch by Rohit Ghumare (MIT, used under attribution).