Introdução rápida ao Llama.swap Model Switcher para LLMs locais compatíveis com OpenAI

Troque modelos de LLM locais a quente sem alterar os clientes.

Conteúdo da página

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

O llama-swap fornece uma única porta de entrada compatível com OpenAI e Anthropic, com um arquivo YAML que mapeia cada nome de model para o comando que inicia o upstream adequado. Ao solicitar um modelo, o proxy inicia ou alterna para ele; configure TTLs e grupos quando a VRAM for limitada ou quando vários modelos precisam coexistir. Este guia cobre os caminhos de instalação, um config.yaml prático, a superfície HTTP e os modos de falha que surgem quando o streaming e os proxies reversos entram em jogo.

llama swap llm infographic Para uma comparação mais ampla das opções de hospedagem de LLMs, veja Hospedagem de LLMs em 2026: Local, Auto-hospedada e Infraestrutura de Nuvem Comparadas

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 único binário, um único 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 à 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 LLMs:

Como eu alterno modelos com um cliente compatível com OpenAI?
Com o llama-swap, você continua usando solicitações normais /v1/..., mas alterna o model que solicita. O llama-swap lê esse valor de model, carrega a configuração de servidor correspondente e, se o upstream “errado” estiver em execução, o substitui pelo correto.

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

O llama-swap é licenciado sob MIT e não possui 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 prendê-lo a um único mecanismo de inferência.
Por padrão (sem agrupamento especial), ele executa um modelo de cada vez: solicite um model diferente e ele para o upstream atual e inicia o correto. Para mais de um modelo residente ou controle mais fino sobre coexistência, configure groups.

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

flowchart LR C[Seu aplicativo ou SDK\nCliente compatível com OpenAI] -->|/v1/chat/completions\nmodel = qwen-coder| LS[proxy llama-swap\nponto de entrada único] LS -->|inicia ou roteia para| U1[Servidor upstream A\nllama-server] LS -->|inicia ou roteia para| U2[Servidor upstream B\nservidor OpenAI do vLLM] LS --> M[Endpoints de gerenciamento\nrunning, unload, events, metrics]

Este também é o motivo pelo qual um proxy de alternância de modelos é diferente de “simplesmente 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

As quatro opções podem lhe dar uma “API local de LLM”, mas otimizam para fluxos de trabalho diferentes. A maneira mais rápida de escolher é decidir se você quer um tempo de execução (download + execução do modelo) ou um roteador/proxy (alternância + orquestração 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 de 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 padrão local usual na porta 11434).
keep_alive controla por quanto tempo um modelo permanece carregado, incluindo 0 para descarregar imediatamente.
Ele atende usuários que querem baixar um modelo e conversar com fiação mínima. O llama-swap atende comandos por modelo, backends mistos e uma única 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 da aba Developer (localhost ou LAN), incluindo modos compatíveis com OpenAI e compatíveis com Anthropic, além de lms server start do terminal.
Ele atende a um ciclo orientado por GUI: navegar modelos, clicar, testar. O llama-swap atende a um papel de 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. A instalação desse servidor e as flags que ele realmente aceita são cobertas no llama.cpp quickstart.
O llama.cpp também inclui um modo roteador: execute llama-server como roteador, --models-dir, então POST /models/load e POST /models/unload para alternar modelos GGUF sem um proxy separado. Para um guia de configuração completo, veja modo roteador do llama-server: alternância dinâmica de modelos sem reinicializações.
Se todos os modelos estiverem sob um único roteador do llama.cpp, um proxy extra muitas vezes é desnecessário. Quando o llama.cpp precisa ficar ao lado do vLLM ou outros servidores formatados como OpenAI, o llama-swap fornece uma única superfície /v1 e muitos processos atrás dele.

Para soluções de hospedagem compatíveis com OpenAI semelhantes, veja LocalAI QuickStart: Execute LLMs Compatíveis com OpenAI Localmente ou SGLang QuickStart: Instale, Configure e Sirva LLMs via API OpenAI

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 compilação a partir do código-fonte. Escolhas comuns: Docker em servidores headless, Homebrew ou WinGet em estações de trabalho, binários standalone quando a pegada de instalação deve permanecer mínima.

Instalação com Docker

