Alternar tema

Otimização de desempenho do Ollama na prática: guia de quantização, lotes e memória

Easton editorial illustration: one compact local-model engine on a performance console

Atualização de 08/06/2026: as variáveis de ambiente foram conferidas com a documentação oficial do Ollama. Controle o número de camadas na GPU pelo parâmetro de modelo num_gpu (OLLAMA_GPU_LAYERS não existe); use OLLAMA_GPU_OVERHEAD, em bytes, para reservar VRAM; e considere também a quantização do KV Cache com OLLAMA_KV_CACHE_TYPE. Os benchmarks são valores de referência e variam conforme a versão e o hardware.

Seu modelo 14B está funcionando, mas a inferência não passa de 10 tokens/s? Ou ele simplesmente fecha com um erro de OOM? A ventoinha da placa de vídeo dispara e a tela fica preta.

É uma situação comum: você baixa o llama3 8B empolgado, executa ollama run e descobre que não há VRAM suficiente. Ou o processo termina com erro, ou fica lento demais. Ao trocar para uma versão quantizada em Q4, o modelo finalmente funciona, mas sobra a dúvida: quanto de qualidade foi perdido?

Quando comecei a usar o Ollama, caí nessas armadilhas. Tentei rodar um modelo 14B com 8 GB de VRAM, imaginando ingenuamente que bastava conseguir iniciá-lo. O resultado era CUDA out of memory ou uma resposta que saía palavra por palavra.

O problema não está no hardware. A configuração é que ainda não foi ajustada.

Este artigo trata de três técnicas centrais de otimização: escolha da quantização, configuração de lotes e ajuste de memória. Entendendo essas três áreas, você pode pelo menos dobrar o desempenho do seu LLM local. Não é o “dobro” de uma frase de marketing, mas um aumento real de tokens/s.

1. Quantização — equilíbrio entre qualidade e velocidade, de Q4 a FP16

1.1 O que é quantização e por que GGUF virou o formato dominante

Em termos simples, quantizar é “encolher” o modelo.

Os parâmetros originais de um modelo grande baixado por você estão em FP16, ou seja, números de ponto flutuante de 16 bits. Em um modelo 7B, apenas os parâmetros ocupam 14 GB de VRAM em FP16. Mas o que acontece se cada parâmetro passar de 16 para 4 bits? Em teoria, o tamanho cai para 3,5 GB. Essa é a lógica central da quantização: representar os valores originais com menos bits para consumir menos memória e acelerar a inferência.

Claro que existe um custo: perda de precisão. É como reduzir uma foto de 4K para 720p. Alguns detalhes desaparecem, mas, na maioria dos cenários, o resultado continua útil.

O GGUF se tornou dominante por um motivo simples: praticidade. Criado especificamente pela equipe do llama.cpp, ele oferece suporte a mapeamento de memória (mmap), permitindo ler o modelo sob demanda em vez de carregá-lo inteiro na RAM. Assim, uma máquina com 16 GB de memória consegue rodar um modelo 13B — algo inviável com formatos tradicionais.

1.2 Tipos de quantização: comparação entre Q4_0, Q4_K_M, Q5_K_M e Q8_0

Esta parte costuma confundir muita gente: Q4_0, Q4_1, Q4_K_M, Q5_K_M, Q8_0… Entre tantas opções, qual escolher?

A tabela abaixo compara os tipos de quantização mais usados:

Tipo de quantizaçãoTaxa de compressãoMemória usada (modelo 7B)Perda de qualidadeCenário indicado
Q4_0Cerca de 4,5xCerca de 4,0 GBMaiorVRAM extremamente limitada e baixa exigência de qualidade
Q4_K_MCerca de 4,5xCerca de 4,7 GBMuito pequenaMelhor custo-benefício, recomendação para o dia a dia
Q5_K_MCerca de 3,5xCerca de 5,8 GBMínimaPrioridade para qualidade e VRAM suficiente
Q8_0Cerca de 2xCerca de 7,2 GBQuase sem perdaMelhor qualidade possível e bastante VRAM
FP161xCerca de 14 GBSem perdaPesquisa acadêmica e placas de vídeo de ponta

Em resumo: Q4_K_M oferece o melhor custo-benefício, com uso baixo de memória e perda de qualidade quase imperceptível. Fiz muitos testes e, em conversas comuns, é muito difícil notar a diferença entre respostas de Q4_K_M e FP16 sem procurar cada detalhe com lupa.

