llama.swap モデル切り換え器の OpenAI 互換ローカル LLM 向けクイックスタート
クライアントを変更せずにホットスワップ可能なローカル LLM。
まもなく vLLM や llama.cpp など、それぞれのスタックが独自のポートで稼働している状態に陥ります。下流のシステムはすべて**/v1というベース URL を求めるため、ポート、プロファイル、ワンオフスクリプトを頻繁に変更することになります。llama-swapは、これらのスタックの前に配置される/v1**プロキシです。
llama-swapは、OpenAI および Anthropic 互換の単一の入り口を提供し、YAML ファイルで各 model 名を適切なアップストリーム起動コマンドにマッピングします。モデルをリクエストすると、プロキシはそのモデルを起動または切り替えます。VRAM が限られている場合や複数のモデルが共存する必要がある場合は、TTL やグループを設定できます。このガイドでは、インストール手順、実用的な config.yaml、HTTP API、そしてストリーミングとリバースプロキシが絡む際の障害モードについて解説します。
LLM ホスティングの選択肢に関する広範な比較については、LLM Hosting in 2026: Local, Self-Hosted & Cloud Infrastructure Compared を参照してください。
llama-swap モデルスイッチャーの概要:OpenAI 互換ローカル LLM API 向け
llama-swap は軽量なプロキシサーバーであり、シンプルな運用モデルに基づいています:1 つのバイナリ、1 つの YAML 設定ファイル、依存関係なし。Go で書かれているため、スタックの残りの部分の隣に単一の静的バイナリとして存在し、Python ランタイムやデスクトップアプリケーションは不要です。これは、あらゆるOpenAI および Anthropic 互換のアップストリームに対してモデル切り替え層として機能します。
概念的には、これはローカル LLM スタックで頻繁に発生する非常に実用的な質問に答えるものです。
OpenAI 互換クライアントでモデルを切り替える方法は?
llama-swap を使用すると、通常の /v1/... リクエストを使い続けることができますが、リクエストする model を変更します。llama-swap はその model 値を読み取り、一致するサーバー設定をロードし、もし「誤った」アップストリームが稼働している場合は、正しいものに切り替えます。
実用的なセットアップでは、いくつかの設計詳細が重要です。
llama-swap は MIT ライセンスでテレメトリなしです。実際のプロンプトを見るホストでは、これを再確認する価値があります。
これは、llama.cpp、vLLM、Whisper、stable-diffusion.cppなどのバックエンドのオンデマンド読み込みのために設計されており、単一の推論エンジンにロックインされるものではありません。
デフォルト設定(特別なグループなし)では、1 つのモデルのみを同時に実行します:異なる model をリクエストすると、現在のアップストリームを停止し、適切なものを起動します。1 つ以上のレジデントモデルや共存のより細かい制御が必要な場合は、groups を設定します。
多くの開発者が有用だと感じるメンタルモデルは以下の通りです。
flowchart LR
C[Your app or SDK\nOpenAI-compatible client] -->|/v1/chat/completions\nmodel = qwen-coder| LS[llama-swap proxy\nsingle endpoint]
LS -->|starts or routes to| U1[Upstream server A\nllama-server]
LS -->|starts or routes to| U2[Upstream server B\nvLLM OpenAI server]
LS --> M[Management endpoints\nrunning, unload, events, metrics]
これが、モデル切り替えプロキシが「単にモデルを実行するだけ」と異なる理由です:これは、1 つ以上の推論サーバーの上にオーケストレーションとルーティングを行うものです。
llama-swap vs Ollama vs LM Studio vs llama.cpp サーバー
この 4 つのオプションはいずれも「ローカル LLM API」を提供できますが、最適化されているワークフローは異なります。選択する最も早い方法は、ランタイム(モデルのダウンロード+実行)を求めているのか、ラーター/プロキシ(ランタイム間の切り替え+オーケストレーション)を求めているのかを決定することです。
llama-swap
llama-swap は、OpenAI 互換のエンドポイント(/v1/chat/completions、/v1/completions、/v1/embeddings、/v1/models を含む)をサポートし、リクエストされたモデルに基づいて適切なアップストリームにリクエストをルーティングする透過的なプロキシに焦点を当てています。また、/running、/logs/stream、/ui などの非推論用オペレーショナルエンドポイントも提供します。
Ollama
Ollama は独自の HTTP API(POST /api/chat、POST /api/generate、およびポート 11434 での通常のローカルデフォルト)を公開します。
keep_alive はモデルがロードされたままの時間を制御し、0 に設定すると即座にアンロードされます。
これは、最小限の配線でモデルをプルしてチャットしたいユーザーに適しています。llama-swapは、モデルごとのコマンド、混合バックエンド、すべてのクライアント向けの単一の OpenAI 形式の URLに適しており、vLLM を llama-server の隣に配置しながらモデルごとに異なるフラグをオーケストレーションすることは、Ollama の目的外です。
LM Studio
LM Studio はデスクトップアプリであり、Developer タブからローカル API サーバー(localhost または LAN)を提供します。OpenAI 互換およびAnthropic 互換モード、およびターミナルからの lms server start コマンドが含まれます。
これは、モデルを閲覧し、クリックしてテストするGUI 優先のループに適しています。llama-swapは、YAML、プロセス監視、混合アップストリーム、デスクトップセッションなしというサーバースタイルの役割に適しています。
llama.cpp サーバー
llama-server は /v1/completions、/v1/chat/completions、/v1/responses を公開し、通常の模式は OpenAI クライアントを base_url 経由でこれに指すことです。
llama.cpp にはラーターモードも付属しています:llama-server をラーターとして実行し、--models-dir を指定してから、POST /models/load と POST /models/unload を使用して、別々のプロキシなしで GGUF モデルをシャッフルします。完全なセットアップガイドについては、llama-server router mode: dynamic model switching without restarts を参照してください。
すべてのモデルが1 つの llama.cpp ラーターの下にある場合、追加のプロキシは不要なことが多いです。llama.cpp が vLLM や他の OpenAI 形式のサーバーの隣に配置される必要がある場合、llama-swap は単一の /v1 表面とその背後に多数のプロセスを提供します。
同様の OpenAI 互換ホスティングソリューションについては、LocalAI QuickStart: Run OpenAI-Compatible LLMs Locally または SGLang QuickStart: Install, Configure, and Serve LLMs via OpenAI API を参照してください。
llama-swap モデルスイッチャーのインストール:Docker、Homebrew、WinGet、バイナリ
Linux、macOS、Windows はすべてファーストクラス対応です:Docker、Homebrew、WinGet、GitHub バイナリ、またはソースからのビルド。一般的な選択肢は、ヘッドレスサーバーでは Docker、ワークステーションでは Homebrew または WinGet、インストールフットプリントを最小限に抑えたい場合はスタンドアロンバイナリです。
Docker でのインストール
ハードウェアに一致するイメージをプルしてください。イメージはアップストリームに密接に追従(ナイトリービルド)しており、CUDA、Vulkan、Intel、MUSA、CPU をカバーしています。習慣で「latest」ではなく、実際に使用しているアクセラレーションに一致するものを選択してください。
# Example platform pulls
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
可能であれば、非ルートのイメージバリアントを優先してください:コンテナ境界が誤っている場合の後悔を減らせます。
Homebrew でのインストール
macOS および Linux では、tap を使用してインストールします。
brew tap mostlygeek/llama-swap
brew install llama-swap
llama-swap --config path/to/config.yaml --listen localhost:8080
WinGet でのインストール
Windows では:
winget install llama-swap
winget upgrade llama-swap
事前構築済みバイナリとリリース
パッケージマネージャーを使いたくない場合は、GitHub リリースから Linux、macOS、Windows、FreeBSD のバイナリが提供されます。
リリース番号は急速に移動します(例:v198、v197 2026 年初頭頃)— 自動化では「昨日そこにあったもの」ではなく、バージョンを固定してください。
llama-swap の設定:モデル切り替え、TTL、グループのための config.yaml
llama-swap のすべては設定駆動です。最小限の機能構成は、単に models: 辞書と各モデルの cmd であり、多くの場合 ${PORT} がモデルごとに置換された状態で llama-server を起動します。
設定システムは「プロセスを起動するだけ」よりもはるかに深く進んでおり、いくつかのオプションは早期に理解する価値があります。これらは、一般的な FAQ 形式の問題(自動アンロード、セキュリティ、/v1/models に依存するクライアント)に直接答えるためです。
実際に使用するグローバル設定
healthCheckTimeout は、llama-swap が起動後にモデルが健全になるのを待つ時間です(デフォルト 120s、最小 15s)。スローディスク上の複数 GB のロードでは、プロキシを責める前にこれを増やしてください。
globalTTL は自動アンロードまでのアイドル秒数です。デフォルトの 0 は「アンロードしない」を意味しますが、設定した場合に限りです。VRAM が忘れられたモデルで埋め込まれないように、おもちゃのセットアップを超えるものには明示的に TTL を選択してください。
startPort は ${PORT} マクロの種です(デフォルト 5800)。割り当てはモデル ID のアルファベット順で決定論的であり、これは「どのポートが誰のものか」をデバッグする際の特徴ですが、モデル名を不用意に改名すると足かせになります。
includeAliasesInList は、エイリアスが /v1/models で別行として表示されるかを決定します。UI が列挙されたモデルのみを提供する場合は、これをオンにします。
apiKeys は、localhost からアクセス可能なものをゲートします:Basic、Bearer、または x-api-key。llama-swap はこれらのヘッダーを転送前に削除するため、アップストリームのログがクライアントの機密情報を保持する可能性が低くなります。
本番運用の使いやすさを解錠するモデルレベルの設定
モデルごとに cmd が唯一の必須フィールドです。
proxy はデフォルトで http://localhost:${PORT} です。これは、そのモデルのアップストリームの転送先です。
checkEndpoint はデフォルトで /health です。バックエンドにヘルスルートがない場合や、待機時間を超えたコールドスタートがある場合は "none" に設定します。壊れた /health にして、なぜ ready に達しないのか不思議に思うことにはしないでください。
ttl: -1 は globalTTL を継承、0 はアンロードしない、N > 0 は N 秒アイドル後にアンロードします—1 つのモデルは長く残し、もう1つはすぐに消滅させたい場合にモデルごとの TTL を使用します。
aliases と useModelName は、特定の識別子を必要とするアップストリームを満たしながら、安定したクライアント向け名を維持します。
cmdStop はコンテナでは必須です:docker stop(または同等のもの)にマップします。これがない場合、llama-swap が起動した PID に対して POSIX SIGTERM / Windows taskkill が実行されます—裸のバイナリには問題ありませんが、コンテナ名には誤りです。
concurrencyLimit は、モデルごとの並行リクエスト数を制限し、超過時に HTTP 429 を返します—永遠にキューに入れるよりも負荷を捨てることを望む場合に設定します。
groups は共存(swap、exclusive)および常時稼働モデル(persistent)をカバーします。フックは起動時にプリロードできます。グループなしで複数のモデルを一度にプリロードすると、競合するのを期待してください—GPU を共有する方法にプリロードが一致するように、まずグループを定義してください。
llama.cpp と vLLM 用の最小限の config.yaml 例
この例は、ベストプラクティスの調整を説明するのに「必要なだけ」を目指しています:デフォルト TTL、明示的なヘルスチェック、安定したエイリアス、そして大きなチャットモデルが切り替わる間に小さな「常時稼働」モデルを稼働させるグループ。
# config.yaml
healthCheckTimeout: 180
globalTTL: 900 # 15 分アイドル後にアンロード
includeAliasesInList: true
startPort: 5800
# ローカル開発を超えたものにはオプションだが推奨
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"
# デフォルトを使用:
# proxy: http://localhost:${PORT}
# checkEndpoint: /health
# ttl: -1 (globalTTL を継承)
qwen-coder:
cmd: |
llama-server --port ${PORT} --model /models/qwen-coder.gguf
--ctx-size 8192
aliases:
- "qwen-coder-latest"
vllm-coder:
# 示唆的なパターン:コンテナ化された OpenAI 互換サーバーを管理
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 # 自動アンロードしない(例:GPU に保持)
groups:
chat-models:
swap: true
exclusive: true
members: ["llama-chat", "qwen-coder"]
always-on:
persistent: true
swap: false
exclusive: false
members: ["vllm-coder"]
これらは装飾的ではありません:cmd はプロセスを駆動し、proxy/checkEndpoint/ttl はルーティングとライフサイクルを制御し、cmdStop は Docker ベースのアップストリームを実際に停止させるものであり、groups は「1 つの大きなモデルのみ」を「これら 2 つのチャットモデルは共存できるが、埋め込みサーバーは固定される」と分離します。
OpenAI 互換エンドポイントを介してモデルを実行して切り替える
llama-swap が稼働すると、他の OpenAI 互換エンドポイントと同様に操作します。API 表面には、/v1/chat/completions、/v1/completions、/v1/embeddings、/v1/models などのコアエンドポイントが含まれており、llama-swap はリクエストされた model を使用して、どのアップストリームを実行してルーティングするかを決定します。
実用的なクイックスタートフロー:
# 1) llama-swap を起動
llama-swap --config ./config.yaml --listen localhost:8080
# 2) 利用可能なモデルを発見
curl http://localhost:8080/v1/models
モデルリストはファーストクラスの管理機能であり、ID によるソート、unlisted モデルの除外、オプションのエイリアス包含などの動作を含みます。
# 3) 特定のモデルへのチャット完了リクエスト
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."}]
}'
ここで "model": "llama-chat" で呼び出しを繰り返すと、llama-swap はアップストリームプロセスを切り替えます(グループ設定が共存を許可しない場合)。これは、リクエストからリクエストされたモデルを抽出し、適切なサーバー設定をロードするためです。
SDK を使用している場合は、クライアントを http://localhost:8080/v1 に向けます—llama-server に向ける OpenAI Python ライブラリと同じトリックですが、安定した URL は現在 llama-swap であり、model フィールドがアップストリームを選択します。
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)
最初の実際のリクエスト前にモデルをウォーム(コールドスタートの遅延を隠す)するには、/upstream/<model> を使用します—必要に応じて自動ロードし、そのアップストリームに直接転送します。ベンチマークやスクリプトテストの前にウェイトがレジデントであることを確認する簡単な方法です。
管理 API エンドポイントと SSE イベントを介して llama-swap を制御・監視
llama-swap は単なる「プロキシ」ではありません。モデルライフサイクルと可観測性周りのツールを構築するためのオペレーショナルコントロールエンドポイントを公開します。
稼働中のものを確認
GET /running は、ロードされたモデルのランタイム状態を返します。ready、starting、stopping、stopped、shutdown などの状態値を含みます。
curl http://localhost:8080/running
VRAM を解放するためにモデルをアンロード
すべてのモデルを即座にアンロードするには、API バージョン付きのエンドポイント POST /api/models/unload を使用します。単一のモデル(ID またはエイリアスで)をアンロードするには、POST /api/models/unload/<model> を使用します。後方互換性のためにレガシーな GET /unload も存在します。
# すべてアンロード
curl -X POST http://localhost:8080/api/models/unload
# 1 つのモデルをアンロード
curl -X POST http://localhost:8080/api/models/unload/qwen-coder
TTL を待つ代わりに今すぐVRAM が必要になった場合に、これらのエンドポイントを使用します—ベンチマーク、クイックなモデル切り替え、意図したよりもはるかに大きなチェックポイントをロードした後など。
SSE を介してライブイベントをストリーミング
GET /api/events は Server-Sent Events ストリームを確立し、モデルステータス変更、ログ、メトリック、実行中のリクエストカウントを含むリアルタイム更新用に設計されています。
curl -N http://localhost:8080/api/events
SSE とトークンストリーミングは、どのミドルボックスもバッファリングする場合に破綻します—nginx(または同等のもの)で /api/events と /v1/chat/completions のバッファリングを無効にしてください。llama-swap は SSE に X-Accel-Buffering: no を設定しますが、プロキシも修正してください—ヘッダーは正しいプロキシ設定の代わりにはなりません。
メトリックとリクエストキャプチャ
GET /api/metrics はトークン使用量のメトリックを返し、メモリ内保持は metricsMaxInMemory(デフォルト 1000)で制御されます。
GET /api/captures/<id> は、captureBuffer > 0 が設定されている場合にのみ、完全なリクエスト/レスポンスキャプチャを取得できます。
ログと Web UI
llama-swap は Web インターフェースのために /ui を公開し、リアルタイム監視のために /logs や /logs/stream などのオペレーショナルログエンドポイントを公開します。

