LLM・RAG

vLLMとは?PagedAttentionの仕組み・使い方とOllama・TensorRT-LLMとの違い・0.32.0の脆弱性対応

vLLMとは?PagedAttentionの仕組み・使い方とOllama・TensorRT-LLMとの違い・0.32.0の脆弱性対応

自社のGPUサーバーでLLMを動かす段になると、モデルを読み込むだけでは業務に耐えません。同時に来る何十本ものリクエストをさばき、GPUメモリを使い切らずに回し続ける層が要ります。その層を担うOSSが vLLM です。本記事では、速さの中核にあるPagedAttentionと連続バッチング、V1エンジンで作り替えられた内部構造、vllm serveで立てるOpenAI互換APIの実装、0.32.0未満に残る脆弱性2件への対処、そしてマネージドAPIから自社運用へ移す損益分岐までを、vLLM公式ドキュメントと2026年10月公開のセキュリティ勧告で確認しながら整理します(2026年11月時点)。推論そのものの仕組みはLLM推論の仕組みと高速化の手法で扱っているため、本記事はエンジン側に絞ります。

まとめ:vLLMの中核と使い方・自社運用の判断の結論

vLLMは、大規模言語モデルの推論とサービングを担うOSSの推論エンジンです。カリフォルニア大学バークレー校のSky Computing Labで生まれ、いまはGitHubのvllm-project/vllmで2,000人を超えるコントリビュータが開発を続けています。ライセンスはApache License 2.0で、商用の自社運用に制約は掛かりません。

速さの土台は2つ。1つはPagedAttentionで、KVキャッシュをOSの仮想メモリのようにページ単位で管理し、確保しすぎた余りや解放後の隙間をほぼ無くします。もう1つは連続バッチングとチャンク化プリフィルで、リクエストの終わりを待たずに次を差し込み、長いプロンプトを分割して生成処理を止めません。

使い方は短い手順で通ります。uv pip install vllmで入れてvllm serveを叩けばOpenAI互換のAPIサーバーが立ち上がり、アプリ側はエンドポイントとモデル名を差し替えるだけ。複数のモデルやマネージドAPIと併用するなら、前段のゲートウェイとしてLiteLLMを置く構成もあります。Anthropic Messages API形式とgRPCの提供も公表されています。

版の進み方は速く、PyPIの配布履歴では0.28.0が2026年8月26日、0.29.0が9月9日、0.30.0が9月22日、0.31.0が10月5日、0.32.0が10月18日と、ほぼ2週間おきに進んでいます。10月28日には、0.32.0未満に影響する脆弱性2件(SHMキャッシュ指定時にワーカーのpickle.loads()へ届く問題と、画像入力からGhostscriptが起動される問題)がGitHub Advisory Databaseに公開されました。本番の版は固定し、検証環境で先に通してから上げる前提は変わりません。そのうえで、0.32.0未満のまま公開エンドポイントを運用している環境は、更新を先に済ませてください。

判断の起点は機能表ではありません。月のトークン量が小さいうちや試作段階では、マネージドAPIのほうが総コストで有利。自社運用へ移す価値が出るのは、機密データを社外へ出せない、GPUを常時埋められる負荷がある、モデルや推論の挙動を自分で固定したいのいずれかに当てはまるときです。

vLLMが推論を速くする仕組み|PagedAttentionと連続バッチングの中身

まず、このエンジンが何を解いているのかを確定させます。

PagedAttentionはKVキャッシュをページ単位で管理して断片化を消す

LLMの生成では、これまでに処理したトークンのKey/Value(KVキャッシュ)をGPUメモリへ置き続けます。従来の実装はリクエストごとに連続した領域を先に確保していたため、実際の生成が短く終われば余りが遊び、解放後には隙間が残りました。空いているのに使えないメモリが積み上がる構造です。

PagedAttentionは、このKVキャッシュを小さな固定サイズのブロックに切り、非連続に割り当てます。着想はOSの仮想メモリとページングで、SOSP 2023採録の原論文「Efficient Memory Management for Large Language Model Serving with PagedAttention」ではKVキャッシュの無駄をほぼゼロに近づけたと報告されました。同じ論文の測定では、当時の主要な実装であるFasterTransformerやOrcaに対し、同じレイテンシで2〜4倍のスループットという値が示されています。なお、KVキャッシュの管理を担うPagedAttentionに対し、アテンション計算そのものを担うのがFLASH_ATTNバックエンドです。その中身はFlashAttentionの仕組みと実装判断で解説しています。

ページ単位にすると副産物も得られます。同じプロンプト接頭辞を持つリクエスト間でブロックを共有でき、並列サンプリングやビームサーチでメモリを重複させずに済む構造。キャッシュそのものの理論と削減手法はKVキャッシュによるLLM推論の高速化とメモリ削減の側で詳しく扱っています。

連続バッチングとチャンク化プリフィルが待ち時間を詰める仕組み