Q5_K_M serve para quem tem alguma folga de VRAM e é mais exigente com a qualidade. Já Q8_0 dificilmente compensa, a menos que você tenha mais de 24 GB de VRAM. Com esse hardware, pode ser mais interessante usar um modelo com mais parâmetros.

1.3 Árvore de decisão para escolher a quantização

Use esta lógica simples:

Etapa 1: confira a VRAM

  • VRAM ≤ 8 GB: escolha Q4_K_M; um modelo 7B fica no limite e um 14B exige offload para CPU
  • VRAM entre 12 e 16 GB: Q4_K_M roda um 14B sem problemas; para 7B, você pode usar Q5_K_M
  • VRAM ≥ 24 GB: Q5_K_M ou Q8_0 funcionam bem, e até um modelo 70B pode ser considerado

Etapa 2: avalie a necessidade

  • Conversas cotidianas e programação: Q4_K_M é suficiente
  • Tradução e escrita sensíveis à qualidade: Q5_K_M
  • Pesquisa acadêmica e comparação de avaliações: Q8_0 ou FP16

Alguns números práticos como referência:

  • Modelo 7B em Q4_K_M: cerca de 4,7 GB de VRAM
  • Modelo 14B em Q4_K_M: cerca de 9 GB de VRAM
  • Modelo 70B em Q4_K_M: cerca de 40 GB de VRAM

Minha sugestão é começar com Q4_K_M. Se as respostas parecerem inadequadas, passe para Q5_K_M. Não persiga uma versão “sem perda” desde o início; muitas vezes a diferença percebida é apenas expectativa.

1.4 Como baixar uma versão quantizada específica

Por padrão, o Ollama baixa a versão quantizada em Q4_K_M. Quer escolher outra versão?

# Baixar Q4_K_M por padrão
ollama run llama3

# Especificar a quantização Q5
ollama run llama3:70b-q5

# Especificar a quantização Q8
ollama run llama3:70b-q8

Nem todo modelo oferece todas as versões de quantização. Consulte a biblioteca oficial de modelos do Ollama ou use estes comandos para ver as tags disponíveis:

# Listar os modelos disponíveis localmente
ollama list

# Exibir detalhes do modelo, incluindo a quantização
ollama show llama3 --modelfile

Para quem usa modelos intensivamente, quantizá-los por conta própria também é uma opção. O llama.cpp fornece uma cadeia completa de ferramentas de quantização, com controle de precisão e parâmetros. Esse é um tema mais avançado e fica fora do escopo deste artigo.

2. Configuração de lotes — aumente a vazão em 50% a 150%

2.1 Como o processamento em lotes acelera a inferência

O conceito de processamento em lotes ainda gera muita confusão. Pense no seguinte exemplo.

Imagine o caixa de um supermercado. Se ele processar apenas um item de cada cliente por vez, precisará alternar repetidamente entre atender, escanear e receber o pagamento, o que reduz a eficiência. Ao escanear juntos os itens de dez clientes, os movimentos ficam contínuos e o trabalho rende mais.

A inferência na GPU segue uma lógica parecida. Ao processar um único token, a GPU passa boa parte do tempo esperando a transferência de dados da memória, com suas unidades de computação ociosas. O lote agrupa vários tokens para serem processados juntos, mantendo a GPU mais ocupada.

Atenção: o processamento em lotes aumenta a vazão, não reduz a latência de uma única solicitação. Se apenas uma pessoa estiver usando o modelo, a diferença percebida será pequena. Em um serviço de API que atende várias solicitações simultâneas, porém, a vazão pode dobrar ou até superar esse valor.

2.2 Entendendo o parâmetro num_batch

num_batch é o principal parâmetro de processamento em lotes do Ollama, com valor padrão de 512.

Quanto maior o valor, maior a utilização da GPU e a vazão. Em contrapartida, o consumo de VRAM aumenta de 20% a 40%.

Como escolher? Depende da folga de VRAM:

Situação da VRAMnum_batch recomendadoResultado esperado
VRAM limitada512 (padrão)Seguro, com possível ociosidade
VRAM moderada1024Aumento de 50% a 80% na vazão
VRAM abundante2048Aumento de 100% a 150% na vazão

Na minha experiência, um RTX 3080 de 10 GB roda um 7B Q4_K_M com num_batch em 1024 sem dificuldade. Em 2048, podem ocorrer erros de OOM. Já um RTX 4090 roda um modelo 14B com 2048 sem problemas.

2.3 num_ctx e KV Cache

num_ctx define o tamanho da janela de contexto; seu valor padrão é 2048. Esse parâmetro afeta o consumo de memória do KV Cache.

