llama.swap: Guia Rápido do Alternador de Modelos para LLMs Locais Compatíveis com OpenAI

Substitua LLMs locais via hot-swap sem alterar os clientes.

Conteúdo da página

Em breve você estará equilibrando vLLM, llama.cpp e mais — cada pilha em sua própria porta. Tudo a jusante ainda deseja uma URL base única /v1; caso contrário, você continua mudando portas, perfis e scripts pontuais. llama-swap é o proxy /v1 antes dessas pilhas.

llama-swap oferece uma porta de entrada única compatível com OpenAI e Anthropic, com um arquivo YAML que mapeia cada nome de modelo para o comando que inicia o upstream correto. Solicite um modelo e o proxy inicia ou troca para ele; configure TTLs e grupos quando a VRAM estiver limitada ou vários modelos devam coexistir. Este guia cobre caminhos de instalação, um config.yaml prático, a superfície HTTP e os modos de falha que aparecem assim que o streaming e os proxies reversos entram em cena.

llama swap llm infographic Para uma comparação mais ampla das opções de hospedagem de LLM, veja LLM Hosting in 2026: Local, Self-Hosted & Cloud Infrastructure Compared

Visão geral do alternador de modelos llama-swap para APIs locais de LLM compatíveis com OpenAI

llama-swap é um servidor proxy leve construído em torno de um modelo operacional simples: um binário, um arquivo de configuração YAML, sem dependências. Ele é escrito em Go, o que significa um único binário estático ao lado do resto da pilha — sem necessidade de runtime Python ou aplicativo de desktop. Ele fica na frente de qualquer upstream compatível com OpenAI e Anthropic como a camada de troca de modelos.

Conceitualmente, isso responde a uma pergunta muito prática que surge em pilhas locais de LLM:

Como mudo de modelo com um cliente compatível com OpenAI?
Com llama-swap você continua usando solicitações normais /v1/..., mas muda o modelo que solicita. O llama-swap lê esse valor de modelo, carrega a configuração do servidor correspondente e, se o upstream “errado” estiver rodando, ele o troca pelo correto.

Alguns detalhes de design importam para configurações de produção:

llama-swap é licenciado MIT com nenhuma telemetria — ainda vale a pena confirmar para qualquer host que veja prompts reais.
Ele é construído para carregar backends sob demanda como llama.cpp, vLLM, Whisper e stable-diffusion.cpp, não para travá-lo em um único motor de inferência.
De fábrica (sem agrupamento especial), ele executa um modelo por vez: solicite um modelo diferente e ele para o upstream atual e inicia o correto. Para mais de um modelo residente ou controle mais fino sobre a coexistência, configure groups.

Aqui está o modelo mental que a maioria dos desenvolvedores encontra útil:

flowchart LR
  C[Seu app ou SDK\nCliente compatível com OpenAI] -->|/v1/chat/completions\nmodel = qwen-coder| LS[llama-swap proxy\nendpoint único]
  LS -->|inicia ou roteia para| U1[Upstream server A\nllama-server]
  LS -->|inicia ou roteia para| U2[Upstream server B\nvLLM OpenAI server]
  LS --> M[Endpoints de gerenciamento\nrodando, descarregar, eventos, métricas]

Isso também é por que um proxy alternador de modelos é diferente de “apenas executar um modelo”: é orquestração e roteamento sobre um ou mais servidores de inferência.

llama-swap vs Ollama vs LM Studio vs servidor llama.cpp

Todas as quatro opções podem fornecer uma “API de LLM local”, mas elas otimizam para fluxos de trabalho diferentes. A maneira mais rápida de escolher é decidir se você quer um runtime (baixar modelo + execução) ou um roteador/proxy (troca + orquestração entre runtimes).

llama-swap
O llama-swap foca em ser um proxy transparente que suporta endpoints compatíveis com OpenAI (incluindo /v1/chat/completions, /v1/completions, /v1/embeddings e /v1/models) e roteia solicitações para o upstream correto com base no modelo solicitado. Ele também fornece endpoints operacionais não relacionados à inferência, como /running, /logs/stream e uma Interface Web em /ui.