2つ目の柱はスケジューリングです。素朴な実装ではリクエストをまとめて1バッチにし、全部の生成が終わるまで次を受け付けません。生成の長さはリクエストごとに違うため、短く終わった分の計算資源が空回りします。

連続バッチングは、終わったリクエストの席を即座に空け、待っている次のリクエストを差し込みます。GPUが遊ぶ時間が減り、同じハードウェアでさばける本数が伸びる仕組み。ここにチャンク化プリフィルが重なります。長いプロンプトの読み込み(プリフィル)を一度に流すと、その間ほかのリクエストの生成が止まりますが、分割して少しずつ混ぜれば生成側の手が止まりません。

公式のチューニング解説によれば、V1ではチャンク化プリフィルは可能な場面で既定として有効です。しかも、スケジューリング方針は待機中のデコードを先にまとめてから、--max-num-batched-tokensの残り枠にプリフィルを差し込む順序。枠に収まらないプリフィルは自動で分割されます。この順序のおかげでトークン間の遅延が縮み、計算律速のプリフィルとメモリ律速のデコードが同じバッチに同居してGPUの使い切りが進むという説明です。

加えて、同じ接頭辞の計算結果を再利用するプレフィックスキャッシュ、n-gram・suffix・EAGLE・DFlashといった投機的デコーディングも並んでいます。

V1エンジンで作り替えられたスケジューラとKVキャッシュ管理の構造

vLLMは内部を一度作り替えています。この世代を「V1」と呼び、スケジューラ、KVキャッシュマネージャ、ワーカー、サンプラー、APIサーバーを再設計した構造。旧世代のV0はすでに完全に廃止され、公式のV1移行ガイドが移行を促しています。

設計上の変化で効くのは、統一スケジューラです。プロンプトのトークンと出力のトークンを区別せず同じものとして扱うため、プリフィルとデコードの位相を厳密に分ける必要がなくなり、チャンク化プリフィルやプレフィックスキャッシュ、投機的デコーディングが同じ枠組みに乗ります。

移行時に把握しておくべき差分も公表されています。CUDAグラフのキャプチャはV0よりメモリを食う、logprobsはロジットの後処理前の値が返る(処理後の値も選べる)、best_ofやリクエスト単位のロジットプロセッサ、GPUとCPU間でのKVキャッシュのスワップは削除、という4点。V0前提で書かれた古い記事や社内手順が残っていれば、この4点から見直してください。

vLLMをuvで入れてOpenAI互換サーバーを起動するまでの手順

ここからは実装です。公式のクイックスタートに沿って、導入から疎通確認までを順に通します。

uvで仮想環境を切りvLLMを導入して本番で使う版を固定する手順

前提として、公式が挙げるOSはLinux、Pythonは3.10〜3.13です。導入は、仮想環境を切ってからパッケージを入れる2段。GPUのバックエンド指定をautoにしておくと、インストールされているCUDAドライバの版を見て適したPyTorchの配布元が選ばれます。特定の版を狙うなら--torch-backend=cu126のように明示できます。

uv venv --python 3.12 --seed
source .venv/bin/activate
uv pip install vllm==0.32.0 --torch-backend=auto
vllm --version

3行目で版を打っているのは意図的です。0.32.0としているのは、後述する脆弱性2件の修正を含む版だからです(2026年11月時点)。本番の再現性を確保するには、GitHubのリリース一覧で差分を読み、検証環境で通した版だけを固定する運用を勧めます。恒久的な環境を作らず試すだけならuv run --with vllmでその場実行もできます。

NVIDIA以外の環境にも配布が用意されています。AMD GPUは専用のホイール配布元を追加する形、Google TPUはvllm-tpuパッケージ、Ascend NPUはコミュニティ保守のvLLM Ascend、Apple SiliconはMLXを計算バックエンドに使うvLLM-Metal。Intel GPU向けの公式Dockerイメージは0.26.0のリリースから同梱されるようになりました。

オフライン推論をPythonから実行して生成結果を確かめる手順

サーバーを立てずに、バッチでまとめて推論する使い方もあります。LLMクラスにモデル名を渡し、SamplingParamsで生成の設定を指定してgenerateを呼ぶ形です。評価用のデータセットを一括で流したいときは、この書き方が短く済みます。

from vllm import LLM, SamplingParams

prompts = ["Hello, my name is", "The capital of France is"]
sampling_params = SamplingParams(temperature=0.8, top_p=0.95)

llm = LLM(model="facebook/opt-125m")
outputs = llm.generate(prompts, sampling_params)

for output in outputs:
    print(output.prompt, output.outputs[0].text)

ここで指定するモデル名はHugging Faceのリポジトリ名です。vLLMはHugging Face上のモデルをそのまま読み込む設計のため、変換工程を挟まずに検証へ入れます。環境変数VLLM_USE_MODELSCOPEを立てればModelScope側から取得する経路にも切り替わります。

生成の設定には落とし穴が1つあります。既定では、モデル配布元のgeneration_config.jsonに書かれた推奨値が適用される挙動。vLLM側の既定値で揃えたい場合は、LLMを作るときにgeneration_configへvllmを指定してください。社内で温度やtop_pを比較検証するときは、この差でスコアが動きます。

