Phase 10 - Lesson 22
Inferência Assíncrona e Hogwild!
This lesson includes a graded coding exercise that runs in your browser, unlocked with lifetime access.
A decodificação especulativa (Fase 10 · 15) paraleliza tokens dentro de uma única sequência. Frameworks multiagentes paralelizam ao longo de sequências inteiras, mas forçam uma coordenação explícita (votação, divisão de subtarefas). A inferência Hogwild! (Rodionov et al., arXiv:2504.06261) faz algo diferente: executa N instâncias do mesmo LLM em paralelo contra um cache key-value COMPARTILHADO. Cada worker vê instantaneamente os tokens gerados por todos os outros workers. Modelos de raciocínio modernos — QwQ, DeepSeek-R1 — conseguem se autocoordenar por meio desse cache compartilhado sem qualquer ajuste fino (fine-tuning). A abordagem é experimental, mas abre um eixo totalmente novo de paralelismo de inferência que é ortogonal à decodificação especulativa. Esta lição implementa um simulador Hogwild! de dois workers em Python stdlib e explica por que a colaboração em cache compartilhado surge das habilidades de raciocínio existentes do modelo.
Tipo: Construção Linguagens: Python (stdlib) Pré-requisitos: Fase 10 · 12 (otimização de inferência), Fase 10 · 15 (decodificação especulativa) Tempo: ~60 minutos
Objetivos de Aprendizado
- Descrever as três topologias comuns de LLM paralelo (votação, divisão de subtarefas, Hogwild!) e citar quais problemas cada uma delas visa resolver.
- Definir a configuração principal do Hogwild!: múltiplos workers, um cache KV compartilhado e coordenação emergente via autoinstrução (self-prompting).
- Calcular o ganho de velocidade (speedup) no tempo de relógio (wall-time) do Hogwild! como uma função da contagem de workers
N, do paralelismo no nível de tarefape do custo de coordenação (coordination overhead)c. - Implementar um simulador Hogwild! com dois workers em um problema de brinquedo e observar a divisão de tarefas emergente.
O Problema
LLMs modernos resolvem problemas complexos gerando longas cadeias de raciocínio — 5.000 tokens de lógica passo a passo é algo comum, e dezenas de milhares de tokens ocorrem em problemas matemáticos complexos. A uma velocidade de decodificação de 35 tokens/s em um modelo de 70B, 50.000 tokens levam 24 minutos. O modelo definitivamente não é interativo.
A decodificação especulativa (Fase 10 · 15) proporciona um aumento de velocidade de 3 a 5 vezes ao paralelizar a geração dentro de uma única sequência. Além disso, a dependência sequencial da decodificação autorregresiva é o limite intransponível. Cada novo token depende de todos os tokens anteriores.
A pergunta óbvia é: podemos paralelizar ao longo de múltiplas sequências? Executar várias cópias do mesmo modelo no mesmo problema, deixá-los cooperar e fazê-los dividir o trabalho?
Trabalhos anteriores: ensembles de votação (executar N modelos e escolher a resposta majoritária), árvore de pensamentos (tree-of-thought, ramificando caminhos de raciocínio e recombinando-os) e frameworks multiagentes (atribuir a cada agente uma subtarefa e usar um coordenador). Todos esses métodos ajudam em domínios de tarefas específicos. No entanto, todos eles também introduzem mecanismos explícitos de coordenação — regras de votação, lógica de ramificação e poda, e protocolos de mensagens de agente para agente.
A Inferência Hogwild! adota uma abordagem diferente. N workers compartilham um único cache KV. Cada worker vê os tokens gerados por todos os outros workers imediatamente, como se fizessem parte do seu próprio contexto. Os workers — sem qualquer treinamento ou ajuste fino — descobrem como dividir o trabalho sozinhos. Modelos de raciocínio modernos (QwQ, DeepSeek-R1, modo de raciocínio da família Claude) conseguem ler o cache compartilhado e dizer coisas como: "Vejo que o worker 2 já tratou do caso base, então vou trabalhar no passo indutivo."
O ganho de velocidade depende da carga de trabalho e é experimental em abril de 2026. Mas vale a pena conhecer a ideia porque ela abre um novo eixo de paralelismo de inferência.
O Conceito
A configuração
Inicialize N processos workers, todos executando o mesmo LLM. Em vez de caches KV individuais por worker, mantenha UM único cache compartilhado. Quando o worker i gera o token t_j, o token é gravado no cache compartilhado na próxima posição. Quando o worker k dá o seu próximo passo, ele lê o estado atual do cache (que inclui tudo o que todos os N workers geraram até o momento).
No momento do passo de geração, os workers competem para escrever os tokens. Não há índice de posição por worker — o cache é uma única sequência em crescimento. A ordem é determinada pelo tempo de chegada da gravação.
Por que a coordenação emerge
Os workers compartilham um prompt. Normalmente, algo como: "Você é uma de N instâncias trabalhando juntas neste problema. Cada instância lê a memória compartilhada e pode ver o que as outras instâncias escreveram. Evite trabalho redundante." O prompt mais o cache compartilhado é o suficiente. Os modelos de raciocínio leem o cache, percebem quais partes do problema já foram abordadas e (frequentemente, mas nem sempre) desviam para as partes inexploradas.
O artigo do Hogwild! (Rodionov et al., 2025) relata observações como:
- Os workers formulam planos e os comunicam a outros workers por meio do cache.
- Os workers percebem erros no raciocínio de outros workers e os apontam.
- Os workers se adaptam quando um plano falha e propõem alternativas.
- Quando instruídos a verificar redundâncias, os workers as detectam e mudam de foco.
Nada disso requer ajuste fino. O comportamento emergente vem das capacidades de raciocínio que o modelo já possui.
A nomenclatura
O nome do artigo faz referência ao Hogwild! SGD (Recht et al., 2011), um otimizador de atualização assíncrona. A analogia: os workers assíncronos do SGD escrevem em um vetor de parâmetros compartilhado; os workers da Inferência Hogwild! escrevem em um cache KV compartilhado. Ambos dependem da convergência empírica em vez de garantias de sincronização.
O RoPE torna isso viável
Os Rotary Position Embeddings (RoPE, Su et al. 2021) codificam informações de posição por meio de rotação nos vetores Q e K. Como as posições são rotações e não offsets estáticos embutidos, a posição de um token pode mudar sem a necessidade de recalcular a entrada correspondente no cache KV. Quando o worker i escreve no cache compartilhado na posição p, outros workers que leem essa posição podem usar a entrada em cache diretamente — sem necessidade de nova rotação.
Em um modelo com posições aprendidas ou posições absolutas, o Hogwild! exigiria a invalidação do cache a cada gravação concorrente. O RoPE permite que o cache permaneça estável.
Matemática do tempo de relógio (Wall-time)
Seja T_serial o tempo para um único worker resolver o problema sozinho. Seja p a fração de paralelização no nível de tarefa. Seja c o custo de coordenação por passo (tempo gasto lendo o cache estendido e decidindo o que escrever).
Tempo com um único worker: T_serial.
Tempo com Hogwild! de N workers, se a coordenação for gratuita: T_serial * ((1 - p) + p / N). A clássica Lei de Amdahl.
Com custo de coordenação: T_serial * ((1 - p) + p / N) + c * steps_per_worker.
Para que um worker seja produtivo, c deve ser pequeno em relação ao tempo de decodificação por passo. Em modelos de raciocínio que geram mais de 5.000 tokens, os workers podem arcar com centenas de tokens de custo de coordenação e ainda sair em vantagem. Em tarefas de chat curtas, a coordenação domina e o Hogwild! apresenta um desempenho pior do que o processamento serial.
Exemplo concreto
Problema de raciocínio: 10.000 tokens de cadeia de pensamento (chain-of-thought). Suponha que o problema tenha p = 0.7 de conteúdo paralelizável (diferentes estratégias de prova, diferentes análises de casos) e c = 200 tokens de custo de coordenação por worker. Com N = 4 workers:
- Tempo serial: 10.000 passos de decodificação.
- Tempo do Hogwild!: 10000 * (0.3 + 0.7 / 4) + 200 * 4 = 10000 * 0.475 + 800 = 5550 passos de decodificação.
- Speedup: 10000 / 5550 = 1.8x.
Isso é modesto. Mas em problemas de raciocínio mais longos (50.000 tokens), o custo de coordenação é amortizado e o aumento de velocidade chega a 2,5-3x. O Hogwild! é o equivalente na inferência ao paralelismo no nível de thread em uma linguagem que permite escrever código multi-threaded naturalmente.
Quando usar o Hogwild!
- Problemas de raciocínio longos (milhares de tokens) em que a tarefa pode ser paralelizada em submetas independentes.
- Modelos de raciocínio que foram treinados para pensar passo a passo. Modelos sem raciocínio não se autocoordenam bem.
- Implantações em nó único (single-node) com VRAM suficiente para conter o cache compartilhado mais N processos workers. O cache é compartilhado, mas cada worker tem sua própria memória de ativação.
Quando não usar
- Chat interativo curto. O custo de coordenação domina.
- Tarefas que não são paralelizáveis (uma única prova linear, uma única compilação). N=1 é o máximo.
- Modelos sem raciocínio. Nenhuma coordenação emerge.
- Implantações multi-nó (multi-node). O cache compartilhado precisa de uma sincronização muito rápida entre os workers. Intra-nó funciona bem; cross-nó é um desastre de latência.
O status experimental
Em abril de 2026, o Hogwild! é um método de pesquisa com uma implementação de código aberto em PyTorch. A adoção em produção ainda não ocorreu. Três impedimentos:
- O gerenciamento do cache KV compartilhado entre processos concorrentes envolve uma engenharia complexa.
- A coordenação emergente depende da tarefa; os benchmarks ainda estão sendo desenvolvidos.
- Os ganhos de velocidade são modestos em comparação com o que a decodificação especulativa já oferece, e embora as duas técnicas possam ser combinadas, a engenharia conjunta adiciona outra camada de complexidade.
Vale a pena conhecer. Vale a pena experimentar. Mas ainda não vale a pena apostar um produto nisso.
Construa
O arquivo code/main.py implementa um simulador simples do Hogwild!:
- Dois processos workers, cada um representando um "LLM" determinístico que produz uma de várias categorias de tokens (token de trabalho, token de observação, token de coordenação) com probabilidades conhecidas.
- Um cache compartilhado (apenas uma lista de tokens) que ambos os workers leem e escrevem.
- Uma lógica de coordenação simples: quando um worker percebe que o outro já produziu tokens de trabalho suficientes em uma categoria, ele escolhe uma categoria diferente.
O simulador roda por um limite fixo de passos e reporta:
- Total de tokens de trabalho produzidos.
- Tempo de relógio total (número de passos dos workers).
- Speedup efetivo sobre um único worker.
- Um rastreamento de qual worker escreveu cada token.
Passo 1: o cache compartilhado
Uma lista na qual ambos os workers adicionam elementos. Em uma implementação real, isso utilizaria um bloqueio simples (como o threading.Lock do Python); simulamos isso com um contador.
Passo 2: o loop do worker
Cada worker, em cada passo:
- Lê o cache compartilhado atual.
- Decide qual categoria de token escrever com base no que já está lá.
- Escreve um token.
Passo 3: a heurística de coordenação
Se a categoria X já possui K tokens no cache e a categoria pretendida do worker é X, o worker muda para a categoria Y. Esta é uma simulação simples para o comportamento de um modelo de raciocínio de "perceber que isso já foi coberto e fazer outra coisa".
Passo 4: medindo o ganho de velocidade (speedup)
Execute o simulador com N=1 worker e com N=2 workers, usando o mesmo limite total de passos. Conte os tokens de trabalho produzidos. N=2 deve produzir cerca de 1,5 a 1,8x mais tokens de trabalho devido à divisão de tarefas baseada na coordenação.
Passo 5: testando os limites da coordenação
Reduza a sensibilidade da heurística de coordenação. Execute novamente. Observe que, sem uma boa coordenação, N=2 produz redundantemente os mesmos tokens e o ganho de velocidade cai abaixo de 1. Isso condiz com a observação do artigo: o truque só funciona se os workers tiverem capacidade de raciocínio para se autocoordenarem.
Use-o
A integração do Hogwild! em produção em abril de 2026 está em nível de pesquisa. A implementação de referência da Yandex/HSE/IST é baseada em PyTorch e visa configurações de processo múltiplo em nó único (single-node) em modelos DeepSeek-R1 e QwQ.
Caminho pragmático de adoção:
- Analise o perfil da sua carga de trabalho de raciocínio. Meça a fração de tokens que são exploratórios (múltiplas estratégias, análises de caso, busca) vs lineares.
- Se a exploração dominar, execute um experimento Hogwild! com dois workers. Meça a melhoria no tempo de relógio (wall-time).
- Se a melhoria for inferior a 1,3x, você está sob o regime dominado pela coordenação. Reverta para o uso de um único worker.
- Se a melhoria for superior a 1,5x, avance para N=4 e meça novamente. O retorno decrescente geralmente ocorre por volta de N=4-8.
Combine com a decodificação especulativa: cada worker Hogwild! pode usar independentemente a decodificação especulativa. Os dois ganhos de velocidade se multiplicam (aproximadamente), elevando uma decodificação especulativa de 3x e um Hogwild! de 1,8x a um ganho efetivo de 5,4x em relação à decodificação simples com um único worker.
Envie para Produção
Esta lição produz o arquivo outputs/skill-parallel-inference-router.md. Dado um perfil de carga de trabalho de raciocínio (limite de tokens, perfil de paralelismo de tarefas, família de modelos, alvo de implantação), ele faz o roteamento entre as estratégias de votação, árvore de pensamentos (tree-of-thought), multiagentes, Hogwild! e decodificação especulativa.
Exercícios
Execute
code/main.pycom as configurações padrão. Confirme se a configuração Hogwild! com N=2 produz mais tokens de trabalho do que a linha de base com N=1 no mesmo tempo de relógio.Reduza a força da heurística de coordenação (defina
coordination_weight=0.1). Execute novamente. Mostre que o ganho de velocidade entra em colapso. Explique o porquê: os workers duplicam o esforço quando não conseguem se coordenar.Calcule o ganho de velocidade esperado do Hogwild! para uma tarefa de raciocínio de 50.000 tokens com
p=0.8, c=500e N=4 workers. Faça o mesmo para uma tarefa de chat de 1.000 tokens comp=0.3, c=200e N=4. Por que um caso é vantajoso e o outro é desvantajoso?Leia a Seção 4 (avaliação preliminar) do artigo do Hogwild!. Identifique os dois modos de falha relatados pelos autores. Descreva como um prompt de coordenação melhor poderia mitigar cada um deles.
Combine o Hogwild! com a decodificação especulativa no modelo simplificado: cada worker usa uma decodificação especulativa interna de 2 tokens. Relate o ganho de velocidade multiplicativo. Que problema de controle de dados (bookkeeping) surge quando ambos os workers desejam estender o mesmo prefixo de cache compartilhado?
Termos-Chave
| Termo | O que as pessoas dizem | O que realmente significa |
|---|---|---|
| Hogwild! | "Workers paralelos, cache compartilhado" | N instâncias do mesmo LLM executando concorrentemente com um cache KV compartilhado; coordenação emergente via autoinstrução (self-prompting) |
| Cache KV compartilhado | "O meio de coordenação" | Um único buffer KV em crescimento que todos os workers leem e escrevem; permite a visibilidade instantânea de tokens entre os workers |
| Coordenação emergente | "Sem necessidade de treinamento" | LLMs capazes de raciocínio conseguem ler o cache compartilhado e dividir o trabalho sem qualquer ajuste fino ou protocolo explícito |
| Custo de coordenação (c) | "Tokens gastos na orientação" | O custo por worker para ler o cache estendido e decidir o que fazer; deve permanecer pequeno em relação ao tempo total de decodificação |
| Fração paralelizável (p) | "O que pode rodar em paralelo" | Paralelismo no nível de tarefa: a fração do trabalho total que não é intrínsecamente sequencial |
| RoPE viabiliza Hogwild! | "Posições rotativas são invariantes por deslocamento" | Como as posições são rotações, escrever em um cache compartilhado não exige recomputar os tokens anteriores |
| Ensemble de votação | "Execute N, escolha a maioria" | A topologia mais simples de inferência paralela; útil para classificação, menos para raciocínio longo |
| Árvore de pensamentos | "Ramifique e pode" | Estratégia de raciocínio que explora múltiplos caminhos e os poda; lógica de coordenação explícita |
| Framework multiagente | "Atribua subtarefas" | Cada agente recebe uma função; um coordenador orquestra; alto custo de protocolo |
Leituras Adicionais
- Rodionov et al. — Hogwild! Inference: Parallel LLM Generation via Concurrent Attention (arXiv:2504.06261) — o artigo do Hogwild!, avaliação preliminar nos modelos QwQ e DeepSeek-R1
- Recht, Re, Wright, Niu — Hogwild!: A Lock-Free Approach to Parallelizing Stochastic Gradient Descent (arXiv:1106.5730, NeurIPS 2011) — o Hogwild! original, a origem do nome
- Su et al. — RoFormer: Enhanced Transformer with Rotary Position Embedding (arXiv:2104.09864) — RoPE, a propriedade que torna a inferência com cache compartilhado viável
- Yao et al. — Tree of Thoughts: Deliberate Problem Solving with Large Language Models (arXiv:2305.10601) — a estratégia de raciocínio de árvore de pensamentos com a qual o Hogwild! atua de forma ortogonal
- Leviathan et al. — Fast Inference from Transformers via Speculative Decoding (arXiv:2211.17192) — decodificação especulativa, o paralelismo intra-sequência com o qual o Hogwild! se integra
- Hogwild! reference PyTorch implementation — a fonte única de verdade para os experimentos do artigo