Skip to main content

ローカルLLM(mlx / mlx-vlm / llama.cpp)を OpenAI 互換 API で束ねるマルチモデルゲートウェイ。gateway.toml のカタログを 1 ポートで配信し、model で振り分け・遅延起動・LRU 退避・MTP 高速化(Ollama 流の共有デーモン)

Project description

local-llm-server

ローカルLLM(mlx / mlx-vlm / llama.cpp)を OpenAI 互換 API で束ねる マルチモデルゲートウェイ。Ollama と同じイメージで、gateway.toml(モデルカタログ)を 書いて 1 プロセス起動するだけ。1 つの公開ポートで複数モデルを配信し、リクエストの model で振り分ける。

  • モデルは初回リクエスト時に遅延起動max_resident 超過で LRU 退避、idle_timeout で自動アンロード(Ollama の keep-alive 相当)。外部アプリ(Ollama / LM Studio)に依存しない。
  • **MTP(投機的デコード)**で本体の出力を変えず ~2倍速(mlx-vlm)。
  • クライアントは公開ポートに繋いで model を選ぶだけ(クライアントはサーバーを起動しない)。
  • ゲートウェイ・MTP 解決は標準ライブラリのみ、付属の高レベルクライアントは公式 openai SDK(コア依存)。推論バックエンドだけ extra で導入。

インストール(uv

uv add "local-llm-server[mlx]"

extras 指定はクォート必須(zsh の glob 展開回避)。内訳:

extra 入るもの 用途
(無し) コア(標準ライブラリ + openai ゲートウェイ・MTP・connect/LLMClient まで全部
mlx mlx-lm / mlx-vlm Apple Silicon で実際に推論する

connect / LLMClient などライブラリ機能は uv add "local-llm-server[mlx]" だけで すべて使える(client 用の追加 extra は不要)。高レベルクライアントは公式 openai SDK を土台にしており、自動リトライ・型付き応答・ツール呼び出し/構造化出力も使える。

使い方

1. gateway.toml(モデルカタログ)を書く

カレントディレクトリに gateway.toml を置く。これがサーバーの唯一の設定。リポジトリ直下に すぐ使える例を同梱(→ gateway.toml):

host = "127.0.0.1"
port = 8799                 # 公開ポート。クライアントの base_url はここ
max_resident = 1            # 同時常駐モデル数の上限。超えたら LRU 退避(省略時 無制限)
idle_timeout = 600          # 10分使われないモデルは自動アンロード(0/省略で無効)
draft_model = "auto"        # MTP の既定(各 [[models]] で上書き・"off" で無効)

[[models]]
model = "mlx-community/Qwen3.6-27B-4bit"   # マルチモーダル(テキスト+画像)
backend = "mlx-vlm"

[[models]]
model = "mlx-community/gemma-4-26B-A4B-it-qat-4bit"
backend = "mlx-vlm"

2. ゲートウェイを起動する

gateway.toml のあるディレクトリで起動するだけ(管理者の唯一の操作):

uv run local-llm-server

1 つの公開ポート(例 http://127.0.0.1:8799/v1)でカタログのモデルを束ねる。各モデルは 初回リクエスト時に遅延起動し、2 回目以降は常駐して即応答。max_resident 超過は LRU 退避、 idle_timeout で自動アンロード。

3. 接続する(OpenAI 互換 API、model で選ぶ)

クライアントは公開ポートに繋ぎ、model で使うモデルを選ぶだけ(api_key は任意)。

curl -s http://127.0.0.1:8799/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "mlx-community/Qwen3.6-27B-4bit",
    "messages": [{"role": "user", "content": "俳句を一つ詠んでください。"}]
  }' | python3 -c "import sys, json; print(json.load(sys.stdin)['choices'][0]['message']['content'])"

Python(付属の LLMClientopenai SDK が土台):

from local_llm_server import LLMClient

llm = LLMClient(model="mlx-community/Qwen3.6-27B-4bit",
                base_url="http://127.0.0.1:8799/v1")
print(llm.respond("ローカルLLMの利点を3つ。"))                # 非ストリーム → str
for piece in llm.respond("もっと詳しく", stream=True):         # ストリーム → Iterator[str]
    print(piece, end="", flush=True)

llm.openai で土台の openai クライアントに直接アクセス(embeddings / tool calling / 構造化出力 / async など)。openai 等の他クライアントも同じ base_url にそのまま繋がる。

運用(status / stop)

uv run local-llm-server --status   # 稼働確認(カタログ=全モデル・pid・ログパス)
uv run local-llm-server --stop     # ゲートウェイ停止(配下のモデルサーバーも全て停止)

Ctrl+C / kill でも、起動済みのモデルサーバーまで一緒に止まる(孫プロセスは残らない)。

ライブラリ API(ゲートウェイを使わず Python から直接)

ゲートウェイを介さず、コードから単一モデルサーバーを起動・利用することもできる:

from local_llm_server import connect

# サーバーが無ければ MTP 付きで自動起動 → 繋がった client を返す(相乗りも可)
llm = connect(model="mlx-community/Qwen3.6-27B-4bit", draft_model="auto")
print(llm.respond("こんにちは"))
llm.stop()   # 自動起動した場合のみ停止

ensure_server()(相乗り/自動起動)、LocalServer / ServerConfig / ServerPool (サーバー制御)、GatewayServer / load_gateway_config(ゲートウェイ自体の組み込み)も公開。

MTP(投機的デコード)

本体モデルの出力を変えずに ~2倍速にする高速化(Qwen3.6-27B で実測 38→75 tok/s、採択率 93%)。gateway.tomldraft_model = "auto"(または connect(draft_model="auto"))で、本体名 から対応ドラフターを自動選択する(mlx-vlm 限定。"off" で無効、HF id で明示も可。対応表 MTP_DRAFTERS / 解決 resolve_drafter)。

examples

実機で動く完全なサンプル(Apple Silicon)。uv run するだけで動く:

uv run examples/connect_and_generate.py    # 自動起動 + 生成(最短)
uv run examples/generate_with_mtp.py       # LocalServer + openai で MTP 生成 + tok/s 表示

詳細は examples/README.md

ライセンス

Apache-2.0

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

local_llm_server-0.6.0.tar.gz (47.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

local_llm_server-0.6.0-py3-none-any.whl (41.1 kB view details)

Uploaded Python 3

File details

Details for the file local_llm_server-0.6.0.tar.gz.

File metadata

  • Download URL: local_llm_server-0.6.0.tar.gz
  • Upload date:
  • Size: 47.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.7

File hashes

Hashes for local_llm_server-0.6.0.tar.gz
Algorithm Hash digest
SHA256 4f61e28e47290e70c37c6f3804a28cd11559c012495db501056699714f7a39e3
MD5 819e00fab105731da3f64b7b47a95767
BLAKE2b-256 edf0182f5b354308c86d8e3afccd8ef268a23b1b4f25979218170a2c6a61610e

See more details on using hashes here.

File details

Details for the file local_llm_server-0.6.0-py3-none-any.whl.

File metadata

File hashes

Hashes for local_llm_server-0.6.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f39744f246de57f5bf80615078a14e0cb7eb8a754e7800e8422a817e3bb52235
MD5 34988baee75b1da046c1822cb73f7c63
BLAKE2b-256 bfe1f9515dfae881a5072567d4d9d35197a2e665425e4d1662e406bc336f6aa6

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page