mcpField
S
serve-model

serve-model

github.com/modularクラウド・DevOps207957 回インストール3 日前に更新
リポジトリ

serve-model について

serve-modelは、MAXで既存モデルを実行する手順を案内するスキルです。最小限のコマンドから始め、アーキテクチャやチェックポイントに基づく設定と起動時の問題解決を支援します。

主な機能

  1. 01カスタムアーキテクチャ向けコマンドの提案
  2. 02デバイス、エンコーディング、コンテキスト長の選択
  3. 03サーバーの起動と準備状態の確認
  4. 04起動エラーのトラブルシューティング

活用シーン

  1. 01MAXで組み込みモデルを起動
  2. 02既存のカスタムアーキテクチャを提供
  3. 03max serveの起動失敗を診断

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/modular/skills --skill serve-model

インストール後、Claude Code で/serve-modelを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
custom-arch.md
flags.md
troubleshooting.md
scripts/
suggest_serve_command.py

詳細

MAX でモデルをサーブする

max serve は、モデル用の OpenAI 互換 HTTP サーバーを起動します。トークン化、バッチ処理、KV キャッシュ、サービングスタック全体を処理します。チェックポイントを指定し、モデルが MAX に組み込まれていない場合は、カスタムアーキテクチャのパッケージも指定します。このスキルでは、「環境がない」状態から「サーバーがリクエストに応答する」状態までの手順を説明し、推測に頼らず、特定のモデルに合ったフラグを選ぶ方法を紹介します。

基本方針は、まず動作する可能性がある最小限のコマンドから始め、モデルやハードウェア上の必要に応じてのみフラグを追加することです。MAX は、ほとんどの項目(dtype、シーケンス長、デバイスのデフォルト設定)を自動検出します。フラグの指定しすぎは、動作していたサーバーを壊してしまう最も一般的な原因です。

このスキルを使う場合:MAX でモデルを実行、起動、またはホストする場合。OpenAI 互換エンドポイントを立ち上げる場合、組み込みアーキテクチャまたはカスタム/移植済みアーキテクチャをサーブする場合、あるいは max serve の起動エラーをデバッグする場合に使います。

このスキルを使わない場合:モデルがまだ MAX に実装されていない場合(動作する arch.py、グラフ、重みがない場合)。これはモデルの導入作業です。アーキテクチャの移植には import-model を、サーブはできるものの出力が正しくない場合には debug-model を使ってください。このスキルは既存のモデルを実行するものであり、モデルを作成するものではありません。

参考資料

ファイル次の場合に参照する
references/custom-arch.mdカスタムアーキテクチャをサーブする場合:arch.py からフラグへの対応、エンコーディングとデバイス、サーブ時の注意点
references/flags.md--model、--devices、--quantization-encoding、--max-length 以外のサーブフラグを選ぶ場合
references/troubleshooting.mdmax serve の起動エラーや、内容が分かりにくいエラーが発生した場合

すべてを最初から読むのではなく、作業内容に応じた参考資料を参照してください。

最短手順(カスタムアーキテクチャ):まずはこれを実行する

MAX がすでにインストールされており、動作するカスタムアーキテクチャのパッケージがある場合、必要な作業は次の 4 回の呼び出しだけです。arch.py と config.json を自分で読んで、フラグについて考える必要はありません。同梱のインスペクターがまさにその作業を行い、実行可能なコマンドとその根拠を表示します。

# 1. Get the recommended command + notes (reads arch.py + config.json for you).
python <skill>/scripts/suggest_serve_command.py \
  --custom-architectures /abs/path/to/my_arch --model <hf-repo-or-path>

# 2. Launch it (add `pixi run` if in a pixi project). On a REMOTE box, wrap with
#    `setsid ... </dev/null` so it survives the SSH session:
setsid <the suggested command> </dev/null > /tmp/max-serve.log 2>&1 &

# 3. Wait for readiness in ONE call (fails fast on a crash; ~10 min budget for
#    a cold compile, advancing `Still compiling` heartbeats are normal):
timeout 600 bash -c 'until grep -qE "Server ready|Uvicorn running" /tmp/max-serve.log; do
  grep -qiE "Traceback|CRASHED|Error building|cannot be found|not found in registry" /tmp/max-serve.log && { echo SERVE_FAILED; tail -30 /tmp/max-serve.log; exit 1; }
  sleep 3; done' && echo SERVE_READY