O que é KV Cache? Em termos simples, durante a inferência o modelo armazena resultados de cálculos anteriores para não precisar repeti-los. Quanto maior o contexto, maior o cache.

Fórmula aproximada do consumo de memória:

Memória do KV Cache ≈ 2 × número de camadas × dimensão oculta × num_ctx × bytes da precisão

Alguns números práticos como referência:

  • Modelo 7B com num_ctx=4096: consumo adicional de cerca de 1 a 2 GB
  • Modelo 14B com num_ctx=8192: consumo adicional de cerca de 3 a 4 GB

Portanto, ao usar contextos longos, como 32K ou 128K, o consumo de VRAM cresce rapidamente. Muita gente acredita que os parâmetros do modelo ocuparam toda a memória, quando na verdade o KV Cache é o principal responsável.

Armadilha: alguns modelos vêm com um num_ctx padrão muito alto. O llama3, por exemplo, aceita até 128K, mas reservar todo esse contexto pode esgotar a VRAM na hora. Para uso cotidiano, 4096 ou 8192 costuma bastar.

2.4 Configuração prática de lotes

Veja exemplos diretos de configuração.

Opção 1: configurar em um Modelfile

# Criar a partir do modelo base
FROM llama3

# Definir o tamanho do lote
PARAMETER num_batch 1024

# Definir a janela de contexto
PARAMETER num_ctx 4096

# Impedir que o prompt do sistema seja removido
PARAMETER num_keep 128

Salve como Modelfile e crie o novo modelo:

ollama create my-llama3 -f Modelfile
ollama run my-llama3

Opção 2: configurar em options na API

curl http://localhost:11434/api/generate -d '{
  "model": "llama3",
  "prompt": "Explique a computação quântica",
  "options": {
    "num_batch": 1024,
    "num_ctx": 4096
  }
}'

Comparação de desempenho (RTX 3080, 7B Q4_K_M):

num_batchVazão (tokens/s)Consumo de VRAM
512455,2 GB
1024726,1 GB
2048987,4 GB

Ao aumentar num_batch de 512 para 1024, a vazão cresce 60%, enquanto o consumo adicional fica abaixo de 1 GB. É uma troca bastante vantajosa.

3. Ajuste de memória — três estratégias para resolver OOM

3.1 Como funciona a alocação de memória da GPU

O gerenciamento de memória da GPU no Ollama é bastante inteligente. Ele verifica automaticamente:

  1. Se há VRAM suficiente para carregar o modelo
  2. Em caso positivo, carrega tudo na GPU
  3. Caso contrário, faz offload automático de parte das camadas para a CPU

Mas ser “inteligente” não significa ser perfeito. Às vezes a estimativa falha, ou um caso limítrofe não é bem tratado, causando OOM.

O parâmetro principal é num_gpu, que controla quantas camadas do modelo ficam na GPU. O padrão -1 significa detecção automática. Você pode informar um número manualmente: num_gpu: 20, por exemplo, coloca apenas as primeiras 20 camadas na GPU e deixa as demais para a CPU.

3.2 Estratégia 1: reduzir a quantização

Esta é a solução mais simples e direta. Ocorreu OOM? Troque para uma quantização menor.

Ordem de redução:

Q8_0 → Q5_K_M → Q4_K_M → Q4_0

Cada redução economiza aproximadamente 20% a 25% de VRAM.

Por exemplo, um modelo 14B em Q5_K_M exige 11 GB de VRAM e falha com OOM. Em Q4_K_M, ele precisa de apenas 9 GB. O consumo cai 18%; e a perda de qualidade? Na prática, ela é difícil de perceber em conversas cotidianas.

Já rodei um 7B Q4_K_M em 8 GB de VRAM sem problemas. Para usar um 14B, Q4_K_M ficava no limite e contextos maiores causavam OOM. O compromisso foi rodar o 14B em Q4_0: a qualidade caiu um pouco, mas o modelo funcionou.

3.3 Estratégia 2: inferência híbrida com offload para CPU

A VRAM ainda não é suficiente? Deixe a CPU assumir parte do trabalho.

O parâmetro num_gpu controla o número de camadas na GPU. Em um modelo com 32 camadas, por exemplo, num_gpu: 24 faz com que as oito últimas sejam processadas na CPU.

O custo é a velocidade. A inferência em CPU é mais de dez vezes mais lenta do que em GPU. Mesmo assim, ainda é melhor do que não conseguir iniciar o modelo por causa de OOM.

