Elton José logo
Elton José
Destilação

Destilação na Prática: Trocando o Modelo Frontier por um 8B Seu a 1/100 do Custo

Destilação na Prática: Trocando o Modelo Frontier por um 8B Seu a 1/100 do Custo
0 visualizações
20 minutos de leitura
#Destilação

Destilação na Prática: Trocando o Modelo Frontier por um 8B Seu a 1/100 do Custo

A pergunta veio de um engenheiro do time no meio de uma retro e ficou martelando a semana inteira. Se a gente já sabe exatamente o que quer que o modelo faça naquela etapa do pipeline, e ele faz exatamente aquilo alguns milhões de vezes por mês, por que estamos pagando um modelo de fronteira para fazer isso?

Eu não tinha resposta boa. Tinha a resposta preguiçosa que quase todo mundo tem: porque funciona, porque a integração já está pronta, porque ninguém aqui treinou modelo antes. Foi olhando para a terceira parte que percebi algo incômodo. Em quase dois anos escrevendo sobre LLM em produção, custo de inferência e FinOps, eu nunca escrevi uma linha sobre adaptar um modelo — sempre tratei o modelo como uma caixa que alguém treina e eu consumo.

Isso deixou de ser uma divisão de trabalho razoável. A receita que mais vejo hoje não é treinar do zero: é usar um modelo de fronteira para gerar dezenas de milhares de exemplos numa tarefa muito estreita, destilar isso num modelo pequeno com QLoRA e servir o pequeno por uma fração do custo. O pipeline inteiro cabe numa GPU alugada por algumas horas.

Vou descrever esse caminho de forma honesta: o que a destilação entrega e o que não entrega, o pipeline com os números que consegui confirmar, o critério para decidir se vale, e as armadilhas que fazem o projeto parecer sucesso no notebook e virar dívida técnica em produção.


Destilação Não Torna O Modelo Mais Inteligente

Quase todo projeto que dá errado começa entendendo isso ao contrário. Destilação é transferência de comportamento numa distribuição estreita, não transferência de capacidade. Você não está deixando o Qwen3 8B mais inteligente: está ensinando ele a imitar o que um modelo maior faz num recorte específico de entradas, e só naquele recorte. Tire uma pergunta de fora dessa distribuição e o que responde continua sendo um 8B.

O mecanismo é simples. Na variante que praticamente todo mundo usa, a destilação caixa-preta, você não tem acesso aos logits nem aos pesos do professor, só ao que ele escreve. Então pega entradas reais, coleta as saídas do modelo grande e treina o pequeno para reproduzi-las. É aprendizado supervisionado comum, com a diferença de que os rótulos vieram de outro modelo em vez de uma pessoa.

A evidência é mais antiga que a moda atual. O trabalho "Distilling Step-by-Step", do Google Research apresentado no ACL 2023, mostrou um T5 de 770 milhões de parâmetros superando um PaLM de 540 bilhões usado com few-shot num benchmark, com 80% dos dados disponíveis. Repare nas condições: um benchmark, uma tarefa, com racionais do professor como supervisão extra. É o tipo de resultado citado sem as condições, virando "modelo 700 vezes menor bate modelo gigante". Não bate. Bate naquela tarefa.

O corolário é o filtro inicial de qualquer projeto: fine-tuning serve para forma, não para fato. Se você quer que o modelo saiba coisas que mudam, isso é RAG. Se quer que ele se comporte de um jeito específico e estável — um formato, uma convenção de domínio, uma decisão repetitiva — aí destilação é a ferramenta certa.

Isso conversa direto com o que escrevi na semana passada sobre colocar um roteador na frente e mandar a maior parte do tráfego para um modelo pequeno. Roteamento é onde você descobre quais fatias do tráfego um modelo pequeno já resolve. Destilação é o passo seguinte: pegar as fatias que ele quase resolve e ensinar ele a resolver.


O Eval Vem Antes Do Dataset

