Seu laptop pode servir um modelo de 70 bilhões de parâmetros atrás do mesmo endpoint no formato OpenAI usado em produção. Na prática, você troca apenas a URL base e mantém o mesmo SDK, payload e fluxo de testes. Isso permite desenvolvimento offline, custo zero por token em ambiente local e um caminho mais privado para dados sensíveis. Este guia mostra como escolher um runtime, expor um endpoint compatível com OpenAI, apontar seu cliente para ele e validar tudo com Apidog antes de promover alterações para um modelo hospedado.
TL;DR
Você pode executar uma API LLM local com Ollama, vLLM ou llama.cpp. Todos conseguem expor um endpoint REST compatível com OpenAI.
O padrão é simples:
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:11434/v1",
api_key="ollama",
)
Com essa troca, o mesmo código que chama https://api.openai.com/v1 pode chamar Llama 3.3, DeepSeek V4 ou Qwen 3.6 localmente. Use ambientes no Apidog para manter os mesmos testes de cenário contra targets locais e hospedados.
Introdução
A pilha de API LLM local deixou de ser apenas experimento. Hoje, os principais runtimes conseguem expor endpoints no formato /v1/chat/completions, compatível com OpenAI. Isso muda a implementação: você não precisa manter dois clientes, dois contratos ou dois fluxos de autenticação.
Para desenvolvedores de API, o ganho está na substituição de configuração, não na reescrita de código.
Exemplo de variável de ambiente:
# local
LLM_BASE_URL=http://localhost:11434/v1
LLM_API_KEY=ollama
# produção
LLM_BASE_URL=https://api.openai.com/v1
LLM_API_KEY=$OPENAI_API_KEY
Se seus modelos de requisição no Apidog hoje apontam para https://api.openai.com/v1/chat/completions, substitua o host por {{BASE_URL}}. Depois, execute o mesmo cenário contra Local e Production.
Se você já rastreia gastos com API por recurso, também pode comparar custo, latência e qualidade entre um modelo local e um hospedado.
Este guia cobre:
- escolha do runtime;
- configuração do servidor local;
- conexão via SDK OpenAI;
- testes de cenário com Apidog;
- trade-offs de quantização;
- comparação de custo e latência.
Para uma visão geral de modelos, consulte Melhores LLMs locais 2026.
Por que LLMs locais fazem sentido para desenvolvedores de API
Você provavelmente depura código que chama LLMs em ambientes imperfeitos: avião, conferência com Wi-Fi ruim, rede corporativa bloqueando saída para *.openai.com ou infraestrutura de cliente sem acesso público. Uma API LLM local resolve esse problema porque espelha o contrato de produção sem depender de rede externa.
Os principais motivos são:
Desenvolvimento offline
Você mantém o ciclo de build, teste e depuração mesmo sem conexão.Privacidade
Prompts podem conter dados regulados: notas clínicas, contratos, identificadores, números de conta ou dados internos. Rodar localmente evita enviar esse conteúdo para um endpoint externo durante desenvolvimento.Custo
Testes, fixtures, geração de dados e pipelines internos podem consumir milhões de tokens. Localmente, o custo marginal por token tende a zero depois que o hardware está disponível.Estabilidade
Um modelo local é um arquivo em disco. Você controla quando atualizar pesos, tags e quantização. Isso ajuda em suítes de regressão que dependem de comportamento estável.
A parte importante: como o endpoint é compatível com OpenAI, o SDK que você já usa continua funcionando.
Três runtimes que entregam endpoints compatíveis com OpenAI
Quatro runtimes dominam o espaço local. Três entregam servidor REST compatível com OpenAI diretamente; o llama.cpp entrega isso via llama-server.
Escolha pela carga de trabalho:
- Ollama: melhor ponto de entrada para laptop e desenvolvimento individual.
- vLLM: melhor para throughput e clusters de desenvolvimento.
- llama.cpp: melhor para controle fino, quantização e hardware variado.
- LM Studio/Jan: úteis para times que preferem GUI, normalmente usando llama.cpp por baixo.
Ollama
Ollama é o caminho mais rápido para subir uma API LLM local. Ele baixa modelos, gerencia quantização GGUF, aplica templates de prompt e expõe HTTP na porta 11434.
Instalação no macOS:
brew install ollama
ollama serve &
ollama pull llama3.3:70b-instruct-q4_K_M
ollama run llama3.3:70b-instruct-q4_K_M
Endpoint compatível com OpenAI:
http://localhost:11434/v1
Teste rápido com curl:
curl http://localhost:11434/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ollama" \
-d '{
"model": "llama3.3:70b-instruct-q4_K_M",
"messages": [
{ "role": "user", "content": "Responda apenas OK." }
]
}'
Use Ollama quando você precisa de:
- setup rápido;
- desenvolvimento local;
- demos;
- runners de CI simples;
- testes de contrato sem custo por token.
vLLM
vLLM é voltado para throughput. Ele usa PagedAttention e batching contínuo para servir muitas requisições concorrentes com maior eficiência.
Instalação e servidor:
pip install vllm
vllm serve meta-llama/Llama-3.3-70B-Instruct \
--port 8000 \
--gpu-memory-utilization 0.9 \
--max-model-len 8192
Endpoint:
http://localhost:8000/v1
Se quiser exigir autenticação:
vllm serve meta-llama/Llama-3.3-70B-Instruct \
--port 8000 \
--api-key dev-secret
Cliente:
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:8000/v1",
api_key="dev-secret",
)
Use vLLM quando você precisa de:
- concorrência;
- batching;
- GPU CUDA ou ROCm;
- ambiente compartilhado para vários devs;
- testes mais próximos de produção.
Ele não é a melhor opção para Apple Silicon.
llama.cpp
llama.cpp é o runtime C++ que popularizou o ecossistema GGUF. Ele roda em muitos tipos de hardware e oferece controle detalhado de quantização, offload para GPU, contexto e uso de memória.
Build com Metal no macOS:
git clone https://github.com/ggerganov/llama.cpp
cd llama.cpp
make -j LLAMA_METAL=1
Servidor compatível com OpenAI:
./llama-server \
-m models/llama-3.3-70b-q4_k_m.gguf \
--port 8080 \
--host 0.0.0.0 \
-c 8192 \
-ngl 99
Endpoint:
http://localhost:8080/v1/chat/completions
A flag -ngl 99 tenta descarregar o máximo de camadas possível para a GPU.
Use llama.cpp quando você precisa de:
- rodar em hardware limitado;
- controlar quantização;
- ajustar memória e contexto;
- testar modelos GGUF específicos;
- evitar dependências pesadas.
LM Studio e Jan encapsulam o llama.cpp em uma interface gráfica e também podem expor endpoints compatíveis com OpenAI em portas configuráveis.
Verifique o endpoint com Python
Depois de subir o runtime, valide o contrato usando o SDK OpenAI.
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:11434/v1",
api_key="ollama",
)
resp = client.chat.completions.create(
model="llama3.3:70b-instruct-q4_K_M",
messages=[
{
"role": "user",
"content": "Reply with the word OK only."
}
],
)
print(resp.choices[0].message.content)
Se a saída for OK, você validou:
- runtime ativo;
- porta correta;
- contrato compatível com OpenAI;
- SDK funcionando;
- modelo carregado.
Teste sua LLM local com Apidog
Uma API LLM local só é útil se seus testes conseguirem alternar entre local e produção sem duplicar cenários. No Apidog, faça isso com variáveis de ambiente.
1. Crie o ambiente local
No Apidog, crie um ambiente chamado Local.
Adicione:
BASE_URL=http://localhost:11434/v1
API_KEY=ollama
MODEL=llama3.3:70b-instruct-q4_K_M
2. Crie o ambiente de produção
Clone seu ambiente existente ou crie um novo chamado Production.
Use:
BASE_URL=https://api.openai.com/v1
API_KEY=<sua-chave>
MODEL=<modelo-hospedado>
3. Parametrize a requisição
Configure a URL:
{{BASE_URL}}/chat/completions
Headers:
Authorization: Bearer {{API_KEY}}
Content-Type: application/json
Body:
{
"model": "{{MODEL}}",
"messages": [
{
"role": "system",
"content": "Você é um assistente que responde em JSON."
},
{
"role": "user",
"content": "Retorne {\"status\":\"ok\"}."
}
],
"temperature": 0.2
}
4. Adicione asserções
Crie um cenário com verificações como:
choices[0].message.role == "assistant"
choices[0].message.content is not empty
usage.total_tokens > 0
Essas asserções validam o contrato mínimo da resposta.
5. Execute contra Local e Production
Rode o cenário com o ambiente Local.
Depois, troque para Production e rode novamente.
O objetivo é manter o mesmo cenário verde nos dois destinos. Se uma atualização de runtime, modelo ou provedor mudar o formato da resposta, você detecta antes de quebrar a aplicação.
O mesmo padrão se aplica a testar agentes de IA que chamam APIs multi-etapas.
Alterne targets no SDK OpenAI
Use variáveis de ambiente para evitar URLs hardcoded.
Python
import os
from openai import OpenAI
def get_client():
return OpenAI(
base_url=os.environ.get("LLM_BASE_URL", "https://api.openai.com/v1"),
api_key=os.environ["LLM_API_KEY"],
)
client = get_client()
response = client.chat.completions.create(
model=os.environ.get("LLM_MODEL", "llama3.3:70b-instruct-q4_K_M"),
messages=[
{
"role": "system",
"content": "You are a JSON-only assistant."
},
{
"role": "user",
"content": "Return {\"status\": \"ok\"}."
},
],
response_format={"type": "json_object"},
)
print(response.choices[0].message.content)
Execução local:
export LLM_BASE_URL=http://localhost:11434/v1
export LLM_API_KEY=ollama
export LLM_MODEL=llama3.3:70b-instruct-q4_K_M
python app.py
Execução em produção:
export LLM_BASE_URL=https://api.openai.com/v1
export LLM_API_KEY=$OPENAI_API_KEY
export LLM_MODEL=<modelo-hospedado>
python app.py
JavaScript
import OpenAI from "openai";
const client = new OpenAI({
baseURL: process.env.LLM_BASE_URL || "https://api.openai.com/v1",
apiKey: process.env.LLM_API_KEY,
});
const resp = await client.chat.completions.create({
model: process.env.LLM_MODEL || "llama3.3:70b-instruct-q4_K_M",
messages: [
{
role: "user",
content: "Say hi."
}
],
});
console.log(resp.choices[0].message.content);
Execução local:
LLM_BASE_URL=http://localhost:11434/v1 \
LLM_API_KEY=ollama \
LLM_MODEL=llama3.3:70b-instruct-q4_K_M \
node app.js
Integre os testes ao CI
Depois que o cenário está funcionando no Apidog, você pode usá-lo como smoke test no CI.
Fluxo recomendado:
- Suba o runtime local no job ou use um host interno.
- Exporte as variáveis do ambiente.
- Execute a coleção com
apidog-cli. - Falhe o build se uma asserção quebrar.
Exemplo conceitual no GitHub Actions:
name: llm-contract-tests
on:
pull_request:
jobs:
test-local-llm:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Start Ollama
run: |
curl -fsSL https://ollama.com/install.sh | sh
ollama serve &
sleep 5
ollama pull llama3.3:70b-instruct-q4_K_M
- name: Run Apidog scenarios
run: |
apidog run ./apidog-collection.json \
--env Local
Engenheiros de QA podem integrar o mesmo padrão em pipelines de teste de API.
Técnicas avançadas e dicas profissionais
Escolha a quantização certa
Quantização decide se um modelo cabe no seu hardware.
Formatos GGUF comuns:
| Quantização | Quando usar |
|---|---|
| Q8 | Melhor qualidade, maior uso de RAM/VRAM |
| Q5_K_M | Bom equilíbrio quando há memória suficiente |
| Q4_K_M | Padrão prático para chat local |
| Q3/Q2 | Útil para memória restrita, com perda visível de qualidade |
Regra prática:
- use Q4_K_M para chat e desenvolvimento geral;
- use Q5_K_M se tiver folga de memória;
- use Q8 para geração de código ou tarefas mais sensíveis à qualidade;
- evite Q2 para raciocínio complexo ou contexto longo.
Ajuste offload para GPU
No llama.cpp, use -ngl:
./llama-server -m model.gguf -ngl 99
No Ollama, controle via configuração do modelo quando necessário.
Quanto mais camadas na GPU, maior o throughput. Se a VRAM acabar, reduza o número de camadas ou use uma quantização menor.
Mantenha mmap ativado
O mapeamento de memória (mmap) permite que o sistema operacional carregue pesos sob demanda. Em geral, mantenha ativado.
Só considere desativar se você tem um motivo específico, como isolamento em contêiner com limites rígidos de memória.
Use batching no vLLM
O vLLM ganha eficiência com concorrência.
Exemplo:
vllm serve meta-llama/Llama-3.3-70B-Instruct \
--max-num-seqs 64
Para hardware maior, como H100, aumente:
vllm serve meta-llama/Llama-3.3-70B-Instruct \
--max-num-seqs 256
Ative streaming
Streaming reduz a latência percebida.
Python:
stream = client.chat.completions.create(
model="llama3.3:70b-instruct-q4_K_M",
messages=[{"role": "user", "content": "Explique streaming em uma frase."}],
stream=True,
)
for chunk in stream:
delta = chunk.choices[0].delta.content
if delta:
print(delta, end="")
JavaScript:
const stream = await client.chat.completions.create({
model: process.env.LLM_MODEL,
messages: [{ role: "user", content: "Explique streaming em uma frase." }],
stream: true,
});
for await (const chunk of stream) {
const token = chunk.choices[0]?.delta?.content;
if (token) process.stdout.write(token);
}
Use Modelfile no Ollama
O Modelfile permite encapsular prompt de sistema, temperatura e sequências de parada.
Exemplo:
FROM llama3.3:70b-instruct-q4_K_M
SYSTEM """
Você é um assistente que responde sempre em JSON válido.
"""
PARAMETER temperature 0.2
PARAMETER stop "</json>"
Crie o modelo:
ollama create my-assistant -f Modelfile
Use no cliente:
response = client.chat.completions.create(
model="my-assistant",
messages=[{"role": "user", "content": "Retorne status ok."}],
)
Erros comuns
Evite estes problemas:
- hardcodar
http://localhost:11434no código de produção; - esquecer de configurar
max_tokens; - não definir sequência de parada em fluxos longos;
- rodar dois runtimes na mesma porta;
- ignorar
Authorization, já que Ollama pode aceitar, mas vLLM com--api-keyrejeita; - esperar qualidade de modelo hospedado premium em um modelo local pequeno e quantizado;
- mudar pesos ou quantização sem rodar os testes de cenário;
- comparar latência local e hospedada sem medir TTFT e throughput separadamente.
Local vs. hospedado: custo e latência
Os números abaixo assumem um M3 Max com 128 GB de memória unificada para uso local e preços públicos atuais para endpoints hospedados. O Tempo para o Primeiro Token, ou TTFT, é medido a frio, sem batching, em um prompt de 1.024 tokens.
| Modelo | TTFT Local | Throughput Local | Equivalente Hospedado | Preço Hospedado | TTFT Hospedado |
|---|---|---|---|---|---|
| Llama 3.3 70B Q4_K_M | 1.2 s | 12 tok/s | GPT-5.5 Instant | $5 / $30 per 1M | 200 ms |
| DeepSeek V4 67B Q4_K_M | 1.4 s | 10 tok/s | DeepSeek-Chat hospedado | $0.55 / $2.20 per 1M | 280 ms |
| Qwen 3.6 32B Q5_K_M | 0.7 s | 28 tok/s | Qwen-Max hospedado | $1.60 / $6.40 per 1M | 240 ms |
| Gemma 4 27B Q4_K_M | 0.5 s | 35 tok/s | Gemini 3 Flash | $0.35 / $1.05 per 1M | 180 ms |
A coluna hospedada tende a vencer em latência. A coluna local vence em custo quando o volume diário de tokens é alto e vence em privacidade desde a primeira requisição.
Um padrão prático:
- use local durante desenvolvimento interno;
- use hospedado em staging para validar integração real;
- mantenha ambos os targets verdes no CI;
- escolha o target de produção com base em latência, custo e classificação de dados.
Para benchmarks e guias específicos, consulte Como executar o DeepSeek V4 localmente e o guia de uso original do DeepSeek V4.
Casos de uso no mundo real
Fintech com dados sensíveis
Uma equipe de conformidade em Singapura usa Ollama nos laptops dos engenheiros para redigir relatórios de atividades suspeitas. Os prompts contêm números de conta e padrões de transação que não podem sair do país sob regras locais.
Implementação prática:
- endpoint local recebe o prompt completo;
- endpoint hospedado recebe apenas uma versão redigida;
- cenário no Apidog verifica se a etapa de redação roda antes de qualquer chamada externa.
Estúdio de jogos
Um estúdio em Estocolmo usa uma instância local do Qwen 3.6 para treinar designers em engenharia de prompt.
Benefícios:
- sem custo por token durante treinamento;
- uso offline;
- menor risco de vazamento de narrativa ou assets;
- mesma coleção de testes usada depois contra Gemini 3 Flash em produção.
Eles podem reutilizar o guia da API Gemini 3 Flash para conectar o target hospedado.
Saúde com vLLM em rede privada
Uma startup de saúde executa vLLM em uma A100 dentro da rede hospitalar do cliente. O endpoint não tem DNS público.
Arquitetura:
- vLLM roda em VLAN interna;
- Jenkins executa testes de integração na mesma rede;
- aplicação usa o mesmo SDK OpenAI;
- ambientes locais, internos e hospedados usam o mesmo contrato.
Checklist de implementação
Use esta sequência para colocar uma API LLM local no seu fluxo:
-
Escolha o runtime:
- Ollama para laptop;
- vLLM para concorrência;
- llama.cpp para controle de memória.
-
Suba o servidor:
- Ollama:
http://localhost:11434/v1; - vLLM:
http://localhost:8000/v1; - llama.cpp:
http://localhost:8080/v1.
- Ollama:
Valide com
curlou SDK OpenAI.Mova
base_url,api_keyemodelpara variáveis de ambiente.-
Configure ambientes no Apidog:
-
Local; -
Production.
-
-
Crie asserções mínimas:
- role do assistant;
- conteúdo não vazio;
- tokens usados;
- status HTTP 200.
Rode os mesmos cenários contra os dois ambientes.
Integre ao CI.
Conclusão
A pilha de API LLM local amadureceu o suficiente para entrar no fluxo normal de desenvolvimento. Você pode mover prompts entre um endpoint hospedado e um endpoint local sem reescrever cliente, testes ou CI.
Resumo operacional:
- use Ollama para começar rápido;
- use vLLM quando precisar de throughput;
- use llama.cpp quando memória e quantização forem críticas;
- exponha um endpoint compatível com OpenAI;
- configure
base_urleapi_keypor ambiente; - valide tudo com cenários no Apidog.
Para escolher um modelo, comece com Melhores LLMs locais 2026. Para testar fluxos agentic sobre esses endpoints, leia Como testar a API de agentes de IA.




Top comments (0)