# 4. Confirm with one request (model field must equal --served-model-name):
curl -s http://localhost:8000/v1/chat/completions -H "Content-Type: application/json" \
  -d '{"model":"my_arch","messages":[{"role":"user","content":"The capital of France is"}],"max_completion_tokens":32}'

インスペクターの # notes: を確認してください。注意点(チェックポイントと一致しない default_encoding、組み込みの名前との衝突、GPU 専用のエンコーディング、MoE など)がここに表示されます。コマンドが動作し、出力に問題がなければ完了です。以下の詳細な手順に進むのは、注意書きやエラーから必要だと分かった場合だけにしてください。このドキュメントの残りの部分では、インスペクターの処理内容と、インスペクターだけでは不十分な場合の対処方法を説明します。

1. MAX がインストールされていることを確認する

ユーザーには、nightly ビルドの max バイナリが必要です。まず確認し、すでにインストールされている場合は再インストールしないでください(max serve コマンドが動作するのは、プロジェクトに max[serve] または max-serve の追加依存関係が含まれている場合のみです)。

max serve --help           # already in a MAX env?
pixi run max serve --help   # or inside a pixi project

max serve コマンドを使用できない場合は、環境をセットアップします。デフォルトは pixi です。重要なのは、conda チャネル https://conda.modular.com/max-nightly/ と conda-forge です。pixi がまだインストールされていない場合は、https://pixi.prefix.dev/latest/#installation にある最新の手順に従ってインストールしてから、次を実行します。

# pixi (conda channels)
pixi init my-max-project \
  -c https://conda.modular.com/max-nightly/ -c conda-forge && cd my-max-project
pixi add max-serve

すでに pixi.toml が存在する場合、channels の行は次のとおりでなければなりません。

[workspace]                                # or [project] on older pixi
channels = ["https://conda.modular.com/max-nightly/", "conda-forge"]

conda の代わりに Modular のホイールインデックスから MAX を取得する uv を好むユーザーもいます。uv がまだインストールされていない場合は、https://docs.astral.sh/uv/getting-started/installation/ にある最新の手順に従ってインストールしてから、次を実行します。

# uv (pip wheels)
uv init my-max-project && cd my-max-project
uv venv && source .venv/bin/activate
uv add "max[serve]" --index https://whl.modular.com/nightly/simple/ --prerelease allow

pixi のセットアップ後は、コマンドの前に pixi run を付けるか、pixi shell に入ってください。uv の場合は、仮想環境を有効化して(source .venv/bin/activate)、max を直接実行します。このスキルの以降の手順では max serve ... と記載しています。pixi プロジェクトでシェルに入っていない場合は、コマンドの前に pixi run を付けてください。

2. 組み込みモデルか、カスタムアーキテクチャかを確認する

MAX には多くのアーキテクチャが付属しています。モデルのアーキテクチャがすでにサポートされている場合、--custom-architectures は不要で、--model のみを指定します。

max list                 # every registered architecture + example repo IDs

チェックポイントの config.json::architectures[0](例:LlamaForCausalLM、Qwen2ForCausalLM)をこのリストと照合します。

  • リストにある:組み込みです。手順 4 に進み、--custom-architectures は省略します。
  • リストにない:カスタムアーキテクチャパッケージが必要です(手順 3)。ユーザーがまだ用意できていない場合、このスキルでは作成できません。これは 立ち上げ タスク(arch.py、model.py、グラフ、重みアダプターの実装)です。モデルの立ち上げワークフローを案内し、ここで終了してください。

3. カスタムアーキテクチャを対象にする

カスタムアーキテクチャは、SupportedArchitecture インスタンスのトップレベルの ARCHITECTURES リストを公開する Python パッケージ(__init__.py を含むディレクトリ)です。--custom-architectures にそのパッケージを指定すると、MAX がインポートし、各アーキテクチャを name で登録します。リクエストごとに、チェックポイントの config.json::architectures[0] を登録済みの name と照合します。

コマンドを作成する前に、パッケージを確認してください。パッケージのアーキテクチャ定義がフラグの大半の根拠になるため、推測は禁物です。次の 2 つのファイルを開いてください。

  • arch.py:SupportedArchitecture(...) の呼び出しです。default_encoding は使用するエンコーディング、supported_encodings は --quantization-encoding に指定できる値の集合です。name はチェックポイントと一致している必要があります。multi_gpu_supported はシャーディングに対応しているかを示します。パッケージに chat_template.jinja がある場合は、--chat-template が必要です。
  • config.json(チェックポイント):architectures[0] は arch.py の name と一致している必要があります。max_position_embeddings は --max-length の上限です。torch_dtype / quantization_config は default_encoding と一致している必要があります。MoE のフィールド(num_experts など)から、--device-graph-capture が必要かどうかを判断できます。