Se eu pudesse cravar uma regra deste post, seria esta: o eval é o primeiro artefato do projeto, não o penúltimo. Não por boa prática genérica, mas porque sem eval você literalmente não tem como saber se destilou.

Pense no que vai acontecer. Você gera dezenas de milhares de exemplos com um modelo caro, roda o treino e olha uma curva de loss caindo. Loss caindo significa que o aluno reproduz melhor os tokens do professor, não que ele resolve o problema do usuário. As duas coisas se correlacionam, e a correlação quebra exatamente nos casos que importam: os difíceis, os raros, os que o professor também errou.

Então, antes de gerar o primeiro exemplo, escreva a definição da tarefa em duas ou três frases, tão estreita que dê para discordar dela. "Extrair sete campos estruturados de descrições de produto em português, devolvendo JSON válido segundo este schema" é uma tarefa. "Melhorar o atendimento" não é. Depois separe de cem a quinhentos exemplos com resposta correta conhecida — e a palavra importante é correta, não do professor.

Esse conjunto precisa vir de dados reais e ser congelado antes do treino. Se ele for gerado pelo mesmo processo que gerou o treino, você mediu concordância com o professor, o que é interessante mas não é qualidade. E se ele tiver chance de estar no corpus de pré-treino da base, sua "melhora" pode ser recall.

Onde a honestidade do projeto se decide: o professor não é o teto de qualidade, é o teto de imitação. Se ele acerta 91% na sua tarefa, o aluno não passa disso de forma consistente e provavelmente fica abaixo. Quanto abaixo é aceitável é pergunta de negócio. Se ninguém consegue responder, não comece.


Gerar E Curar: O Professor Também Erra

A geração de dados parece a parte trivial e é a que mais determina o resultado.

O erro mais comum é gerar as entradas também. Alguém pede ao modelo grande "gere dez mil descrições de produto e extraia os campos delas", e sai um dataset lindo, homogêneo e inútil, porque entrada sintética não tem erro de digitação, campo faltando, formatação quebrada nem cliente escrevendo em caixa alta. O modelo destilado brilha no laboratório e desmonta no primeiro lote de produção.

A forma certa é usar as suas entradas reais e chamar o professor só para produzir a saída. Se você já roda a tarefa em produção com o modelo de fronteira, o dataset praticamente já existe: é o seu log. O projeto deixa de ser "gerar dados" e vira "curar dados que eu já tenho", que é mais barato e mais fiel.

A curadoria é onde o professor deixa de ser oráculo. Ele erra, e treinar em cima do erro dele é ensinar o erro. Se a saída é verificável, dá para filtrar de forma brutal: JSON que não valida sai, código que não compila sai, valor extraído que não aparece no texto de entrada sai. Se não é verificável, use amostragem com rejeição: gere três vezes, fique com a resposta majoritária, descarte quando as três discordarem — exemplo em que o professor discorda de si mesmo é o que você menos quer no treino.

Depois vêm as obrigações chatas: deduplicação, filtro de comprimento e verificação de que nenhum exemplo do eval vazou para o treino. Essa última merece um teste automatizado, porque o vazamento acontece em silêncio quando alguém regenera o dataset e esquece de reaplicar o corte.

import hashlib, json
from jsonschema import validate, ValidationError

SCHEMA = json.load(open("schema.json"))
eval_hashes = {h.strip() for h in open("eval_input_hashes.txt")}

def key(texto: str) -> str:
    return hashlib.sha256(texto.strip().lower().encode()).hexdigest()