Configuração:

# Modelfile
FROM llama3
PARAMETER num_gpu 24

Ou pela API:

curl http://localhost:11434/api/generate -d '{
  "model": "llama3",
  "prompt": "Olá",
  "options": {
    "num_gpu": 24
  }
}'

Referência de velocidade da inferência híbrida (14B Q4_K_M, RTX 3080 10 GB + i7-12700K):

num_gpuVelocidade de inferênciaConsumo de VRAM
40 (tudo na GPU)OOM12 GB (estouro)
3018 tokens/s9,2 GB
2012 tokens/s6,5 GB
0 (somente CPU)4 tokens/s0,5 GB

Com num_gpu=30, a velocidade continua aceitável sem estourar a VRAM. Esse é o valor da inferência híbrida.

3.4 Estratégia 3: otimizar o KV Cache

O KV Cache costuma ser ignorado, mas pode consumir uma grande parcela da VRAM.

Método 1: ativar Flash Attention

Flash Attention é uma forma otimizada de calcular a atenção que reduz significativamente o consumo de VRAM.

# Definir a variável de ambiente
export OLLAMA_FLASH_ATTENTION=1

# Ou iniciar pelo Docker
docker run -e OLLAMA_FLASH_ATTENTION=1 ollama/ollama

Resultado: o consumo de VRAM do KV Cache cai de 30% a 50%. É altamente recomendável ativá-lo.

Método 2: reduzir num_ctx

Quanto maior o contexto, maior o KV Cache. Se você não precisa de um contexto de 32K, use um valor menor.

PARAMETER num_ctx 2048  # O padrão 2048 é suficiente para conversas cotidianas

Método 3: preservar o prompt do sistema com num_keep

O parâmetro num_keep controla quantos tokens são preservados durante o corte do contexto. Ajuste-o ao tamanho do prompt do sistema para impedir que esse prompt seja descartado quando a janela deslizar.

PARAMETER num_keep 128

3.5 Fluxo prático para resolver OOM

Ao encontrar um erro de OOM, siga este fluxo:

Etapa 1: verifique o consumo de VRAM

nvidia-smi

Confira quanta VRAM está em uso e quanto ainda está disponível.

Etapa 2: verifique os parâmetros do modelo

ollama show llama3 --modelfile

Veja se parâmetros como num_ctx e num_batch estão altos demais.

Etapa 3: reduza os valores gradualmente

  • Primeiro, reduza num_batch: 1024 → 512
  • Depois, reduza num_ctx: 4096 → 2048
  • Por fim, reduza a quantização: Q5_K_M → Q4_K_M

Etapa 4: ative o offload para CPU
Defina num_gpu como 70% a 80% do total de camadas.

Etapa 5: último recurso — inferência somente em CPU
Se a VRAM realmente não for suficiente, resta usar apenas a CPU. É mais lento, mas funciona.

# Forçar o uso apenas da CPU com num_gpu=0 (API ou Modelfile)
curl http://localhost:11434/api/generate -d '{"model":"llama3","prompt":"Olá","options":{"num_gpu":0}}'

Na prática, a inferência somente em CPU chega a aproximadamente um décimo da velocidade da GPU. Ainda pode ser aceitável para uso ocasional ou tarefas em lote.

4. Benchmarks e referência de hardware

4.1 Velocidade de inferência em diferentes hardwares

Reuni dados de velocidade de inferência em diferentes configurações de hardware para você comparar com seu ambiente:

Placas NVIDIA (modelo 7B Q4_K_M)

Modelo da GPUVRAMtokens/sObservação
RTX 306012 GB52Excelente custo-benefício
RTX 308010 GB68Escolha estável
RTX 309024 GB95Roda 14B Q4
RTX 4070 Ti12 GB78Vantagem da arquitetura mais recente
RTX 409024 GB120Configuração de ponta

Placas NVIDIA (modelo 14B Q4_K_M)

Modelo da GPUVRAMtokens/sObservação
RTX 306012 GB28Funciona no limite
RTX 308010 GBOOMExige offload para CPU
RTX 309024 GB55Funciona com folga
RTX 409024 GB72Muito rápido

Apple Silicon (aceleração Metal)

Modelo do dispositivoMemória7B tokens/s14B tokens/s
M2 Air 8 GB8 GB35OOM
M2 Pro 16 GB16 GB4822
M2 Max 32 GB32 GB5832
M2 Ultra 64 GB64 GB6545

