Transformers · LLMs · RAG · Bases Vetoriais

Engenharia de LLMs, da atenção à produção

Uma apostila para quem já programa e quer dominar modelos de linguagem em profundidade: a matemática da atenção, o ciclo de vida de um LLM, recuperação vetorial, RAG de ponta e tudo que separa um protótipo de um sistema em produção — com foco direto no mercado de Engenharia de IA.

nível: intermediário → muito avançado · pré-requisitos: Python, álgebra linear básica · atualizada: 2026
CAPÍTULO 01

Fundamentos: como máquinas representam linguagem

Antes da arquitetura, o insumo. Este capítulo estabelece o vocabulário que todo o resto assume: tokens, embeddings, o problema que as RNNs não resolveram e a ideia que mudou tudo.

1.1 Tokens: a unidade atômica

Um LLM não lê texto — lê uma sequência de inteiros. A tokenização converte texto em unidades de um vocabulário fixo (tipicamente 32k–256k entradas). O algoritmo dominante é o BPE (Byte-Pair Encoding): parte-se de bytes individuais e, iterativamente, funde-se o par de símbolos adjacentes mais frequente no corpus, criando novos tokens até atingir o tamanho de vocabulário desejado.

  • byte-level BPE (GPT-2 em diante): opera sobre bytes UTF-8, então qualquer string é tokenizável — não existe token desconhecido.
  • SentencePiece/Unigram (Llama, Gemma): trata o texto como stream bruto e aprende um vocabulário por máxima verossimilhança, removendo tokens que menos contribuem.
  • Palavras comuns viram 1 token; palavras raras ou em português frequentemente viram 2–4 tokens. Isso tem consequência direta em custo (APIs cobram por token) e em desempenho (línguas sub-representadas gastam mais tokens pelo mesmo conteúdo).
Por que engenheiros precisam entender tokenização

Muitos bugs "misteriosos" de LLM são tokenização: aritmética falha porque números são fatiados de forma inconsistente; strings com espaços à esquerda tokenizam diferente de sem espaço (" casa""casa"); limites de contexto e custos de API são medidos em tokens, não caracteres. Use tiktoken (OpenAI) ou tokenizers (Hugging Face) para inspecionar antes de otimizar.

1.2 Embeddings: significado como geometria

Cada token do vocabulário é associado a um vetor denso em ℝd (d tipicamente 768–16384), armazenado numa matriz de embedding E ∈ ℝ^{V×d} aprendida junto com o modelo. A intuição central, herdada do word2vec (2013), é a hipótese distribucional: palavras que ocorrem em contextos parecidos ganham vetores próximos. A geometria do espaço passa a codificar semântica — proximidade é similaridade, e direções podem codificar relações.

A diferença crucial dos embeddings modernos: word2vec dava um vetor por palavra ("banco" de sentar e "banco" financeiro colidiam). Um Transformer produz embeddings contextuais: o vetor de "banco" na camada 20 depende de toda a frase ao redor. É essa contextualização progressiva, camada a camada, que a atenção implementa — e é ela que reaparece no Capítulo 4 como base das buscas vetoriais.

1.3 De RNNs à atenção: o problema e a virada

Até 2017, sequências eram processadas por RNNs/LSTMs: um estado oculto h_t atualizado token a token. Dois defeitos estruturais:

  1. Gargalo sequencial — h_t depende de h_{t-1}; impossível paralelizar no tempo. Treinar em corpora de trilhões de tokens era inviável.
  2. Memória comprimida — toda a história precisa caber num vetor de tamanho fixo; dependências longas se degradam (gradientes que somem/explodem, mitigados mas não resolvidos por gates).

O mecanismo de atenção surgiu primeiro como remendo para tradução (Bahdanau, 2014): em vez de comprimir a frase-fonte num vetor, o decoder "olha" para todos os estados do encoder com pesos aprendidos. O paper "Attention Is All You Need" (Vaswani et al., 2017) fez a pergunta radical: e se removêssemos a recorrência e ficássemos com atenção? O resultado — o Transformer — trocou profundidade temporal por largura paralela: todos os tokens são processados simultaneamente, e a comunicação entre posições acontece via atenção. Isso casou perfeitamente com GPUs e destravou a era do scaling.

Tradução para o mercado

Em entrevistas de Engenheiro de IA, "por que Transformers substituíram RNNs?" é pergunta de aquecimento. A resposta forte tem três pontos: paralelização total no treino (uma multiplicação de matrizes vs. um loop), caminho de gradiente O(1) entre quaisquer posições (vs. O(n) na RNN) e escalabilidade empírica (scaling laws, Cap. 3). Cite o trade-off: atenção custa O(n²) na sequência, o que motiva metade das inovações do Capítulo 2.

CAPÍTULO 02

A arquitetura Transformer em profundidade

O coração da apostila. Aqui você deriva a atenção da intuição à fórmula, entende cada componente do bloco moderno (RMSNorm, SwiGLU, RoPE, GQA), as otimizações que tornam a inferência viável (KV cache, FlashAttention, MLA) e implementa um GPT funcional do zero.

2.1 Self-attention: derivando a fórmula

A pergunta que a atenção responde: para atualizar a representação do token i, quanta informação buscar de cada token j? A solução é um mecanismo de recuperação suave (soft lookup) com três projeções lineares aprendidas por token:

  • Query (Q) — "o que estou procurando": q_i = x_i W_Q
  • Key (K) — "o que eu ofereço como índice": k_j = x_j W_K
  • Value (V) — "o conteúdo que entrego se for selecionado": v_j = x_j W_V

A afinidade entre a posição i e a posição j é o produto escalar q_i · k_j. Normalizamos as afinidades de cada query com softmax, obtendo uma distribuição de probabilidade sobre as posições, e usamos esses pesos para fazer uma média ponderada dos values:

Scaled Dot-Product AttentionAttention(Q, K, V) = softmax( QKᵀ / √d_k ) V

Por que dividir por √d_k? Se as componentes de q e k são i.i.d. com média 0 e variância 1, então Var(q·k) = d_k. Com d_k = 128, os logits teriam desvio-padrão ~11 — o softmax saturaria em quase one-hot, e os gradientes através dele desapareceriam. Dividir por √d_k devolve variância 1 aos logits e mantém o softmax numa região "macia" e treinável. É o tipo de detalhe que separa quem decorou a fórmula de quem a entende.

Máscara causal. Em modelos autorregressivos (GPT-like), o token i não pode ver o futuro. Antes do softmax, soma-se −∞ nas posições j > i, zerando esses pesos. Encoders bidirecionais (BERT, e a maioria dos modelos de embedding do Cap. 4) não usam máscara causal — cada token vê a frase inteira.

Leitura avançada da mesma fórmula

Cada camada de atenção computa, para cada token, uma combinação convexa dos values — a saída vive no fecho convexo dos v_j. A atenção move informação entre posições (mixing no eixo da sequência); a FFN que vem depois processa informação dentro de cada posição (mixing no eixo dos canais). Essa divisão de trabalho — comunicação vs. computação — é o jeito mais útil de pensar o Transformer, e é a base da literatura de interpretabilidade (circuits, induction heads).

2.2 Multi-Head Attention — e suas descendentes MQA, GQA e MLA

Uma única atenção força o modelo a resumir todos os tipos de relação (sintaxe, correferência, posição, semântica) numa distribuição só. Multi-Head Attention (MHA) divide o espaço em h cabeças de dimensão d_k = d/h; cada cabeça tem suas próprias W_Q, W_K, W_V, atende de forma independente e as saídas são concatenadas e projetadas por W_O:

Multi-HeadMHA(X) = Concat(head_1, …, head_h) W_O,  head_i = Attention(XW_Q⁽ⁱ⁾, XW_K⁽ⁱ⁾, XW_V⁽ⁱ⁾)

Na inferência, porém, MHA tem um custo escondido: o KV cache (seção 2.5) guarda K e V de todas as cabeças para todos os tokens — e memória de cache é o gargalo real de serving. Daí a linhagem de otimizações:

VarianteIdeiaKV cacheQuem usa
MHAh cabeças completas de Q, K e V2·n·h·d_k por camadaGPT-2/3, BERT
MQA (Multi-Query)h queries, mas uma única cabeça de K/V compartilhada÷h (enorme economia, alguma perda de qualidade)PaLM, Falcon
GQA (Grouped-Query)g grupos de K/V (1 < g < h); meio-termo÷(h/g), qualidade ≈ MHALlama 2/3, Mistral, Qwen — o padrão atual
MLA (Multi-head Latent)comprime K/V num vetor latente de baixo posto; descomprime on-the-fly~1/10 do MHA com qualidade igual ou melhorDeepSeek-V2/V3/R1

MLA merece atenção especial por ser o estado da arte em eficiência: em vez de cachear K e V, cacheia-se apenas uma projeção latente c_t = x_t W_DKV de dimensão pequena (ex.: 512), e K/V são reconstruídos por up-projections absorvíveis nas matrizes de Q e O. Foi uma das chaves para o DeepSeek treinar e servir modelos de fronteira a custo radicalmente menor.

2.3 Posição: de senos e cossenos ao RoPE

A atenção é permutation-equivariant: sem informação posicional, "cão morde homem" e "homem morde cão" seriam idênticos. Soluções, em ordem histórica:

  • Sinusoidal (Transformer original): soma-se ao embedding um vetor fixo de senos/cossenos em frequências geométricas. Simples, mas posição vira "ruído aditivo" no conteúdo.
  • Embeddings posicionais aprendidos (GPT-2, BERT): uma linha de tabela por posição. Não extrapola além do contexto de treino.
  • ALiBi: sem embedding; penaliza logits de atenção linearmente pela distância |i−j|. Extrapola bem; usado no MPT e BLOOM.
  • RoPE (Rotary Position Embedding) — o padrão moderno (Llama, Qwen, Mistral, DeepSeek, Gemma).

A ideia do RoPE: em vez de somar posição ao conteúdo, rotacionar os vetores q e k. Divide-se o vetor em pares de dimensões; cada par (2t, 2t+1) é tratado como um número complexo e rotacionado por um ângulo proporcional à posição m, com frequência θ_t = base^{−2t/d} (base tipicamente 10.000 a 1M):