def curar(registros):
    vistos, saida = set(), []
    descartes = {"dup": 0, "eval": 0, "schema": 0, "nao_ancorado": 0}

    for r in registros:                  # r["entrada"] vem do log de producao
        k = key(r["entrada"])            # r["saida"] vem do modelo professor

        if k in eval_hashes:             # contaminacao do holdout: fatal, nunca "so um pouco"
            descartes["eval"] += 1; continue
        if k in vistos:
            descartes["dup"] += 1; continue
        vistos.add(k)

        try:
            obj = json.loads(r["saida"]); validate(obj, SCHEMA)
        except (json.JSONDecodeError, ValidationError):
            descartes["schema"] += 1; continue

        # ancoragem: todo valor extraido precisa existir no texto de origem.
        # pega alucinacao do professor sem precisar de revisao humana.
        if not all(str(v) in r["entrada"] for v in obj.values() if v):
            descartes["nao_ancorado"] += 1; continue

        saida.append({"messages": [
            {"role": "system", "content": SYSTEM_PROMPT},
            {"role": "user", "content": r["entrada"]},
            {"role": "assistant", "content": json.dumps(obj, ensure_ascii=False)},
        ]})

    return saida, descartes

O dicionário de descartes não é enfeite: se 30% das saídas do professor não validam contra o schema, o problema está no prompt de geração, não no aluno que você ainda nem treinou. E o consenso sobre volume decepciona quem esperava número grande — para tarefa realmente estreita, quinhentos a dois mil exemplos bem curados já movem a agulha, e quinhentos limpos batem cinco mil sujos com folga.


O Treino É A Parte Mais Barata Do Pipeline

Aqui está a inversão de expectativa que surpreende quem nunca fez: com QLoRA, treinar é a parte mais barata e mais rápida do projeto inteiro.

Vale entender o mecanismo porque ele explica os números. O trabalho original de QLoRA, de Dettmers e colegas em 2023, combina três coisas: quantização da base para 4 bits num tipo de dado chamado NormalFloat, que os autores argumentam ser teoricamente ótimo para pesos normalmente distribuídos; dupla quantização, que quantiza as próprias constantes de quantização; e otimizadores paginados para absorver picos de memória. A base fica congelada em 4 bits e só os adaptadores treinam em precisão maior. O paper reporta ajustar um modelo de 65 bilhões de parâmetros numa única GPU de 48 GB preservando a performance do fine-tuning completo em 16 bits.

Para memória, a fonte que eu uso é a tabela da documentação do Unsloth. Com QLoRA em 4 bits: 5 GB de VRAM para um 7B, 6 GB para um 8B, 8,5 GB para um 14B e 41 GB para um 70B — os mesmos modelos com LoRA em 16 bits pedem 19, 22, 33 e 164 GB. A documentação avisa que são mínimos absolutos e que o consumo sobe com comprimento de sequência, batch e módulos alvo. Traduzindo para decisão de compra: um 8B com QLoRA cabe numa placa de consumidor de 12 GB, e cabe com folga numa de 24.

# axolotl: config de destilacao para tarefa estreita, 8B, GPU unica
base_model: Qwen/Qwen3-8B          # Apache 2.0 — checar a licenca ANTES do treino
adapter: qlora
load_in_4bit: true

sequence_len: 2048                 # p95 do seu dataset tokenizado, nao o maximo
sample_packing: true

lora_r: 32                         # 8-16 para formato/estilo, 32-64 para mudanca de dominio
lora_alpha: 32
lora_dropout: 0.05
lora_target_linear: true           # todas as lineares; o custo extra de VRAM e pequeno

datasets:
  - path: ./train.jsonl
    type: chat_template            # o MESMO template usado na inferencia. sem excecao.
val_set_size: 0.1

num_epochs: 2                      # 1-3. mais que isso em dataset pequeno e decorar
learning_rate: 2e-4                # 1e-4 se a loss oscilar
lr_scheduler: cosine
warmup_steps: 50
micro_batch_size: 2
gradient_accumulation_steps: 8     # batch efetivo 16
optimizer: adamw_bnb_8bit
gradient_checkpointing: true

evals_per_epoch: 8                 # pare na loss de validacao, nao no numero de epocas
seed: 42