A vantagem do Apple Silicon é a memória unificada, que oferece um espaço maior equivalente à VRAM. Porém, seu desempenho por núcleo fica abaixo do de GPUs de ponta.

Inferência somente em CPU

Modelo da CPUMemória7B tokens/s14B tokens/s
i7-12700K32 GB63
Ryzen 9 7950X64 GB84
M2 Max (somente CPU)32 GB126

Funciona, mas é lento. É adequado para tarefas em lote, não para conversas em tempo real.

4.2 Ganho de vazão com processamento em lotes

Esta tabela mostra como diferentes valores de num_batch afetam a vazão:

Ambiente de teste: RTX 3080, 7B Q4_K_M, várias solicitações simultâneas

num_batchLatência por solicitaçãoVazão simultâneaConsumo de VRAM
51222 ms/token45 tokens/s5,2 GB
102422 ms/token72 tokens/s6,1 GB
204822 ms/token98 tokens/s7,4 GB

Principais conclusões:

  • A latência de uma única solicitação praticamente não muda: o processamento em lotes não afeta a velocidade de resposta de uma solicitação isolada
  • A vazão mais do que dobra: em cenários simultâneos, num_batch=2048 entrega 118% mais vazão que 512
  • O custo de VRAM é controlável: para aumentar a vazão em 118%, são usados apenas 2,2 GB adicionais de VRAM

4.3 Resumo das variáveis de ambiente

Estas são algumas das variáveis de ambiente mais úteis aceitas pelo Ollama:

# Flash Attention (altamente recomendado; combinado à quantização do KV Cache, economiza bastante VRAM)
export OLLAMA_FLASH_ATTENTION=1

# Quantização do KV Cache: f16 (padrão)/q8_0 (economiza cerca da metade)/q4_0 (economiza cerca de três quartos); exige Flash Attention
export OLLAMA_KV_CACHE_TYPE=q8_0

# Reservar VRAM para o sistema e outros programas (em bytes; padrão 0)
export OLLAMA_GPU_OVERHEAD=1073741824  # Reservar 1 GB

# Tamanho padrão do contexto (substitui o valor padrão do modelo)
export OLLAMA_CONTEXT_LENGTH=4096

# Tempo de permanência do modelo na memória (padrão de 5 minutos)
export OLLAMA_KEEP_ALIVE=24h

# Limite de solicitações na fila
export OLLAMA_MAX_QUEUE=512

# Nível de log
export OLLAMA_DEBUG=1

Exemplo completo de configuração do Docker Compose:

version: '3'
services:
  ollama:
    image: ollama/ollama
    container_name: ollama
    restart: unless-stopped
    environment:
      - OLLAMA_FLASH_ATTENTION=1
      - OLLAMA_KEEP_ALIVE=24h
      - OLLAMA_MAX_QUEUE=512
    volumes:
      - ollama_data:/root/.ollama
    ports:
      - "11434:11434"
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities: [gpu]

volumes:
  ollama_data:

Salve a configuração acima como docker-compose.yml e execute:

docker-compose up -d

Leituras relacionadas

Conclusão

Depois de todos esses detalhes, o processo de otimização pode ser resumido em três etapas:

Primeira etapa: escolha a quantização
Confira primeiro a quantidade de VRAM e selecione uma versão adequada. Q4_K_M oferece o melhor custo-benefício e é suficiente na maioria dos casos. Considere Q5_K_M apenas se houver memória de sobra.

Segunda etapa: ajuste o lote
Há folga de VRAM? Aumente num_batch para 1024 ou até 2048. A vazão pode dobrar, ao custo de um pouco mais de memória.

Terceira etapa: resolva o OOM
Ainda não foi suficiente? Ative Flash Attention, reduza num_ctx ou use offload para CPU. Testando nessa ordem, você encontrará um ponto de equilíbrio.

Otimização de desempenho não se resolve de uma vez. Hardware, tamanho do modelo e cenário de uso variam, portanto os ajustes precisam ser graduais. Recomendo começar pela quantização, confirmar que o modelo funciona, ajustar os parâmetros de lote e só então mexer nas variáveis de ambiente mais avançadas.

Se você encontrar um problema específico — por exemplo, como configurar determinado modelo ou resolver certo erro — consulte a documentação oficial do Ollama. A comunidade também reúne experiências práticas que muitas vezes são mais úteis do que uma explicação apenas teórica.

15 min de leitura · Publicado em: 10 abr 2026 · Atualizado em: 8 set 2026

Comentários

Entre com GitHub para comentar

Easton BlogEaston Blog