RoPEq̃_m = R(mθ) q_m,  k̃_n = R(nθ) k_n  ⇒  q̃_m · k̃_n depende apenas de (m − n)

A mágica: como rotações preservam norma e o produto interno de dois vetores rotacionados depende só da diferença dos ângulos, o score de atenção passa a codificar posição relativa automaticamente — sem parâmetros extras, aplicado dentro de cada camada. Dimensões de alta frequência distinguem vizinhos imediatos; as de baixa frequência, distâncias longas.

Extensão de contexto: como modelos chegam a 1M de tokens

RoPE treinado até 8k degrada além disso — as rotações extrapolam para ângulos nunca vistos. As técnicas de extensão manipulam as frequências: Position Interpolation comprime as posições (m → m/s); NTK-aware scaling aumenta a base θ para esticar só as baixas frequências; YaRN combina interpolação por faixa de frequência com um ajuste de temperatura na atenção, e é o método usado em vários modelos de contexto longo. Na prática de mercado: contexto longo ≠ atenção uniforme — avalie sempre com testes tipo needle-in-a-haystack e atenção ao fenômeno de lost in the middle.

2.4 O bloco Transformer moderno, peça por peça

Um decoder block de 2026 (Llama 3, Qwen 3, DeepSeek-V3) difere do paper de 2017 em quase todos os detalhes. A receita atual:

# Pseudocódigo do bloco moderno (pre-norm)
x = x + Attention( RMSNorm(x) )   # GQA/MLA + RoPE, com máscara causal
x = x + SwiGLU( RMSNorm(x) )      # FFN gated, d_ff ≈ 2.7·d
  • Pre-norm em vez de post-norm. Normalizar antes de cada sub-camada (e não depois da soma residual) cria um "fluxo residual" limpo da entrada à saída — gradientes fluem sem atravessar normalizações, permitindo treinar centenas de camadas sem warm-up delicado.
  • RMSNorm em vez de LayerNorm. Remove a centralização pela média e o bias; apenas reescala pela raiz da média dos quadrados: x̂ = x / RMS(x) · g. Mais barato, igualmente estável.
  • SwiGLU em vez de ReLU/GELU. A FFN vira uma unidade com gate: FFN(x) = (Swish(xW_gate) ⊙ xW_up) W_down. O gate multiplicativo dá à rede um mecanismo de seleção de features; empiricamente melhora perplexidade de forma consistente.
  • Sem biases nas projeções lineares (estabilidade e menos parâmetros); weight tying entre a matriz de embedding e a cabeça de saída em modelos menores.
  • A FFN concentra ~2/3 dos parâmetros do modelo. A literatura de interpretabilidade a descreve como memória associativa chave-valor — onde grande parte do "conhecimento factual" reside.

2.5 Inferência autorregressiva: KV cache e FlashAttention

Gerar texto é um loop: prever a distribuição do próximo token, amostrar, anexar, repetir. Recalcular a atenção de toda a sequência a cada passo custaria O(n²) por token. O KV cache resolve: como K e V dos tokens passados não mudam (a máscara é causal), guardamo-los; a cada passo novo, computa-se apenas q, k, v do token atual e atende-se contra o cache.

Memória do KV cache (por sequência)bytes = 2 · n_layers · n_kv_heads · d_head · seq_len · bytes_dtype
Ex.: Llama-3-70B, 8k tokens, FP16 ≈ 2·80·8·128·8192·2 ≈ 2.7 GB por requisição

Duas consequências de engenharia que caem em entrevista:

  1. Prefill vs. decode. O processamento do prompt (prefill) é paralelo e compute-bound; a geração token a token (decode) é memory-bandwidth-bound — o tempo é dominado por ler os pesos e o KV cache da HBM. Por isso batching agressivo (continuous batching, vLLM) multiplica o throughput: dilui a leitura dos pesos entre várias sequências.
  2. PagedAttention (vLLM). Alocar cache contíguo por requisição fragmenta memória. O vLLM gerencia o KV cache como memória virtual de SO: blocos (pages) de tamanho fixo, tabela de páginas por sequência, compartilhamento copy-on-write entre requisições com prefixo comum (prefix caching). Resultado: 2–4× mais throughput.

FlashAttention ataca o outro gargalo: a matriz de atenção n×n nunca deveria materializar na HBM. O kernel computa a atenção em tiles que cabem na SRAM do chip, usando online softmax (mantém máximo corrente e soma corrente, reescalando parcial­mente) para nunca precisar da matriz inteira. Memória cai de O(n²) para O(n), e a parede de banda é evitada. FlashAttention-2/3 refinam paralelismo e uso de FP8 em Hopper. É exemplo canônico de hardware-aware algorithm — e resposta pronta para "como você faria atenção escalar em contexto longo?".

2.6 Mixture of Experts (MoE): parâmetros ≠ FLOPs

Em modelos densos, todo token ativa todos os pesos. Um MoE substitui a FFN de cada bloco por E experts (FFNs independentes) e um router aprendido que escolhe o top-k (tipicamente k=1–8) para cada token:

MoE layery = Σ_{i ∈ TopK(g(x))} g_i(x) · FFN_i(x),   g(x) = softmax(x W_router)
  • Desacopla capacidade de custo: DeepSeek-V3 tem 671B parâmetros, mas ativa ~37B por token. Qwen3-MoE, Mixtral, GPT-4 (reportadamente) e a maioria dos modelos de fronteira atuais seguem o padrão.
  • Desafios reais: balanceamento de carga entre experts (auxiliary losses ou, no DeepSeek-V3, estratégia loss-free com bias ajustável por expert), custo de comunicação all-to-all em treino distribuído, e maior pegada de memória no serving (todos os experts residem na GPU mesmo que poucos ativem).
  • Tendências: experts finos e numerosos + shared experts sempre ativos (DeepSeek), roteamento por sequência vs. por token, e MoE também na atenção (mais raro).

2.7 Implementação: um GPT mínimo e moderno em PyTorch

O código abaixo implementa um decoder-only com as escolhas modernas (RMSNorm, RoPE, GQA, SwiGLU, pre-norm, KV cache). É pequeno o bastante para treinar em um corpus de brinquedo e fiel o bastante para servir de base de estudo séria — digno de repositório de portfólio.

modern_gpt.py — decoder-only com GQA + RoPE + SwiGLU
import math, torch
import torch.nn as nn
import torch.nn.functional as F

class RMSNorm(nn.Module):
    def __init__(self, d, eps=1e-5):
        super().__init__(); self.g = nn.Parameter(torch.ones(d)); self.eps = eps
    def forward(self, x):
        return x * torch.rsqrt(x.pow(2).mean(-1, keepdim=True) + self.eps) * self.g

def rope_freqs(d_head, max_len, base=10_000.0, device="cpu"):
    inv = 1.0 / (base ** (torch.arange(0, d_head, 2, device=device) / d_head))
    t = torch.arange(max_len, device=device)
    ang = torch.outer(t, inv)                      # (max_len, d_head/2)
    return torch.polar(torch.ones_like(ang), ang)  # e^{i·mθ}

def apply_rope(x, freqs):                        # x: (B, n_heads, T, d_head)
    xc = torch.view_as_complex(x.float().reshape(*x.shape[:-1], -1, 2))
    out = torch.view_as_real(xc * freqs[None, None, :xc.shape[2]])
    return out.reshape(*x.shape).type_as(x)