vllm serveでOpenAI互換APIを立てcurlとSDKで疎通を取る

本番構成では、HTTPサーバーとして常駐させます。コマンドはモデル名を渡すだけで通り、既定で8000番ポートを開いてOpenAI互換のエンドポイントを公開する挙動。実務では容量に関わるオプションを最初から添えておくほうが手戻りが減ります。

vllm serve Qwen/Qwen2.5-1.5B-Instruct \
  --max-model-len 8192 \
  --gpu-memory-utilization 0.90 \
  --max-num-seqs 64 \
  --port 8000

立ち上がったら、まずモデル一覧のエンドポイントで応答を見て、次に生成のエンドポイントを1本叩きます。ここでモデル名の綴りとポートの開き方まで確認しておくと、アプリ側の配線に入ってからの切り分けが楽になります。

curl http://localhost:8000/v1/models

curl http://localhost:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{"model": "Qwen/Qwen2.5-1.5B-Instruct", "messages": [{"role": "user", "content": "自己紹介して"}]}'

クライアント側の書き換えは軽く済みます。OpenAIのSDKをそのまま使い、api_keyにダミー値、base_urlにローカルのエンドポイントを渡すだけで通ります。既存のアプリケーションがOpenAI APIを叩いている構成なら、差し替えは接続先とモデル名の2箇所です。

from openai import OpenAI

client = OpenAI(api_key="EMPTY", base_url="http://localhost:8000/v1")
completion = client.chat.completions.create(
    model="Qwen/Qwen2.5-1.5B-Instruct",
    messages=[{"role": "user", "content": "San Francisco is a"}])
print(completion.choices[0].message.content)

公式ドキュメントでは、OpenAI互換APIに加えてAnthropic Messages API形式とgRPCの提供も挙げられています。ツール呼び出しや推論過程のパーサ、構造化出力、ストリーミングも機能として並ぶため、APIからの載せ替え先として検証を始めやすい構成です。

起動時に決めるモデル長・メモリ使用率・並列度の3つのオプション

既定値のまま本番へ出すと、たいてい容量で詰まります。先に決めるのは次の3つです。

  • --max-model-len:扱う最大コンテキスト長。長く取るほどKVキャッシュを食う
  • --gpu-memory-utilization:GPUメモリのうちKVキャッシュへ先に確保する割合
  • --tensor-parallel-size:モデルを分割して載せるGPU枚数

1つ目のモデル長は業務要件から決めます。社内文書を丸ごと投げる想定がないなら短く切り、その分をKVキャッシュの余白へ回すほうが同時実行数は伸びます。2つ目の使用率は、確保しすぎればモデルの重みが載らず、絞りすぎればキャッシュが足りません。3つ目は単一GPUにモデルが収まらないときに引き上げる値で、収まるうちは1のままで構いません。

llama.cpp・TGI・TensorRT-LLMとの違いとvLLMを選ぶ判断軸

推論エンジンは複数あります。優劣ではなく担当領域で振り分けるのが実務です。

llama.cpp・Ollamaとの違いはGPU前提の同時処理能力にある

llama.cppとその上に乗るOllamaは、CPUと小さなGPUで動かすことを主眼に置いた実装です。1台の端末やサーバーで少数の推論を回す用途では扱いやすく、モデルの入れ替えも軽い。対してvLLMは、GPUを前提に多数の同時リクエストをさばくサービング基盤として設計されています。

分岐点は同時実行数です。社内の数人が順番に使う検証環境なら、vLLMの容量設計を組む工数は回収できません。全社の業務システムからリクエストが並列で飛ぶ構成になった段階で、連続バッチングとPagedAttentionの効きが費用差として表れます。GPUを持たない環境での構築手順はローカルLLMの構築手順とOllamaでの動かし方の側で扱っています。

TensorRT-LLM・TGI・SGLangと並べたときのvLLMの位置

GPU前提の同じ土俵にも複数の選択肢が並ぶ状況です。NVIDIAのTensorRT-LLMは同社GPUに寄せた作り込みが持ち味で、エンジンをビルドする工程を挟む代わりに単一構成での性能を詰められます。なお1.3系ではそのエンジンビルド工程自体が廃止され、実行フローはLLM APIとtrtllm-serveへ移りました。移行の実務と採用条件はTensorRT-LLMの仕組みと採用判断を解説した記事で整理しています。Hugging FaceのTGIは同社エコシステムとの結び付きが強く、SGLangは複雑なプロンプト制御やエージェント的な呼び出しの扱いに軸を置いた設計です。vLLMをTriton Inference Serverのバックエンドとして載せ、ほかのモデルと同じサーバーから配信する構成はTriton Inference Serverの設定手順と採用判断で整理しています。なおTGIは2025年12月にメンテナンスモードへ移り、2026年3月にリポジトリがアーカイブされました。提供状況と移行の判断はText Generation Inference(TGI)とはに整理しています。