Ollama
O Ollama expõe sua própria API HTTP (POST /api/chat, POST /api/generate e o local padrão usual na porta 11434).
keep_alive controla por quanto tempo um modelo permanece carregado, incluindo 0 para descarregar imediatamente.
Ele se adapta a usuários que querem baixar um modelo e conversar com fiação mínima. llama-swap se adapta a comandos por modelo, backends mistos e uma URL formatada como OpenAI para cada cliente — orquestrar vLLM ao lado de llama-server com flags diferentes por modelo está fora do que o Ollama visa.

LM Studio
O LM Studio é um aplicativo de desktop com um servidor de API local na aba Developer (localhost ou LAN), incluindo modos compatíveis com OpenAI e compatíveis com Anthropic, além de lms server start no terminal.
Ele se adequa a um loop primeiro por GUI: navegar modelos, clicar, testar. llama-swap se adequa a um papel estilo servidor: YAML, supervisão de processos, upstreams mistos, sem sessão de desktop.

Servidor llama.cpp
llama-server expõe /v1/completions, /v1/chat/completions, /v1/responses, e o padrão usual é apontar um cliente OpenAI para ele via base_url.
O llama.cpp também inclui um modo roteador: execute llama-server como roteador, --models-dir, depois POST /models/load e POST /models/unload para equilibrar modelos GGUF sem um proxy separado.
Se cada modelo estiver sob um roteador llama.cpp, um proxy extra geralmente não é necessário. Quando llama.cpp deve ficar ao lado do vLLM ou outros servidores formatados como OpenAI, o llama-swap fornece uma superfície /v1 e muitos processos atrás dele.

Para soluções de hospedagem compatíveis com OpenAI semelhantes, veja LocalAI QuickStart: Run OpenAI-Compatible LLMs Locally ou SGLang QuickStart: Install, Configure, and Serve LLMs via OpenAI API

Instale o alternador de modelos llama-swap com Docker, Homebrew, WinGet ou binários

Linux, macOS e Windows são todos de primeira classe: Docker, Homebrew, WinGet, binários do GitHub ou construir do código-fonte. Escolhas comuns: Docker em servidores headless, Homebrew ou WinGet em estações de trabalho, binários autônomos quando a pegada de instalação deve permanecer mínima.

Instalação Docker

Puxe uma imagem que corresponda ao seu hardware. As imagens acompanham de perto o upstream (compilações noturnas) e cobrem CUDA, Vulkan, Intel, MUSA e CPU — escolha a que corresponde a como você realmente acelera, não “latest” por hábito.

# Exemplo de puxadas de plataforma
docker pull ghcr.io/mostlygeek/llama-swap:cuda
docker pull ghcr.io/mostlygeek/llama-swap:vulkan
docker pull ghcr.io/mostlygeek/llama-swap:intel
docker pull ghcr.io/mostlygeek/llama-swap:musa
docker pull ghcr.io/mostlygeek/llama-swap:cpu

Prefira as variantes de imagem não-root quando puder: menos para se arrepender se o limite do container estiver errado.

Instalação Homebrew

No macOS e Linux, use o tap e instale:

brew tap mostlygeek/llama-swap
brew install llama-swap
llama-swap --config path/to/config.yaml --listen localhost:8080

Instalação WinGet

No Windows:

winget install llama-swap
winget upgrade llama-swap

Binários pré-construídos e lançamentos

O GitHub Releases oferece binários Linux, macOS, Windows e FreeBSD se você não quiser um gerenciador de pacotes.
Os números de lançamento mudam rápido (por exemplo v198, v197 no início de 2026) — fixe uma versão na automação em vez de flutuar “o que lá estava ontem”.

Configure llama-swap com config.yaml para troca de modelos, TTL e grupos

Tudo no llama-swap é impulsionado por configuração. A configuração mínima viável é simplesmente um dicionário models: e um cmd para cada modelo, frequentemente iniciando llama-server com ${PORT} substituído por modelo.