A escolha de ferramenta segue o formato do hardware, não o que está em alta: Unsloth para uma GPU só, Axolotl quando há múltiplas GPUs e você quer um YAML revisável em pull request, TRL da Hugging Face quando precisa mexer no loop, MLX no Mac. E duas coisas quebram mais treinos do que qualquer hiperparâmetro. A primeira é divergência de template: treinar com um formato de chat e inferir com outro produz saída sem sentido, e o sintoma confunde porque o treino corre lindo — renderize cinco exemplos com o tokenizer antes de disparar e leia com os olhos. A segunda é esquecimento catastrófico, quando o modelo fica ótimo na sua tarefa e pior em tudo mais; com LoRA o dano é limitado, já que a base fica congelada, e misturar de 5% a 20% de dados de instrução geral é a mitigação padrão.

Sobre custo, a faixa repetida em guias de 2026 é de dezenas de minutos numa A100 para um 7B com poucos milhares de exemplos. Os "ajustei um modelo por 11 dólares" que circulam em vídeo são plausíveis, mas são custo de GPU, não custo do projeto. O projeto é a curadoria, o eval e a operação. A GPU é troco.


Avaliar Contra O Professor, Não Contra A Sua Expectativa

A avaliação tem três camadas, e pular qualquer uma gera uma surpresa específica. A primeira é regressão de capacidade geral: rode um harness padrão antes e depois para confirmar que não quebrou a base. Alguma queda é esperada, já que você está especializando de propósito; queda grande em raciocínio ou seguimento de instrução é sinal de taxa de aprendizado alta demais ou épocas demais.

A segunda é o eval da tarefa, comparando três coisas no mesmo conjunto congelado: o professor, o modelo base sem adaptação e o destilado. Essa terceira coluna é a que quase todo mundo esquece de medir e é a mais importante. Se a base já resolvia 85% com um prompt bem escrito e o destilado resolve 88%, você gastou três semanas por três pontos.

Diz-se com frequência que um modelo destilado captura a maior parte da qualidade do professor na tarefa. Isso vem com uma condição forte embutida: quanto mais estreita e mais verificável a tarefa, mais perto o aluno chega. Em extração estruturada e classificação, chegar muito perto é comum. Em geração aberta com julgamento de estilo, a distância é maior e a métrica é mais frouxa. Não existe porcentagem universal, e desconfie de quem oferecer uma.

A terceira camada é produção. Espelhe uma fatia do tráfego real para os dois modelos, sem servir a resposta do aluno ao usuário, e compare por alguns dias antes de trocar. É a única camada que não dá para enganar, porque é a única que vê a distribuição real de entradas.


Servir: O Multi-Adapter É O Que Fecha A Conta

O modelo destilado só vale o que a camada de serving conseguir extrair dele, e é aqui que a economia deixa de ser teórica. O detalhe que muda o cálculo é que um adaptador LoRA não é um modelo: é um par de matrizes pequenas que se somam ao cálculo da base, com posto tipicamente entre 16 e 64. Isso permite manter uma cópia só do modelo base na VRAM e trocar adaptadores por requisição. O time da AWS descreveu bem o efeito no blog do vLLM em fevereiro de 2026: cinco clientes usando 10% de uma GPU dedicada cada um podem ser servidos de uma GPU só.

O mesmo post mostra o outro lado. A implementação inicial de multi-LoRA para modelos MoE no vLLM teve tempo até o primeiro token dez vezes pior que o do modelo base, por recompilação de kernel Triton a cada novo comprimento de contexto, e só virou aceitável depois de correções de compilação e ajuste fino de kernel. A lição não é técnica, é de expectativa: multi-adapter em produção amadureceu recentemente e a performance depende de versão. Fixe a versão e meça no seu hardware.

Na prática, o modo suportado é declarar os adaptadores no start do servidor com --enable-lora e --lora-modules. Existe carregamento dinâmico por endpoint atrás de uma flag de ambiente, mas a documentação avisa que não é adequado para produção, entre outras razões porque não garante que o adaptador foi carregado em todas as réplicas. A alternativa é mesclar o adaptador na base e servir um modelo único: mais simples de operar, sem a economia de compartilhar a base. Eu escolheria mesclado com um adaptador só, e multi-adapter a partir do terceiro.