class GQAttention(nn.Module):
    def __init__(self, d, n_heads=8, n_kv_heads=2):
        super().__init__()
        self.nh, self.nkv, self.dh = n_heads, n_kv_heads, d // n_heads
        self.wq = nn.Linear(d, n_heads   * self.dh, bias=False)
        self.wk = nn.Linear(d, n_kv_heads* self.dh, bias=False)
        self.wv = nn.Linear(d, n_kv_heads* self.dh, bias=False)
        self.wo = nn.Linear(d, d, bias=False)
        self.cache_k = self.cache_v = None          # KV cache p/ inferência

    def forward(self, x, freqs, use_cache=False):
        B, T, _ = x.shape
        q = self.wq(x).view(B, T, self.nh,  self.dh).transpose(1, 2)
        k = self.wk(x).view(B, T, self.nkv, self.dh).transpose(1, 2)
        v = self.wv(x).view(B, T, self.nkv, self.dh).transpose(1, 2)
        q, k = apply_rope(q, freqs), apply_rope(k, freqs)
        if use_cache:                                # decode: anexa ao cache
            if self.cache_k is not None:
                k = torch.cat([self.cache_k, k], dim=2)
                v = torch.cat([self.cache_v, v], dim=2)
            self.cache_k, self.cache_v = k, v
        k = k.repeat_interleave(self.nh // self.nkv, dim=1)  # GQA: expande grupos
        v = v.repeat_interleave(self.nh // self.nkv, dim=1)
        # SDPA despacha p/ FlashAttention quando disponível
        out = F.scaled_dot_product_attention(q, k, v, is_causal=not use_cache)
        return self.wo(out.transpose(1, 2).reshape(B, T, -1))

class SwiGLU(nn.Module):
    def __init__(self, d, mult=8/3):
        super().__init__()
        h = int(mult * d)
        self.gate = nn.Linear(d, h, bias=False)
        self.up   = nn.Linear(d, h, bias=False)
        self.down = nn.Linear(h, d, bias=False)
    def forward(self, x):
        return self.down(F.silu(self.gate(x)) * self.up(x))

class Block(nn.Module):
    def __init__(self, d, n_heads, n_kv_heads):
        super().__init__()
        self.n1, self.n2 = RMSNorm(d), RMSNorm(d)
        self.attn, self.ffn = GQAttention(d, n_heads, n_kv_heads), SwiGLU(d)
    def forward(self, x, freqs, use_cache=False):
        x = x + self.attn(self.n1(x), freqs, use_cache)   # pre-norm residual
        return x + self.ffn(self.n2(x))

class ModernGPT(nn.Module):
    def __init__(self, vocab=32_000, d=512, n_layers=8,
                 n_heads=8, n_kv_heads=2, max_len=2048):
        super().__init__()
        self.emb = nn.Embedding(vocab, d)
        self.blocks = nn.ModuleList(Block(d, n_heads, n_kv_heads) for _ in range(n_layers))
        self.norm = RMSNorm(d)
        self.head = nn.Linear(d, vocab, bias=False)
        self.head.weight = self.emb.weight               # weight tying
        self.register_buffer("freqs", rope_freqs(d // n_heads, max_len), persistent=False)

    def forward(self, idx, targets=None):
        x = self.emb(idx)
        for b in self.blocks: x = b(x, self.freqs)
        logits = self.head(self.norm(x))
        loss = None
        if targets is not None:      # next-token prediction: cross-entropy
            loss = F.cross_entropy(logits.view(-1, logits.size(-1)),
                                   targets.view(-1), ignore_index=-100)
        return logits, loss

    @torch.no_grad()
    def generate(self, idx, max_new=100, temperature=0.8, top_p=0.95):
        for _ in range(max_new):
            logits, _ = self(idx[:, -2048:])
            logits = logits[:, -1] / max(temperature, 1e-6)
            probs = F.softmax(logits, dim=-1)
            sp, si = torch.sort(probs, descending=True)     # nucleus (top-p)
            mask = sp.cumsum(-1) - sp > top_p
            sp[mask] = 0.0; sp /= sp.sum(-1, keepdim=True)
            nxt = si.gather(-1, torch.multinomial(sp, 1))
            idx = torch.cat([idx, nxt], dim=1)
        return idx
O que estudar a partir deste código
  • Trace as shapes de cada tensor no papel — entrevistas técnicas adoram "qual a shape aqui?".
  • Meça o efeito de n_kv_heads no tamanho do cache; troque SDPA por uma atenção manual e compare velocidade.
  • Exercícios de extensão: adicionar sliding-window attention, um router MoE simples no lugar da SwiGLU, e speculative decoding no generate.
  • Referências de ouro para aprofundar: nanoGPT/nanochat (Karpathy), os papers do Llama 3 e do DeepSeek-V3 (relatórios de engenharia excepcionais).
CAPÍTULO 03

LLMs: o ciclo de vida completo

Um Transformer vira um LLM através de um pipeline: pré-treino em trilhões de tokens, adaptação supervisionada, alinhamento por preferências, e — na fronteira atual — treino de raciocínio por RL. Depois, tudo precisa ser servido rápido e barato.

3.1 Pré-treino: next-token prediction em escala

O objetivo é enganosamente simples: maximizar a verossimilhança do próximo token em um corpus gigante.

Objetivo autorregressivoL(θ) = − Σ_t log p_θ( x_t | x_<t )

Prever bem o próximo token exige, implicitamente, sintaxe, fatos, raciocínio, tradução, código — o pré-treino é aprendizado multitarefa disfarçado. Os ingredientes de escala:

  • Dados (o diferencial real). Web filtrada (Common Crawl → pipelines como FineWeb), código, artigos, livros, dados multilíngues e crescentemente dados sintéticos (gerados/reescritos por LLMs, ex.: linhagem Phi e boa parte dos modelos 2025+). O pipeline de dados — dedupe (MinHash), filtros de qualidade por classificadores, mistura de domínios, currículo (dados melhores no fim do treino) — é hoje mais decisivo que a arquitetura.
  • Scaling laws. Kaplan (2020) mostrou que a loss cai como lei de potência em parâmetros N, dados D e compute C. Chinchilla (2022) corrigiu a alocação: para um orçamento fixo de FLOPs (C ≈ 6·N·D), o ótimo é D ≈ 20·N tokens. Mas o "ótimo de treino" ignora inferência: modelos modernos são deliberadamente overtrained (Llama 3 8B viu ~15T tokens, ~200× N) porque um modelo menor e mais treinado é mais barato de servir pelo resto da vida.
  • Treino distribuído. Nenhuma GPU comporta o modelo. Combina-se Data Parallelism (réplicas com gradientes agregados; ZeRO/FSDP fragmentam pesos, gradientes e estados do otimizador), Tensor Parallelism (fatiar matrizes individuais entre GPUs do mesmo nó), Pipeline Parallelism (camadas em estágios, com micro-batches para reduzir bolhas) e, em MoE, Expert Parallelism. Treina-se em BF16 com acumulação FP32; a fronteira usa FP8 (DeepSeek-V3) com escalonamento fino por bloco.

3.2 Pós-treino I — SFT e fine-tuning eficiente (LoRA/QLoRA)

O modelo base completa texto; não conversa. SFT (Supervised Fine-Tuning) treina o mesmo objetivo de next-token, mas em pares instrução→resposta de alta qualidade, mascarando a loss nos tokens do prompt (só a resposta gera gradiente). Qualidade > quantidade: alguns milhares a poucas centenas de milhares de exemplos curados superam milhões medíocres.

LoRA (Low-Rank Adaptation) é a técnica de fine-tuning que você mais usará no mercado. Hipótese: a atualização de pesos necessária para adaptar um modelo tem posto baixo. Então congela-se W e aprende-se só uma correção fatorada:

LoRAW' = W + (α/r) · B·A,   A ∈ ℝ^{r×d}, B ∈ ℝ^{d×r},  r ≪ d (ex.: r = 8–64)
  • Treina-se ~0,1–1% dos parâmetros; B inicia em zero (o modelo começa idêntico ao base); após o treino, BA pode ser fundido em W — latência de inferência zero.
  • QLoRA: o modelo base fica quantizado em NF4 (4 bits, formato ótimo p/ pesos normalmente distribuídos) com double quantization, e os adaptadores LoRA treinam em BF16 por cima. Fine-tuning de um 70B em uma única GPU de 48 GB.
  • Serving multi-tenant: dezenas de LoRAs sobre o mesmo base model, trocados por requisição (S-LoRA, vLLM multi-LoRA) — padrão em produtos B2B.
Decisão de mercado: fine-tuning vs. RAG vs. prompt

Regra prática que impressiona em entrevista: prompt engineering para comportamento e formato (custo zero); RAG para conhecimento que muda ou precisa de citação (o modelo não deve "decorar" seu banco de dados); fine-tuning para estilo, formato estrito, domínio de vocabulário e destilar capacidade de um modelo caro num barato. Fine-tuning não é a ferramenta certa para injetar fatos atualizáveis — conhecimento paramétrico não tem citação, não expira e sofre de esquecimento catastrófico.

3.3 Pós-treino II — Alinhamento por preferências: RLHF, DPO, GRPO

SFT ensina a imitar; preferências ensinam o que é melhor. O pipeline clássico RLHF (InstructGPT, 2022):

  1. Coletam-se comparações humanas entre respostas (A ≻ B).
  2. Treina-se um reward model r_φ com loss de Bradley-Terry: maximizar log σ(r(x, y_w) − r(x, y_l)).
  3. Otimiza-se a política com PPO, maximizando a reward com uma penalidade KL contra o modelo de referência para evitar reward hacking e colapso: max E[r(x,y)] − β·KL(π‖π_ref).

DPO (Direct Preference Optimization) eliminou o reward model e o loop de RL: mostra-se que a solução ótima do objetivo RLHF tem forma fechada, e o reward implícito pode ser expresso pela própria política. A loss vira uma classificação direta sobre os pares de preferência:

DPOL = −log σ( β·[ log π(y_w|x)/π_ref(y_w|x) − log π(y_l|x)/π_ref(y_l|x) ] )

Simples, estável, sem amostragem online — tornou-se o caminho padrão para times fora dos grandes laboratórios. Variantes: IPO (regulariza contra overfitting da preferência), KTO (não precisa de pares, só rótulos bom/ruim), ORPO (funde SFT + preferência).

GRPO (Group Relative Policy Optimization), popularizado pelo DeepSeek: remove o modelo de valor (critic) do PPO. Para cada prompt amostram-se G respostas; a vantagem de cada uma é sua reward normalizada dentro do grupo (z-score). Barato, e brilha quando a reward é verificável — nota de teste unitário, resposta matemática exata — o regime chamado RLVR (RL with Verifiable Rewards), motor dos modelos de raciocínio.

3.4 Modelos de raciocínio e test-time compute

A fronteira 2024–2026 deslocou o scaling do treino para a inferência: deixar o modelo "pensar mais" antes de responder.

  • Chain-of-Thought (CoT): gerar passos intermediários melhora tarefas de raciocínio — cada token gerado é compute adicional condicionando os próximos.
  • Modelos de raciocínio (OpenAI o1/o3, DeepSeek-R1, Claude com extended thinking, Gemini thinking, Qwen QwQ): treinados com RL (tipicamente GRPO/RLVR) para produzir longas cadeias internas de pensamento — com verificação, backtracking e autocorreção emergentes — antes da resposta final. O DeepSeek-R1 demonstrou que raciocínio forte emerge de RL puro sobre recompensas verificáveis, sem supervisão de cadeias humanas (R1-Zero), destilável depois para modelos pequenos.
  • Test-time compute como eixo de scaling: best-of-N com verificador, self-consistency (votação entre cadeias), busca guiada por process reward models. O custo por resposta vira um dial: problemas fáceis pensam pouco, difíceis pensam muito ("reasoning effort").
  • Implicação para engenheiros: latência e custo de modelos de raciocínio são ordens de magnitude maiores e variáveis — roteie: modelo rápido para o trivial, modelo pensante para o difícil (model routing/cascading é padrão de arquitetura em produção).

3.5 Inferência: sampling, quantização e serving de alto desempenho

Estratégias de decodificação

  • Temperatura T reescala logits (z/T): T→0 vira greedy (determinístico); T alto achata a distribuição. Top-p (nucleus) amostra do menor conjunto cuja massa acumulada ≥ p; top-k e min-p são alternativas. Para extração estruturada use T baixa; para criatividade, T 0.7–1.0.
  • Decodificação especulativa: um modelo rascunho pequeno (ou cabeças extras — Medusa/EAGLE) propõe k tokens; o modelo grande os verifica em um único forward paralelo, aceitando o prefixo que bate com sua própria distribuição (via rejection sampling que preserva exatamente a distribuição original). Speedups de 2–3× sem perda de qualidade — só é possível porque verificar k tokens custa quase o mesmo que gerar 1 (decode é memory-bound, lembra?).
  • Saída estruturada: constrained decoding com gramáticas/JSON Schema (Outlines, XGrammar, structured outputs das APIs) mascara logits inválidos a cada passo — elimina "JSON quebrado" por construção.

Quantização

MétodoComo funcionaUso típico
GPTQQuantização pós-treino camada a camada, minimizando erro com informação de segunda ordem (Hessiana aproximada)4-bit para serving em GPU
AWQIdentifica ~1% de canais salientes (por magnitude de ativação) e os protege reescalando antes de quantizar4-bit, robusto, muito usado com vLLM
GGUF (llama.cpp)Formato + esquemas k-quants/i-quants (2–8 bits) para inferência em CPU/Apple SiliconLocal/edge
FP8 / INT8Quantização de pesos e ativações com suporte nativo de hardware (Hopper/Blackwell); SmoothQuant migra dificuldade das ativações para os pesosServing de alta escala
KV cache quantCache em FP8/INT4 — dobra/quadruplica sequências simultâneasContexto longo

Regra de bolso: 4-bit weight-only preserva ~99% da qualidade na maioria das tarefas e corta memória em ~4× vs FP16 — mas sempre avalie na sua tarefa (raciocínio e código degradam primeiro).

Motores de serving

  • vLLM — continuous batching + PagedAttention + prefix caching; padrão de facto open-source.
  • SGLang — RadixAttention (reuso agressivo de prefixos em árvore), forte em workloads agênticos e structured output.
  • TensorRT-LLM — kernels NVIDIA máximos; mais atrito, mais performance.
  • llama.cpp / Ollama — local, CPU/metal, prototipagem e edge.
  • Métricas que você reportará em produção: TTFT (time to first token, dominado pelo prefill), TPOT/ITL (tempo por token de decode), throughput (tokens/s agregado) e goodput sob SLO. Desagregar prefill e decode em pools separados (prefill/decode disaggregation) é a tendência de arquitetura de serving em larga escala.
CAPÍTULO 04

Embeddings e bases vetoriais

Busca semântica é o alicerce do RAG. Aqui você entende como modelos de embedding são treinados, a matemática da similaridade, os algoritmos de busca aproximada (HNSW, IVF, PQ) e como escolher e operar um banco vetorial de verdade.

4.1 Modelos de embedding modernos

Um modelo de embedding mapeia um texto inteiro para um único vetor e ∈ ℝ^d tal que textos semanticamente próximos fiquem geometricamente próximos. Arquitetura típica: um encoder Transformer (bidirecional, ou um LLM decoder adaptado como nos modelos Qwen3-Embedding/NV-Embed) com pooling (média dos tokens ou último token) e normalização L2.

Como são treinados — contrastive learning. O objetivo dominante é o InfoNCE: aproximar pares positivos (pergunta ↔ documento relevante) e afastar negativos, com os demais exemplos do batch servindo de negativos ("in-batch negatives"):

InfoNCEL = −log [ exp(sim(q, d⁺)/τ) / Σ_j exp(sim(q, d_j)/τ) ]
  • Hard negatives (documentos parecidos mas errados, minerados por BM25 ou outro modelo) são o que separa embeddings medianos de excelentes.
  • Pipeline moderno: pré-treino contrastivo fraco em pares massivos da web → fine-tuning supervisionado com hard negatives → frequentemente destilação de um cross-encoder ou LLM.
  • Assimetria query/documento: muitos modelos usam prefixos de instrução ("query: …" vs "passage: …") — ignorar isso derruba o recall silenciosamente. Leia sempre o cartão do modelo.
  • Matryoshka Representation Learning (MRL): treina-se a loss em prefixos aninhados do vetor (ex.: primeiras 64, 128, 256… dims), permitindo truncar o embedding para economizar armazenamento com perda mínima — recurso padrão nas APIs atuais (OpenAI text-embedding-3, Gemini embedding, vários open-source).
  • Onde comparar modelos: benchmark MTEB (com ceticismo saudável — contaminação e overfitting a benchmark existem; valide no seu domínio). Famílias fortes: BGE/BGE-M3, E5, GTE, Qwen3-Embedding, Voyage, Cohere Embed, OpenAI, Gemini.

4.2 A matemática da similaridade

MétricaFórmulaQuando usar
Cosseno(a·b)/(‖a‖‖b‖)Padrão para texto; ignora magnitude
Produto interno (dot)a·bSe o modelo foi treinado p/ isso; magnitude carrega sinal (ex.: relevância)
Euclidiana (L2)‖a−b‖Dados não normalizados; visão geométrica

Detalhe que evita bugs: com vetores L2-normalizados, as três métricas induzem o mesmo ranking (‖a−b‖² = 2 − 2·a·b). Por isso a maioria dos pipelines normaliza tudo e usa dot product (mais rápido). Cuidado clássico: usar métrica diferente da usada no treino do modelo degrada resultados de forma silenciosa.

A maldição da dimensionalidade — e por que embeddings escapam dela

Em alta dimensão, distâncias entre pontos aleatórios concentram (contraste entre o vizinho mais próximo e o mais distante colapsa). Embeddings funcionam porque os dados não são aleatórios: vivem numa variedade de dimensão intrínseca muito menor (manifold hypothesis). Ainda assim, a geometria de alta dimensão é contraintuitiva — quase todo o volume de uma bola está na casca; vetores aleatórios são quase ortogonais — e é ela que motiva índices aproximados em vez de busca exata.

4.3 Busca aproximada (ANN): HNSW, IVF e Product Quantization

Busca exata (k-NN por força bruta) é O(N·d) por query — inviável para milhões/bilhões de vetores com latência de milissegundos. Índices ANN (Approximate Nearest Neighbor) trocam recall marginal por ordens de magnitude de velocidade. Os três pilares:

HNSW — Hierarchical Navigable Small World

  • Um grafo de proximidade em camadas: a camada superior tem poucos nós e arestas longas ("rodovias"); camadas inferiores são densas e locais ("ruas"). A busca entra pelo topo, desce gulosamente em direção à query, e na camada 0 faz best-first search com uma fila de candidatos.
  • Complexidade de busca ~O(log N); recall altíssimo. Parâmetros que você vai tunar: M (grau do grafo; ↑M = ↑recall, ↑memória), efConstruction (qualidade do índice) e efSearch (largura da busca; o dial recall × latência em runtime).
  • Custo: memória (grafo + vetores residem em RAM) e deleções/updates são desajeitados (tombstones + rebuild periódico). É o índice default de Qdrant, Weaviate, Milvus, pgvector.

IVF — Inverted File Index

  • Clusteriza o espaço com k-means em nlist células; cada vetor entra na lista invertida do seu centróide. Na busca, compara-se a query só com as nprobe células mais próximas.
  • Mais simples e amigável a disco/updates que HNSW; recall depende de nprobe. Base do FAISS clássico e de sistemas bilionários.

PQ — Product Quantization (compressão)

  • Divide o vetor em m sub-vetores; cada sub-vetor é quantizado para o centróide mais próximo de um codebook de 256 entradas → o vetor vira m bytes (ex.: 1024 dims float32 = 4 KB → 64 bytes, 64×).
  • Distâncias são aproximadas por lookup tables (ADC), sem descomprimir. Combina-se: IVF-PQ (padrão em bilhões de vetores), com re-ranking dos top candidatos pelos vetores originais (refine).
  • Quantização binária/int8: mais simples que PQ, muito popular em 2024+ — vetores binários (1 bit/dim) com distância de Hamming para o primeiro corte + rescore float nos top-k; corta custo em ~30× com recall ~95%+ em embeddings MRL grandes.

Além dos três

  • DiskANN/Vamana: grafo otimizado para SSD (vetores comprimidos em RAM, grafo+full vectors em disco) — bilhões de vetores por máquina.
  • ScaNN (Google): quantização anisotrópica que otimiza o erro na direção que afeta o ranking por dot product, não o erro de reconstrução.
  • GPU ANN (FAISS-GPU, cuVS/CAGRA): construção e busca aceleradas — relevante em ingestão massiva.

4.4 Bancos vetoriais na prática

Um banco vetorial de produção é mais que um índice ANN: é CRUD + filtragem por metadados + busca híbrida + replicação + multi-tenancy em cima do índice.

OpçãoPerfilQuando escolher
pgvector / pgvectorscaleExtensão do Postgres (HNSW, halfvec, binary quant; StreamingDiskANN no pgvectorscale)Você já tem Postgres; < dezenas de milhões de vetores; quer transações, joins e um stack só. Default racional para a maioria dos produtos.
QdrantRust, HNSW com filtragem integrada ao grafo, quantização nativa, ótimo custo-benefícioServiço dedicado self-hosted/cloud com filtros pesados
MilvusDistribuído, separa storage/compute, GPU, muitos tipos de índiceBilhões de vetores, time de infra disponível
WeaviateHíbrido nativo (BM25+vetor), módulos de vetorizaçãoBusca híbrida out-of-the-box
PineconeServerless gerenciadoZero ops, pagar pelo conforto
FAISS / usearchBiblioteca, não bancoPesquisa, batch offline, ou embutido no seu serviço
Elasticsearch/OpenSearchHNSW + BM25 maduroVocê já opera Elastic e quer híbrido
Filtered search: o problema difícil escondido

"Buscar top-10 similares onde tenant_id=X e data>Y" quebra índices ingênuos: pós-filtrar os top-k pode devolver zero resultados se o filtro for seletivo; pré-filtrar e fazer força bruta é lento se o filtro for amplo. Soluções reais: filtragem durante a travessia do grafo (Qdrant, com heurísticas que trocam de estratégia conforme a cardinalidade estimada), particionamento por tenant, e índices por segmento. Em entrevista de system design, mencionar esse trade-off é sinal claro de senioridade.

exemplo — Qdrant: coleção, ingestão e busca filtrada
from qdrant_client import QdrantClient, models
from sentence_transformers import SentenceTransformer

model = SentenceTransformer("BAAI/bge-m3")          # 1024 dims, multilíngue
client = QdrantClient(url="http://localhost:6333")

client.create_collection(
    collection_name="docs",
    vectors_config=models.VectorParams(
        size=1024, distance=models.Distance.COSINE,
        on_disk=True,                                # vetores originais em disco
    ),
    quantization_config=models.ScalarQuantization(   # int8 em RAM p/ 1º corte
        scalar=models.ScalarQuantizationConfig(type=models.ScalarType.INT8,
                                               always_ram=True)),
    hnsw_config=models.HnswConfigDiff(m=16, ef_construct=256),
)

chunks = [{"id": 1, "text": "Política de reembolso: até 30 dias…",
           "tenant": "acme", "doc": "politicas.pdf"}]
client.upsert("docs", points=[
    models.PointStruct(id=c["id"],
                       vector=model.encode(c["text"], normalize_embeddings=True),
                       payload=c)
    for c in chunks])

hits = client.query_points(
    "docs",
    query=model.encode("qual o prazo para devolver um produto?",
                       normalize_embeddings=True),
    query_filter=models.Filter(must=[                # filtro DURANTE a busca
        models.FieldCondition(key="tenant", match=models.MatchValue(value="acme"))]),
    search_params=models.SearchParams(hnsw_ef=128), # dial recall × latência
    limit=10,
).points
Checklist de operação (o que diferencia você em produção)
  • Medir recall@k contra ground truth de força bruta ao tunar ef/nprobe — nunca confie no default.
  • Planejar re-embedding: trocar de modelo de embedding invalida o índice inteiro; versione (embedding_v2) e faça migração dual-read.
  • Dimensionar memória: HNSW ≈ vetores + ~M·8 bytes de arestas por vetor; quantização int8/binária corta 4–32×.
  • Isolamento multi-tenant por payload ou por coleção/partição — e teste o pior caso do filtro.
  • Backups e reindexação sem downtime (blue/green de coleções).
CAPÍTULO 05

RAG: do pipeline canônico ao agêntico

Retrieval-Augmented Generation conecta LLMs a conhecimento externo: atualizável, citável e privado. É também onde a maioria dos projetos de IA corporativos vive — e onde a maioria falha por detalhes de recuperação, não de geração.

5.1 O pipeline canônico — e onde ele quebra

Indexação (offline): carregar documentos → limpar/parsear → chunking → embeddar → indexar com metadados. Consulta (online): embeddar a pergunta → recuperar top-k → montar o prompt com os trechos → gerar resposta com citações.

Chunking: a decisão mais subestimada

  • Tamanho: chunks pequenos (128–256 tokens) dão precisão de recuperação mas perdem contexto; grandes (1024+) diluem o sinal do embedding. Ponto de partida sensato: 300–800 tokens com overlap de 10–15% — e avalie.
  • Estratégias: por estrutura (headers de Markdown, seções de PDF — a melhor quando existe estrutura), recursiva por separadores, semântica (quebra onde a similaridade entre sentenças adjacentes cai), e por elemento em documentos complexos (tabelas separadas de prosa).
  • Small-to-big / parent document: indexe chunks pequenos (bons de buscar), devolva ao LLM o pai maior (bom de ler). Simples e eficaz.
  • Contextual retrieval (Anthropic, 2024): antes de embeddar, um LLM prefixa cada chunk com 1–2 frases situando-o no documento ("Este trecho é da seção de garantias do contrato X…"). Reduz falhas de recuperação em ~35–49% combinado com híbrida+rerank. Custo de indexação maior, amortizado por prompt caching.
  • Parsing é metade do jogo: PDFs com tabelas, múltiplas colunas e figuras destroem pipelines ingênuos. Ferramentas: Docling, Unstructured, marker; modelos de visão para páginas complexas.
Onde o RAG realmente falha (diagnóstico antes de remédio)

Falhas se dividem em: (1) recuperação — o trecho certo não veio (chunking ruim, embedding fraco no domínio, vocabulário divergente, filtro errado); (2) uso do contexto — veio, mas o modelo ignorou (contexto poluído, lost-in-the-middle, conflito com conhecimento paramétrico); (3) a resposta não existe no corpus — e o sistema deveria dizer "não sei". Instrumente cada etapa separadamente (seção 5.4): otimizar geração quando o problema é recall é o erro nº 1 de times iniciantes.

5.2 Busca híbrida, fusão e reranking

Denso + esparso

Embeddings capturam parafrase mas erram termos exatos (códigos de erro, nomes próprios, siglas, números de peça). BM25 — o clássico léxico baseado em TF-IDF saturado com normalização por tamanho de documento — captura exatamente isso. Busca híbrida roda os dois e funde os rankings. Alternativa neural ao BM25: SPLADE (esparso aprendido, com expansão de termos).

Reciprocal Rank Fusion (RRF)score(d) = Σ_sistemas 1 / (k + rank_sistema(d)),  k ≈ 60

RRF é robusto porque usa posições, não scores (que vivem em escalas incomparáveis). Weaviate, Qdrant, OpenSearch e pgvector (via SQL) suportam nativamente.

Reranking: o upgrade de melhor custo-benefício

  • Bi-encoder (o que indexa): query e doc viram vetores independentes; interação limitada a um dot product. Rápido, mas grosseiro.
  • Cross-encoder (o reranker): concatena query+documento e passa pelo Transformer inteiro — atenção total entre cada palavra da pergunta e do texto. Muito mais preciso; caro demais para o corpus todo, perfeito para reordenar os top 50–150 recuperados.
  • Opções: Cohere Rerank, Voyage/Jina rerankers, BGE-reranker, ou um LLM como juiz de relevância (listwise). Pipeline padrão de mercado: híbrida (top 100) → cross-encoder (top 100 → top 5–10) → LLM.
  • ColBERT (late interaction): meio-termo elegante — um vetor por token, score = soma dos MaxSim entre tokens da query e do doc. Pré-computável como um índice, quase tão preciso quanto cross-encoder. Implementações: RAGatouille, Qdrant multivector, Jina-ColBERT.

Transformação de consultas

  • Query rewriting: reescrever a pergunta do usuário (coloquial, com dêixis de conversa: "e no plano anual?") em consulta autocontida — obrigatório em chat multi-turno.
  • Multi-query: gerar 3–5 variações e fundir resultados (RRF).
  • HyDE: gerar uma resposta hipotética e buscar por ela — alinha a query ao espaço dos documentos.
  • Decomposição: quebrar perguntas multi-hop ("compare a política de 2023 com a de 2025") em sub-consultas.
  • Roteamento: classificar a intenção e direcionar (vetorial vs. SQL vs. web vs. responder direto). Text-to-SQL sobre dados estruturados é um irmão do RAG que aparece nos mesmos produtos.

5.3 RAG avançado e agêntico

  • Self-RAG / CRAG (corretivo): o sistema critica a própria recuperação — um avaliador leve nota os trechos; se insuficientes, reformula a busca, amplia a janela ou cai para busca web; a geração é verificada contra as evidências antes de sair.
  • GraphRAG: na indexação, um LLM extrai entidades e relações, montando um grafo de conhecimento + resumos hierárquicos por comunidade (Leiden). Responde o que RAG vetorial não alcança: perguntas globais ("quais os temas dominantes neste corpus?") e multi-hop por relações. Custo de indexação alto; variantes leves (LightRAG, LazyGraphRAG) reduzem. Use quando as relações entre entidades são o cerne do domínio (jurídico, investigação, engenharia de requisitos).
  • RAG agêntico — o padrão 2025/26: em vez de um pipeline fixo, um LLM em loop com ferramentas de busca decide quando, o quê e quantas vezes buscar: reformula após resultados ruins, navega entre documentos, junta evidências de múltiplas fontes e para quando tem o suficiente (o padrão por trás de "deep research"). Custa mais latência/tokens; brilha em perguntas complexas. O termo guarda-chuva atual para projetar o que entra no modelo — instruções, memória, trechos recuperados, resultados de tools — é context engineering.
  • Contexto longo mata o RAG? Não: custo/latência crescem com o contexto (e prefill é O(n²) na atenção), atenção degrada no meio de contextos enormes, corpora corporativos excedem qualquer janela, e citação/controle de acesso exigem recuperação. A síntese prática: janelas maiores permitem chunks maiores e top-k maior, com prompt caching baixando o custo de contexto repetido — RAG e long context são complementares.
  • Multimodal: embeddings de imagem-texto (CLIP-like, ColPali para PDFs como imagens) permitem recuperar figuras, tabelas e páginas inteiras sem OCR perfeito — tendência forte para documentos corporativos.

5.4 Avaliação de RAG: sem isso, você está dirigindo vendado

Avalie recuperação e geração separadamente, sempre contra um conjunto de teste do seu domínio (100–300 perguntas com respostas e trechos-fonte anotados; LLMs ajudam a gerar o rascunho, humanos validam).

CamadaMétricasComo medir
RecuperaçãoRecall@k, Precision@k, MRR, nDCGContra os trechos-fonte anotados; é aqui que se tuna chunking, híbrida, rerank
GeraçãoFaithfulness (a resposta é sustentada pelos trechos? — mede alucinação), answer relevancy, correção vs. gabaritoLLM-as-judge com rubricas (frameworks: RAGAS, DeepEval, TruLens) + amostra humana para calibrar o juiz
SistemaTaxa de "não sei" correta, latência p95, custo/consulta, satisfaçãoTelemetria em produção + testes de regressão a cada mudança
esqueleto — RAG híbrido com rerank e avaliação de recall
from qdrant_client import QdrantClient, models
from sentence_transformers import SentenceTransformer, CrossEncoder

emb = SentenceTransformer("BAAI/bge-m3")
reranker = CrossEncoder("BAAI/bge-reranker-v2-m3")
qc = QdrantClient("http://localhost:6333")

def retrieve(question: str, k_dense=50, k_final=6):
    # 1) híbrida: densa + BM25 fundidas por RRF no servidor
    res = qc.query_points(
        "docs",
        prefetch=[
            models.Prefetch(query=emb.encode(question).tolist(),
                            using="dense", limit=k_dense),
            models.Prefetch(query=models.Document(text=question, model="bm25"),
                            using="sparse", limit=k_dense),
        ],
        query=models.FusionQuery(fusion=models.Fusion.RRF),
        limit=k_dense,
    ).points
    # 2) rerank com cross-encoder: precisão onde importa
    pares = [(question, p.payload["text"]) for p in res]
    scores = reranker.predict(pares)
    top = sorted(zip(res, scores), key=lambda t: -t[1])[:k_final]
    return [p for p, _ in top]

def recall_at_k(testset, k=6):
    # testset: [{"q": ..., "gold_ids": {...}}]  — anotado no SEU domínio
    hits = 0
    for case in testset:
        ids = {p.id for p in retrieve(case["q"], k_final=k)}
        hits += bool(ids & set(case["gold_ids"]))
    return hits / len(testset)

PROMPT = """Responda APENAS com base nos trechos abaixo, citando [n].
Se a resposta não estiver nos trechos, diga que não encontrou.

{contexto}

Pergunta: {pergunta}"""
A escada de melhoria (ordem de ROI comprovada)

1) Corrija parsing e chunking → 2) adicione BM25 + RRF → 3) adicione reranker → 4) query rewriting p/ chat → 5) contextual retrieval → 6) só então considere GraphRAG/agêntico. Cada degrau só sobe com o conjunto de avaliação dizendo que o anterior saturou. Contar essa história num projeto de portfólio — com números — vale mais que citar dez frameworks.