O sistema de configuração vai muito além de apenas “iniciar um processo”, e algumas opções valem a pena entender cedo porque elas respondem diretamente a problemas comuns de estilo FAQ (descarregamento automático, segurança e clientes que dependem de /v1/models).

Configurações globais que você realmente usará

healthCheckTimeout é quanto tempo o llama-swap aguarda um modelo se tornar saudável após a inicialização (padrão 120s, mínimo 15s). Para cargas de vários GB em discos lentos, aumente isso antes de culpar o proxy.
globalTTL é segundos ociosos antes do descarregamento automático; padrão 0 significa “nunca descarregar” a menos que você defina — escolha explicitamente TTLs para qualquer coisa além de uma configuração de brinquedo para que a VRAM não encha de modelos esquecidos.
startPort semeia o macro ${PORT} (padrão 5800); a atribuição é determinística por ID de modelo alfabético, o que é um recurso quando você depura “quem pegou qual porta” e uma armadilha se você renomear modelos descuidadamente.
includeAliasesInList decide se aliases aparecem como linhas separadas em /v1/models; ative se sua UI só oferece modelos enumerados.
apiKeys protege qualquer coisa acessível fora do localhost: Basic, Bearer ou x-api-key. O llama-swap remove esses cabeçalhos antes de encaminhar para que os logs upstream tenham menos chance de reter segredos do cliente.

Configurações de nível de modelo que desbloqueiam ergonomia de produção

Por modelo, cmd é o único campo obrigatório.
proxy padrão é http://localhost:${PORT} — esse é o alvo de encaminhamento para o upstream desse modelo.
checkEndpoint padrão é /health; defina "none" quando o backend não tiver rota de saúde ou inicialização a frio exceder o que você está disposto a aguardar — não deixe um /health quebrado e se pergunte por que nada chega a ready.
ttl: -1 herda globalTTL, 0 nunca descarrega, N > 0 descarrega após N segundos de ociosidade — use TTL por modelo quando um modelo deve permanecer e outro deve desaparecer rapidamente.
aliases e useModelName mantêm nomes estáveis voltados para o cliente enquanto satisfazem upstreams que exigem um identificador específico.
cmdStop é não opcional para containers: mapeie para docker stop (ou equivalente); sem ele você obtém POSIX SIGTERM / Windows taskkill contra qualquer PID que o llama-swap iniciou — bom para um binário cru, errado para um nome de container.
concurrencyLimit limita solicitações paralelas por modelo com HTTP 429 quando excedido — defina quando você preferisse descartar carga em vez de enfileirar para sempre.

groups cobrem coexistência (swap, exclusive) e modelos sempre ativos (persistent). Hooks podem pré-carregar na inicialização; se você pré-carregar vários modelos de uma vez sem um grupo, espere que eles lute — defina um grupo primeiro para que o pré-carregamento corresponda a como você quer que os modelos compartilhem a GPU.

Exemplo mínimo de config.yaml para llama.cpp e vLLM

Este exemplo visa ser “apenas o suficiente” para ilustrar controles de melhores práticas: um TTL padrão, verificação de saúde explícita, aliases estáveis e um grupo que mantém um modelo pequeno “sempre ativo” rodando enquanto modelos de chat maiores trocam.

# config.yaml
healthCheckTimeout: 180
globalTTL: 900            # 15 minutos de ociosidade então descarregar
includeAliasesInList: true
startPort: 5800

# Opcional mas recomendado para qualquer coisa além de desenvolvimento localhost
apiKeys:
  - "${env.LLAMASWAP_API_KEY}"

models:
  llama-chat:
    cmd: |
      llama-server --port ${PORT} --model /models/llama-chat.gguf
      --ctx-size 8192      
    aliases:
      - "llama-chat-latest"
    # Usa padrões:
    # proxy: http://localhost:${PORT}
    # checkEndpoint: /health
    # ttl: -1 (herdar globalTTL)

  qwen-coder:
    cmd: |
      llama-server --port ${PORT} --model /models/qwen-coder.gguf
      --ctx-size 8192      
    aliases:
      - "qwen-coder-latest"

  vllm-coder:
    # Padrão ilustrativo: gerenciar um servidor compatível com OpenAI containerizado
    proxy: "http://127.0.0.1:${PORT}"
    cmd: |
      docker run --name ${MODEL_ID} --init --rm -p ${PORT}:8000 vllm/vllm-openai:latest      
    cmdStop: docker stop ${MODEL_ID}
    checkEndpoint: "none"
    ttl: 0                 # nunca descarregar automaticamente (ex. manter na GPU)