詳しいガイドは references/custom-arch.md にあります。arch.py からフラグへのフィールドごとの対応表、エンコーディングとデバイスの対応表、そして推論時に見落としやすい注意点(overlap-scheduler と logprobs の関係、port-8001 のメトリクスとの競合、trust-remote-code)が記載されています。カスタムアーキテクチャで推論を行う際は、必ず参照してください。

--custom-architectures には、パッケージのディレクトリを指定してください(スクリプトやリモートホストでは、絶対パスが最も安全です)。IMPORT_PATH:MODULE_NAME のコロン形式も使えますが、ほとんどのツールではディレクトリパスを使用します。

max serve --model <hf-repo-or-path> --custom-architectures /abs/path/to/my_arch

スタックトレースを読む前に、まず次の 3 点を確認してください。これで、カスタムアーキテクチャの推論で発生する問題のほとんどを防げます。

  1. SupportedArchitecture の name= が、config.json::architectures[0] と完全に一致していること。
  2. supported_encodings に、チェックポイントで実際に使われているエンコーディングが含まれていること(bf16 チェックポイントには bfloat16、GPTQ チェックポイントには gptq など)。
  3. weight_adapters に、チェックポイントの重み形式に対応する項目があること(.safetensors の場合は WeightsFormat.safetensors、.gguf の場合は WeightsFormat.gguf)。

モデルに、すでに動作するカスタムアーキテクチャパッケージがない場合(グラフ、重みアダプター、設定がまだ実装されていない場合)、それは推論ではなく、立ち上げの作業です。このスキルは既存のパッケージで推論を行うものであり、パッケージを作成するものではありません。

4. serve コマンドを構築する(デフォルト優先)

最小限のコマンドから始めて実行します。残りは MAX に自動検出させましょう。

max serve --model <hf-repo-or-path> [--custom-architectures ...]

これだけで、0.0.0.0:8000 にバインドし、GPU があれば GPU で、なければ CPU でサービングし、チェックポイントから dtype を推定して、max_position_embeddings に基づいて max_length を設定します。GPU がデフォルトなので、一般的なシングル GPU のケースでは --devices を渡す必要はありません。シングル GPU で多くのモデルを使う場合、この最小限のコマンドだけで十分です。

具体的な理由がある場合に限り、フラグを追加します。特に使用することが多いのは、次の 3 つです。

フラグ追加する場合例
--devices特定の GPU を指定する必要がある場合、GPU 間でシャーディングする場合、または CPU を強制する場合(GPU はすでにデフォルトです)。--devices gpu:0 · --devices gpu:0,1,2,3 · --devices gpu:all · --devices cpu
--quantization-encodingリポジトリに複数の形式がある場合、または自動検出で誤った形式が選ばれる場合。--quantization-encoding bfloat16
--max-lengthモデルの最大値より短いコンテキストにしたい場合(KV メモリを節約します)、または収まるよう上限を設定する必要がある場合。--max-length 4096

それ以外(デバイスメモリ、バッチサイズ、タスクの選択、スライディングウィンドウ、trust-remote-code、マルチ GPU 並列処理、投機的デコード)については、references/flags.md を参照してください。設定するか迷うフラグを追加する前に読んでください。各フラグの役割と、設定しないほうがよい場合について説明されています。

判断する順序:

  1. まずデフォルトを試す。最小限のコマンドを試します。組み込みの構成では通常、自動検出が適切で、デフォルトのデバイスは GPU です。
  2. カスタムアーキテクチャの場合は、パッケージを読む。arch.py の default_encoding が --quantization-encoding の値になります。このエンコーディングによってデバイスが制約されます。fp8、fp4、gptq は GPU 専用であり、GPU はすでにデフォルトなので、これらの場合に --devices を追加する必要はありません(references/custom-arch.md を参照)。--max-length は config.json::max_position_embeddings 以下に設定します。チェックポイントにカスタムのモデリングファイルが含まれる場合は --trust-remote-code を、パッケージにチャットテンプレートが含まれる場合は --chat-template を追加します。これらは推測ではなく、パッケージと設定を確認すれば分かります。
  3. 選択に大きく影響する場合は、さらに調べる。スライディングウィンドウ、部分 RoPE、MoE ルーティングなど、一般的でない特性については、config.json を確認し、調査結果に基づいて references/flags.md から適切なフラグを選びます。
  4. 判断に迷ったら尋ねる。どの GPU が空いているか、必要なコンテキストの長さ、CPU と GPU のどちらを使うかなど、確認できない情報に判断が左右される場合は、推測するのではなくユーザーに尋ねます。誤った --devices や dtype を指定すると、失敗に時間がかかり、原因も分かりにくくなります。簡単に質問するほうが効率的です。