エンジン 前提ハード 向く場面
vLLM GPU中心・CPUも可 多数同時のサービング
llama.cpp・Ollama CPU・小規模GPU 1台で少数の推論
TensorRT-LLM NVIDIA GPU 単一構成の性能追求
SGLang GPU 複雑なプロンプト制御

vLLMを選ぶ理由になりやすいのは、対応ハードウェアの幅です。公式にはNVIDIA GPU、AMD GPU、x86/ARM/PowerPCのCPUに加え、Google TPU、Intel Gaudi、IBM Spyre、Huawei Ascend、Rebellions NPU、Apple Silicon、MetaX GPUが挙がります。調達できるアクセラレータが読めない段階でも、載せ替えの余地を残せる構成です。

量子化形式ごとの対応GPU世代を互換表で確かめてから重みを選ぶ

量子化はGPUメモリを空ける主要な手ですが、形式と世代の組み合わせで動かない場面があります。公式の量子化ページには形式と対応ハードウェアの互換表が載っており、重みを決める前にここを見るのが早道。2026年9月時点で列挙されているのは、AutoAWQ、BitsAndBytes、GPTQModel、Intel Neural Compressor、LLM Compressor、FP8 W8A8、INT4 W4A16、INT8 W4A8/W8A8、NVIDIA Model Optimizer、オンライン量子化、AMD Quark、量子化KVキャッシュ、TorchAO、FP8 ViTエンコーダアテンションです。

形式 対応する世代 選ぶ場面
AWQ Turing以降のNVIDIA GPU GPU向けの主流
GPTQ Volta以降のNVIDIA GPU 旧世代GPUが残る構成
FP8 W8A8 Ada・Hopper・AMD GPU 新しい世代のGPU
INT8 W8A8 Turing以降とx86 CPU CPU構成でも通す場合
GGUF Volta以降とAMD GPU llama.cpp由来の資産

表で目を引くのは、Voltaのような古い世代でAWQが外れ、逆にGPTQとGGUFは通るという非対称です。手元のGPUが数世代前なら、形式の選択肢がここで絞られます。Intel Gaudi向けの量子化対応はvLLM-Gaudiへ移管された点も、調達済みハードがある場合は確認してください。

GGUFは事情がもう1つあります。読めますが、この形式はllama.cppの実行形式として設計されたものであり、CPUオフロードを含む単体実行に強みがある容器です。GPUを潤沢に確保してvLLMで並列にさばく構成なら、AWQやGPTQ、あるいはFP8系の重みを使うほうが素直。形式そのものの構造はGGUFの仕組みとGPTQ・AWQとの違いで詳しく扱っています。

ビット幅を落とすほどGPUメモリは空き、同時実行数へ回せます。ただし日本語の指示追従は落ちやすいため、代表タスクで品質を測ってから採用の可否を決める順番を崩さないでください。

起動ログでKVキャッシュ量と同時実行数を読み容量設計を詰める手順

運用で詰まるのは、ほぼメモリと同時実行数の綱引きです。勘で設定値をいじる前に、起動ログが吐く実測値を読みます。

起動ログのKVキャッシュ量と同時実行数の推定値を正しく読み取る

vLLMは起動時に、指定した割合のGPUメモリをKVキャッシュ用として先に確保し、その結果をログへ出します。公式の並列化ガイドが読み方まで示している2行が次のものです。

INFO 07-23 13:56:04 [kv_cache_utils.py:775] GPU KV cache size: 643,232 tokens
INFO 07-23 13:56:04 [kv_cache_utils.py:779] Maximum concurrency for 40,960 tokens per request: 15.70x

上の行は、GPU上のKVキャッシュへ一度に置けるトークン総数。下の行は、1リクエストが指定トークン数を使う前提で同時に何本さばけるかの推定です。ここでいう1リクエストあたりのトークン数は--max-model-lenの値が使われるため、モデル長を半分に切れば推定同時実行数はおおよそ倍になります。この15.70xという数字が業務要件の同時接続数に届いていなければ、設定値ではなくGPUかノードを足す局面だと切り分けられます。

余白を作る手は2つで、使用率の割合を上げるか、最大コンテキスト長を短く切るか。順番としては、モデル長を業務要件まで絞るほうを先に試します。使用率を上げすぎると、モデルの重みや実行時の作業領域が圧迫され、起動そのものが通らなくなる場面があるため。長文を投げる要件が本当にあるのかを業務側と確認し、必要な分だけ取るのが手戻りの少ない進め方です。なお、モデル側が学習長を超える指定を受け付けるかは位置エンコーディングの拡張設定で決まるため、RoPEの拡張方式の解説と併せて確認してください。

テンソル並列・パイプライン並列・データ並列を使い分ける判断基準