apiKeys を有効にする場合は、多層防御を想定してください:/health と /ui の一部はキーなしでアクセス可能です—ローカルな信頼境界では問題ありませんが、共有ネットワーク上のホストでは問題があります。llama-swap を実際のポリシーを強制する何かの背後に配置してください。組み込み認証はカジュアルなクライアントを正しく保つためのもので、パブリックなマルチテナント API 用ではありません。
本番運用での llama-swap モデル切り替えのトラブルシューティング
llama-swap の問題のほとんどは、いくつかのオペレーショナルカテゴリに分類されます:リバースプロキシを介したストリーミング、コールドスタート中のヘルスチェック、ポートとプロセスライフサイクル、認証。
nginx や他のリバースプロキシの背後でストリーミングが破綻する
nginx は SSE とストリーミング完了をバッファリングしてしまいます。/api/events と /v1/chat/completions に対して proxy_buffering(および proxy_cache)を無効にしてください。llama-swap は SSE で X-Accel-Buffering: no を送信しますが、これは助けになります—それでもプロキシを修正してください。
モデルが決して ready にならない
デフォルトでは、モデルごとの checkEndpoint は /health であり、プロセスが ready と見なされるには HTTP 200 を返す必要があります。checkEndpoint を別のパスに設定するか、ヘルスチェックを完全に無効にする "none" に設定できます。
大きなモデルのロードに時間がかかる場合は、healthCheckTimeout(デフォルト 120s)を増やすか、特定のアップストリーム向けに調整されたヘルスチェックを使用してください。
モデル切り替えで古いコンテナが稼働し続ける
アップストリームが Docker または Podman の場合は、cmdStop を設定してください。そうしないと、llama-swap はラッパープロセスを停止しますが、コンテナはバックグラウンドで VRAM を消費し続けます。
セキュリティを有効にした後 401 レスポンスになる
apiKeys が設定されている場合、llama-swap は有効なキーを必要とし、3 つの方法(Basic 認証、Bearer トークン、x-api-key)を受け入れます。また、アップストリーム転送前に認証ヘッダーを削除します。
429 Too Many Requests になる
concurrencyLimit は超過時に 429 を返します—設計上です。プロビジョニング不足の場合は上限を上げ、意図しないスロットリングの場合は制限を下げてください。
ポート競合や奇妙なルーティング問題
cmd でハードコードされたポートを避け、${PORT} を使用し、5800+ が他と競合する場合は startPort を移動してください。ポートはモデル ID のアルファベット順に割り当てられることを覚えておいてください—モデル名を改名するとポートマッピングがシフトします。
運用デバッグチェックリスト
真実には /running、起動が不透明な場合は /logs/stream、VRAM が今すぐ必要になった場合は POST /api/models/unload を使用します。このトリオは、ほとんどの「なぜ GPU が満杯なのか」セッションをカバーします。