OpenAI互換エンドポイントのサービング
エンジンを一度起動してチャットウィンドウで話すなら、おもちゃを持っている。全員がすでに話す形でHTTP越しにサーブするなら、インフラを持っている。エディタ、UI、エージェント、自分のスクリプトがすべて同じローカルモデルを操縦できる。このページはローカルエンドポイントを立ち上げ、その後ストリーミング、SDK、セキュリティ、ウォームロードを扱う。
OpenAIの形が勝った理由
chat-completionsリクエスト形式——モデル名、{role, content}メッセージのリスト、いくつかのノブ——は、すべてのツール作者が最初にそのクライアントを書いたことで事実上の標準になった。会社をどう思おうと、形は中立で、単なるPOST上のJSON。実用的な帰結:これを模倣するローカルサーバはすべて、既存ソフトウェアの巨大な山と瞬時に互換になる。エンジン選択とクライアント選択が独立した決定になる(エンジンを参照)。
1分でllama-server
llama-server -m model.gguf -c 8192 --port 8080
# UIは http://127.0.0.1:8080 —— APIは /v1/chat/completions
注釈付きリクエスト。
curl http://127.0.0.1:8080/v1/chat/completions -H "Content-Type: application/json" -d '{"model":"model","messages":[{"role":"user","content":"Why run local? One sentence."}],"temperature":0.7,"max_tokens":60}'
model——llama-serverは起動したものをサーブする。このフィールドは大抵無視されるが、まともな名前を送る。messages——会話全体。システムプロンプトが先頭。ステートレスなサーバで、履歴はあなたが保持。max_tokens——返信の上限。暴走生成から守る。
応答(トリム済み)は回答と、無料のデバッグに欲しくなるトークン会計を運ぶ。
{
"choices": [
{ "message": { "role": "assistant", "content": "No accounts, no rate limits, and your data never leaves the machine." } }
],
"usage": { "prompt_tokens": 14, "completion_tokens": 15 }
}
usageは、プロンプトが実際にコンテキストでいくらを要するかを知る方法——「忘れた」ことでモデルを責める前に確認(トークンを参照)。
ストリーミング
"stream": trueを追加すると、サーバはサーバ送信イベントに切り替わる。改行区切りのdata:チャンクが小さなデルタを運び、番兵で終わる。
data: {"choices":[{"delta":{"content":"No "}}]}
data: {"choices":[{"delta":{"content":"accounts"}}]}
data: [DONE]
クライアント側:[DONE]行までdelta.contentを蓄積する。ストリーミングは生成を速くしない——待ち時間を耐えられるようにするだけで、チャットUXでは同じこと(速度を参照)。
Ollama:1サービス、2つのAPI
OllamaのネイティブAPIはわずかに豊か——リクエストごとのオプションとモデルのライフサイクル制御。
curl http://127.0.0.1:11434/api/chat -d '{"model":"qwen3:8b","messages":[{"role":"user","content":"hi"}],"stream":false,"keep_alive":-1}'
さらにOpenAI互換ルートも/v1/chat/completionsでサーブするので、OpenAI型クライアントは変更なしでOllamaに対して動く。keep_aliveやリクエストごとのエンジンオプションが欲しいときはネイティブAPI、それ以外はすべて/v1。
GPUサーバ向けvLLM
vllm serve Qwen/Qwen3-8B --max-model-len 16384 --port 8000
vLLMはsafetensorsの重みを取得し、一度ロードし、その下でコティニュアスバッチングを効かせて同じOpenAI形をサーブする——同時ユーザーが現れたら正しい道具(同時実行を参照)。NVIDIA VRAMと本物のGPUを要求する。単一ユーザーのデスクトップに持ち出すな。
公式SDKをlocalhostへ向ける
公式OpenAIライブラリは単なるHTTPクライアント。ベースURLを交換すれば、APIキーフィールドは飾りになる。
from openai import OpenAI
client = OpenAI(base_url="http://127.0.0.1:8080/v1", api_key="local")
r = client.chat.completions.create(
model="qwen3-8b",
messages=[{"role": "user", "content": "Why run local?"}],
)
print(r.choices[0].message.content)
import OpenAI from "openai";
const client = new OpenAI({ baseURL: "http://127.0.0.1:11434/v1", apiKey: "ollama" });
const r = await client.chat.completions.create({
model: "qwen3:8b",
messages: [{ role: "user", content: "Why run local?" }],
});
サーバ側で設定されていない限り、キーには任意の文字列が使える。このベースURL交換が、あらゆる「ローカルモデルで動く」ツールのトリックのすべて。
これで解放されるもの
- エディタとチャットUI——UIと統合を参照。
- 自分のアプリ。自分のバックエンドの後ろのローカルモデル、トークンあたりコストゼロ。
- スキーマ保証のスクリプトパイプライン——構造化出力を参照。
- ツールを呼び反復するエージェントループ——エージェントを参照。
- このフォーラムのゲームコーナー。チェスとチャンギのエージェントは、上のcurlとまったく同じようにローカルchat-completionsエンドポイントを叩いてプレイする。
ドアに鍵を掛ける
モデルサーバは、ポートに届く誰にでも効く無料のLLMだ。デフォルトは安全——llama-serverとOllamaは127.0.0.1にバインドする——ノートPCではそのまま維持すること。LANに公開するには、APIキーを設定し(llama-serverとvLLMの--api-key、前面のUIの認証)、TLSにはリバースプロキシを推奨。認証なしで0.0.0.0にバインドするな。ネットワーク上の誰もがあなたのGPUを燃やし、コンテキストを埋め、構成を探れる。
ウォームに保つ
コールドロード——重みをディスクからVRAMへ——はTTFTに数秒〜数十秒を要求する。llama-serverとvLLMは起動時にロードして常駐するので、最初のリクエストだけが支払う。Ollamaはkeep_alive(デフォルト約5分)の後にアンロードする。"keep_alive": -1を送ればモデルを無期限に保持、0ならバースト後に直ちにVRAMを解放。「最初は遅く、その後は快適」に感じるなら、それは遅いモデルではなくコールドロード——負荷下では、ロードストームは現実の障害モード(同時実行を参照)。