Baixe uma imagem que corresponda ao seu hardware. As imagens acompanham de perto os upstreams (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 downloads por 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 variações de imagem não-root quando puder: menos para lamentar se a fronteira do container estiver errada em algum momento.

Instalação com Homebrew

Em 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 com WinGet

No Windows:

winget install llama-swap
winget upgrade llama-swap

Binários pré-compilados e lançamentos

Os Lançamentos do GitHub disponibilizam binários para Linux, macOS, Windows e FreeBSD, caso você não queira um gerenciador de pacotes.
Os números de lançamento mudam rápido (por exemplo v198, v197 em meados de 2026)—fixe uma versão na automação em vez de flutuar “o que havia ontem”.

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

Tudo no llama-swap é dirigido 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 respondem diretamente a problemas comuns estilo FAQ (descarregamento automático, segurança e clientes que dependem de /v1/models).

Configurações globais que você realmente usará

healthCheckTimeout é por quanto tempo o llama-swap espera por 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 de ociosidade 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 se encha com modelos esquecidos.
startPort semeia a macro ${PORT} (padrão 5800); a atribuição é determinística por ID do modelo em ordem alfabética, o que é uma característica quando você depura “quem pegou qual porta” e uma pegadinha se você renomear modelos descuidadamente.
includeAliasesInList decide se os aliases aparecem como linhas separadas em /v1/models; ative se sua UI só oferecer modelos enumerados.
apiKeys controla tudo acessível fora do localhost: Basic, Bearer ou x-api-key. O llama-swap remove esses cabeçalhos antes de retransmitir, para que os logs do upstream sejam menos propensos a reter segredos do cliente.

Configurações por modelo que liberam ergonomia de produção

Por modelo, cmd é o único campo obrigatório.
proxy padrão é http://localhost:${PORT} — esse é o alvo de retransmissão para o upstream daquele modelo.
checkEndpoint padrão é /health; defina "none" quando o backend não tiver uma rota de saúde ou quando a inicialização a frio exceder o que você está disposto a esperar — não deixe um /health quebrado e se pergunte por que nada atinge 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 requerem um identificador específico.
cmdStop é não opcional para containers: mapeie-o para docker stop (ou equivalente); sem ele, você recebe POSIX SIGTERM / Windows taskkill contra qualquer PID que o llama-swap iniciou — certo 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 quando você preferir descartar carga a ficar na fila 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 briguem — 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 “suficiente” para ilustrar os ajustes de melhor prática: um TTL padrão, verificação de saúde explícita, aliases estáveis e um grupo que mantém um pequeno modelo “sempre ativo” em execução enquanto modelos de chat maiores são alternados.

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

# Opcional, mas recomendado para qualquer coisa além de desenvolvimento local
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 em container
    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 dirige 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 “esses 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 em execução, você interage com ele como com 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 model solicitado para decidir qual upstream executar e para qual rotear.

Um fluxo prático de inicialização:

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

A listagem de modelos é uma função de gerenciamento de primeira classe e inclui comportamentos como ordenação por ID, exclusão de modelos unlisted e inclusão opcional de aliases.

# 3) Faça 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":"Escreva uma função TypeScript que faz retry de fetch com backoff."}]
  }'

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

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

from openai import OpenAI

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

resp = client.chat.completions.create(
    model="qwen-coder",
    messages=[{"role": "user", "content": "Explique a diferença entre mutexes e semáforos."}],
)
print(resp.choices[0].message.content)

Para aquecer um modelo antes do primeiro pedido real (ocultar a latência de inicialização a frio), use /upstream/<model> — ele carrega automaticamente se necessário e retransmite diretamente para esse upstream. Uma 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 ao redor do ciclo de vida e observabilidade dos modelos.

Verificar o que está em execução
GET /running retorna o estado de runtime 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 com versão de API POST /api/models/unload. Para descarregar um modelo único (por ID ou alias), use POST /api/models/unload/<model>. Um legado GET /unload existe para compatibilidade reversa.

# descarregar todos
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 stream de Server-Sent Events e é projetado para atualizações em tempo real que incluem mudanças de status de 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 — desative o buffer no nginx (ou equivalente) para /api/events e /v1/chat/completions. O llama-swap define X-Accel-Buffering: no no SSE; desative o buffer no proxy também — cabeçalhos não são um substituto para uma configuração de proxy correta.

Métricas e capturas de solicitações
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 a 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 do /ui permanecem acessíveis sem uma chave — certo para fronteiras de confiança locais, errado se o host estiver em uma rede compartilhada. Coloque o llama-swap atrás de algo que强制执行 sua política real; a autenticação embutida é para manter clientes casuais honestos, não para uma API multi-inquilino pública.

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

A maioria dos problemas do llama-swap se enquadra 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 felizmente fará buffer do seu SSE e dos completions transmitidos. Desative 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 se torna 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 desativar completamente as verificações de saúde.
Se modelos grandes levarem mais tempo para carregar, aumente healthCheckTimeout (padrão 120s), ou use verificações de saúde adaptadas para seu upstream específico.

Alternar modelos deixa um container antigo em execução
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 retransmitir para o upstream.

Recebo 429 Too Many Requests
concurrencyLimit retorna 429 quando excedido — por design. Aumente o limite se você o provisionou insuficientemente, ou reduza o limite se não quis limitar.

Conflitos de porta ou problemas de roteamento estranhos
Evite portas codificadas em cmd; use ${PORT} e mova startPort se 5800+ conflitar com outra coisa. Lembre-se de que as portas são atribuídas em ordem alfabética por ID do modelo — renomeie um modelo e o mapeamento de portas 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 de “por que a GPU está cheia”.

Subscrever

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