Pular para o conteúdo principal

Documentação oficial desta página · v0.20.6

LLMs Locais no Mac

Este guia mostra passo a passo como rodar um servidor de LLM local no macOS com uma API compatível com a da OpenAI. Você ganha privacidade total, custo zero de API e um desempenho surpreendentemente bom no Apple Silicon.

Cobrimos dois backends:

BackendInstalaçãoMelhor emFormato
llama.cppbrew install llama.cppMenor tempo até o primeiro token, cache KV quantizado para pouca memóriaGGUF
omlxomlx.aiGeração de tokens mais rápida, otimização nativa para MetalMLX (safetensors)

Os dois expõem um endpoint /v1/chat/completions compatível com a OpenAI. O Hermes funciona com qualquer um dos dois — basta apontá-lo para http://localhost:8080 ou http://localhost:8000.

Só Apple Silicon

Este guia é voltado para Macs com Apple Silicon (M1 e posteriores). Macs Intel funcionam com o llama.cpp, mas sem aceleração por GPU — espere um desempenho bem mais lento.


Como escolher um modelo​

Para começar, recomendamos o Qwen3.5-9B — é um modelo forte de raciocínio que cabe folgado em 8 GB ou mais de memória unificada com quantização.

VarianteTamanho em discoRAM necessária (contexto de 128K)Backend
Qwen3.5-9B-Q4_K_M (GGUF)5,3 GB~10 GB com cache KV quantizadollama.cpp
Qwen3.5-9B-mlx-lm-mxfp4 (MLX)~5 GB~12 GBomlx

Regra de bolso para memória: tamanho do modelo + cache KV. Um modelo 9B Q4 tem cerca de 5 GB. O cache KV com contexto de 128K e quantização Q4 acrescenta uns 4 a 5 GB. Com o cache KV padrão (f16), isso infla para cerca de 16 GB. As flags de cache KV quantizado do llama.cpp são o truque decisivo em sistemas com pouca memória.

Para modelos maiores (27B, 35B), você vai precisar de 32 GB ou mais de memória unificada. O 9B é o ponto ideal para máquinas de 8 a 16 GB.


Opção A: llama.cpp​

O llama.cpp é o runtime de LLM local mais portátil. No macOS ele usa Metal para aceleração por GPU sem precisar de configuração.

Instale​

brew install llama.cpp

Isso te dá o comando llama-server globalmente.

Baixe o modelo​

Você precisa de um modelo em formato GGUF. A fonte mais fácil é o Hugging Face pela huggingface-cli:

brew install huggingface-cli

Depois baixe:

huggingface-cli download unsloth/Qwen3.5-9B-GGUF Qwen3.5-9B-Q4_K_M.gguf --local-dir ~/models
Modelos com acesso restrito

Alguns modelos no Hugging Face exigem autenticação. Rode huggingface-cli login antes, se você receber um erro 401 ou 404.

Suba o servidor​

llama-server -m ~/models/Qwen3.5-9B-Q4_K_M.gguf \
-ngl 99 \
-c 131072 \
-np 1 \
-fa on \
--cache-type-k q4_0 \
--cache-type-v q4_0 \
--host 0.0.0.0

O que cada flag faz:

FlagPara que serve
-ngl 99Joga todas as camadas para a GPU (Metal). Use um número alto para garantir que nada fique na CPU.
-c 131072Tamanho da janela de contexto (128K tokens). Reduza se você estiver com pouca memória.
-np 1Número de slots paralelos. Mantenha em 1 para uso individual — mais slots dividem o seu orçamento de memória.
-fa onFlash attention. Reduz o uso de memória e acelera a inferência de contexto longo.
--cache-type-k q4_0Quantiza o cache de chaves em 4 bits. É aqui que a memória é mais economizada.
--cache-type-v q4_0Quantiza o cache de valores em 4 bits. Junto com a opção acima, corta cerca de 75% da memória do cache KV em relação ao f16.
--host 0.0.0.0Escuta em todas as interfaces. Use 127.0.0.1 se você não precisa de acesso pela rede.

O servidor está pronto quando aparece:

main: server is listening on http://0.0.0.0:8080
srv update_slots: all slots are idle

Otimização de memória em sistemas apertados​

As flags --cache-type-k q4_0 --cache-type-v q4_0 são a otimização mais importante em sistemas com memória limitada. Veja o impacto com contexto de 128K:

Tipo de cache KVMemória do cache KV (ctx 128K, modelo 9B)
f16 (padrão)~16 GB
q8_0~8 GB
q4_0~4 GB

Em um Mac de 8 GB, use cache KV q4_0 e escolha um modelo menor que ainda caiba no contexto mínimo de 64K exigido pelo Hermes. Com 16 GB, você consegue usar contexto de 128K com tranquilidade. Com 32 GB ou mais, você pode rodar modelos maiores ou vários slots paralelos.

Se ainda estiver faltando memória, reduza o contexto apenas até o mínimo de 64K do Hermes; abaixo disso, troque para um modelo menor ou uma quantização menor (Q3_K_M em vez de Q4_K_M).

Teste​

curl -s http://localhost:8080/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "Qwen3.5-9B-Q4_K_M.gguf",
"messages": [{"role": "user", "content": "Olá!"}],
"max_tokens": 50
}' | jq .choices[0].message.content