GPUを増やす方向にも順番があります。公式ドキュメントの指針は明快です。

  • テンソル並列:単一GPUにモデルが載らないとき。ノード内のGPU枚数を指定する
  • パイプライン並列:単一ノードにも載らないとき。ノード数を指定して層で分ける
  • データ並列:モデル全体を複製できるGPU数があるとき。同時利用者が多い構成に効く
  • エキスパート並列:MoE(Mixture of Experts)の仕組みとVRAM要件を持つモデル専用。エキスパートの計算をGPU間で均す

コマンドは、単一ノードならテンソル並列だけ、複数ノードなら両方を掛け合わせる形です。8枚のGPUを2ノードに分けるなら、テンソル並列にノード内の枚数、パイプライン並列にノード数を割り当てます。

vllm serve facebook/opt-13b --tensor-parallel-size 4

vllm serve gpt2 --tensor-parallel-size 4 --pipeline-parallel-size 2

公式が挙げる例外も押さえておくと事故が減ります。GPU枚数でモデルサイズが割り切れない構成では、層で分けるパイプライン並列のほうが不均等な分割を許容できるため、テンソル並列を1にしてパイプライン並列へGPU枚数を寄せる形が案内されています。NVLinkのないGPU(L40Sなど)でも、通信量の少ないパイプライン並列のほうが処理量で有利という記述。分散の実行基盤は、複数ノードならRay、単一ノードならPythonのマルチプロセスが既定で、--distributed-executor-backendで切り替えられます。

混同しやすいのはテンソル並列とデータ並列です。前者は1つのモデルを切って複数GPUへ分けて載せる手法で、後者は同じモデルを丸ごと複数用意して振り分ける手法。載らないから分けるのか、さばききれないから増やすのかで選ぶものが変わります。

プリエンプションの警告ログを見て設定値を4つの方向から見直す

バッチ中のリクエスト全部を抱えるだけのKVキャッシュが無くなると、vLLMは処理中のリクエストを退避させます。V1での既定の退避方式は再計算(RECOMPUTE)で、退避した分は後からもう一度計算し直す挙動。当然、端から端までの応答時間は悪化します。実際に出る警告は次の形です。

WARNING 05-09 00:49:33 scheduler.py:1057 Sequence group 0 is preempted by
PreemptionMode.RECOMPUTE mode because there is not enough KV cache space.
This can affect the end-to-end performance.
Increase gpu_memory_utilization or tensor_parallel_size to provide more KV cache memory.
total_cumulative_preemption_cnt=1

公式ドキュメントが示す対処は4方向です。GPUメモリ使用率を上げてキャッシュ領域を広げる、--max-num-seqsか--max-num-batched-tokensを下げて同時に抱える量を絞る、テンソル並列度を上げて1枚あたりの重みを軽くする、パイプライン並列度を上げて層を分散させる。後ろ2つには同期のオーバーヘッドや遅延の代償が付くと明記されているため、余白を広げられるなら前2つから手を付けます。

発生本数はPrometheusのメトリクスで監視でき、disable_log_statsを偽にすれば累計をログへ出せます。まず監視で件数を掴み、設定変更の前後で減ったかを見る順番にしてください。

処理量と応答性のつまみとしても、この値は効きます。--max-num-batched-tokensを2048程度の小さい値にするとトークン間の遅延(ITL)が改善し、大きく取ると最初のトークンまでの時間(TTFT)が改善する関係。処理量そのものを伸ばしたい場面では8192を超える値が案内されており、小さいモデルを大きなGPUで回す構成では特に効きます。なおチャンク化プリフィルを無効にする構成では、この値を最大モデル長より大きく取る必要があります。

コンパイルキャッシュと起動オプションで再起動の待ち時間を削る

見落とされやすいのが、サーバーの起動時間です。同じモデルと設定で何度も立ち上げ直す開発中や、ノードを入れ替える運用では、ここが待ち時間の主因になります。公式は3つの手を挙げています。

  • コンパイル成果物のキャッシュ再利用:既定は~/.cache/vllm配下で、コンテナイメージへ焼き込める
  • --kv-cache-memoryの指定:起動時のメモリ計測と推定の工程を丸ごと省ける
  • --enforce-eager:コンパイルとCUDAグラフの取得を省く代わり、定常時の性能は落ちる

1つ目には注意点が付きます。モデル・設定・環境変数・torchのビルド・GPUの機種のいずれかが変わるとキャッシュは無効になり、黙って再コンパイルへ落ちる挙動。VLLM_FORCE_AOT_LOADを立てておけば、キャッシュを外したときに失敗として気付けます。2つ目は、渡した値でKVキャッシュのサイズが固定される点が代償です。控えめな値を渡せば同時実行数の上限が下がり、強気な値なら確保の段階で落ちます。GPUや同居プロセスが変わって起動時にメモリ不足になったら、まずこのフラグを外して計測し直してください。

コンパイル段階の作り込みの度合いは-O0から-O3の4段階で選べ、既定は-O2。起動の速さと定常時の性能のどちらを取るかで下げ幅を決める設計です。

0.32.0未満に残る2件の脆弱性と公開エンドポイントで先に確かめる設定