CAPÍTULO 06

Produção e LLMOps

O que separa o notebook do produto: arquitetura, segurança, observabilidade, custo e agentes. É o capítulo que mais aparece em descrições de vaga de Engenheiro de IA — e o que menos aparece em cursos.

6.1 Arquitetura de sistemas com LLM

Um sistema LLM de produção raramente é "uma chamada de API". A anatomia típica:

  1. Gateway de modelo: uma camada única por onde passam todas as chamadas (LiteLLM, OpenRouter, gateway próprio) — centraliza chaves, retries com backoff, fallback entre provedores, timeouts, rate limiting e telemetria. Trocar de modelo vira config, não refactor.
  2. Roteamento e cascata: classifique a dificuldade/intenção e roteie — modelo pequeno/barato para o trivial (classificação, extração), grande/pensante para o difícil. Cascading: tente o barato, escale ao caro se a confiança for baixa. Corta 50–90% do custo em workloads reais.
  3. Caching em camadas: exact-match (mesma requisição → mesma resposta), prompt caching do provedor (prefixos repetidos — system prompt, few-shots, documentos — com desconto de até 90% e TTFT muito menor; ordene o prompt do estável para o variável) e, com cautela, caching semântico (respostas para perguntas similares — cuidado com falsos positivos).
  4. Filas e streaming: chamadas de LLM são lentas (segundos) e falham; desacople com filas para trabalhos batch e use streaming (SSE) para UX interativa — TTFT percebido importa mais que tempo total.
  5. Saída estruturada e validação: JSON Schema/structured outputs + validação com Pydantic + retry com o erro no prompt. Nunca confie em parsing de texto livre para dados que entram no seu sistema.
  6. Versionamento de prompts: prompts são código — versione, revise, teste em CI contra o conjunto de avaliação antes de fazer deploy. Mudança de prompt sem regression test é a causa nº 1 de incidentes silenciosos.