5. 起動して動作を確認する

起動します(バックグラウンドで実行し、後から確認できるログを出力します)。

max serve --model <hf-repo-or-path> [flags] > /tmp/max-serve.log 2>&1 &

SSH 経由でリモートマシン上で起動する場合、単独の & では SSH セッションが閉じたときに終了し、コンパイルが接続時間を超えることがあります。完全に切り離して実行します。

setsid max serve --model <hf-repo-or-path> [flags] </dev/null > /tmp/max-serve.log 2>&1 &

ログのハートビートを監視する単一の呼び出しで準備完了を待ちます。タイムアウトいっぱいまで待つのではなく、クラッシュ時には速やかに失敗します。

timeout 600 bash -c 'until grep -qE "Server ready|Uvicorn running" /tmp/max-serve.log; do
  grep -qiE "Traceback|CRASHED|Error building|cannot be found|not found in registry" /tmp/max-serve.log && { echo SERVE_FAILED; tail -30 /tmp/max-serve.log; exit 1; }
  sleep 3; done' && echo SERVE_READY

サーバーは準備ができると、次の行を出力します。

Server ready on http://0.0.0.0:8000 (Press CTRL+C to quit)

大規模モデルは初回起動時にコンパイルされます。Still compiling model (Ns elapsed) のハートビートが表示される間、何も出力されない時間があっても正常です。停止しているわけではありません。経過時間カウンターが稼働状況を示すシグナルです。カウンターが進んでいる間は待ち、カウンターが止まった場合(またはプロセスが稼働中なのにログの mtime が更新されなくなった場合)にのみ、サーバーが停止していると判断してください。

ヘルスチェックを行い、実際のリクエストを送信します。

curl -s http://localhost:8000/v1/health          # 200 when ready
curl -s http://localhost:8000/v1/models           # served model name

curl -X POST http://localhost:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "<hf-repo-or-path>",
    "messages": [{"role": "user", "content": "The capital of France is"}],
    "max_completion_tokens": 32
  }'

リクエストの model フィールドは、--model に渡した値(または上書きした場合は --served-model-name に渡した値)と一致している必要があります。レスポンスを読み、出力に一貫性があり、繰り返しや意味不明な内容になっていないことを確認してください。サーバーが稼働していても、単にサーバーが緑色になっただけでは起動確認は完了していません。サーバーは稼働しているのに出力が誤っている場合、それはサービングの問題ではなく、パリティ/正確性の問題です。

重みとコンパイル結果をキャッシュして、次回以降の起動を高速化する

モデルの初回サービング時には、重みのダウンロードとグラフのコンパイルが行われます。これが時間のかかる処理です。どちらの結果もキャッシュされるため、同じモデルを次回以降にサービングすると、大幅に速くなります。

  • 重みは huggingface_hub を通じて、共有の Hugging Face キャッシュにダウンロードされます(デフォルトは ~/.cache/huggingface です。保存先を変更するには HF_HOME を設定します)。 同じリポジトリを再度サービングする際は、キャッシュされた重みが再利用され、再ダウンロードは行われません。

  • コンパイル結果もキャッシュされます。両方のキャッシュを事前にウォームアップして(デモやデプロイの前に実施することで)、初回の max serve でダウンロードや Still compiling の待ち時間が発生しないようにするには、先に max warm-cache を実行します。

    max warm-cache --model <hf-repo-or-path> [--custom-architectures /abs/path/to/my_arch]
    

    コンパイル済みの成果物(MEF)はプラットフォーム固有です。そのため、同じハードウェア上でキャッシュをウォームアップするか、別のホストからデプロイ先向けにコンパイルする場合は cuda:sm_90 などの --target を渡してください。

トラブルシューティング

症状に合った項目を references/troubleshooting.md で確認してください。起動時の一見不可解なエラーでも、1 行で解決できるもの(エンコーディングの不一致、architectures[0] の名前の不一致、trust_remote_code、ロード時の OOM、使用中のポート、誤ったデバイスへのルーティング)を取り上げています。まずサービングのログを確認してください。実際のエラーは通常、最後のトレースバックより数行前にあります。

コメント