Descubra o nome do modelo​

Se você esquecer o nome do modelo, consulte o endpoint de modelos:

curl -s http://localhost:8080/v1/models | jq '.data[].id'

Opção B: MLX pelo omlx​

O omlx é um aplicativo nativo do macOS que administra e serve modelos MLX. O MLX é o framework de aprendizado de máquina da própria Apple, otimizado especificamente para a arquitetura de memória unificada do Apple Silicon.

Instale​

Baixe e instale em omlx.ai. Ele oferece uma interface gráfica para administrar modelos e um servidor embutido.

Baixe o modelo​

Use o aplicativo omlx para navegar e baixar modelos. Busque por Qwen3.5-9B-mlx-lm-mxfp4 e baixe. Os modelos ficam guardados localmente (normalmente em ~/.omlx/models/).

Suba o servidor​

Por padrão, o omlx serve modelos em http://127.0.0.1:8000. Comece a servir pela interface do aplicativo, ou use a CLI se ela estiver disponível.

Teste​

curl -s http://127.0.0.1:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "Qwen3.5-9B-mlx-lm-mxfp4",
"messages": [{"role": "user", "content": "Olá!"}],
"max_tokens": 50
}' | jq .choices[0].message.content

Liste os modelos disponíveis​

O omlx consegue servir vários modelos ao mesmo tempo:

curl -s http://127.0.0.1:8000/v1/models | jq '.data[].id'

Benchmarks: llama.cpp x MLX​

Os dois backends foram testados na mesma máquina (Apple M5 Max, 128 GB de memória unificada) rodando o mesmo modelo (Qwen3.5-9B) em níveis de quantização comparáveis (Q4_K_M para GGUF, mxfp4 para MLX). Cinco prompts variados, três execuções cada, backends testados em sequência para evitar disputa por recursos.

Resultados​

Métricallama.cpp (Q4_K_M)MLX (mxfp4)Vencedor
TTFT (média)67 ms289 msllama.cpp (4,3x mais rápido)
TTFT (p50)66 ms286 msllama.cpp (4,3x mais rápido)
Geração (média)70 tok/s96 tok/sMLX (37% mais rápido)
Geração (p50)70 tok/s96 tok/sMLX (37% mais rápido)
Tempo total (512 tokens)7,3s5,5sMLX (25% mais rápido)

O que isso significa​

  • O llama.cpp se destaca no processamento do prompt — o pipeline de flash attention + cache KV quantizado entrega o primeiro token em cerca de 66 ms. Se você está construindo aplicações interativas em que a sensação de resposta imediata importa (chatbots, autocompletar), essa é uma vantagem relevante.

  • O MLX gera tokens cerca de 37% mais rápido depois que engata. Para cargas em lote, geração de texto longo ou qualquer tarefa em que o tempo total de conclusão importa mais que a latência inicial, o MLX termina antes.

  • Os dois backends são extremamente consistentes — a variação entre execuções foi desprezível. Você pode confiar nesses números.

Qual deles escolher?​

Caso de usoRecomendação
Chat interativo, ferramentas de baixa latênciallama.cpp
Geração de texto longo, processamento em massaMLX (omlx)
Memória apertada (8 a 16 GB)llama.cpp (o cache KV quantizado não tem rival)
Servir vários modelos ao mesmo tempoomlx (suporte embutido a múltiplos modelos)
Máxima compatibilidade (inclusive Linux)llama.cpp

Conecte ao Hermes​

Com o seu servidor local rodando:

hermes model

Selecione Custom endpoint e siga as perguntas. Ele vai pedir a URL base e o nome do modelo — use os valores do backend que você configurou acima.


Timeouts​

O Hermes detecta automaticamente endpoints locais (localhost, IPs de rede local) e relaxa os seus timeouts de streaming. Na maioria das configurações, não é preciso configurar nada.

Se você ainda topar com erros de timeout (por exemplo, contextos muito grandes em hardware lento), pode sobrescrever o timeout de leitura do stream:

# No seu .env — sobe dos 120s padrão para 30 minutos
HERMES_STREAM_READ_TIMEOUT=1800
TimeoutPadrãoAjuste automático localSobrescrita por variável de ambiente
Leitura do stream (nível de socket)120sSobe para 1800sHERMES_STREAM_READ_TIMEOUT
Detecção de stream travado180sDesligada por completoHERMES_STREAM_STALE_TIMEOUT
Chamada de API (sem streaming)1800sNão precisa mudarHERMES_API_TIMEOUT

O timeout de leitura do stream é o que mais tende a causar problema — é o prazo, no nível do socket, para receber o próximo pedaço de dados. Durante o prefill de contextos grandes, modelos locais podem ficar minutos sem produzir saída enquanto processam o prompt. A detecção automática lida com isso de forma transparente.

Um primeiro turno silencioso costuma ser prefill, não travamento

O Hermes envia o prompt de sistema e os esquemas de ferramentas em toda chamada, então, em hardware mais lento, o primeiro turno pode ter minutos de silêncio enquanto o modelo processa esse prompt antes de gerar qualquer coisa. Isso é o prefill trabalhando, não uma sessão travada. Veja Primeira resposta lenta (prefill) no guia do Ollama para mitigações como manter o modelo carregado e enxugar o prompt fixo com hermes prompt-size.