Build vs. buy: API ou modelo próprio (self-host)?

API (OpenAI, Anthropic, Google, etc.): fronteira de qualidade, zero infra, custo variável, dados saem do perímetro (verifique contratos de retenção). Self-host (vLLM/SGLang + Llama/Qwen/DeepSeek): controle total, dados internos, custo fixo — mas exige GPUs, MLOps e aceitar qualidade um degrau abaixo da fronteira. Padrão de mercado: começar com API, migrar workloads estáveis e de alto volume para open-source fine-tunado quando o custo justificar. A conta de break-even (tokens/mês × preço API vs. custo de GPU dedicada + time) é pergunta clássica de entrevista sênior.

6.2 Segurança: prompt injection e o OWASP LLM Top 10

A vulnerabilidade definidora de sistemas LLM é a prompt injection: o modelo não distingue estruturalmente instruções do desenvolvedor de texto malicioso vindo de dados. Variantes:

  • Direta: o usuário tenta sobrescrever instruções ("ignore tudo acima e…").
  • Indireta (a perigosa): a instrução maliciosa vem de conteúdo que o sistema processa — uma página web, um PDF no RAG, um e-mail, a descrição de um issue. Num agente com ferramentas, isso vira execução de ações: exfiltrar dados via uma tool de e-mail, apagar registros, seguir links maliciosos.