2026年10月28日、GitHub Advisory DatabaseにvLLMの脆弱性が2件公開されました。どちらも影響範囲は0.32.0未満で、修正版は10月18日にPyPIへ出た0.32.0。9月以前に版を固定したまま運用している環境は、すべて対象範囲に入ります。版を固定して検証してから上げるという前節までの運用を、ここで実際に回す場面です。

項目 SHMキャッシュ 画像形式の判定
勧告ID GHSA-6757-hggm-hp2w GHSA-h3rc-j82p-2c3h
CVE CVE-2026-115912 CVE-2026-115915
CVSS v3.1 7.5(High) 8.1(High)
攻撃者に要る権限 推論APIの認証済み利用者 不要(経路に届けば可)
発動の前提 SHMキャッシュの指定 画像入力と旧Ghostscript
起こりうる被害 ワーカーで任意のPython実行 DoS・コマンド実行
修正版 0.32.0 0.32.0

SHMキャッシュ指定時に偽造ハンドルでpickle.loadsへ届くGHSA-6757

GHSA-6757-hggm-hp2w(CVE-2026-115912、CVSS v3.1で7.5)は、マルチモーダル入力の前処理結果を共有メモリ(SHM)経由でワーカーへ渡す設定に潜む欠陥です。--mm-processor-cache-type shmを指定すると、キャッシュ済みの項目は「アドレス」と「monotonic_id」の組だけで表され、ワーカーはこの組を信じて共有メモリを読みに行きます。ところが公開のスケールアウト用ルートは、利用者が送ったfeatures.kwargs_dataを検証せずにエンジンへ渡していました。認証済みの利用者であれば、偽の組を差し込めた構造です。

勧告に載った再現の流れは、通常のHTTPルートだけで完結します。/v1/chat/completions/renderで正規の特徴量の封筒を得て、/v1/chat/completionsで任意のバイト列をSHMのリングバッファへ置き、/inference/v1/generateへ偽の組を投げると、ワーカー側のpickle.loads()まで到達する手順。危険なシリアライズを許すVLLM_ALLOW_INSECURE_SERIALIZATIONを立てていない構成でも通る点が厄介です。0.32.0では、SHMの組にサーバーが発行するHMACを添え、公開側の境界で検証してからエンジンへ渡す修正が入りました。pickleの読み込みがなぜ任意コード実行に直結するのかは、安全でないデシリアライゼーションの仕組みと言語別の防御実装で整理しています。

該当するのは、起動引数でshmを指定した構成に限られます。SHMキャッシュを指定していなければ、この経路は開きません。SHMを選んでいた環境は、0.32.0へ上げるまでの間はshmの指定を外しておくのが手堅い判断です。

画像入力のEPSがGhostscriptへ渡り任意コード実行に至るGHSA-h3rc

GHSA-h3rc-j82p-2c3h(CVE-2026-115915、CVSS v3.1で8.1)は、画像入力の読み込みを担うImageMediaIOが、受け付ける画像形式を絞っていなかった問題です。リクエストがimage/pngと名乗っていても、実際のデコーダはPillowがバイト列の先頭から自動判定します。中身がEPS(PostScript)なら、PillowのEPS処理を経てホストのGhostscriptが起動される構造でした。

被害の大きさはホストの構成で分かれます。Ghostscriptが既知の脆弱性CVE-2024-29510を抱えた版(勧告では10.03.1で修正と記載)なら、-dSAFERの制限を抜けて、vLLMのプロセス権限でコマンドが走ります。Ghostscriptが入っていないか修正済みの版であれば、このコマンド実行の連鎖は成立しません。加えて、Pillow 12.0.0〜12.2.0と組み合わせた環境では、同じ判定の境界を通るCVE-2026-59203により、画像読み込みのワーカーが枯渇するDoSも報告されています。Pillow側の更新はPillowの脆弱性と13.0.0への更新手順で扱っています。

勧告者の検証範囲も押さえておきます。読み込み関数単体でのコマンド実行は再現済みで、HTTP経路はソースの追跡による確認にとどまる、と明記されています。とはいえ、OpenAI互換のチャットAPIで画像のdata URLを受け付けている構成なら、外部の利用者から届く経路と見なして扱うほうが安全側でしょう。

自社のvLLMが該当するかを版と起動引数で確かめ0.32.0へ上げる手順

該当の判定に要るのは、インストール済みの版、起動引数のSHM指定、同じ環境のGhostscriptとPillowの版の3点です。コンテナで動かしているなら、本番と同じイメージの中で次を流します。

# 1. vLLMの版(0.32.0未満なら2件とも対象範囲)
python -c "import vllm; print(vllm.__version__)"

# 2. 起動中のプロセスにSHMキャッシュの指定があるか
ps -eo args | grep -- "--mm-processor-cache-type"

# 3. Ghostscriptの有無と版、Pillowの版
gs --version || echo "ghostscript not installed"
python -c "import PIL; print(PIL.__version__)"

# 4. 検証環境で修正版へ上げる
uv pip install vllm==0.32.0 --torch-backend=auto
vllm --version

