Infraestrutura de LLM · Série Técnica GEO · Negócio no Mapa
FlashAttention e o gargalo real de inferência: por que memória, não FLOPs, decide a velocidade
Numa GPU moderna, o cálculo bruto de atenção quase nunca é o que trava um pipeline de LLM em produção — é a ida e volta de dado entre dois níveis de memória física com velocidades ordens de grandeza diferentes. Entender essa física explica por que FlashAttention virou padrão em praticamente toda stack de inferência de 2026.
Esta página é tradução técnica, não inovação — não estou propondo nada novo sobre FlashAttention, estou pegando um paper denso de sistemas de computação e traduzindo pra decisão prática de quem opera uma agência de GEO. O objetivo muda conforme o público:
Pra mim: documentar publicamente o raciocínio técnico que já uso pra decidir infraestrutura, e deixar rastro verificável de que a decisão foi fundamentada, não intuitiva. Pra Negócio no Mapa: registro de referência interno — quando alguém da equipe precisar entender por que rodamos com FlashAttention habilitado ou por que separamos diagnóstico de Prefill e Decoding, a explicação já está publicada, não precisa ser refeita. Pro mercado: a maioria do conteúdo de GEO em português trata “modelo local” como escolha binária (rodar ou não rodar), sem entrar na engenharia que decide se isso é viável em produção — esta página preenche esse degrau técnico que falta entre “GEO estratégico” e “infraestrutura de fato”.
Continua sendo a mesma lógica da página anterior desta série, sobre quantização: mesmo cinturão de infraestrutura, agora do lado de dentro da GPU em vez do tamanho do modelo em disco.
Dois níveis de memória, uma ordem de grandeza de diferença
Dentro de uma GPU NVIDIA moderna existem duas memórias fisicamente distintas:
A HBM (memória global da GPU, 40-80GB numa A100) é grande, mas cerca de dez vezes mais lenta que a SRAM —
memória interna de cada Streaming Multiprocessor, minúscula (centenas de KB) mas extremamente rápida. No
mecanismo de atenção padrão, a matriz N×N inteira precisa ser escrita na HBM e lida de volta
antes de multiplicar por V — para contexto longo, essa ida e volta domina o tempo total, não o cálculo em
si.
FlashAttention: eliminar a viagem, não o cálculo
O FlashAttention (Dao et al., 2022) resolve isso fundindo as operações num único kernel — divide Q, K, V
em blocos pequenos o bastante para caber na SRAM, calcula o Softmax de forma incremental via estatística
online (sem nunca materializar a matriz N×N inteira na HBM), e só escreve o resultado final.
Ponto técnico que costuma ser mal entendido: FlashAttention não reduz o número de operações
matemáticas (FLOPs continuam O(N²d)) — reduz o tráfego de memória,
de O(N²) para O(N). É otimização de I/O, não de álgebra. É por isso que o
resultado é atenção exata, idêntica matematicamente à versão padrão — não uma aproximação.
Compilador: automatizar o que costumava ser trabalho manual de CUDA
Escrever kernel nativo em CUDA C++ exige gerenciar manualmente posição de thread, indexação de memória compartilhada e sincronização — um erro de alinhamento derruba performance pela metade. Ferramentas como Triton (OpenAI, linguagem e compilador aberto) e TorchCompile (TorchInductor) automatizam isso em três camadas:
Captura de grafo
O compilador analisa o código imperativo do PyTorch e transforma em um grafo de computação estático.
Fusão vertical de operadores
Operações sequenciais (ex: LayerNorm sobre SwiGLU somado a residual) são fundidas num único loop — em vez de alocar tensor temporário na HBM a cada etapa, os dados intermediários ficam nos registradores do chip.
Autotuning
O compilador gera dezenas de variantes de kernel, testa diretamente no hardware local e seleciona a mais rápida para aquela GPU específica.
Duas fases de inferência, dois gargalos diferentes
Uma requisição de LLM passa por duas fases com perfil de desempenho opostos:
- PrefillProcessa todo o prompt de entrada de uma vez — compute-bound, limitado por FLOPs da GPU. Determina a latência até o primeiro token aparecer.
- DecodingGera um token por vez, sequencialmente — memory-bound, limitado pela banda de memória para ler os pesos do modelo a cada passo. Determina a taxa de geração contínua.
Otimizar as duas fases exige táticas diferentes — reduzir FLOPs ajuda o Prefill, mas não resolve o Decoding; aumentar banda efetiva de memória (via cache melhor, batching, ou quantização) ajuda o Decoding, mas pouco muda no Prefill.
O que isso muda no pipeline de uma agência
- 01 Nunca rode inferência de produção sem FlashAttention habilitado. É suporte nativo hoje em praticamente todo framework de serving relevante (vLLM, TGI) — deixar desligado é jogar fora ganho de velocidade sem custo de qualidade.
- 02 Diagnostique qual fase está travando antes de otimizar. Se a demora é até o primeiro token, o problema é Prefill/compute; se é a geração lenta token a token, é Decoding/memória — otimizações erradas não ajudam.
- 03 Combine com quantização (página anterior) para efeito composto. Menos bits por peso reduz o volume de dado que precisa viajar HBM↔SRAM a cada passo de Decoding — as duas otimizações atacam o mesmo gargalo de ângulos diferentes.
Fontes: Dao, T. et al., “FlashAttention: Fast and Memory-Efficient Exact Attention with IO-Awareness” (NeurIPS 2022, arXiv:2205.14135) — speedups de 3× (GPT-2) e 2,4× (contexto longo) reportados no paper original; benchmark independente citando até 7,6× (Shreyansh Singh, análise técnica, 2023). Ansel, J. et al., “PyTorch 2: Faster Machine Learning Through Dynamic Python Bytecode Transformation and Graph Compilation” (TorchInductor/TorchCompile).