Defesas (em profundidade, nenhuma é suficiente sozinha):

  • Privilégio mínimo nas ferramentas: escopos de acesso por usuário (a permissão é do usuário, não do agente), tools de escrita exigem confirmação humana (human-in-the-loop) para ações irreversíveis.
  • Separar dados de instruções: delimitadores claros, marcar conteúdo externo como não-confiável no prompt, e tratar toda saída do LLM como entrada não-confiável para o resto do sistema (nada de eval, SQL direto ou HTML sem sanitizar).
  • Classificadores de entrada/saída (guardrails: Llama Guard, moderação de provedor, regras próprias) para injection, jailbreak, PII e conteúdo fora de escopo.
  • Regra de ouro para agentes (a "tríade letal"): evite combinar num mesmo agente acesso a dados privados + exposição a conteúdo não-confiável + canal de saída externo. Se as três coexistem, exfiltração é questão de tempo — quebre uma das pernas.

O OWASP Top 10 para LLMs organiza o restante: vazamento de dados sensíveis no prompt/logs, envenenamento de dados de treino/RAG, negação de serviço por prompts caros, supply chain de modelos/pesos, excesso de agência das tools, e overreliance (confiar sem verificar). Conhecer a lista pelo nome é diferencial imediato em entrevistas.

6.3 Observabilidade, avaliação contínua e custo

  • Tracing: cada requisição vira um trace com spans (retrieval, rerank, chamadas de modelo, tools), com prompt, resposta, tokens, latência e custo. Ferramentas: Langfuse, LangSmith, Phoenix/Arize, Braintrust, W&B Weave — ou OpenTelemetry + seu stack.
  • Métricas de produto: taxa de thumbs-down, taxa de escalada para humano, retenção da resposta (usuário copiou/usou?), custo por sessão. Métricas de modelo sem métricas de produto enganam.
  • Avaliação contínua: o conjunto de teste do Cap. 5 roda em CI a cada mudança de prompt/modelo/índice; amostras de produção entram num loop de curadoria (as falhas de hoje são o dataset de teste — e de fine-tuning — de amanhã). LLM-as-judge calibrado com auditoria humana periódica.
  • Drift: provedores atualizam modelos por baixo; fixe versões (model-2026-01-15) e monitore benchmarks internos para detectar mudanças.
  • Custo: orçamento por feature/tenant; alertas de anomalia; otimize na ordem — cache → roteamento → prompt menor → modelo menor/fine-tunado → batch API (50% de desconto para o que não é interativo).

6.4 Agentes, function calling e MCP

Um agente é um LLM num loop: recebe um objetivo, decide chamar ferramentas, observa resultados e itera até concluir. A base mecânica é o function calling: você declara tools com JSON Schema; o modelo emite uma chamada estruturada; seu código executa e devolve o resultado; o modelo continua.

function calling — o loop essencial (API Anthropic)
import anthropic, json
client = anthropic.Anthropic()

TOOLS = [{
    "name": "buscar_pedido",
    "description": "Busca o status de um pedido pelo ID.",
    "input_schema": {"type": "object",
        "properties": {"pedido_id": {"type": "string"}},
        "required": ["pedido_id"]},
}]

def executar(nome, args):
    if nome == "buscar_pedido":
        return db.pedidos.get(args["pedido_id"])   # valide permissões AQUI

msgs = [{"role": "user", "content": "Cadê meu pedido A-1042?"}]
while True:
    resp = client.messages.create(model="claude-sonnet-4-6", max_tokens=1024,
                                  tools=TOOLS, messages=msgs)
    if resp.stop_reason != "tool_use":
        break                                        # resposta final
    msgs.append({"role": "assistant", "content": resp.content})
    resultados = [
        {"type": "tool_result", "tool_use_id": b.id,
         "content": json.dumps(executar(b.name, b.input))}
        for b in resp.content if b.type == "tool_use"]
    msgs.append({"role": "user", "content": resultados})
  • MCP (Model Context Protocol): padrão aberto (Anthropic, 2024; adotado amplamente em 2025) que desacopla ferramentas de aplicações — um servidor MCP expõe tools/recursos/prompts por um protocolo comum, e qualquer cliente compatível os consome. É o "USB-C das integrações de IA": escreva o conector uma vez, use em qualquer agente. Saber construir um servidor MCP é linha de currículo em 2026.
  • Padrões de projeto: comece com workflows determinísticos (cadeias fixas com um passo LLM onde precisa) e só adote autonomia de agente onde a variabilidade da tarefa exige; um agente forte com boas tools supera hierarquias complexas de multiagentes na maioria dos casos; contexto é o recurso escasso — resuma, pagine resultados de tools, isole subtarefas em sub-agentes com contexto limpo (context engineering de novo).
  • Confiabilidade: limite de iterações, orçamento de tokens/custo por execução, timeouts por tool, checkpoints para retomar, e trilha de auditoria de cada ação. Avalie agentes por resultado (a tarefa foi concluída?) e por trajetória (fez chamadas absurdas no caminho?).
CAPÍTULO 07

Carreira: Engenheiro de IA/LLM

Como converter o conteúdo desta apostila em contratação: o que as vagas pedem de verdade, que projetos construir, e como são as entrevistas.

7.1 O que o mercado cobra (de verdade)

O título "AI Engineer" consolidou-se como engenharia de software que integra e opera modelos — distinto de ML Engineer clássico (treina modelos) e de Research. A distribuição típica de requisitos em vagas:

