Início Rápido do Seletor de Modelos llama.swap para LLMs Locais Compatíveis com OpenAI

Troca quente de LLMs locais 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 /v1; caso contrário, você continuará movendo portas, perfis e scripts pontuais. O llama-swap é o proxy /v1 antes dessas pilhas.

O llama-swap fornece uma porta ú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 alterna para ele; configure TTLs e grupos quando a VRAM estiver limitada ou quando 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 quando o streaming e os proxies reversos entram em cena.

llama swap llm infographic Para uma comparação mais ampla de 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

O llama-swap é um servidor proxy leve construído em torno de um modelo operacional simples: um único 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 tempo de execução Python ou aplicativo de desktop necessário. Ele fica na frente de qualquer upstream compatível com OpenAI e Anthropic como a camada de alternância de modelos.

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

Como alternar modelos com um cliente compatível com OpenAI?
Com o llama-swap, você continua usando solicitações normais /v1/..., mas altera 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 substitui pelo correto.

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

O llama-swap tem licença MIT e sem telemetria — ainda vale a pena confirmar para qualquer host que veja prompts reais.
Ele é construído para carregamento sob demanda de backends 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 de cada 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 acha útil:

flowchart LR
  C[Seu app ou SDK\ncliente compatível OpenAI] -->|/v1/chat/completions\nmodel = qwen-coder| LS[proxy llama-swap\nendpoint único]
  LS -->|inicia ou roteia para| U1[Servidor upstream A\nllama-server]
  LS -->|inicia ou roteia para| U2[Servidor upstream B\nservidor vLLM OpenAI]
  LS --> M[endpoints de gerenciamento\nexecutando, descarregar, eventos, métricas]

Isso também é por que um proxy alternador de modelos é diferente de “apenas rodar 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 lhe dar 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 tempo de execução (baixar modelo + executar) ou um roteador/proxy (alternar + orquestrar entre tempos de execução).

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 adequa a usuários que querem baixar um modelo e conversar com fiação mínima. O llama-swap se adequa a comandos por modelo, backends mistos e uma URL formatada 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 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 ciclo primeiro por GUI: navegar por modelos, clicar, testar. O llama-swap se adequa a um papel estilo servidor: YAML, supervisão de processos, upstreams mistos, sem sessão de desktop.

servidor llama.cpp
O 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 fornece 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. Para um guia de configuração completo, veja llama-server router mode: dynamic model switching without restarts.
Se cada modelo ficar sob um roteador llama.cpp, um proxy extra muitas vezes é desnecessário. Quando o llama.cpp deve ficar ao lado do vLLM ou de outros servidores formatados OpenAI, o llama-swap fornece uma superfície única /v1 e muitos processos atrás dela.

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 compilar do código-fonte. Escolhas comuns: Docker em servidores headless, Homebrew ou WinGet em workstations, binários autônomos quando a pegada de instalação deve permanecer mínima.

Instalação via Docker

Puxe uma imagem que corresponda ao seu hardware. As imagens acompanham de perto o upstream (builds noturnos) e cobrem CUDA, Vulkan, Intel, MUSA e CPU — escolha a que corresponde à forma 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 lamentar se o limite do container estiver errado.

Instalação via 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 via WinGet

No Windows:

winget install llama-swap
winget upgrade llama-swap

Binários pré-compilados e releases

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

Configure o llama-swap com config.yaml para alternância de modelos, TTL e grupos

Tudo no llama-swap é conduzido por configuração. A configuração mínima viável é simplesmente um dicionário models: e um cmd para cada modelo, muitas vezes 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 é o tempo que o llama-swap espera para 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 são segundos ociosos antes do descarregamento automático; o padrão 0 significa “nunca descarregar” a menos que você defina — escolha TTLs explicitamente para qualquer coisa além de uma configuração de brinquedo para que a VRAM não se 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 com descuido.
includeAliasesInList decide se aliases aparecem como linhas separadas em /v1/models; ative se sua UI só oferece modelos enumerados.
apiKeys controla 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 liberam ergonomia de produção

Por modelo, cmd é o único campo obrigatório.
proxy é padrão para http://localhost:${PORT} — esse é o alvo de encaminhamento para o upstream desse modelo.
checkEndpoint é padrão para /health; defina "none" quando o backend não tem rota de saúde ou a inicialização a frio excede o que você está disposto a esperar — 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 ociosos — use TTL por modelo quando um modelo deve permanecer e outro deve desaparecer rapidamente.
aliases e useModelName mantêm nomes estáveis voltados ao 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 nu, errado para um nome de container.
concurrencyLimit limita solicitações paralelas por modelo com HTTP 429 quando excedido — defina-o se você preferir descartar carga a enfileirar para sempre.

groups cobrem coexistência (swap, exclusive) e modelos sempre ligados (persistent). Hooks podem pré-carregar na inicialização; se você pré-carregar vários modelos de uma vez sem um grupo, espere que eles briguem — defina um grupo primeiro para que o pré-carregamento corresponda à forma 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 os melhores controles: um TTL padrão, verificação de saúde explícita, aliases estáveis e um grupo que mantém um pequeno modelo “sempre ligado” rodando enquanto modelos de chat maiores alternam.

# config.yaml
healthCheckTimeout: 180
globalTTL: 900            # 15 minutos ocioso 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 (herda 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 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 é o que separa “um grande modelo de cada vez” de “estes dois modelos de chat podem coexistir enquanto o servidor de embeddings permanece fixado”.

Execute e alterne 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.

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

# 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 comportamentos 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 alterará os processos upstream (a menos que sua configuração de grupo permita coexistência) 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 de mirar a biblioteca Python do OpenAI no llama-server, exceto que a URL estável agora é o llama-swap e o campo modelo 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 (esconder 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 o llama-swap via endpoints de API de gerenciamento e eventos SSE

O 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 de 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 da 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 retroativa.

# 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 esses endpoints quando a VRAM for necessária de volta agora em vez de esperar pelo TTL — benchmarks, alternâncias rápidas de modelos ou após carregar um checkpoint muito maior do que o pretendido.

Transmitir eventos ao vivo via SSE
GET /api/events estabelece um fluxo de 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 andamento.

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

SSE e streaming de tokens quebram quando qualquer caixa intermediária faz buffer — desabilite o buffer no nginx (ou equivalente) para /api/events e /v1/chat/completions. O llama-swap define X-Accel-Buffering: no no SSE; desabilite o buffer no proxy também — cabeçalhos não substituem 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 está configurado.

Logs e interface Web

O 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 imponha 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 na 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 processo e autenticação.

Streaming quebra atrás do nginx ou outro proxy reverso
O nginx fará buffer felizmente do seu SSE e conclusões streamadas. 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 demoram mais 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 requer 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 não quis limitar.

Conflitos de porta ou problemas estranhos de roteamento
Evite portas hard-coded 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.

Checklist de depuração operacional
/running para a 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”.

Assinar

Receba novos artigos sobre sistemas, infraestrutura e engenharia de IA.