Llama-Server ルーターモード - リスタートなしでの動的モデル切り替え
リスタートなしでLLMの提供と入れ替えを実現します。
長らく llama.cpp には顕著な制限がありました。1つのプロセスで1つのモデルしか提供できず、モデルの切り替えには再起動が必要だったのです。
その時代は終わりました。
最近のアップデートで llama-server にルーターモードが導入され、現代のローカルLLMランタイムに求められる機能が大幅に実現しました。
- モデルの動的な読み込み
- 必要に応じたアンロード
- リクエストごとの切り替え
- プロセスの再起動なし

言い換えれば、トレーニングホイールなしのOllamaのような動作が可能になりました。
ローカルランタイム、クラウドAPI、セルフホスト型インフラのいずれを選ぶべきか迷っている場合は、 LLMホスティングの概要 が良い出発点となります。
前提条件
ルーターモードには比較的新しい llama-server のビルドが必要です(2024年年中以降のバージョン)。古いビルドには --models-preset や --models-dir フラグが含まれていません。
インストールオプション(パッケージマネージャー、事前ビルド済みバイナリ、CUDA対応の完全ソースビルドなど)については、 llama.cpp クイックスタート を参照してください。
llama-server を入手したら、ビルドがルーターモードをサポートしているか確認します。
llama-server --help | grep -i models
--models-preset または --models-dir が表示されれば問題ありません。表示されない場合は、新しいビルドにアップデートしてください。
現在のモデル関連ヘルプの出力例:
-cl, --cache-list キャッシュ内のモデルリストを表示
Prefix/Suffix/Middle) as some models prefer this. (default: disabled)
models with dynamic resolution (default: read from model)
models with dynamic resolution (default: read from model)
embedding models (default: disabled)
--models-dir PATH ルーターサーバー用のモデルを含むディレクトリ (default: disabled)
(env: LLAMA_ARG_MODELS_DIR)
--models-preset PATH ルーターサーバー用のモデルプリセットを含むINIファイルへのパス
(env: LLAMA_ARG_MODELS_PRESET)
--models-max N ルーターサーバーで同時に読み込むモデルの最大数
(env: LLAMA_ARG_MODELS_MAX)
--models-autoload, --no-models-autoload
ルーターサーバーでモデルを自動的にロードするかどうか (default:
(env: LLAMA_ARG_MODELS_AUTOLOAD)
ルーターモードの実際の動作
ルーターモードは llama-server をモデルディスパッチャに変えます。
-m を通じて単一のモデルにバインドする代わりに、サーバーは以下の動作を行います。
- モデルをロードせずに起動
- モデル名を指定したリクエストを受信
- メモリにまだロードされていない場合はそのモデルをロード
- 推論を実行
- レスポンス後、モデルをアンロードするか、次のリクエストのために保持するかを選択
基本概念
これまでは以下のように実行していました。
./llama-server -m model.gguf
今後は以下のように実行します。
./llama-server --models-preset models.ini --port 8080
そして、クライアントが実際にリクエストした内容に基づき、サーバーが何を、いつロードするかを決定させます。
これは重要な変化です。1つの永続的なプロセスがモデルの一群全体をサービングでき、クライアントがタスクごとに適切なモデル(コーディング用モデル、チャット用モデル、要約用モデルなど)を選択できます。これにより、ユーザー側の調整オーバーヘッドは不要になります。
設定:モデルの定義
ここはまだ少し荒削りな部分があります。
完全に安定した公式フォーマットはまだ存在しませんが、現在のビルドでは設定ファイル経由で INIスタイルのモデル定義 をサポートしています。
models.ini の例
[llama3]
model = /opt/models/llama-3-8b-instruct.Q5_K_M.gguf
ctx-size = 8192
ngl = 35
threads = 8
[mistral]
model = /opt/models/mistral-7b-instruct-v0.3.Q4_K_M.gguf
ctx-size = 4096
ngl = 20
threads = 8
[qwen]
model = /opt/models/qwen2.5-coder-7b-instruct.Q5_K_M.gguf
ctx-size = 16384
ngl = 35
threads = 8
各セクション名は、APIリクエストの "model" フィールドでクライアントが使用するモデル識別子になります。
主要な設定パラメータ
| パラメータ | 制御内容 |
|---|---|
model |
GGUFファイルへの絶対パス |
ctx-size |
トークン単位でのコンテキストウィンドウサイズ。値が大きいほどVRAM使用量が増加します。 |
ngl |
GPUにオフロードするレイヤー数。CPUのみ使用する場合は 0 に設定し、VRAMの限界に達するまで増やします。 |
threads |
CPUに留まるレイヤー用のCPUスレッド数。 |
適切な ngl 値の選択はGPUの利用可能なVRAMに依存します。GPUの選択とハードウェアのコストについては、コンピュータハードウェアガイド が有用な参照資料です。VRAM消費量をリアルタイムで監視しながら調整するには、Linux用GPUモニタリングツール を参照してください。
設定によるサーバーの起動
./llama-server --models-preset /opt/llama.cpp/models.ini --port 8080
サーバーが正しく起動したことを確認します。
curl http://localhost:8080/v1/models | jq '.data[].id'
models.ini の各セクション名がモデルIDとしてリストされるはずです。
安定性に関する注意点
INI設定インターフェースはまだ進化中です。
- コミット間でフラグが変更される可能性があります
- 一部のパラメータは特定のビルド構成でのみ認識されます
- ドキュメントは実装に追いついていません
再起動間の再現性が必要な場合は、特定のllama.cppコミットに固定してください。
APIの使用:リクエストによるモデル切り替え
サーバーが稼働中なら、モデル切り替えは標準のOpenAI互換APIを通じて行われます。単に "model" フィールドを設定するだけです。
登録済みモデルのリスト
curl http://localhost:8080/v1/models
コンプリケーションリクエスト — 最初のモデル
curl http://localhost:8080/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "llama3",
"messages": [
{"role": "user", "content": "ルーターモードを1段落で説明してください"}
]
}'
同じエンドポイント、同じポートで別のモデルに切り替え
curl http://localhost:8080/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "qwen",
"messages": [
{"role": "user", "content": "CSVファイルを読み取るPython関数を書いてください"}
]
}'
サーバーはアンロード/ロードサイクルを透過的に処理します。クライアントコードは変更不要で、model フィールドのみが変更されます。
Pythonの例
openai Pythonクライアントを使用している場合:
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8080/v1", api_key="not-needed")
# コーディングモデルを使用
response = client.chat.completions.create(
model="qwen",
messages=[{"role": "user", "content": "GoのHTTPハンドラを書いてください"}],
)
print(response.choices[0].message.content)
# チャットモデルに切り替え — 同じクライアント、異なるモデル名
response = client.chat.completions.create(
model="llama3",
messages=[{"role": "user", "content": "オーストラリアの首都はどこですか?"}],
)
print(response.choices[0].message.content)
内部的な動作
qwen に対するリクエストが届き、現在 llama3 がロードされている場合:
llama3がVRAMからアンロードされるqwenの重みがディスクから読み取られ、VRAMにロードされる- 推論が実行される
- 次のリクエストで
qwenの保持か再びの切り替えかが決定される
これにより、一般的な疑問に直接答えることができます。
ローカルLLMサーバーは再起動せずにモデルを切り替えられるのですか?
起動時にバインドするのではなく、リクエストごとにモデルを動的にロードすることで可能になります。
Systemdサービス:本番環境向けのセットアップ
専用ユーザーとディレクトリの作成
sudo useradd --system --shell /usr/sbin/nologin --home-dir /opt/llama.cpp llm
sudo mkdir -p /opt/llama.cpp/models
sudo chown -R llm:llm /opt/llama.cpp
バイナリとモデル設定を適切な場所にコピーします。
sudo cp build/bin/llama-server /opt/llama.cpp/
sudo cp models.ini /opt/llama.cpp/
/etc/systemd/system/llama-server.service
[Unit]
Description=Llama.cpp Router Server
After=network.target
[Service]
Type=simple
User=llm
WorkingDirectory=/opt/llama.cpp
ExecStart=/opt/llama.cpp/llama-server --models-preset /opt/llama.cpp/models.ini --port 8080
Restart=always
RestartSec=5
Environment=LLAMA_LOG_LEVEL=info
[Install]
WantedBy=multi-user.target
有効化と起動
sudo systemctl daemon-reload
sudo systemctl enable llama-server
sudo systemctl start llama-server
確認とログの検査
sudo systemctl status llama-server
journalctl -u llama-server -f
正常に起動すると、サーバーがリスニング中であり、モデルレジストリがロードされたことを示す行が表示されます。簡単な健全性チェック:
curl -s http://localhost:8080/v1/models | jq '.data[].id'
これで自動再起動と集中管理されたモデル切り替えを持つ永続的なサービスが完成です。手動のプロセス管理は不要です。同じパターンを他のバイナリに適用したい場合は、Linuxで任意の実行ファイルをサービスとしてホスティング で一般的なアプローチが解説されています。
llama-server の --metrics フラグはPrometheus互換のエンドポイントを公開します。llama.cpp固有のダッシュボード、PromQLクエリ、アラートルールについては、LLM推論モニタリングガイド を参照してください。より広範なオブザーバビリティ設定については、オブザーバビリティガイド がフルスタックをカバーしています。
理解しておくべき制限事項
ルーターモードは確かに有用ですが、本番環境で依存する前に明確にするべきトレードオフがあります。
同時にメモリに存在するモデルは1つのみ
models.ini に複数のモデルが定義されていても、任意の時点でワーカーごとのVRAMに存在するのは1つだけです。切り替えは完全なアンロードと再ロードサイクルを意味します。
- 切り替えは再ロードを意味する
- レイテンシの急増は避けられない
- 典型的な7Bモデル(Q5量子化)の場合、ディスク速度とVRAM帯域幅に応じて再ロードに3〜10秒かかることがある
これにより、もう1つの重要な疑問に答えます。
llama.cppは複数のモデルを同時にサービングできますか?
厳密にはできません。複数の定義 はサポートしていますが、同時のレジデンスではありません。2つのモデルを真に並行してロードする必要がある場合は、2つのGPU上の2つのプロセスが必要です。
測定されたVRAM消費量とモデルサイズごとのトークン/秒については、LLMパフォーマンスベンチマーク が全体像をカバーしています。16 GB GPUでのllama.cppに特化した数値(19K、32K、64Kコンテキストでの密集型およびMoEモデル)については、16 GB VRAM llama.cppベンチマーク を参照してください。
スマートキャッシュなし
Ollamaはウォームプールを維持し、最近のアクセスに基づいてモデルを破棄するのに対し:
- 自動モデル破棄戦略はない
- バックグラウンドでのプリウォーミングはない
- 頻繁に使用されるモデルのための優先キューはない
llama3 と mistral への交互のリクエストを送信すると、各リクエストが再ロードをトリガーします。これはメタに近い(低レベルな)動作をするための根本的なコストです。
混合ワークロードでのレイテンシは予測不可能
1つのモデルを一貫して使用する動作の良いワークロードは高速です。複数のモデルを交互に使用するワークロードは低速になります。クライアントのルーティングロジックを適切に計画し、可能な限りモデルごとにリクエストをグループ化してください。
設定は安定していない
INIサポートは存在し、最近のビルドでは機能していますが、完全に標準化されていません。フラグとパラメータ名はバージョン間で変更されています。llama-server をアップグレードする場合は、展開前に新しいビルドに対して models.ini をテストしてください。
Llama.cpp vs Ollama:率直な比較
| 機能 | llama.cpp ルーター | Ollama |
|---|---|---|
| 動的読み込み | Yes | Yes |
| モデル切り替え | Yes | Yes |
| 内蔵レジストリ | 部分的(INI) | Yes(pullベース) |
| メモリ管理 | 基本 | 高度 |
| モデル破棄 | なし | TTLベース |
| UXの磨き | 低 | 高 |
| OpenAI API互換性 | Yes | Yes |
| コントロール | 最大 | 意見のある(Opinionated) |
| 設定の安定性 | 実験的 | 安定 |
意見のある見解
以下のことを望む場合は、llama.cppのルーターモードを選択してください。
- モデルごとのランタイムパラメータに対する最大限の制御
- 最小限のプロセスオーバーヘッド
- 抽象化レイヤーなしでのllama.cppフラグへの直接アクセス
- カスタムツールングのためのハックしやすいベース
以下のことを望む場合は、Ollamaを選択してください。
- 安定した、磨かれた体験
- 自動的なモデルダウンロードとバージョン管理
- 設定なしでのスマートなキープアライブと破棄
- 最初の日からバッテリー込み(包括的な機能)
どちらも間違っているわけではありません。選択は、自分自身でどれだけ管理したいかに依存します。
Ollamaを選択した場合、日常のコマンドは Ollama CLIチートシート を参照してください。vLLM、LM Studio、LocalAIも含むより広範な比較については、2026年の異なるローカルランタイムの比較 を参照してください。
Llama.cpp vs llama-swap
llama-swap は1つ以上の llama-server インスタンスの前に配置される外部オーケストレータです。
- リクエストをインターセプトし、
modelフィールドを検査する - そのモデル用の適切な
llama-serverプロセスを起動する - 設定可能なタイムアウト後にアイドル状態のインスタンスをシャットダウンする
- モデルの準備が整うとリクエストをプロキシする
ハンズオンセットアップについては、llama-swap クイックスタート を参照してください。
主な違い
| 側面 | ルーターモード | llama-swap |
|---|---|---|
| 内蔵 | Yes | No(別バイナリ) |
| 成熟度 | 実験的 | より安定 |
| 柔軟性 | 限定的 | 高 |
| コントロール層 | 内部 | 外部プロキシ |
| モデルごとの設定 | INIファイル | YAMLファイル |
| プロセスモデル | 単一プロセス | モデルごとに1プロセス |
llama-swap を使用するタイミング
llama-swap はモデルごとのプロセスレベルの分離を提供するため、1つのモデルインスタンスでのクラッシュは他のインスタンスに影響を与えません。また、各モデルが完全に独立した llama-server フラグで実行することを可能にします。
以下が必要な場合は使用します。
- より良いライフサイクル制御と分離
- 設定可能なアイドルタイムアウトを持つスマートな切り替えロジック
- より予測可能なレイテンシ(各モデルは最初のロード後にウォームプロセスを持つ)
- 将来的ではなく、今日の本番環境安定性
ネイティブルーターモードで十分すぎる場合
以下を望む場合は、内蔵のルーターを使用します。
- 外部依存のゼロ
- 管理するプロセスは1つのみ
- シンプルなデプロイ(1つのバイナリ、1つの設定ファイル)
- 開発または単一ユーザーセットアップ用の最小限のスタック
最後の言葉
ルーターモードは llama-server にとって意味のある前進です。
長年の要望に答えています。
llama.cppサーバーのルーターモードとは何ですか?
静的バイナリを動的推論サービスに変える欠けていたレイヤーです。カタログ全体のモデルのリクエストに対応できる1つのプロセスです。
しかし、それはまだ完成していません。
現在は以下のような状態です。
- 実際のワークロードに十分強力
- より洗練されたルーティングの基盤として有望
- 設定と安定性の面で少し荒削り
ワークロードが予測可能で、モデルごとにリクエストをグループ化できる場合、ルーターモードは今日でも良好に機能します。本番環境グレードの信頼性とモデルごとの分離が必要な場合は、ネイティブ実装が成熟する間に llama-swap を選択してください。
ベンチマーク実行、メンテナンスウィンドウ、またはクリーンな開発リセットのために再起動せずにVRAMを解放する必要がある場合、スクリプタブルなアプローチはロード済みモデルをリストし、各モデルに対してアンロードエンドポイントを呼び出すことです。完全なcurlとjqのパターンは 再起動せずにすべてのllama.cppルーターモデルをアンロード でカバーされています。
いずれにせよ、Ollamaのような動作を、仕組みを隠さずに手に入れることができます。