BlocoPesoNesta apostila
Engenharia de software sólida (Python, APIs, testes, Docker, cloud, SQL)Alto — é a base eliminatóriapré-requisito seu
RAG + bases vetoriais + avaliaçãoAltíssimo — o grosso dos projetos corporativosCaps. 4–5
Agentes, function calling, MCP, orquestraçãoAlto e crescendo rápidoCap. 6.4
LLMOps: observabilidade, custo, guardrails, segurançaAlto — diferencia sêniorCap. 6
Fine-tuning (LoRA/QLoRA, DPO) e serving open-source (vLLM)Médio — nichos e empresas maioresCaps. 3, 2.5
Fundamentos profundos (atenção, KV cache, quantização)Médio no dia a dia, alto em entrevistaCaps. 1–3
  • Frameworks: conheça LangChain/LangGraph, LlamaIndex e SDKs de agentes — mas entrevistadores experientes valorizam quem sabe fazer sem framework (o loop do 6.4 em ~30 linhas) e escolhe frameworks por razões, não por moda.
  • Habilidade transversal nº 1: avaliação. Quem chega com "eu construo o eval set antes da feature" se separa de 90% dos candidatos.
  • Acompanhe a área de forma sustentável: relatórios técnicos de modelos (Llama, DeepSeek, Qwen), blogs de engenharia (Anthropic, OpenAI, vLLM, Qdrant), e reimplemente uma ideia por mês.

7.2 Portfólio: três projetos que contam uma história

  1. Fundamentos: seu mini-GPT (Cap. 2.7) treinado num corpus pequeno em português, com um README que explica as decisões (por que GQA, por que RoPE, gráfico de loss, ablations simples). Prova profundidade.
  2. RAG de produção: um assistente sobre um corpus real (legislação, docs técnicas, normas) com: ingestão robusta de PDF, híbrida + rerank, citações, conjunto de avaliação com números (recall@k antes/depois de cada melhoria — a "escada" do Cap. 5), tracing com Langfuse, Docker Compose com Qdrant/pgvector, e uma seção de custos. Prova que você entrega o que as empresas mais compram.
  3. Agente com MCP: um agente que resolve uma tarefa real de negócio com 3–5 tools (uma delas um servidor MCP seu), human-in-the-loop para ações de escrita, guardrails contra injection e avaliação de trajetórias. Prova que você está na fronteira aplicada.

Regras do portfólio: repositórios que rodam com um comando; READMEs com arquitetura, trade-offs e números; um post técnico por projeto (o texto é o que recrutadores leem). Profundidade em 3 > superficialidade em 10.

7.3 Entrevistas: o que esperar

  • Coding: padrão de engenharia (estruturas de dados moderadas) + exercícios de LLM: implementar atenção/softmax do zero, parsear saída de modelo com robustez, consumir APIs com retry/streaming.
  • System design de IA: "projete um assistente sobre os documentos internos da empresa" — percorra: ingestão → chunking → índice (e por quê) → híbrida/rerank → prompt com citações → avaliação → segurança/permissões → custo/latência → o que monitoraria. Esta apostila é o roteiro.
  • Conceitual: por que √d_k; o que é KV cache e por que GQA/MLA existem; LoRA em uma equação; DPO vs. RLHF; quando fine-tuning vs. RAG; como funciona HNSW; o que é prompt injection indireta; por que decode é memory-bound.
  • Comportamental: tenha 2–3 histórias com estrutura problema → decisão técnica com trade-off → número de impacto.
Roteiro de 12 semanas (sugestão de execução)
  • Sem. 1–3: Caps. 1–2 + implementar e treinar o mini-GPT.
  • Sem. 4–5: Cap. 3 + um fine-tuning LoRA/QLoRA real (ex.: classificação ou estilo) com avaliação antes/depois.
  • Sem. 6–9: Caps. 4–5 + construir o RAG de produção subindo a escada de melhorias com números.
  • Sem. 10–11: Cap. 6 + transformar o RAG em agente com tools/MCP, guardrails e tracing.
  • Sem. 12: escrever os posts, polir READMEs, simular entrevistas com as perguntas do 7.3.
REFERÊNCIA

Glossário

Os termos essenciais do vocabulário de Engenharia de LLMs, em ordem alfabética. Use como revisão pré-entrevista: se você consegue explicar cada verbete em voz alta sem olhar, está pronto.

