vLLM をデプロイ production
vLLMを本番環境にデプロイするには、Linuxにインストールし(pipまたはDockerイメージ vllm/vllm-openai)、使用するモデルを指定して vllm serve を起動し、--gpu-memory-utilization と --max-model-len を設定して、--api-key を有効にしたうえで、前段にリバースプロキシを配置してください。サーバーはポート8000で待ち受け、OpenAI互換APIを提供します。一度に提供するモデルは1つだけで、多数のユーザーが同時に利用する場合のスループットを重視しています。
vLLM は、1 つの GPU を多数の並列リクエストで共有するために設計された推論サーバーです。本ガイドでは、必要なメモリ容量の見積もり(これが本題です)、インストール、起動、Docker と systemd、重要なパラメータ、スループットの測定、セキュリティについて解説します。また、重要な訂正点として、--api-key オプションが保護するのは一部のルートだけであることも説明します。
#vLLMでできることと必要な条件
vLLMは、カリフォルニア大学バークレー校のSky Computing Labで生まれたオープンソースの推論エンジンです。中心となる仕組みのPagedAttentionは、OSの仮想メモリのように、アテンションのキー・バリューキャッシュをページ単位で管理します。2023年のプロジェクトの初期発表によると、既存のシステムはメモリの大きな割合を無駄にしており、vLLMは当時のテストでHugging Face Transformersの最大24倍、TGIの最大3.5倍のスループットを達成しました。これらは古い数値で、そのベンチマーク環境に限られた結果です。方向性を示すものであり、お使いのモデルやGPUで得られる性能を示すものではありません。
動作要件として、現在のドキュメントではLinuxとPython 3.10〜3.13が必要とされています。Macでは、MLXを利用するvLLM-Metalという別の方法があります。サーバーはOpenAI互換のAPIを公開し、デフォルトではポート8000で待ち受けます。一度に提供できるモデルは1つだけなので、複数のモデルを提供するには複数のインスタンスが必要です。
#OllamaではなくvLLMを選ぶべき場面
お使いのマシンで、プライベートかつ無料のChatGPTを1時間で構築 — LM Studio、Ollama、Open WebUI、ご自身のドキュメント、クラウド不要。
- 永久に利用できるオンラインスペース
- PDF + ファイル
- 生涯アップデート
違いは、リクエストを並列に処理できるかどうかではなく、メモリの共有方法にあります。並列処理はOllamaでも可能です。OllamaのFAQによると、モデルの並列処理では、コンテキストサイズがリクエスト数倍になります。たとえば、2,000トークンのコンテキストで4件のリクエストを並列処理する場合、メモリ上では8,000トークン分のコンテキストが事前に確保されます。vLLMは必要に応じてキャッシュをブロック単位で割り当て、処理中のリクエストをまとめて同じ計算で処理します。
| 基準 | Ollama | vLLM |
|---|---|---|
| 同時ユーザー数 | 1 から数個まで;OLLAMA_NUM_PARALLEL は並列処理を制御します | 数十の同時リクエスト |
| 提供するモデル | 複数あり、必要に応じて読み込み・解放 | インスタンスごとに1つ |
| 導入 | コマンド1つでインストール | Python、CUDAおよび調整が必要なパラメータ |
| 量子化方式 | GGUF、幅広い選択肢 | Hubのフォーマット(AWQ、GPTQ、FP8);GGUFは一部対応 |
| モニタリングメトリクス | このガイドでは詳細に説明されていません | ドキュメントに記載された /metrics エンドポイント |
| 典型的な使用例 | 個人用、小規模チーム | 内部サービスまたは製品 |
実用上の目安として、モデルを同時に使う人数が3人未満の場合や、頻繁にモデルを切り替えたい場合は、Ollama で十分です。それ以上の人数で使う場合や、単一のモデルを継続的に提供する場合は、vLLM の複雑さに見合うメリットが得られます。比較ガイドで選び方を詳しく解説しています。
#vLLMが適切な選択でない場合
8〜12 GBのGPUを一人で使う場合、vLLMには利点がありません。共有キャッシュに必要なメモリが足りず、Ollamaやllama.cppのほうが簡単に起動できます。一日のうちに5つのモデルを切り替えて使う場合にも不向きです。モデルごとにインスタンスを起動し直す必要があるためです。Macでは別の方法を取り、MLXを使います。最後に、高負荷のAPIよりもチーム向けのチャット画面が必要な場合は、OllamaとOpen WebUIを組み合わせた構成のほうが適しており、運用の手間も少なくなります。
#必要なメモリ容量を見積もる:何よりも先に行う計算
vLLM サーバーの容量設計を左右するのは、モデルの重みではなく KV キャッシュです。モデルを読み込んだ後、vLLM は GPU メモリの一定割合を確保します。現在の設定コードによると、デフォルトは 92%です。その確保した領域のうち、モデルの読み込み後に残る容量をすべてキャッシュに充てます。この残りの容量によって、同時に保持できる会話トークン数、つまり同時に対応できるユーザー数が決まります。
Qwen2.5-7B-Instruct を例にとると、その仕様には 76.1億のパラメータ、28 層、4 つのキーバリューヘッド(Grouped-Query Attention)と記載されています。16 ビットでの重みは約 15.2 GB です。1 トークンのキャッシュは 2(キーとバリュー)× 28 層 × 4 ヘッド × 128 次元 × 2 バイトで、57 344 バイト、約 56 KiB になります。
| GPUメモリ | 92%を確保した場合のメモリ量 | キャッシュに使える残りのメモリ | キャッシュトークン(上限) | 4,096トークン相当のリクエスト |
|---|---|---|---|---|
| 24 GB | 22.1 GB | 6.9 GB | 約12万 | 約29 |
| 48 GB | 44.2GB | 28.9 GB | 約50万 | 約120 |
| 80 GB | 73.6 GB | 58.4 GB | 約100万 | 約250 |
これらの上限値は高めです。計算用バッファとCUDAグラフが残りのメモリの一部を消費し、モデルによってメモリ使用の特性が異なる場合もあります。この方法はどのモデルにも使えます。モデルの仕様に記載されたレイヤー数とキーバリューヘッド数を確認し、トークンあたりのメモリ使用量を計算して、残りのメモリ容量をその値で割ってください。ログにプリエンプションが記録されている場合、ドキュメントではgpu_memory_utilizationを増やすか、max_num_seqsを減らすことを推奨しています。
グラフィックカードを交換せずにキャッシュを拡大する方法は2つあります。量子化したモデルを読み込んで重みが占めるメモリの一部を空けるか、--max-model-len を制限して、誰も使わない長さのコンテキスト用にメモリが確保されるのを防ぐ方法です。前者は品質が少し低下する可能性があります。後者は、リクエストが短い限り、デメリットはありません。
#1. インストール
ドキュメントではuvが推奨されています。uvはCUDAドライバーに応じて適切なPyTorchのバージョンを自動的に選択します。AMD GPUの場合は専用のインデックスからインストールします。Intel、TPU、Ascend向けにはプラグインがあります。本番環境では、Dockerイメージを使うことでCUDAのバージョン競合を避けられ、タグを変更するだけで更新できます。
#2. サーバーを起動
vllm serve コマンドは、以前の python -m vllm.entrypoints.openai.api_server による起動方法に代わるものです。現在のドキュメントでは、以前の起動方法は使われていません。初回起動時には、モデルの重みが Hugging Face からダウンロードされます。ディスク容量を確保してください(16ビットの7Bモデルで約15GB)。サーバーはデフォルトでモデルリポジトリの generation_config.json を適用するため、モデルの提供元が推奨するサンプリングパラメータが使われます。--generation-config vllm を指定すると、vLLM のデフォルト値に戻ります。
#3. Docker および systemd
公式イメージvllm/vllm-openaiを使うのが最も安全な方法です。重みを再ダウンロードしないようにHugging Faceのキャッシュをマウントし、コンパイルキャッシュ用のボリュームもマウントしてください。そうしないと、新しいコンテナは毎回空のキャッシュで起動し、そのモデルの生成物を再コンパイルします。なお、このイメージはデフォルトでrootとして実行されます。ドキュメントには、非特権ユーザーで実行する方法(--user 2000:0)が記載されています。
#4. 重要な設定
| パラメータ | 役割 | アドバイス |
|---|---|---|
| --gpu-memory-utilization | 確保するGPUメモリの割合(デフォルトは0.92) | 別のプロセスがGPUを使用している場合は値を下げる。ログにプリエンプションが見られる場合は値を上げる。 |
| --max-model-len | 受け入れ可能な最大コンテキスト長 | できるだけ低く設定する:コンテキストの各トークンがキャッシュを消費するため |
| --max-num-seqs | バッチ内の最大リクエスト数 | メモリが不足する場合は値を下げる |
| --tensor-parallel-size | ノード内の複数のGPUにモデルを分散する | GPUに収まらない場合にのみ |
| --api-key | 特定のルートにはキーが必要です | セキュリティの節を参照してください:これだけでは不十分です |
| --generation-config vllm | モデルのgeneration_config.jsonを無視します | 期待と異なる回答が得られた場合に使用してください |
ドキュメンテーションの原則として、モデルが 1 つの GPU に収まる場合、分散処理はおそらく不要です。収まらないが 1 つのノードに収まる場合は、--tensor-parallel-size を使用してテンソル並列処理を行います。すでに量子化されたモデルは、特別なオプションなしで Hub から直接読み込むことができます。--quantization オプションは、動的量子化のみに使用されます。
#5. スループットを正しく測定する
vllm bench serve コマンドはサーバーにリクエストを送り、スループット、最初のトークンが出るまでの時間(TTFT)、トークン間のレイテンシを報告します。ドキュメントでは、これらのベンチマークは主に機能の評価とリグレッションの検出に使うものと説明されており、本番環境のサーバーのテストにはGuideLLMを推奨しています。
#稼働開始と運用
サイズ設定が完了すると、導入は常に同じ手順に従います。これは、20人程度のチームが24 GBまたは48 GBのカード上で70億から80億パラメータの同じモデルを照会する場合に適用されます。
- 01モデルとフォーマットを選択1インスタンスにつきモデルは一つです。利用可能なメモリに応じて、量子化済みのモデル、または16ビットのモデルを提供するリポジトリを優先してください。
- 02キャッシュを計算するサイジングのセクションにあるトークンあたりの計算を使って、--max-model-lenと--max-num-seqsを設定してください。
- 03Dockerで起動するアップデートで動作が変わるのを避けるため、Hugging Faceのキャッシュをマウントし、latestではなく固定したバージョンタグを指定して、公式イメージを使ってください。
- 04プロキシを追加ルートの許可リスト、TLS、レート制限を備えたリバースプロキシを配置し、さらに補助的な対策としてAPIキーを追加します。
- 05測定するvllm bench serveでシードを変えながら負荷テストを実行し、TTFTと総スループットを記録してください。
- 06監視する監視ツールで /metrics エンドポイントからメトリクスを収集するよう設定してください。
監視すべきなのは、キャッシュ不足の兆候です。ログに記録されるプリエンプション、TTFTの上昇、長くなる待ち行列が該当します。ドキュメントによると、プリエンプションはデフォルトでは再計算モードで動作し、サービスを保護する一方で、エンドツーエンドのレイテンシを悪化させます。頻繁に発生する場合は、gpu_memory_utilizationを上げるか、コンテキストを短くするか、同時リクエスト数を制限してください。最後の手段として、GPUを追加し、テンソル並列化でモデルを分散してください。
#6. セキュリティと公開:--api-key だけでは不十分です
よく見かける説明とは異なり、vLLMは--api-keyまたは環境変数VLLM_API_KEYを使ってAPIキーを検証できます。ただし、セキュリティドキュメントは、キーで保護されるのは/v1、/v2、/inference、/cohere配下のルートだけだと強調しています。それ以外のルートは認証なしのままで、/v1配下ではない推論ルート、/pauseや/abort_requestsなどの制御ルート、/healthも含まれます。したがって、--api-keyだけに頼ることは決して避けてください。
- リバースプロキシ
- vLLMの前段にnginx、Envoy、またはKubernetesゲートウェイを配置し、公開するルートだけを許可リストに登録して、それ以外のルートはすべてブロックしてください。
- ネットワーク
- VPNまたは隔離ネットワーク:分散デプロイメント内のノード間の通信はデフォルトで安全に保護されていません
- 開発モード
- 本番環境では VLLM_SERVER_DEV_MODE=1 を絶対に有効にしないでください。危険なルートが公開されます。
- 制限
- ドキュメントの推奨どおり、プロキシ側でレート制限とリクエストの検証を適用してください。
- ログ
- デバッグや監査のために、誰が何を送信したかを記録してください。
本番環境では、vLLMはOllamaより優れていますか?+
OpenAI互換APIを備えたvLLMサーバーを起動するにはどうすればよいですか?+
vLLM にはどのくらいのVRAMが必要ですか?+
vLLMのセキュリティを確保するには、--api-keyオプションだけで十分ですか?+
vLLMはMacまたはAMDカードで動作しますか?+
ご意見、誤りのご指摘、補足はありますか?ぜひお知らせください。皆さんにとってより良いガイドにするために役立ちます。