更新は前述の版固定と同じ流れで進めます。検証環境で0.32.0を通し、代表プロンプトの出力と起動ログの同時実行数の推定値を旧版と突き合わせてから、本番の固定値を書き換える順番です。0.28.0から上げる場合は4版分の差分が入るため、0.32.0のリリースノートと間の版の変更点も読んでおいてください。

すぐに上げられない場合の暫定策は3つあります。

  • SHMキャッシュの指定(--mm-processor-cache-type shm)を外す
  • 画像を扱わない用途なら、前段のゲートウェイで画像付きのリクエストを止める
  • 実行環境からGhostscriptを外すか、CVE-2024-29510の修正版へ上げる

公開エンドポイントとして社外や他部署へ開く構成なら、--api-keyの指定と前段での到達制限も、この機会に見直す価値があります。2件とも、誰がその経路に届くかで危険度が変わる性質の脆弱性だからです。LLMアプリ全体の脅威の洗い出しは、OWASP Top 10 for LLMの全10項目と実務での対策を起点にすると漏れが減ります。

vLLMを自社で運用すべき条件と、マネージドAPIへ寄せるべき3場面

ここからは判断です。技術的に動くかではなく、払う価値があるかを切り分けます。

トークン量・機密要件・稼働率から引く自社運用に必要な下限条件

起点は1つ。GPUを常時埋められるだけの負荷があるかです。マネージドAPIは使った分だけの課金ですが、自社運用のGPUは遊んでいる時間も課金され続けます。日中の数時間だけ数百リクエストという負荷なら、GPUの遊休費用がAPI課金を上回る計算になりやすい。

それでも自社運用へ移す条件は3つあります。1つ目は機密要件で、外部APIへ送信できないデータを扱うなら負荷の大小に関係なく自前で持つ判断。2つ目は恒常的に大きいトークン量で、GPUを昼夜埋められるなら単価は逆転します。3つ目は挙動の固定で、モデルのバージョンや生成の再現性を自分で握りたい場合。この3つのいずれにも当てはまらないなら、マネージドAPIのまま設計を進めるほうが総額は下がります。

どちらへ倒すかを社内で決めきれない段階なら、要件整理と小さな検証から入る手もあります。用途と扱うデータの機密度を並べたうえで比較したい場合は、生成AI導入支援のように業務側の整理から入れる体制へ相談するほうが、いきなりGPUを調達するより手戻りが小さくなります。

vLLMを見送るべき場面と、導入前に先に潰しておく運用前提の3項目

見送る判断がはっきりする場面もあります。まず、社内の数人が順番に触る検証環境。この規模では連続バッチングの効きが出ず、Ollamaのほうが立ち上げも入れ替えも軽く済みます。次に、GPUを調達できずCPUのみで動かす構成。動作はしますが、多数同時をさばく前提が崩れるためエンジンを選ぶ理由が消えます。3つ目は、モデルを自分で持たずAPI利用で完結する構成です。

逆に、GPUノードを複数持ちクラスタ全体へ推論を広げる段になると、llm-dによるKubernetesネイティブな分散推論のようなオーケストレーション層が別途必要になります。

採用する場合は、着手前に3項目を潰しておいてください。

  • GPUの確保計画:機種・枚数・調達期間と、遊休時間の費用の見積もり
  • 監視の設計:TTFTとトークン毎秒、プリエンプション発生、キャッシュ使用率の可視化に加え、セキュリティ勧告の購読
  • 版の管理:vLLM本体とモデルの更新手順、切り戻しの経路

3つ目は見落とされやすい箇所です。vLLMは0.x系のまま更新が速く、2026年11月時点の最新は0.32.0(2026年10月18日公開)。0.28.0(8月26日)のあと、0.29.0が9月9日、0.30.0が9月22日、0.31.0が10月5日と続き、V0の完全廃止のように内部構造が動く変更も入ります。加えて、0.32.0のように脆弱性の修正を含む版も出るため、固定した版を据え置き続ける運用にも危うさが残る。本番の版は固定しつつ、勧告が出たら修正版を検証環境に通して上げる手順と担当を、導入前に決めておいてください。

LLM推論基盤の構築を外部へ委託するとき見積書で確認する5項目

推論基盤の構築を外部へ任せる場合、見積書の粒度で後の追加費用が決まります。確認したいのは次の5点です。

  • 対象モデルと量子化形式、想定する最大コンテキスト長
  • 目標とする同時リクエスト数と、TTFT・トークン毎秒の受け入れ基準
  • GPUの調達主体(自社か委託先か)と遊休時間の費用負担
  • 監視・ログ・アラートがどこまで成果物に含まれるか
  • vLLM本体とモデルの更新、脆弱性対応、切り戻しの運用を誰が担うか

