Como treinar agentes de RL sem queimar GPUs: O que aprendi lendo o artigo do GLM-5
Se você já tentou treinar um agente de IA com Reinforcement Learning (RL) para tarefas longas como resolver issues do GitHub ou navegar na web sabe o drama: a GPU fica ociosa a maior parte do tempo, esperando o agente rodar código, executar ferramentas e coletar observações. É um pesadelo de eficiência.
Recentemente, eu estava lendo o artigo técnico do GLM-5 (o novo modelo da Zhipu AI) e me deparei com uma seção que me chamou muita atenção: a infraestrutura de RL assíncrono para agentes.
Só para deixar claro: eu não projetei isso, nem trabalho na Zhipu. Sou apenas um cientista da computação curioso que gosta de ler artigos e traduzir a engenharia dos outros em conceitos práticos. Mas fiquei tão impressionado com a solução deles que precisei escrever sobre ela.
O problema: por que treinar agentes com RL é tão lento?
No RL tradicional (tipo PPO ou GRPO), o fluxo é síncrono:
- O agente (com a política atual) executa uma trajetória no ambiente abrir navegador, rodar código, compilar, executar testes. Isso pode levar minutos.
- Enquanto isso, a GPU fica parada, esperando o rollout terminar.
- Só então o lote de trajetórias é usado para atualizar os pesos da rede neural.
Segundo o artigo, isso cria "bolhas" enormes de tempo ocioso. Para agentes que precisam de centenas de passos, a GPU fica mais tempo esperando do que calculando. O GLM-5 precisou de uma solução radical para escalar isso.
A virada de chave: desacoplar a geração do treino
Pelo que entendi do paper, a grande sacada do GLM-5 foi separar completamente duas coisas:
- O Inference Engine (motor de geração), rodando em GPUs dedicadas, fica amostrando trajetórias o tempo todo, sem parar.
- O Training Engine (motor de treino), em outras GPUs, consome essas trajetórias em lotes e atualiza os pesos.
- De tempos em tempos, os pesos do treino são copiados para o motor de inferência.
Isso acaba com o tempo ocioso. Mas cria um problema clássico: as trajetórias podem ter sido geradas por versões antigas do modelo, tornando o treino "off-policy" (ou seja, os dados não são da política atual).
Para resolver isso sem perder a eficiência, eles propõem três técnicas que achei geniais. Vou tentar explicar cada uma do jeito que eu entendi.
1. TITO Gateway: chega de re-tokenizar os textos
O que o artigo diz: Em muitos sistemas, o motor de inferência devolve um texto pronto (text-in-text-out). O treinador então precisa re-tokenizar esse texto para calcular a perda. Isso parece bobo, mas na prática pode destruir o alinhamento dos tokens com as recompensas.
O que eles fizeram: Criaram um negócio chamado TITO (Token-in-Token-out) Gateway. Em vez de devolver texto, o motor de inferência devolve os IDs exatos dos tokens que foram gerados, junto com as log-probabilidades. O treinador usa esses números brutos, sem passar por nenhuma re-tokenização.
Minha leitura: É como se você pedisse um bolo e, em vez de entregar o bolo pronto, entregasse a receita exata que foi usada. Você garante que o que foi amostrado é exatamente o que vai ser otimizado, sem ruído de tradução. Simples, mas muito eficaz.
2. Importance Sampling com Clipping Duplo (Double-sided)
O que o artigo diz: Em sistemas assíncronos, uma mesma trajetória pode ser gerada por várias versões do modelo, já que os pesos mudam durante a coleta. Guardar todas as versões antigas para calcular a razão de importância exata (π_old) é inviável na prática — consumiria memória e comunicação demais.
O que eles fizeram: Eles simplificaram a fórmula. Em vez de comparar com π_old, eles comparam diretamente a política atual (π_θ) com a política que realmente rodou no rollout (π_rollout), usando as log-probabilidades que foram salvas no TITO.
Além disso, eles aplicam um clipping simétrico: se a razão de importância sair do intervalo [1 - ε_l, 1 + ε_h], o token é simplesmente ignorado (mascarado) no cálculo do gradiente.
Minha leitura: Eles aceitam um pequeno "viés" controlado para ganhar velocidade e estabilidade. Se o comportamento atual é muito diferente do comportamento antigo, melhor descartar aquele token do que forçar uma atualização que pode destabilizar o treino. É aquele velho ditado do mundo real: "melhor prevenir do que remediar".
3. DP-aware Routing: reutilizando o cache de atenção
O que o artigo diz: Agentes multi-turn (várias rodadas de interação) acumulam um histórico enorme (conversas, logs, ferramentas). Se as requisições de um mesmo agente caem em GPUs diferentes (por causa do Data Parallelism), cada GPU precisa recomputar o KV-cache (as chaves e valores da atenção) do zero a cada rodada.
O que eles fizeram: Eles implementaram um roteamento baseado em hashing consistente. Cada agente (rollout_id) é sempre mapeado para a mesma GPU.
Minha leitura: É como ter um armário com gavetas fixas para cada cliente. O garçom (GPU) não precisa procurar a ficha do cliente do zero a cada pedido; ela já está na gaveta certa. O custo do "prefill" (processamento do contexto) cai drasticamente, porque você só processa os tokens novos da rodada, não o histórico inteiro de novo.
O maquinário por trás de tudo: o Multi-Task Rollout Orchestrator
Além dessas três técnicas, o artigo descreve um orquestrador central que gerencia tarefas diferentes (engenharia de software, terminal, busca, geração de slides) como microsserviços.
Segundo os autores, esse orquestrador consegue rodar mais de 1.000 rollouts concorrentes, ajustando dinamicamente a proporção de cada tarefa e monitorando o progresso de forma granular. Tudo isso mantendo as trajetórias padronizadas em um formato único para o treino.
Isso me lembrou um pouco a arquitetura de microsserviços em sistemas web, mas aplicada a treinamento de IA em escala massiva.
E o resultado disso tudo?
Bom, segundo os números do próprio artigo (e eles são públicos), essa infraestrutura permitiu ao GLM-5:
- Construir e treinar agentes em mais de 10 mil ambientes SWE reais (problemas de GitHub) de forma estável.
- Alcançar 77,8% no SWE-bench Verified (estado-da-arte entre modelos open-weight) e 75,9% no BrowseComp.
- Utilização de GPU muito maior e tempo de treino reduzido, mesmo com tarefas que exigem centenas de passos.
O que eu, como leitor, tiro de lição disso
Eu não tenho um cluster de GPUs para replicar essa infraestrutura amanhã, mas os princípios são valiosos para qualquer pessoa que está construindo agentes:
- Desacople a geração do treino sempre que possível. Se o seu agente demora para agir, não deixe o treino esperando.
- Cuidado com a re-tokenização. Guarde os tokens gerados, não apenas o texto final.
- Não tente manter todas as políticas antigas. Aceite um viés controlado e use clippings agressivos para estabilidade.
- Roteie por afinidade para reutilizar caches, especialmente em agentes com longas conversas.
No fim das contas, o mais impressionante para mim é ver como a engenharia de sistemas está se tornando tão crítica quanto a ciência dos modelos. O GLM-5 não é só um modelo maior; é um exemplo de como arquitetar o treino para que agentes realmente autônomos possam existir em escala.
Gostou da análise? Lembre-se: tudo isso foi tirado da leitura do artigo 2602.15763v2.pdf da equipe GLM-5. Nada disso é invenção minha — sou só um cientista da computação que adora destrinchar papers e compartilhar o que aprendeu. Se você quiser se aprofundar, o artigo está disponível no arXiv