groups:
  chat-models:
    swap: true
    exclusive: true
    members: ["llama-chat", "qwen-coder"]

  always-on:
    persistent: true
    swap: false
    exclusive: false
    members: ["vllm-coder"]

Nada disso é decorativo: cmd impulsiona o processo, proxy/checkEndpoint/ttl controlam roteamento e ciclo de vida, cmdStop é o que faz upstreams baseados em Docker realmente pararem, e groups são o que separam “um modelo grande por vez” de “estes dois modelos de chat podem coexistir enquanto o servidor de embeddings permanece fixo”.

Execute e troque modelos via endpoints compatíveis com OpenAI

Uma vez que o llama-swap esteja rodando, você interage com ele como qualquer outro endpoint compatível com OpenAI. A superfície da API inclui endpoints principais como /v1/chat/completions, /v1/completions, /v1/embeddings e /v1/models, e o llama-swap usa o modelo solicitado para decidir qual upstream executar e rotear para.

Um fluxo de início rápido prático:

# 1) Iniciar llama-swap
llama-swap --config ./config.yaml --listen localhost:8080
# 2) Descobrir modelos disponíveis
curl http://localhost:8080/v1/models

A listagem de modelos é um recurso de gerenciamento de primeira classe e inclui comportamento como ordenação por ID, exclusão de modelos unlisted e opcionalmente inclusão de aliases.

# 3) Fazer uma solicitação de conclusão de chat para um modelo específico
curl http://localhost:8080/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer ${LLAMASWAP_API_KEY}" \
  -d '{
    "model": "qwen-coder",
    "messages": [{"role":"user","content":"Write a TypeScript function that retries fetch with backoff."}]
  }'

Se você agora repetir a chamada com "model": "llama-chat", o llama-swap trocará processos upstream (a menos que sua configuração de grupo permita que eles coexistam) porque ele extrai o modelo solicitado da solicitação e carrega a configuração do servidor apropriada.

Se você estiver usando um SDK, aponte o cliente para http://localhost:8080/v1 — mesmo truque que mirar a biblioteca Python OpenAI no llama-server, exceto que a URL estável agora é llama-swap e o campo model escolhe o upstream.

from openai import OpenAI

client = OpenAI(
    base_url="http://localhost:8080/v1",
    api_key="sk-your-llamaswap-key"
)

resp = client.chat.completions.create(
    model="qwen-coder",
    messages=[{"role": "user", "content": "Explain the difference between mutexes and semaphores."}],
)
print(resp.choices[0].message.content)

Para aquecer um modelo antes da primeira solicitação real (ocultar latência de inicialização a frio), use /upstream/<model> — ele carrega automaticamente se necessário e encaminha diretamente para aquele upstream. Maneira direta de garantir que os pesos estejam residentes antes de um benchmark ou teste scriptado.

Controle e monitore llama-swap via endpoints de API de gerenciamento e eventos SSE

llama-swap não é apenas “um proxy”; ele também expõe endpoints de controle operacional que permitem construir ferramentas em torno do ciclo de vida do modelo e observabilidade.

Verificar o que está rodando
GET /running retorna o estado em tempo de execução para modelos carregados, incluindo valores de estado como ready, starting, stopping, stopped e shutdown.

curl http://localhost:8080/running

Descarregar modelos para liberar VRAM
Para descarregar tudo imediatamente, use o endpoint versionado pela API POST /api/models/unload. Para descarregar um único modelo (por ID ou alias), use POST /api/models/unload/<model>. Um GET /unload legado existe para compatibilidade reversa.

# descarregar tudo
curl -X POST http://localhost:8080/api/models/unload

