概要
オープンモデルは公開のペースが速く、新しいモデルが出るたびに「手元のvLLMで動くか」を確かめる作業が発生します。出たばかりのモデルは、インストール済みのvLLM安定リリースでは起動できないことがあります。一方で、検証のために本番で動いている推論環境を書き換えると、今使えている構成まで壊れて戻せなくなる恐れがあります。
本記事では、DigitalBaseの開発で新しいモデルを検証してきた経験をもとに、どの方式で新しいvLLMを試すかの見分け方、本番構成を壊さない試し方と巻き戻し、そして GPUや構成ごとに必要になる回避策の管理 を整理します。
新しいモデルが安定リリースで動かない理由
新しいモデルが動かない原因は、多くの場合次の2つのどちらかです。
| 原因 | 内容 |
|---|---|
| アーキテクチャの実装がない | モデルの構造(MoE、Mamba系のハイブリッドなど)にvLLMやTransformersがまだ対応していない |
| parserがない | tool callingやreasoningの出力形式を解釈するparserがまだ収録されていない |
たとえば社内の記録では、新しいMoEアーキテクチャのモデルを当時の安定リリースで読み込もうとすると、次のエラーで止まりました。
The checkpoint you are trying to load has model type `qwen3_5_moe` but Transformers does not recognize this architecture.
このときはnightlyビルドに上げることで起動できました。一方で、別の時期に検証した新しいモデルは、安定リリースのままで tool calling も画像入力も問題なく動きました。新しいモデルだから必ずnightlyが必要、というわけではありません。 まず安定リリースで試し、足りないものを特定してから次の手段を選びます。
どの方式を使うかを見分ける
新しいvLLMを試す方式は2つあり、どちらを使うかはモデル側の要求で決まります。
| 方式 | 使う場面 | 隔離の単位 |
|---|---|---|
| A. nightlyビルドを別のPython仮想環境に入れる | 対応がvLLMのmainブランチにすでに入っているモデル | 仮想環境(venv) |
| B. モデル専用のコンテナイメージを使う | mainにまだ入っておらず、専用のイメージタグが配布されているモデル | コンテナ |
見分けるには、モデルカードに書かれている起動コマンドを見ます。
vllm serve ...だけが書かれている場合は、Aで足りる可能性が高いvllm/vllm-openai:<モデル名>のように 専用のイメージタグ が指定されている場合は、そのparserやアーキテクチャがmainにまだ入っていないため、Bを使う
方式A:nightlyビルドを別のvenvで試す
本番のvenvには入れない
nightlyビルドは、必ず本番とは別のvenvに入れます。本番がvLLMを起動するのに使っているvenvに直接入れると、今動いている構成ごと壊れ、戻す手段がなくなります。
uv venv ~/venvs/vllm-nightly --python 3.12 uv pip install --python ~/venvs/vllm-nightly/bin/python \ -U vllm --torch-backend=auto \ --extra-index-url https://wheels.vllm.ai/nightly --prerelease=allow ~/venvs/vllm-nightly/bin/python -c "import vllm; print(vllm.__version__)"
切り替える前に対応を確認する
nightlyに目的の対応が入っているかは、切り替える前に確認できます。インストールしたパッケージの中を、parser名で検索します。
V=~/venvs/vllm-nightly/lib/python3.12/site-packages/vllm grep -ril "<parser名>" $V | head ls $V/reasoning/ ls $V/tool_parsers/
何も見つからなければ、nightlyでもそのモデルは動きません。parserだけでなくアーキテクチャの実装ごとないこともあるため、深追いせず方式Bに進みます。
切り替えと巻き戻し
切り替えは「vLLMを起動するPythonのパス」を設定ファイルの1行で新しいvenvに向けるだけにしておくと、巻き戻しはその行を消して再起動するだけで済みます。モデル名や、モデルカードにある追加の起動オプション(tool call parser、reasoning parserなど)も、同じ設定ファイルにまとめておきます。
完全に片付ける場合は、nightly用のvenvのディレクトリを削除します。本番のvenvには一切触れていないため、元の構成はそのまま残ります。
方式B:モデル専用のコンテナイメージで動かす
mainに入っていないparserやアーキテクチャは、モデルの提供元が専用のイメージを配布していることが多くあります。業務アプリがvLLMとOpenAI互換のHTTP APIで通信する構成であれば、vLLMがホストのvenvで動いていてもコンテナで動いていても、接続先のURLを変えるだけで使えます。
GPUを空けてから起動する
既存のvLLMがGPUメモリを確保したままだと、コンテナは起動できません。先に既存のサービスを止め、nvidia-smi でメモリが解放されたことを確かめます。コンテナから --gpus all でGPUを使うには、DockerとあわせてNVIDIA Container Toolkitが必要です。
docker run -d --name vllm-test --gpus all --ipc=host \ -p 8000:8000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ vllm/vllm-openai:<tag> \ <org>/<model> \ --max-model-len 131072 \ --enable-auto-tool-choice --tool-call-parser <parser> \ --reasoning-parser <parser> docker logs -f vllm-test curl -s localhost:8000/v1/models
モデルの置き場所
HuggingFaceのキャッシュをコンテナにマウントすれば、venv側とコンテナ側でダウンロード済みのモデルを共有できます。キャッシュのディレクトリ構成は両者で同じです。
HuggingFaceを経由しないモデル(社内で配布されたもの、オフラインで持ち込んだものなど)は、config.json・*.safetensors・トークナイザ一式が入ったディレクトリをマウントし、そのパスをモデル名の代わりに渡します。外部への接続を完全に断つ場合は -e HF_HUB_OFFLINE=1 を付けると、起動時のメタデータの問い合わせも止まります。
撤去
docker rm -f vllm-test docker rmi vllm/vllm-openai:<tag>
専用イメージは10GB級になるため、評価が終わったらイメージも削除します。
評価の観点
起動できたことは、評価の入り口にすぎません。次の点を順に確かめます。
- 起動ログ:
/v1/modelsが応答するまでのログに警告やエラーがないか。量子化モデルの場合は、どのカーネルが選ばれたかの行も確認する - tool callingとreasoning:モデルカードどおりのtool call parserとreasoning parserが指定され、ツール呼び出しが期待どおりに返るか
- 画像入力:マルチモーダルモデルなら、画像付きのリクエストが通るか
- 性能:生成速度・TTFT・並列スループットを、前のモデルと同じ条件で測る
parserはモデルの系統によって決まるため、アプリ側で既定値を決め打ちしない方が安全です。そのうえで、tool call parserが設定されていないサーバーにはツール付きのリクエストを送らず、「このモデルではtool callingが設定されていない」と明示的にエラーにしておくと、原因の切り分けが容易になります。
よくあるつまずき
| 症状 | 原因 | 対処 |
|---|---|---|
max_num_seqs (256) exceeds available Mamba cache blocks (N) | Mamba系のハイブリッドモデルは、デコード1本につきMamba用のキャッシュブロックを1つ使う。既定の256がブロック数を超えている | --max-num-seqs をN以下にする |
Free memory on device ... is less than desired GPU memory utilization | 先に起動したchatサーバーがメモリを確保し、後から起動したembeddingサーバーの取り分がない | 各サーバーの gpu_memory_utilization の合計を0.90程度までに抑える |
KVキャッシュが max_model_len より小さい | max_model_len を指定せず、モデルの既定値(262144など)が使われた | --max-model-len を明示する |
Device capability 8.9 not supported の警告が出るが動く | Ada世代では一部の通信最適化が無効になるだけ | 無視してよい |
社内の検証では、あるMamba系ハイブリッドモデルが、VRAMに余裕のある構成では設定なしで動き、VRAMの少ない構成ではコンテキスト長を131072に制限し、--max-num-seqs 128 を指定して初めて起動しました。同じモデルでも、GPUの構成によって必要な設定が変わります。
量子化とGPUの世代
| チェックポイント | Ada(SM 8.9) | Blackwell(SM 10.x・12.x) |
|---|---|---|
| NVFP4 W4A16(重みのみ4bit) | 動く(Marlinで展開) | 動く(ネイティブ) |
| NVFP4 W4A4(活性化も4bit) | ネイティブのカーネルがない。動いてもエミュレーションで低速 | 動く |
| AWQ・GPTQ(重み4bit) | 動く | 動く |
モデルカードに「Blackwell required」と書かれていれば、Ada世代での性能は期待できません。起動ログのカーネル選択の行で、実際にどの経路で動いているかを確認します。
GPU・構成ごとの回避策を管理する
vLLMを新しいバージョンに上げたり、新しいGPUで動かしたりすると、特定の条件でだけ起動に失敗したり、不安定になったりすることがあります。社内で実際に必要になった回避策の例です。
| 条件 | 症状 | 回避策 |
|---|---|---|
| SM 12.x(Blackwell系)でブロック単位のFP8モデル | DeepGEMMにsm_12x向けのカーネルがなく、起動に失敗する | VLLM_USE_DEEP_GEMM=0(MoEは VLLM_MOE_USE_DEEP_GEMM=0 も) |
| nvccがなく、FlashInferのビルド済みカーネルもない | JITコンパイルができない | FlashInferのsamplerを無効にする。FP8のKVキャッシュならTriton attentionを使う |
| GeForce・RTX PROを複数枚使うtensor parallel | PCIe越しのP2P通信でNCCLの初期化が止まる、または落ちる | NCCL_P2P_DISABLE=1、--disable-custom-all-reduce |
| WSL2 | pinned memoryが既定で無効 | VLLM_WSL2_ENABLE_PIN_MEMORY=1(有効にするとデコードが約12%速くなる) |
| CPUとGPUがメモリを共有する機種 | 起動時のメモリ確保で共有領域を使い切り、ホストが固まる | PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True、--max-num-seqs 32 |
回避策は、増えるほど「なぜ入れたのか」「もう不要なのか」が分からなくなります。DigitalBaseでは、回避策を1件ずつ次の項目を持つデータとして定義し、起動時に条件を判定して自動で適用しています。
- 適用条件:GPUの世代、枚数と種類、nvccの有無、WSL2かどうか、など
- 理由と上流のissueのURL
- 追加した日と外す条件(「このissueが閉じ、回避策なしで起動できたら」など)
- 利用者が同じ環境変数や起動オプションを明示的に指定していれば、そちらを優先する
適用中の回避策は管理画面のエンジン情報に表示します。新しいvLLMに上げるたびに外す条件を確かめ、不要になったものを削除します。
本番のエンジンを更新するときの順序
検証が済んで本番のvLLMを更新するときは、次の順序を守ると、失敗しても今の構成を残せます。
- 入るかを先に確かめる:
uv pip install --dry-runで依存関係が解決できるかを確認する。解決できなければ、サービスを止めずに中断する - 止めてから入れ替える:解決できることを確かめてから、サービスを止めてvenvを作り直す
- 入ったものを確かめる:インストールされたvLLMのバージョンが指定どおりか、torchのビルドがそのGPU向けかを確認する
- 巻き戻しはバージョン指定で:前のバージョンを指定してもう一度インストールする
nightlyのバージョン表示は 0.x.yrc1.devNN+g<コミット> のようにビルドごとに異なります。本番で使う場合は、評価したときのバージョン表示を控えておくと、後から同じものかどうかを確かめられます。
まとめ
新しいオープンモデルをvLLMで動かす際の要点は、次のとおりです。
- まず安定リリースで試す:新しいモデルでも安定リリースのままで動くことがある。動かなければ、足りないのがアーキテクチャかparserかを特定する
- 方式を見分ける:モデルカードの起動コマンドが
vllm serveだけならnightly、専用イメージタグがあればそのコンテナを使う - 本番を壊さない:nightlyは別のvenvに入れ、切り替える前にparserが収録されているかを確かめる
- 評価は起動の先まで:ログ、tool calling、画像入力、性能を前のモデルと同じ条件で確かめる
- 回避策は理由と外す条件ごと管理する:GPUの世代や構成ごとの回避策を、issueと外す条件とともに記録し、更新のたびに見直す
モデルの更新は今後も続きます。試す・評価する・戻す手順を決めておくことで、新しいモデルを安全に取り込めるようになります。