Vale reler o que escrevi sobre como a escolha do framework de inferência muda o throughput da mesma GPU, porque destilar para depois servir mal é trocar um desperdício por outro.


Quando Vale E Quando Não Vale

Essa é a tabela que eu levaria para a reunião em que a decisão é tomada, porque ela evita a conversa virar entusiasmo contra ceticismo.

SinalVale destilarNão vale destilar
VolumeMilhões de chamadas/mês numa tarefa sóAlguns milhares/dia; a economia não paga o esforço
Estabilidade da tarefaDefinição estável há mesesRequisito muda toda semana; cada mudança é um retreino
VerificabilidadeSaída checável por schema, teste ou regraJulgamento subjetivo, sem critério automatizável
EvalConjunto congelado com resposta corretaNão existe; você não vai saber se funcionou
Natureza do ganhoComportamento: formato, convenção, decisão repetidaConhecimento que muda; isso é RAG
DadosLog de produção real disponível e utilizávelSó entradas sintéticas ou dados que você não pode usar
TimeAlguém dono do modelo depois do lançamentoNinguém para operar; vira órfão em três meses

As linhas não têm o mesmo peso: eval e estabilidade da tarefa são eliminatórias. Sem eval você não consegue decidir se lançou, e com tarefa instável você assinou um contrato de retreino permanente que ninguém orçou. Volume baixo é o caso mais frequente e o pior julgado — a conta correta não é comparar custo por token do 8B com o do modelo de fronteira, e sim o custo total de propriedade, incluindo GPU parada nos vales de tráfego, curadoria, retreino, plantão e versionamento de adaptador, contra a economia absoluta em reais.


As Armadilhas Que Não Aparecem No Slide

A primeira é vazamento, em duas formas. A que compromete o resultado é o eval vazando para o treino, que infla a métrica e transforma o relatório em ficção. A que compromete a empresa é o dado sensível: se as entradas vieram do log, os dados gerados carregam tudo que estava lá, inclusive o que não deveria. Anonimizar depois de treinar não existe — o dado já está nos pesos do adaptador.

A segunda é licença, com dois lados que costumam ser olhados separadamente quando deveriam ser olhados juntos. Do lado do modelo base, o histórico da família Llama é didático: a licença original do Llama 3 proibia usar as saídas do modelo para melhorar outros modelos de linguagem, e as versões 3.1 e 3.3 passaram a permitir explicitamente geração de dados sintéticos e destilação. Mesmo permitindo, a licença comunitária impõe obrigações concretas: exibir "Built with Llama" de forma visível e começar o nome do modelo derivado com "Llama". Se isso for inconveniente, existem bases sob Apache 2.0 que não impõem nada disso. Já discuti a lógica mais ampla em quando modelo aberto compensa contra API fechada; em destilação, a letra da licença vira restrição de arquitetura.

Do lado do professor, os termos de uso dos provedores fechados costumam restringir o uso das saídas para desenvolver modelos concorrentes, e o assunto deixou de ser hipotético: em fevereiro de 2026 a OpenAI enviou memorando ao comitê da Câmara dos EUA alegando que a DeepSeek teria usado roteadores de terceiros para extrair saídas em violação dos termos. O ponto não é a disputa, é que esses limites mudam de versão para versão e a leitura dos termos vigentes precisa ser feita antes do projeto. Some o AI Act europeu, plenamente aplicável desde agosto de 2026, que exige documentar os procedimentos de treino incluindo origem dos dados.

A terceira é deriva do eval. O conjunto congelado representa a distribuição de entradas daquele momento. Seis meses depois o produto mudou, os usuários mudaram, e o eval continua dando 94%: o número está certo e a resposta está errada, porque ele mede um mundo que não existe mais. Trate o eval como código com data de validade. Métrica que só sobe é métrica que parou de medir.