# descarregar um modelo
curl -X POST http://localhost:8080/api/models/unload/qwen-coder

Use estes endpoints quando a VRAM for necessária de volta agora em vez de aguardar o TTL — benchmarks, trocas rápidas de modelo ou após carregar um checkpoint muito maior do que o pretendido.

Transmitir eventos ao vivo via SSE
GET /api/events estabelece um fluxo Server-Sent Events e é projetado para atualizações em tempo real que incluem mudanças de status do modelo, logs, métricas e contagens de solicitações em trânsito.

curl -N http://localhost:8080/api/events

SSE e streaming de tokens quebram quando qualquer caixa intermediária faz buffer — desabilite buffering no nginx (ou equivalente) para /api/events e /v1/chat/completions. O llama-swap define X-Accel-Buffering: no no SSE; desabilite buffering no proxy também — cabeçalhos não são substitutos para uma configuração de proxy correta.

Métricas e capturas de solicitação
GET /api/metrics retorna métricas de uso de tokens, com retenção em memória controlada por metricsMaxInMemory (padrão 1000).
GET /api/captures/<id> pode recuperar capturas completas de solicitação/resposta, mas apenas quando captureBuffer > 0 estiver configurado.

Logs e Interface Web

llama-swap expõe /ui para uma interface web e endpoints de log operacional como /logs e /logs/stream para monitoramento em tempo real.

llama-swap web UI for switching models

Se você habilitar apiKeys, assuma defesa em profundidade: /health e partes de /ui permanecem acessíveis sem uma chave — bom para limites de confiança locais, não bom se o host estiver em uma rede compartilhada. Coloque o llama-swap atrás de algo que force sua política real; a autenticação embutida é para manter clientes casuais honestos, não para uma API pública multi-inquilino.

Solução de problemas de alternância de modelos llama-swap em produção

A maioria dos problemas do llama-swap cai em um pequeno conjunto de categorias operacionais: streaming através de um proxy reverso, verificações de saúde durante inicializações a frio, portas e ciclo de vida de processos e autenticação.

Streaming quebra atrás do nginx ou outro proxy reverso
O nginx fará felizmente buffer de seus SSE e conclusões transmitidas. Desabilite proxy_buffering (e proxy_cache) para /api/events e /v1/chat/completions. O llama-swap emite X-Accel-Buffering: no no SSE, o que ajuda — corrija o proxy de qualquer forma.

Um modelo nunca fica pronto
Por padrão, checkEndpoint por modelo é /health e deve retornar HTTP 200 para o processo ser considerado pronto. Você pode definir checkEndpoint para outro caminho ou para "none" para desabilitar verificações de saúde completamente.
Se modelos grandes levam mais tempo para carregar, aumente healthCheckTimeout (padrão 120s), ou use verificações de saúde personalizadas para seu upstream específico.

Alternar modelos deixa um container antigo rodando
Se o upstream for Docker ou Podman, defina cmdStop — caso contrário, o llama-swap para o processo wrapper enquanto o container continua consumindo VRAM em segundo plano.

Recebo respostas 401 após habilitar segurança
Quando apiKeys está configurado, o llama-swap exige uma chave válida e aceita três métodos (autenticação Basic, token Bearer, x-api-key). Ele também remove cabeçalhos de autenticação antes de encaminhar upstream.

Recebo 429 Too Many Requests
concurrencyLimit retorna 429 quando excedido — por design. Aumente o limite se você subdimensionou, ou diminua o limite se você não pretendia limitar.

Conflitos de porta ou problemas de roteamento estranhos
Evite portas codificadas em cmd; use ${PORT} e mova startPort se 5800+ colidir com outra coisa. Lembre-se que portas são atribuídas em ordem alfabética por ID de modelo — renomeie um modelo e o mapeamento de porta muda.

Lista de verificação de depuração operacional
/running para verdade, /logs/stream quando a inicialização é opaca, POST /api/models/unload quando a VRAM é necessária de volta agora. Essa tríade cobre a maioria das sessões “por que a GPU está cheia”.