特に2点目と5点目は曖昧にされやすい箇所です。受け入れ基準を決めずに「速くなる」だけで契約すると、負荷試験の段階で合否の判定ができません。前節で触れた起動ログの同時実行数の推定値は、この受け入れ基準を数字で握るときの共通言語になります。設計から運用の引き渡しまで含めて相談するなら、生成AI開発・AI受託開発のようにモデル選定と基盤構築を一体で扱える体制かを確認してください。

よくある質問

vLLMの検討時に問い合わせが多い論点を7つ挙げます。

vLLMとOllamaはどちらを選べばよいですか?

同時にさばく本数で決まります。1台で少数の推論を回す検証環境や個人利用ならOllamaで足り、モデルの入れ替えも軽く済みます。GPUを確保して多数の同時リクエストを処理量重視でさばく本番構成ならvLLMです。両者は競合というより担当領域が違い、検証をOllamaで進めて本番をvLLMへ載せる進め方も成立します。

vLLMを動かすのに必要なGPUメモリはどれくらいですか?

モデルの重みに加えてKVキャッシュの分が要るため、重みのサイズだけでは足りません。実際の当たりは起動ログで取れます。起動時に出る「GPU KV cache size」と「Maximum concurrency」の2行を読み、想定する同時接続数に届いているかを見てください。届かなければ--max-model-lenを短く切るか、量子化でビット幅を落として重み側を圧縮するか、GPUを足すかの三択になります。

vLLMはCPUだけでも動きますか?

公式の対応ハードウェアにはx86・ARM・PowerPCのCPUが挙がっており、動作可能です。ただしvLLMの設計思想はGPU上で多数同時をさばくところにあり、CPUのみでは処理量が頭打ちになります。GPUを用意できない構成なら、CPUオフロードを前提に組まれたllama.cppやOllamaのほうが扱いやすく、量子化済みの重みで実用速度に届く場面もあります。

OpenAI互換APIならアプリ側のコードは変えずに済みますか?

接続先とモデル名の変更で通る場面は多いものの、無条件ではありません。OpenAI SDKをそのまま使えるのは大枠の話で、モデル固有のパラメータや構造化出力の指定、ツール呼び出しの形式は実際に確認が要ります。V1ではlogprobsがロジット後処理前の値を返す仕様変更もあるため、この値を業務判定に使っている場合は挙動を突き合わせてください。

vLLMの起動が遅いのですが短縮できますか?

同じモデルと設定で立ち上げ直すなら、コンパイル成果物のキャッシュを使い回すのが第一手です。キャッシュ先はコンテナイメージへ焼き込めるため、ノードを増やす構成でも効きます。加えて、起動ログに出た--kv-cache-memoryの値を次回に渡せばメモリ計測の工程を省け、開発中の反復なら--enforce-eagerでコンパイル自体を飛ばせます。ただし後ろ2つは同時実行数の上限や定常時の性能を削るため、本番構成ではキャッシュ再利用に留めるのが無難です。

vLLMの脆弱性が公開されたと聞きました。どの版を使えばよいですか?

2026年11月時点では0.32.0以上を使ってください。10月28日に公開された2件(SHMキャッシュ指定時のpickle到達と、画像入力からのGhostscript起動)は、どちらも0.32.0未満が影響範囲で、0.32.0で修正されています。SHMキャッシュを指定しておらず、画像入力も受けない構成なら発動の前提を満たしませんが、版を据え置く理由にはなりません。検証環境で0.32.0を通してから本番の固定値を書き換え、以後はGitHub Advisory Databaseの勧告を監視する運用にしておくと、次の修正版にも同じ手順で追従できます。

vLLMの商用利用やライセンスに制約はありますか?

vLLM自体のライセンスはApache License 2.0で、商用の自社運用に追加の許諾は要りません。注意が要るのは載せるモデル側です。商用可否・再配布条件・利用者数の上限は元モデルの規約が定めるため、Llama系やQwen系など個別のライセンス原文を導入前に確認してください。社内利用と外部提供で条件が変わる例もあります。

関連記事

お気に入りに入れた記事の一覧

一創の公式 SNS

X では毎朝の新着記事と IT ニュースの速報を、YouTube・TikTok・Instagram・LinkedIn・Facebook では記事の解説動画を配信しています。

この記事は以下の記事からリンクされています

ほか 57 件の記事からもリンクされています。

資料請求

今日のトレンド記事 直近 24 時間で、いつもより多く読まれている記事

  1. 2026.10.29 テックブログ ソニー生命の不正アクセス:38.5万件の対象確認と窓口、停止中の手続き
  2. 2026.10.31 テックブログ 松屋の不正アクセス:237万件の対象確認と窓口、漏れたパスワードの守り方
  3. 2026.10.31 テックブログ 無印良品の情報漏洩:MUJIアプリ最大2,726万件の対象確認となりすましメール対策
  4. 2026.10.31 テックブログ osinaの情報漏洩:約23万人の対象確認とSNS連携の解除、分析ツールへ渡すデータの絞り方
  5. 2026.05.18 テックブログ マネーフォワードで連携できない・失敗するときの対処法|エラー別の原因と再連携のやり方

RELATED POSTS 関連記事

目次