O que é inferência de LLM no CPU

Por muito tempo, rodar um modelo de linguagem grande em uma CPU parecia inviável. GPUs dominavam o campo por causa de sua capacidade de processar milhares de operações em paralelo, essencial para a multiplicação de matrizes que alimenta os transformers. Mas isso esta mudando rapidamente.

Em 2023, surgiu o llama.cpp, um projeto open source criado por Georgi Gerganov que implementa inferência de LLMs diretamente em C++, sem depender de CUDA ou qualquer framework de GPU. O projeto foi um divisor de aguas: de repente, era possível rodar modelos grandes no seu notebook ou servidor antigo sem nenhuma placa dedicada.

Hoje, essa abordagem evoluiu ao ponto de alguém conseguir rodar o Gemma 4, o modelo aberto mais recente do Google com cerca de 26 a 27 bilhoes de parâmetros, em um servidor com Xeon de 2013 chegando a 5 tokens por segundo. Não e rápido para produção com muitos usuários, mas e mais do que suficiente para uso pessoal, experimentação e ambientes com requisitos de privacidade.

Como funciona a quantização e o llama.cpp

O segredo por trás da inferência viável no CPU esta na quantização. Um modelo de 27 bilhoes de parâmetros em float16 ocupa cerca de 54 GB de RAM, algo impossível para a maioria dos setups. Com quantização Q4_K_M (4 bits por peso, com ajuste adaptativo por camada), esse tamanho cai para aproximadamente 15 a 17 GB, algo que cabe na memoria de um servidor com DDR3 ECC.

O llama.cpp aproveita instruções SIMD disponíveis nos processadores modernos, como AVX2 e AVX512, para acelerar as operações matriciais. Um Xeon E5 de segunda geração, mesmo sendo de 2013, tem suporte a AVX1 e SSE4.2, o que ainda permite uma aceleração significativa em comparação com aritmética escalar pura.

Outro fator crucial e a largura de banda de memoria. LLMs em inferência são fortemente limitados pela velocidade de leitura dos pesos da RAM, não apenas pelo poder de computação. Por isso, um sistema com múltiplos canais de DDR3 em 1600 ou 1866 MHz pode ser surpreendentemente competente quando os pesos já foram quantizados para um tamanho menor.

💡
Dica

A quantização Q4_K_M oferece o melhor equilíbrio entre tamanho e qualidade de resposta. Evite Q2 ou Q3 em modelos grandes - a perda de qualidade e perceptivel. Para o Gemma 4 27B, use Q4_K_M ou Q5_K_M se tiver RAM suficiente.

Principais recursos do setup

O llama.cpp possui uma serie de funcionalidades que tornam a inferência no CPU prática e flexível. Veja o que você pode fazer com ele:

  • Suporte ao formato GGUF: o padrão atual para modelos quantizados, compatível com praticamente todos os modelos relevantes disponíveis no Hugging Face
  • Servidor HTTP com API compatível com OpenAI: o llama.cpp inclui um servidor que usa o mesmo formato de API da OpenAI, permitindo integrar qualquer biblioteca existente sem mudar código
  • Contexto longo: o Gemma 4 suporta contextos de até 128K tokens; no CPU você pode usar contextos menores para manter a velocidade
  • Multi-thread automático: o llama.cpp detecta e usa todos os núcleos disponíveis por padrão, aproveitando CPUs com muitos cores como os Xeons
  • Suporte a múltiplas plataformas: Linux, Windows e macOS são suportados, com compilações prebuilt disponíveis para quem não quer compilar do zero

O Gemma 4 foi lançado pelo Google como parte da família Gemma, com foco em modelos abertos que podem ser executados localmente. A versão de 27B e a maior da serie principal, com desempenho competitivo em benchmarks de raciocínio, código e conversação.

Como começar: instalação passo a passo

Para rodar o Gemma 4 no CPU, você vai precisar de: um sistema Linux (recomendado) ou Windows, pelo menos 20 GB de RAM disponível, e o llama.cpp compilado localmente. A compilação e simples e leva menos de 5 minutos em qualquer máquina com GCC instalado.

Passo 1: clone e compile o llama.cpp:

git clone https://GitHub.com/ggerganov/llama.cpp
cd llama.cpp
make -j$(nproc)

Passo 2: baixe o modelo quantizado do Hugging Face. Instale o cliente e baixe a versão Q4_K_M do Gemma 4 27B:

pip install huggingface-hub
huggingface-cli download bartowski/gemma-4-27b-it-GGUF --include "*Q4_K_M*.gguf" --local-dir ./models

Passo 3: inicie o servidor HTTP para usar com qualquer cliente compatível com a API da OpenAI:

./llama-server -m models/gemma-4-27b-it-Q4_K_M.gguf --host 0.0.0.0 --port 8080 -c 4096 -t $(nproc)
⚠️
Atenção

O arquivo GGUF Q4_K_M do Gemma 4 27B tem cerca de 15 a 17 GB. Certifique-se de ter espaço em disco suficiente e uma conexão estável antes de iniciar. O download pode levar de 20 minutos a mais de 1 hora dependendo da sua conexão.

Exemplo prático: 5 tokens por segundo no Xeon de 2013

O experimento que viralizou no Hacker News usou um servidor com dois processadores Intel Xeon E5-2680 v2, lançados em 2013, totalizando 20 núcleos físicos e 40 threads. A memoria era DDR3 ECC em modo multi-canal, com largura de banda total considerável entre os dois sockets NUMA.

Com o modelo Q4_K_M do Gemma 4 27B carregado inteiramente na RAM, o setup atingiu aproximadamente 5 tokens por segundo em geração. Uma resposta de 200 tokens leva cerca de 40 segundos, o que é lento para um chatbot interativo, mas perfeitamente aceitável para processamento em batch ou uso esporádico.