A — C
Agentecap. 6
LLM operando em loop: recebe um objetivo, decide chamar ferramentas, observa os resultados e itera até concluir a tarefa, com autonomia sobre o caminho.
ALiBi
Método posicional que dispensa embeddings: penaliza os logits de atenção linearmente pela distância entre tokens. Extrapola bem para sequências mais longas que as de treino.
Alinhamento
Etapa de pós-treino que ajusta o modelo a preferências humanas e políticas de comportamento (utilidade, honestidade, segurança), via RLHF, DPO e afins.
Alucinação
Saída fluente porém factualmente incorreta ou inventada. Mitigada com grounding (RAG com citações), avaliação de faithfulness e instruções para admitir incerteza — nunca eliminada por completo.
ANNApproximate Nearest Neighbor
Família de algoritmos (HNSW, IVF, PQ) que encontra vizinhos aproximadamente mais próximos em espaços vetoriais, trocando recall marginal por buscas ordens de magnitude mais rápidas que a exata.
Atenção (self-attention)
Mecanismo em que cada token computa pesos sobre todos os demais (via queries e keys) e agrega seus values numa média ponderada — a forma como informação circula entre posições no Transformer.
AWQActivation-aware Weight Quantization
Quantização pós-treino de 4 bits que identifica ~1% de canais salientes (pela magnitude das ativações) e os protege reescalando antes de quantizar.
Bi-encoder
Arquitetura de recuperação em que query e documento são embeddados de forma independente e comparados por produto interno. Rápido e indexável; menos preciso que um cross-encoder.
BM25
Algoritmo clássico de busca léxica baseado em frequência de termos (TF-IDF com saturação e normalização por tamanho). Imbatível em termos exatos: códigos, siglas, nomes. Par natural da busca densa na híbrida.
BPEByte-Pair Encoding
Algoritmo de tokenização que funde iterativamente os pares de símbolos mais frequentes do corpus até formar o vocabulário. Em versão byte-level, tokeniza qualquer string sem tokens desconhecidos.
Chain-of-Thought (CoT)
Técnica em que o modelo gera passos intermediários de raciocínio antes da resposta. Cada token gerado é compute adicional condicionando os próximos — base dos modelos de raciocínio.
Chinchilla (scaling ótimo)
Resultado (DeepMind, 2022) de que, para um orçamento fixo de compute, o ótimo é ~20 tokens de treino por parâmetro. Modelos modernos deliberadamente ultrapassam isso (overtraining) para baratear a inferência.
Chunking
Divisão de documentos em trechos para indexação em RAG. Tamanho, sobreposição e respeito à estrutura do documento afetam diretamente o recall — a decisão mais subestimada do pipeline.
ColBERT / late interaction
Recuperação com um vetor por token: o score é a soma dos melhores casamentos (MaxSim) entre tokens da query e do documento. Quase a precisão de um cross-encoder com índice pré-computável.
Context engineering
Disciplina de projetar tudo que entra na janela do modelo — instruções, memória, trechos recuperados, resultados de tools — tratando o contexto como recurso escasso a ser curado.
Context window (janela de contexto)
Número máximo de tokens que o modelo processa de uma vez (prompt + geração). Janelas atuais vão de 8k a 1M+; atenção e custo crescem com ela.
Contrastive learning
Regime de treino de embeddings que aproxima pares positivos e afasta negativos no espaço vetorial (loss InfoNCE). A qualidade dos hard negatives define a qualidade do modelo.
Contextual retrieval
Técnica de indexação em que um LLM prefixa cada chunk com frases que o situam no documento original antes de embeddar, reduzindo falhas de recuperação de forma expressiva.
Continuous batching
Estratégia de serving que insere e remove requisições do batch a cada passo de geração (em vez de esperar o batch inteiro terminar), maximizando a ocupação da GPU. Núcleo do vLLM.
Cross-encoder
Modelo que processa query e documento juntos, com atenção total entre eles, produzindo um score de relevância. Preciso demais para o corpus todo, ideal como reranker dos top-k recuperados.
D — G
Decodificação especulativa
Um modelo rascunho propõe vários tokens; o modelo grande os verifica num único forward paralelo, aceitando os que batem com sua distribuição. Acelera 2–3× sem alterar a distribuição de saída.
Destilação
Treinar um modelo menor (student) para imitar as saídas — ou distribuições — de um maior (teacher). Usada para comprimir capacidade, inclusive de raciocínio (ex.: destilados do DeepSeek-R1).
DPODirect Preference Optimization
Alinhamento por preferências sem reward model nem RL: uma loss de classificação direta sobre pares (resposta preferida vs. rejeitada), derivada da solução fechada do objetivo RLHF.
Embedding
Vetor denso que representa um token, sentença ou documento num espaço onde proximidade geométrica corresponde a similaridade semântica. Base da busca vetorial e do RAG.
Faithfulness
Métrica de avaliação de RAG: grau em que cada afirmação da resposta é sustentada pelos trechos recuperados. É a métrica que operacionaliza a medição de alucinação.
Few-shot / zero-shot
Uso do modelo com alguns exemplos no prompt (few-shot) ou nenhum (zero-shot), explorando o in-context learning em vez de treinar.
FFNfeed-forward network
A MLP aplicada por posição em cada bloco Transformer (hoje tipicamente SwiGLU). Concentra ~2/3 dos parâmetros; descrita como memória associativa onde reside conhecimento factual.
Fine-tuning
Continuar o treino de um modelo pré-treinado em dados específicos para adaptar comportamento, estilo ou domínio. Formas eficientes: LoRA/QLoRA. Não é a ferramenta certa para fatos atualizáveis — para isso, RAG.
FlashAttention
Kernel de atenção que processa em tiles na SRAM do chip com online softmax, sem materializar a matriz n×n na memória. Reduz memória de O(n²) para O(n) e evita a parede de banda.
FSDP / ZeRO
Técnicas de data parallelism que fragmentam pesos, gradientes e estados do otimizador entre GPUs, em vez de replicá-los — essenciais para treinar modelos que não cabem numa GPU.
Function calling / tool use
Capacidade do modelo de emitir chamadas estruturadas (JSON) a funções declaradas com schema; o código executa e devolve o resultado. Mecanismo base dos agentes.
GGUF
Formato de pesos quantizados do llama.cpp (esquemas de 2 a 8 bits) para inferência eficiente em CPU e Apple Silicon — o padrão do ecossistema local.
GPTQ
Quantização pós-treino camada a camada que minimiza o erro de saída usando informação de segunda ordem (aproximação da Hessiana). Clássico do 4-bit em GPU.
GQAGrouped-Query Attention
Variante da multi-head em que grupos de cabeças de query compartilham cabeças de K/V, encolhendo o KV cache com qualidade ≈ MHA. Padrão em Llama 3, Mistral, Qwen.
GraphRAG
RAG que indexa o corpus como grafo de conhecimento (entidades + relações extraídas por LLM) com resumos por comunidade, habilitando perguntas globais e multi-hop que a busca vetorial não alcança.
GRPOGroup Relative Policy Optimization
Algoritmo de RL sem critic: amostra G respostas por prompt e usa a reward normalizada dentro do grupo como vantagem. Barato e eficaz com recompensas verificáveis; motor do DeepSeek-R1.
Guardrails
Camadas de validação de entrada e saída (classificadores, regras, schemas) que bloqueiam injection, conteúdo fora de política, PII e formatos inválidos antes que causem dano.
H — M
Hard negatives
Exemplos negativos difíceis (parecidos com o positivo, mas errados) usados no treino contrastivo de embeddings e rerankers. São o principal fator de qualidade desses modelos.
HNSWHierarchical Navigable Small World
Índice ANN em grafo com camadas hierárquicas: busca desce de arestas longas para locais, com complexidade ~O(log N) e recall altíssimo. Default de Qdrant, Weaviate, Milvus e pgvector.
HyDEHypothetical Document Embeddings
Transformação de consulta em que o LLM gera uma resposta hipotética e a busca é feita pelo embedding dela, aproximando a query do espaço dos documentos.
In-context learning
Capacidade emergente de o modelo aprender uma tarefa a partir de exemplos fornecidos no próprio prompt, sem atualização de pesos.
IVFInverted File Index
Índice ANN que clusteriza o espaço com k-means e busca apenas nas células (nprobe) mais próximas da query. Simples, amigável a disco; base do FAISS clássico.
KV cache
Armazenamento das keys e values já computados durante a geração autorregressiva, evitando recomputar a atenção do prefixo a cada token. É o principal consumidor de memória no serving.
LLM-as-judge
Uso de um LLM com rubrica para avaliar saídas de outro (relevância, faithfulness, qualidade) em escala. Exige calibração periódica contra julgamento humano.
Logits
Scores brutos (pré-softmax) que o modelo atribui a cada token do vocabulário no próximo passo. Temperatura, top-p e constrained decoding operam sobre eles.
LoRALow-Rank Adaptation
Fine-tuning eficiente que congela os pesos e aprende correções de baixo posto (W + BA), treinando <1% dos parâmetros e permitindo fundir o adaptador sem custo de inferência.
Lost in the middle
Fenômeno em que modelos recuperam pior informação posicionada no meio de contextos longos do que no início ou fim — argumento para ranquear bem os trechos no prompt.
MCPModel Context Protocol
Protocolo aberto que padroniza como aplicações expõem ferramentas, recursos e prompts a modelos — o conector universal do ecossistema de agentes.
MLAMulti-head Latent Attention
Atenção que cacheia apenas uma compressão latente de baixo posto de K/V, reconstruindo-os on-the-fly. Corta o KV cache em ~10× (DeepSeek-V2/V3).
MoEMixture of Experts
Arquitetura em que a FFN é substituída por vários experts e um router ativa só o top-k por token — desacoplando número de parâmetros de custo por token.
MQAMulti-Query Attention
Todas as cabeças de query compartilham uma única cabeça de K/V, encolhendo o KV cache em h× com alguma perda de qualidade. Precursora da GQA.
MRL / Matryoshka
Treino de embeddings em prefixos aninhados do vetor, permitindo truncá-lo (ex.: 1024→256 dims) com perda mínima — economia direta de armazenamento e latência.
MTEB
Benchmark padrão para comparar modelos de embedding em dezenas de tarefas. Útil como filtro inicial; sempre valide no seu domínio.
Multi-head attention
Divisão da atenção em h cabeças paralelas de dimensão menor, cada uma com projeções próprias, permitindo capturar tipos distintos de relação simultaneamente.
N — R
NF4
Tipo de dado de 4 bits com níveis posicionados para pesos normalmente distribuídos, usado no QLoRA para manter o modelo base quantizado durante o fine-tuning.
nDCG / MRR / Recall@k
Métricas de recuperação: Recall@k (o item certo veio nos top-k?), MRR (posição do primeiro relevante) e nDCG (qualidade do ranking inteiro com ganhos descontados por posição).
PagedAttention
Gerência do KV cache como memória virtual: blocos de tamanho fixo com tabela de páginas por sequência e compartilhamento de prefixos, eliminando fragmentação. Coração do vLLM.
Perplexidade
Exponencial da cross-entropy média por token; mede quão "surpreso" o modelo fica com um texto. Métrica clássica de pré-treino — não substitui avaliação de tarefa.
PPOProximal Policy Optimization
Algoritmo de RL usado no RLHF clássico: otimiza a política com passos limitados (clipping) e penalidade KL contra o modelo de referência para evitar colapso e reward hacking.
PQProduct Quantization
Compressão vetorial que divide o vetor em sub-vetores quantizados por codebooks, reduzindo cada vetor a poucos bytes com distâncias aproximadas por lookup. Base do IVF-PQ bilionário.
Prefill / Decode
As duas fases da inferência: processar o prompt em paralelo (prefill, limitado por compute) e gerar token a token (decode, limitado por banda de memória). Definem TTFT e TPOT.
Prompt caching
Reuso, pelo provedor ou motor de serving, do KV cache de prefixos repetidos do prompt (system prompt, documentos), com grandes descontos de custo e latência.
Prompt injection
Ataque em que instruções maliciosas — digitadas pelo usuário (direta) ou embutidas em conteúdo processado (indireta) — sequestram o comportamento do modelo. A vulnerabilidade nº 1 do OWASP LLM Top 10.
QLoRA
LoRA sobre um modelo base quantizado em NF4 com double quantization, permitindo fine-tuning de modelos de dezenas de bilhões de parâmetros numa única GPU.
Quantização
Representar pesos (e às vezes ativações e KV cache) em menos bits (8, 4, até 2) para cortar memória e acelerar inferência, com perda de qualidade controlada.
Query rewriting
Reescrever a pergunta do usuário (resolvendo referências da conversa, expandindo termos) em consulta autocontida antes da busca — obrigatório em RAG conversacional.
RAGRetrieval-Augmented Generation
Padrão que recupera trechos relevantes de uma base externa e os injeta no prompt, dando ao modelo conhecimento atualizável, citável e privado sem retreinar.
Reranking
Reordenar os top-k recuperados com um modelo mais preciso (cross-encoder ou LLM) antes de montar o prompt. O upgrade de melhor custo-benefício de um pipeline RAG.
Reward model
Modelo treinado em comparações humanas para prever a qualidade de uma resposta; fornece o sinal de recompensa no RLHF clássico.
RLHF
Alinhamento por RL com feedback humano: coleta de preferências → reward model → otimização da política (PPO) com restrição KL. O pipeline que criou o ChatGPT.
RLVRRL with Verifiable Rewards
RL em que a recompensa é verificável automaticamente (teste unitário passa, resposta matemática exata) — o regime que destravou os modelos de raciocínio.
RMSNorm
Normalização que reescala pela raiz da média dos quadrados, sem centralização nem bias. Mais barata que LayerNorm; padrão nos modelos modernos.
RoPERotary Position Embedding
Codificação posicional que rotaciona pares de dimensões de q e k por ângulos proporcionais à posição, fazendo o score de atenção depender apenas da posição relativa. Padrão atual.
RRFReciprocal Rank Fusion
Fusão de rankings de sistemas distintos somando 1/(k + posição), robusta por ignorar escalas de score. O jeito padrão de combinar BM25 com busca densa.
S — Z
Sampling (temperatura, top-p, top-k)
Estratégias de amostragem do próximo token: temperatura reescala logits (0 = determinístico); top-p amostra do menor conjunto com massa acumulada ≥ p; top-k limita aos k mais prováveis.
Scaling laws
Relações empíricas de lei de potência entre loss e parâmetros/dados/compute, que tornaram o desempenho de LLMs previsível e justificaram a corrida de escala.
SFTSupervised Fine-Tuning
Fine-tuning supervisionado em pares instrução→resposta de alta qualidade (com loss apenas nos tokens de resposta), que transforma um modelo base em assistente.
Sliding window attention
Atenção restrita a uma janela local de w tokens por camada, reduzindo custo para O(n·w); camadas empilhadas propagam informação além da janela. Frequentemente intercalada com atenção global.
Speculative decoding
Ver decodificação especulativa.
SPLADE
Modelo de recuperação esparsa aprendida: gera pesos por termo do vocabulário (com expansão de termos), unindo interpretabilidade léxica e treino neural.
Structured output / constrained decoding
Geração restrita por gramática ou JSON Schema, mascarando tokens inválidos a cada passo — garante saída parseável por construção.
SwiGLU
FFN com gate multiplicativo — (Swish(xW_g) ⊙ xW_u)W_d — que melhora perplexidade de forma consistente; padrão nos blocos modernos.
System prompt
Instruções do desenvolvedor que definem papel, regras e formato do assistente, colocadas antes da conversa e (idealmente) estáveis para aproveitar prompt caching.
Test-time compute
Escalar a qualidade gastando mais compute na inferência (cadeias longas de raciocínio, best-of-N, busca com verificadores) em vez de só no treino. O eixo de scaling da fronteira atual.
Token
Unidade mínima processada pelo modelo — subpalavra, palavra ou bytes — mapeada a um inteiro do vocabulário. Custos, limites e métricas de LLM são medidos em tokens.
TTFT / TPOT
Time To First Token (latência até o primeiro token, dominada pelo prefill) e Time Per Output Token (ritmo do decode). As duas métricas centrais de latência em serving.
Vector database (base vetorial)
Sistema que armazena embeddings com índices ANN, filtragem por metadados, CRUD e replicação — a infraestrutura de busca semântica do RAG.
vLLM
Motor de serving open-source com continuous batching, PagedAttention e prefix caching; o padrão de facto para servir LLMs open-weights em produção.
Weight tying
Compartilhar a matriz de embedding com a camada de saída, economizando parâmetros — comum em modelos pequenos e médios.