A quarta é o custo escondido de manter. Um modelo próprio é um serviço com ciclo de vida: acompanhar a GPU, atualizar o runtime de inferência, retreinar quando a distribuição mudar, versionar adaptadores, decidir rollback quando o novo for pior. Nada disso aparece na planilha que comparou preço por milhão de tokens. Sem esse trabalho no roadmap, o modelo funciona bem por um trimestre e vira a caixa que ninguém mexe.


O Cálculo Pode Inverter, E Provavelmente Vai

Esta é a parte que me deixa desconfortável em recomendar destilação com entusiasmo.

O número do título é de blog, não de medição minha. A ordem de grandeza de 1/100 aparece com frequência em guias de 2026 e é plausível no caso extremo: tarefa de altíssimo volume, prompt longo, servida num 8B quantizado numa GPU bem utilizada, comparada ao preço de tabela de um modelo de fronteira. Mude qualquer uma dessas variáveis e o fator despenca — GPU com 30% de utilização média não é 1/100 de nada, é uma máquina cara parada. Trate isso como teto teórico da economia, não como estimativa.

E a base de comparação se mexe. A curva de preço de inferência de fronteira vem caindo de forma consistente, e já escrevi sobre como esses preços caíram e o que isso fez com o FinOps de IA. O investimento é feito hoje contra um preço de hoje e amortizado ao longo de meses em que esse preço vai cair. Existe um cenário realista em que você lança o modelo destilado, ele funciona, e nove meses depois o modelo de fronteira está barato o suficiente para tornar a operação do modelo próprio irrelevante.

Isso não é argumento contra destilar, é argumento a favor de destilar de um jeito reversível. Mantenha a chamada ao provedor externo atrás da mesma interface, com uma chave de configuração que devolve o tráfego para lá. E guarde o dataset curado, que é o ativo durável do projeto: refazer o treino num modelo base melhor daqui a um ano custa horas, refazer a curadoria custa semanas.


Conclusão

O que mudou em 2026 não foi a técnica. QLoRA é de 2023, destilação é bem mais antiga, e os hiperparâmetros que funcionam hoje são quase os mesmos de dois anos atrás. O que mudou foi a barreira de entrada cair até o ponto em que um time de produto faz isso sem contratar ninguém: um dataset que já existe no log, uma GPU de 12 GB, algumas horas de treino.

Justamente porque ficou fácil, o gargalo migrou inteiro para as partes que não são treino. A qualidade do modelo destilado é a qualidade da sua curadoria, e a confiança nele é a qualidade do seu eval. Um time com eval bom e dados sujos descobre rápido que não funcionou. Um time com dados bons e sem eval lança sem saber, e descobre pelo suporte.

Eu ainda não destilei nada em produção. Vou passar as próximas semanas fazendo o exercício mais chato que descrevi aqui: montar o conjunto de avaliação congelado para uma etapa do nosso pipeline e medir duas colunas, professor e modelo base com prompt bem feito. Se a segunda já estiver perto o suficiente, o projeto morre ali e eu economizo um mês. Essa possibilidade, de o exercício preliminar matar o projeto, é o melhor argumento a favor de fazê-lo primeiro.

Fontes:

Newsletter

Receba os artigos mais relevantes da semana, sem quebrar seu ritmo de leitura

Um resumo semanal com os melhores posts sobre IA, engenharia de software e tecnologia, enviado no melhor momento para continuar a conversa depois da leitura.

Foto de Elton José

Escrito por

eltonjose

Engenheiro de software e estrategista de produtos digitais, focado em IA pragmática e em transformar experiências de trabalho remoto em aprendizados aplicáveis. Compartilho frameworks e decisões reais que uso em consultorias e projetos.

  • Principais temasDestilação, Fine-Tuning
  • Formato do conteúdoGuia prático + insights de carreira