./llama-cli -m models/gemma-4-27b-it-Q4_K_M.gguf -t 40 --temp 0.7 -n 200 -p "Explique o que é machine learning em 3 parágrafos"

O resultado típico em um Xeon E5 de 2013 com Q4_K_M e entre 4 e 6 tokens por segundo, dependendo do comprimento do contexto. Com CPUs mais modernos como Xeons de 3a ou 4a geração com AVX512, esse número pode dobrar ou triplicar.

🚀
Pro tip

Se você tiver dois sockets físicos (dois CPUs), use numactl para fixar a execução em um único NUMA node. Isso reduz a latência de acesso a memoria e pode aumentar o throughput em 20 a 30%: numactl --cpunodebind=0 --membind=0 ./llama-server ...

Comparação com alternativas

Rodar no CPU e apenas uma das opcoes disponíveis. As principais alternativas são:

  • GPU local (NVIDIA RTX 4090): velocidades de 60 a 120 tokens por segundo com o modelo completo. Muito mais rápido, mas o custo da GPU e alto e os 24 GB de vRAM limitam modelos maiores
  • APIs cloud (Groq, Together AI, Google AI Studio): centenas de tokens por segundo, sem custo de hardware, mas com custo por token e sem privacidade de dados
  • Ollama: abstrai o llama.cpp em uma interface mais amigável, ótimo para quem não quer compilar nada, mas com menos controle sobre parâmetros avançados
  • CPU com llama.cpp: 4 a 20 tokens por segundo dependendo do hardware, custo operacional zero se você já tem o servidor, privacidade total dos dados

A grande vantagem do CPU e que muitas empresas já tem servidores antigos ociosos. Aproveitar esse hardware para inferência local e economicamente atraente, especialmente para equipes com requisitos de privacidade ou compliance regulatorio.

Pontos positivos e limitações

A inferência no CPU tem vantagens reais que vao além do custo zero de hardware novo:

  • Privacidade total: seus dados nunca saem da sua infraestrutura. Para setores como saúde, direito ou finanças, isso pode ser decisivo
  • Custo marginal zero: depois do setup inicial, cada inferência não custa nada. Em uso intenso de batch, isso representa economia significativa
  • Sem rate limits: você não vai receber erro 429 por exceder limites de APIs cloud
  • Controle total: ajuste temperatura, contexto e system prompt sem restrições de nenhum provedor

Mas as limitações são igualmente reais:

  • Velocidade baixa: 5 tokens por segundo e lento para interação humana em tempo real. A experiência e frustrante para chatbots responsivos
  • Consumo alto de RAM: o modelo Q4_K_M ocupa cerca de 15 a 17 GB. Sistemas com menos memoria não conseguem rodar
  • Primeiro token lento: o tempo até o primeiro token (TTFT) no CPU e maior do que na GPU, impactando a percepção de responsividade
  • Dificuldade de escala: atender múltiplos usuários simultâneos no CPU e muito mais difícil do que na GPU

Casos de uso reais

Onde faz sentido usar inferência no CPU com modelos grandes como o Gemma 4?

  • Processamento de documentos em batch: resumir ou classificar centenas de documentos sem necessidade de resposta imediata. Um documento de 500 palavras e processado em menos de 2 minutos a 5 tokens por segundo
  • Ambientes com restrição de privacidade: advogados, médicos e analistas financeiros que não podem enviar dados para APIs externas se beneficiam diretamente de uma solução local
  • Prototipagem e experimentação: testar prompts, avaliar qualidade de respostas e ajustar system prompts sem custo de API
  • Servidores ociosos na empresa: muitas empresas tem hardware antigo sem uso. Transformar esse hardware em um servidor de inferência local e uma alternativa economicamente atraente

Dicas e boas práticas

💡
Dica

Use contextos curtos (2048 a 4096 tokens) no CPU. O custo de processamento do contexto (prefill) cresce rapidamente com o comprimento, então contextos muito longos ficam lentos no CPU e comprometem a velocidade de geração.

🚀
Pro tip

Compile o llama.cpp com suporte a OpenBLAS para acelerar a fase de prefill: make LLAMA_OPENBLAS=1 -j$(nproc). Instale antes com: sudo apt install libopenblas-dev. Pode melhorar o tempo de processamento do prompt em 30 a 50%.

⚠️
Atenção

Em sistemas com dois sockets NUMA, o llama.cpp pode distribuir threads entre os dois nodes por padrão, aumentando a latência de memoria. Sempre teste com numactl para verificar se a performance melhora ao restringir a um único node.

🔴
Cuidado

Não use quantizações Q2 ou Q3 no Gemma 4 27B. A qualidade das respostas cai visivelmente. Se o seu sistema não tem RAM suficiente para Q4_K_M, use o modelo menor de 9B da família Gemma 4 em vez de sacrificar a precisão das respostas.

Vale a pena?

Depende do seu caso de uso. Se você tem hardware ocioso e privacidade e uma preocupação real, vale a pena experimentar. O setup com llama.cpp e surpreendentemente simples e em menos de uma tarde você tem um LLM de 27 bilhoes de parâmetros rodando localmente sem custo adicional.

Se você precisa de respostas rápidas e interativas, a inferência no CPU ainda não e adequada para essa finalidade. Nesse caso, considere APIs cloud ou invista em uma GPU de custo moderado, que oferece muito mais throughput por real investido.

O próximo passo sugerido: baixe o llama.cpp, encontre um servidor antigo na sua empresa ou rack domestico, e comece com o Gemma 4 9B. O modelo menor e mais rápido e já e bastante capaz. Quando você estiver confortável com o setup, faca o upgrade para o 27B e experimente tarefas mais complexas.