- Authors
- Name
- 1. LLM推論の特殊性
- 2. KV Cacheメカニズムとメモリ問題
- 3. PagedAttention詳細分析
- 4. Continuous Batching vs Static Batching
- 5. vLLMのインストールとOpenAI互換APIサーバーの構築
- 6. vLLMの主要機能
- 7. TensorRT-LLMの概要とモデル変換
- 8. 量子化技法の比較
- 9. ベンチマーク比較:Throughput、Latency、TTFT
- 10. SGLangとの簡易比較
- 11. 結論
- References
1. LLM推論の特殊性
Large Language Model(LLM)の推論(Inference)は、従来のディープラーニングモデルの推論とは根本的に異なる特性を持つ。この違いを理解することが最適化の出発点である。
1.1 Autoregressive Decoding
LLMは**自己回帰(Autoregressive)**方式でトークンを生成する。つまり、以前に生成されたすべてのトークンを入力として使用し、次の1つのトークンを予測し、この過程をEnd-of-Sequence(EOS)トークンが出るまで繰り返す。これは画像分類やObject Detectionのように、入力を1回Forward Passすれば結果が出るモデルとは本質的に異なる。
Input: "今日の天気は"
Step 1: "今日の天気は" → "良"
Step 2: "今日の天気は良" → "い"
Step 3: "今日の天気は良い" → "です"
Step 4: "今日の天気は良いです" → [EOS]
この反復的な特性のため、LLM推論はMemory-Boundな作業となる。各ステップで数十億個のモデルパラメータをGPUメモリから読み込む必要があるが、実際の演算量(トークン1つに対する行列積)は比較的少ない。GPUの演算能力(FLOPS)よりも**メモリ帯域幅(Memory Bandwidth)**がボトルネックとなる。
1.2 Prefill Phase vs Decode Phase
LLM推論は、明確に区分される2つのフェーズに分かれる。
Prefill Phase(プロンプト処理)
ユーザーが入力したプロンプト全体を一度に処理するフェーズである。入力トークンを並列処理できるため、Compute-Boundの特性を示す。このフェーズですべての入力トークンに対するKey-Value(KV)ベクトルを計算してキャッシュに保存する。ユーザーが最初のトークンを受け取るまでの遅延時間である**TTFT(Time To First Token)**は、主にこのフェーズの性能によって決定される。
Decode Phase(トークン生成)
Prefill後にトークンを1つずつ順次生成するフェーズである。毎ステップでトークン1つのみ処理するため演算量が少なく、モデルの重みをメモリからロードするコストが支配的なMemory-Boundな作業となる。このフェーズの性能が全体の**Throughput(スループット)とTPOT(Time Per Output Token)**を決定する。
この2つのフェーズの演算特性が完全に異なるという点が、LLM推論最適化を困難にする核心要因である。PrefillはGPU演算ユニットを最大限活用する必要があり、Decodeはメモリ帯域幅を最大限活用する必要がある。
2. KV Cacheメカニズムとメモリ問題
2.1 KV Cacheとは何か
Autoregressive Decodingにおいて、毎ステップで以前のすべてのトークンのAttentionを最初から再計算すると、莫大な重複演算が発生する。これを防ぐために、以前のステップで計算したKeyとValueベクトルをGPUメモリにキャッシュするのがKV Cacheである。
Transformerの各レイヤーにおけるSelf-Attentionは、Query(Q)、Key(K)、Value(V)の3つのベクトルを使用する。新しいトークンを生成する際、そのトークンのQベクトルのみ新たに計算し、以前のトークンのK、Vベクトルはキャッシュから取得する。これにより演算量をO(n^2)からO(n)に削減できる。
2.2 KV Cacheのメモリ消費
KV Cacheのメモリ使用量は以下のように計算される。
KV Cache Memory = 2 x num_layers x num_heads x head_dim x seq_len x batch_size x dtype_size
例えば、Llama-2-70Bモデル(80 Layers、64 KV Heads、Head Dim 128)でFP16基準、1つのシーケンス(seq_len=2048)に対するKV Cacheは以下の通りである。
2 x 80 x 64 x 128 x 2048 x 2 bytes = 約5.24 GB
たった1つのシーケンスに5GB以上が必要である。Batch Sizeを大きくするとこの値が線形に増加するため、KV CacheはGPUメモリの最大の消費者となる。80GBのA100 GPUでモデルの重みに約35GB(FP16基準で70Bモデル)を使用すると、KV Cacheに割り当てられるメモリは約40GB程度であり、これが同時処理可能なリクエスト数(Batch Size)を直接的に制限する。
2.3 既存システムのメモリ浪費
既存のLLM Servingシステムは、KV Cache用にシーケンスの最大長分だけ連続したメモリを事前に割り当てていた。この方式には3つの深刻な非効率がある。
- Internal Fragmentation:実際のシーケンス長が最大長より短い場合、残りの領域が無駄になる。
- External Fragmentation:さまざまなサイズのメモリブロックが割り当て/解放されることで、使用可能だが連続していないメモリ断片が生じる。
- Reservation Waste:生成が完了するまで最大長分を予約するため、実際に使用されないメモリがロックされる。
vLLM論文によると、既存システムではKV Cacheメモリの60〜80%が浪費されていた。これがPagedAttentionが解決しようとした核心問題である。
3. PagedAttention詳細分析
3.1 核心アイデア:オペレーティングシステムの仮想メモリ
PagedAttentionは、UC BerkeleyのWoosuk Kwonらが2023年SOSPで発表した論文*"Efficient Memory Management for Large Language Model Serving with PagedAttention"*で提案された技術である。核心アイデアは、OSの仮想メモリとページング技法をKV Cache管理に適用することである。
OSではプロセスの仮想アドレス空間は連続しているが、実際の物理メモリ(RAM)では固定サイズのPage単位で分散格納される。Page Tableが仮想アドレスを物理アドレスにマッピングする。PagedAttentionはこの概念をそのままKV Cacheに適用する。
3.2 Block基盤KV Cache管理
PagedAttentionはKV Cacheを固定サイズのBlockに分割する。各Blockは固定数のトークン(例:16個)に対するKeyとValueベクトルを格納する。核心メカニズムは以下の通りである。
- 非連続メモリ割り当て:BlockはGPUメモリのどこにでも配置できる。連続したメモリ空間は不要。
- Block Table:各シーケンスは自身の論理的Block番号を物理的Block位置にマッピングするBlock Tableを持つ。OSのPage Tableと同一の概念である。
- 動的割り当て:Blockはトークンが生成される際に必要に応じて1つずつ割り当てられる。シーケンスの最大長を事前に予約する必要がない。
- 即時解放:シーケンス生成が完了すると、該当BlockがすぐにFree Listに返却される。
Sequence "今日の天気は良いです。":
Logical Block 0 → Physical Block 7 (トークン: "今日の", "天気は", "良いです")
Logical Block 1 → Physical Block 2 (トークン: "。", [padding])
Block Table:
[0] → 7
[1] → 2
3.3 メモリ効率の改善
PagedAttentionは既存システムと比較してメモリ浪費をほぼ排除する。
- Internal Fragmentation:最後のBlockでのみ発生し、平均的にBlock Sizeの半分未満である。
- External Fragmentation:すべてのBlockが同一サイズのため完全に排除される。
- Reservation Waste:必要な時にのみBlockを割り当てるため排除される。
vLLM公式ドキュメントによると、PagedAttentionを通じてKV Cacheメモリをほぼ最適に近い形で使用でき、これは同一GPUで処理可能なBatch Sizeを2〜4倍以上増加させる効果をもたらす。Batch Sizeの増加はすなわちThroughputの増加を意味する。
3.4 メモリ共有
PagedAttentionのもう1つの利点はメモリ共有である。Parallel SamplingやBeam Searchにおいて、同一のPromptを共有する複数のシーケンスがある場合、Promptに該当するKV Cache BlockをコピーせずにBlock Tableレベルで共有できる。Copy-on-Write(CoW)方式を使用し、シーケンスが分岐するポイントでのみ新しいBlockを割り当てる。これによりBeam Searchでメモリ使用量を最大55%削減できる。
4. Continuous Batching vs Static Batching
4.1 Static Batchingの限界
従来のStatic Batchingは複数のリクエストを1つのBatchにまとめて同時処理するが、Batch内のすべてのシーケンスが完了するまで待った後に次のBatchを処理する。問題は、LLMの応答長がリクエストごとに大きく異なることである。
例えばBatch Size 4で処理する場合、あるリクエストは10トークンのみ生成し、別のリクエストは500トークンを生成するとき、10トークンのリクエストが終了した後も500トークンのリクエストが完了するまで該当スロットのGPUリソースがアイドル状態のまま残る。この非効率が本番環境でThroughputを大幅に低下させる。
4.2 Continuous Batching(Iteration-Level Scheduling)
Continuous Batchingはステップ(Iteration)単位でスケジューリングを行う。核心の動作方式は以下の通りである。
- 到着するリクエストを待機キュー(Waiting Queue)に入れる。
- 毎Forward Pass(Generation Step)ごとにSchedulerが待機キューを確認する。
- 現在実行中のBatchに余裕があれば、待機中の新しいリクエストをBatchに追加する。
- GPUが現在Batchのすべてのシーケンスに対して1ステップのDecodingを実行する。
- あるシーケンスが生成を完了すると(EOS到達)、即座に該当スロットのリソースを解放する。
- 次のステップで空きスロットに新しいリクエストを投入する。
Static Batching:
Step 1: [A, B, C, D] ← 4つ同時処理
Step 2: [A, B, C, D]
Step 3: [A, _, C, D] ← B完了、しかしスロットは空き
Step 4: [A, _, _, D] ← C完了、まだ待機中
Step 5: [_, _, _, D] ← D完了まで待機後、新しいBatch開始
Continuous Batching:
Step 1: [A, B, C, D]
Step 2: [A, B, C, D]
Step 3: [A, E, C, D] ← B完了、即座にEを投入
Step 4: [A, E, F, D] ← C完了、即座にFを投入
Step 5: [G, E, F, D] ← A完了、即座にGを投入
Anyscaleのベンチマークによると、Continuous BatchingはStatic Batchingと比較して最大23倍のThroughput向上を達成できる。GPUが常に最大限のシーケンスを処理し続けるためである。
4.3 PagedAttentionとのシナジー
Continuous Batchingが効果的に動作するためには、さまざまな長さのシーケンスが動的に出入りする状況でKV Cacheメモリを柔軟に管理する必要がある。PagedAttentionはBlock単位の細粒度なメモリ割り当て/解放を提供するため、Continuous Batchingの動的スケジューリングと完璧に結合する。この2つの技術の組み合わせがvLLMの核心的な競争力である。
5. vLLMのインストールとOpenAI互換APIサーバーの構築
5.1 インストール
vLLM公式ドキュメントによると、pipで簡単にインストールできる。Python 3.9以上とCUDA 12.xが必要である。
# pipによるインストール(推奨)
pip install vllm
# uvを使用した環境管理(公式推奨)
uv pip install vllm
Dockerを使用する場合、vLLMが提供する公式イメージを使用できる。
docker run --runtime nvidia --gpus all \
-v ~/.cache/huggingface:/root/.cache/huggingface \
-p 8000:8000 \
--ipc=host \
vllm/vllm-openai:latest \
--model meta-llama/Llama-3.1-8B-Instruct
5.2 Offline Inference(バッチ処理)
シンプルなバッチ推論にはLLMクラスを使用する。
from vllm import LLM, SamplingParams
# モデルロード
llm = LLM(model="meta-llama/Llama-3.1-8B-Instruct")
# サンプリングパラメータ設定
sampling_params = SamplingParams(temperature=0.7, top_p=0.9, max_tokens=256)
# バッチ推論実行
prompts = [
"LLM推論最適化の核心技術は",
"PagedAttentionの原理を説明すると",
]
outputs = llm.generate(prompts, sampling_params)
for output in outputs:
print(f"Prompt: {output.prompt}")
print(f"Generated: {output.outputs[0].text}")
5.3 OpenAI互換APIサーバー
vLLMはOpenAI APIと互換性のあるHTTPサーバーを提供する。vllm serveコマンドで起動できる。
# サーバー起動
vllm serve meta-llama/Llama-3.1-8B-Instruct \
--dtype auto \
--api-key token-abc123 \
--host 0.0.0.0 \
--port 8000 \
--max-model-len 4096 \
--gpu-memory-utilization 0.9
サーバーが実行されると、OpenAI Pythonクライアントライブラリをそのまま使用できる。
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:8000/v1",
api_key="token-abc123",
)
# Chat Completions API
response = client.chat.completions.create(
model="meta-llama/Llama-3.1-8B-Instruct",
messages=[
{"role": "system", "content": "あなたは親切なAIアシスタントです。"},
{"role": "user", "content": "PagedAttentionとは何ですか?"},
],
temperature=0.7,
max_tokens=512,
)
print(response.choices[0].message.content)
vLLMのOpenAI互換サーバーは/v1/completions、/v1/chat/completions、/v1/embeddingsなどのエンドポイントをサポートし、既存のOpenAI APIを使用するアプリケーションのコード変更なしにバックエンドだけを置き換えられるという大きな利点がある。
5.4 主要サーバー設定オプション
| オプション | 説明 | デフォルト |
|---|---|---|
--model | HuggingFaceモデル名またはパス | 必須 |
--dtype | データ型(auto, float16, bfloat16) | auto |
--max-model-len | 最大シーケンス長 | モデル設定 |
--gpu-memory-utilization | GPUメモリ使用率 | 0.9 |
--tensor-parallel-size | Tensor Parallelism GPU数 | 1 |
--pipeline-parallel-size | Pipeline Parallelismステージ数 | 1 |
--quantization | 量子化方法(awq, gptq, fp8など) | None |
--enable-prefix-caching | Prefix Cachingの有効化 | False |
--max-num-seqs | 最大同時処理シーケンス数 | 256 |
6. vLLMの主要機能
6.1 Speculative Decoding
Speculative Decodingは、小さく高速なDraft Modelが複数のトークンを事前に生成(推測)し、大きなTarget Modelがこれを一括で検証する技法である。検証を通過したトークンはそのまま採用され、間違ったトークンから再生成する。これにより、生成品質を維持しながらInter-Token Latencyを削減できる。
vLLM公式ドキュメントによると、以下のSpeculative Decoding方式がサポートされている。
- Draft Model:小さなモデル(例:Llama-68M)をDraftとして使用し、複数のトークンを事前に生成
- EAGLE:ニューラルネットワークベースの効率的なDraft生成方式
- MLP Draft Model:MLPベースの軽量Draft生成
- N-gram Speculation:入力テキストのN-gramパターンに基づくトークン予測
- Suffix Decoding:Suffixベースの予測戦略
# Draft Modelを使用したSpeculative Decodingサーバー実行
vllm serve meta-llama/Llama-3.1-70B-Instruct \
--speculative-model meta-llama/Llama-3.2-1B-Instruct \
--num-speculative-tokens 5 \
--use-v2-block-manager
Speculative Decodingは、QPS(Queries Per Second)が低いまたは中程度のMemory-Boundワークロードで特に効果的であり、高QPS環境ではDraft Modelの追加演算負担により、かえって性能が低下する場合がある。
6.2 Automatic Prefix Caching(APC)
Automatic Prefix Cachingは、同一のPrefixを持つリクエストが繰り返される場合に、そのPrefixのKV Cacheを再利用する機能である。例えば、同一のSystem Promptを持つ数千のリクエストが来る場合、System PromptのKV Cacheを一度だけ計算し、以降のリクエストで再活用する。
vLLMにおけるPrefix CachingはBlock単位で動作する。リクエストが到着するとPromptのトークンをBlock単位で分割し、既にキャッシュに存在するBlockは再利用し、新しいトークンが現れるポイントからのみ新しいBlockを生成する。
# Prefix Cachingの有効化
vllm serve meta-llama/Llama-3.1-8B-Instruct \
--enable-prefix-caching
この機能は、RAG(Retrieval-Augmented Generation)、Few-shot Learning、Multi-turn会話など、同一のPrefixが繰り返されるシナリオでTTFTを大幅に短縮する。
6.3 LoRA Serving
vLLMは1つのBase Modelに複数のLoRA(Low-Rank Adaptation)Adapterを動的にロードしてサービングできる。これにより、さまざまなFine-tunedモデルのバリエーションを1つのサーバーインスタンスで処理できる。
# LoRA Adapterを使用したサーバー実行
vllm serve meta-llama/Llama-3.1-8B-Instruct \
--enable-lora \
--lora-modules my-adapter=./path/to/lora/adapter \
--max-lora-rank 64
リクエスト時にmodelパラメータでLoRA Adapter名を指定すると、そのAdapterが適用された結果が返される。Tensor Parallelism環境では、デフォルトでLoRA演算の半分のみ分散処理されるが、--fully-sharded-lorasオプションを使用すると、長いシーケンスや高いRankでより良い性能が得られる。
7. TensorRT-LLMの概要とモデル変換
7.1 TensorRT-LLMとは
TensorRT-LLMはNVIDIAが開発したLLM推論最適化ライブラリで、TensorRTエンジンをLLMに特化して構築したものである。Python APIを通じてLLMモデルを定義し、NVIDIA GPUで最適化された推論エンジンにコンパイルする。主要な特徴は以下の通りである。
- NVIDIA GPU専用最適化:CUDAカーネルをNVIDIAアーキテクチャに合わせて最適化
- FP8/NVFP4量子化:Hopper(H100)、Ada Lovelace、Blackwell(B200)アーキテクチャのハードウェアアクセラレーション量子化をサポート
- In-flight Batching:Continuous BatchingのTensorRT-LLM実装
- Tensor/Pipeline Parallelism:マルチGPU分散推論をサポート
- Paged KV Cache:PagedAttentionと類似のメモリ管理
- EAGLE-3 Speculative Decoding:最新のSpeculative Decoding技法をサポート
7.2 モデル変換ワークフロー
TensorRT-LLMのモデル変換は2つのステップで行われる。
Step 1:チェックポイント変換
HuggingFace等のフレームワークのチェックポイントをTensorRT-LLM形式に変換する。
# Llamaモデルチェックポイント変換
python convert_checkpoint.py \
--model_dir /path/to/Llama-3.1-8B-Instruct \
--output_dir ./tllm_checkpoint_1gpu \
--dtype float16
# Tensor Parallelism適用時
python convert_checkpoint.py \
--model_dir /path/to/Llama-3.1-70B-Instruct \
--output_dir ./tllm_checkpoint_4gpu_tp4 \
--dtype float16 \
--tp_size 4
Step 2:TensorRTエンジンビルド
変換されたチェックポイントをtrtllm-buildコマンドで最適化されたTensorRTエンジンにコンパイルする。
trtllm-build \
--checkpoint_dir ./tllm_checkpoint_1gpu \
--output_dir ./trt_engines/llama-8b/fp16/1-gpu \
--gemm_plugin auto \
--max_batch_size 64 \
--max_input_len 2048 \
--max_seq_len 4096
7.3 Python APIによるビルド
Python APIを使用してプログラム的に変換とビルドを行うこともできる。
import tensorrt_llm
from tensorrt_llm import BuildConfig
# HuggingFaceモデルから直接変換・ビルド
llama = tensorrt_llm.LLaMAForCausalLM.from_hugging_face(
model_dir="/path/to/Llama-3.1-8B-Instruct",
dtype="float16",
)
# エンジンビルド
build_config = BuildConfig(max_batch_size=64)
engine = tensorrt_llm.build(llama, build_config)
# エンジン保存
engine.save("./trt_engines/llama-8b")
この過程でconvert_checkpoint.pyのようなCLIツールは内部APIを使用するため、TensorRT-LLMのバージョンとexamplesフォルダのスクリプトバージョンを必ず一致させる必要がある。
8. 量子化技法の比較
量子化(Quantization)は、モデルの重みと活性化値をより低い精度で表現して、メモリ使用量と演算量を削減する技法である。LLM推論で最も広く使用される量子化技法を比較する。
8.1 GPTQ(Post-Training Quantization)
GPTQはレイヤーごとにHessian情報を活用して量子化誤差を最小化する**Post-Training Quantization(PTQ)**技法である。
- 原理:各レイヤーの重みを量子化する際、出力活性化の変化を最小化するよう補正(Compensation)を行う。補正過程でHessian行列の逆行列を近似して最適な量子化値を求める。
- 精度:主にINT4 Weight-Only(W4A16)
- 利点:キャリブレーションデータセットのみあれば良く、学習なしで量子化可能
- 欠点:キャリブレーションに数十分かかり、AWQに比べてわずかに低い精度が報告
8.2 AWQ(Activation-Aware Weight Quantization)
AWQは重みの重要度を活性化(Activation)分布に基づいて判断し、重要な重みを保護する量子化技法である。
- 原理:すべての重みが同等に重要なわけではなく、活性化の大きさが大きいチャネルに接続された重みがモデル性能により大きな影響を与える。この少数の重要な重み(約1%)を高精度で維持し、残りをより積極的に量子化する。
- 精度:INT4 Weight-Only(W4A16)またはW4A8
- 利点:GPTQに比べて高い精度維持(約95% Quality Retention)、ハードウェア効率的
- 欠点:キャリブレーション過程が必要
8.3 SqueezeLLM
SqueezeLLMはUC Berkeleyが提案した技法で、不均一(Non-uniform)量子化とDense-and-Sparse分解を組み合わせる。
- 原理:各出力チャネルに個別のLookup Tableを割り当て、チャネル単位の不均一量子化を行う。またOutlierの重みをSparse行列として分離して別途処理する。既存のGPTQ/AWQが個別レイヤーの出力変化を最小化するのとは異なり、SqueezeLLMはモデルの最終出力の変化を最小化するよう最適化する。
- 精度:INT3、INT4レベル
- 利点:極めて低ビットの量子化でも高い精度を維持
- 欠点:実装の複雑さが高く、推論時にLookup Table演算のオーバーヘッドが存在
8.4 FP8量子化
FP8(8ビット浮動小数点)はNVIDIA Hopper(H100)以降のアーキテクチャでハードウェアレベルでサポートされる量子化形式である。
- 原理:FP16/BF16の重みと活性化を8ビット浮動小数点(E4M3またはE5M2)に変換する。Tensor CoreがFP8演算をネイティブにサポートするため、INT8とは異なり、別途の逆量子化(Dequantization)オーバーヘッドがほとんどない。
- 精度:W8A8(重みと活性化の両方を8ビット)
- 利点:最も高い精度維持、最も速いキャリブレーション(分単位)、H100/B200でハードウェアアクセラレーション
- TensorRT-LLM基準性能:Llama-v2-7BでFP16比、Batch Size 1で1.51倍、Batch Size 8で1.40倍の速度向上(NVIDIA公式ベンチマーク)
8.5 量子化選択ガイド
TensorRT-LLM公式ドキュメントの推奨事項は以下の通りである。
| シナリオ | 推奨方式 | 理由 |
|---|---|---|
| Small Batch(BS 4以下) | Weight-Only(W4A16, W8A16) | Memory Bandwidthがボトルネックのため、重みサイズの削減が効果的 |
| Large Batch(BS 16以上) | FP8(W8A8)優先 | 演算量が多くなるため、重みと活性化の両方を量子化することが有利 |
| 最高精度が必要 | FP8 | 精度損失が最も少ない |
| 最大圧縮が必要 | INT4 AWQ/GPTQ | 4ビットでモデルサイズを約75%削減 |
| H100/B200使用 | FP8またはNVFP4 | ハードウェアネイティブサポートで最高性能 |
vLLMで量子化モデルを使用する方法は以下の通りである。
# AWQ量子化モデルのサービング
vllm serve TheBloke/Llama-2-7B-AWQ \
--quantization awq \
--dtype auto
# GPTQ量子化モデルのサービング
vllm serve TheBloke/Llama-2-7B-GPTQ \
--quantization gptq \
--dtype auto
# FP8量子化サービング(H100以上)
vllm serve meta-llama/Llama-3.1-8B-Instruct \
--quantization fp8 \
--dtype auto
9. ベンチマーク比較:Throughput、Latency、TTFT
9.1 主要性能指標
LLM推論性能を評価する際の核心指標は以下の通りである。
- Throughput:1秒あたりに処理できるトークン数(tokens/second)またはリクエスト数(requests/second)
- Latency:リクエスト開始からレスポンス完了までの全体所要時間
- TTFT(Time To First Token):リクエスト開始から最初のトークンが生成されるまでの時間。ユーザー体感のレスポンス速度に直結
- TPOT(Time Per Output Token):最初のトークン以降、各トークンが生成される平均時間。ストリーミング出力速度に直結
- ITL(Inter-Token Latency):トークン間の生成間隔
9.2 vLLM vs TensorRT-LLM比較
2025年の多数のベンチマーク結果を総合すると、2つのフレームワークはそれぞれ異なる強みを示す。
Throughput
TensorRT-LLMは全般的に最も高いThroughputを記録する。NVIDIA GPUに最適化されたCUDAカーネルとTensorRTエンジンコンパイル最適化のおかげである。約180〜220 req/secレベルであり、vLLMは120〜160 req/secレベルで2番目に高い性能を示す。ただしこの数値はモデル、GPU、Batch Size、シーケンス長などによって大きく変わる。
TTFT(Time To First Token)
TTFTではvLLMが優れた性能を示す。同時ユーザー数が増加しても50〜80msレベルを安定的に維持する。TensorRT-LLMは低い同時接続数では35〜50msとより速いが、高い同時接続数でのスケーリング特性がvLLMより劣る場合が報告されている。
Latency
Per-Token LatencyはTensorRT-LLMが低い同時接続数で優勢である。特にB200 GPUではTensorRT-LLMがすべての指標でSGLangとvLLMを上回る。
総合比較
| 指標 | vLLM | TensorRT-LLM |
|---|---|---|
| Throughput | 高い(2位) | 非常に高い(1位) |
| TTFT(Low QPS) | 優秀 | 非常に優秀 |
| TTFT(High QPS) | 安定的 | 可変的 |
| 設定難易度 | 低い | 高い(ビルド過程が必要) |
| モデル互換性 | 非常に広い | NVIDIA GPU専用 |
| 柔軟性 | 高い(Python API) | 中程度(エンジン再ビルド要) |
| コミュニティ/エコシステム | 非常に活発 | NVIDIA主導 |
9.3 フレームワーク選択基準
- 高速プロトタイピングと柔軟なサービング:vLLMが適している。pip install一行で始められ、HuggingFaceモデルを直接ロードして即座にサービングできる。
- 最大性能が必要なプロダクション:TensorRT-LLMが適している。モデル変換とエンジンビルドに時間がかかるが、最適化されたエンジンの性能が優れている。特にNVIDIA最新GPU(H100、B200)でFP8/NVFP4を活用する際に性能差が最大化される。
- 多様なモデルと迅速な実験:vLLMが有利である。LoRA Adapterの交換、量子化方式の変更などがサーバー再起動だけで可能。
- 最新NVIDIA GPU活用の最大化:TensorRT-LLMが有利である。HopperやBlackwellアーキテクチャのハードウェア機能を最も早く、最も深く活用する。
10. SGLangとの簡易比較
SGLang(Structured Generation Language)は、UC Berkeley LMSYSが開発したLLM推論フレームワークで、vLLMとTensorRT-LLMに続いて注目されているエンジンである。
10.1 核心的差別化要素:RadixAttention
SGLangの核心技術はRadixAttentionである。これはPrefix Cachingを**Radix Tree(基数木)**データ構造で管理する方式で、vLLMのBlock単位のPrefix Cachingよりも細かいトークンレベルのPrefixマッチングと再利用を可能にする。
Radix Treeは複数のリクエストのPrefixをツリー構造で共有するため、Multi-turn会話で前のターンのKV Cacheを効率的に再活用できる。ベンチマークでは、RadixAttentionは大規模Multi-turn会話でvLLM比約10%の性能向上を示した。
10.2 性能比較
2025年のベンチマーク結果を総合すると以下の通りである。
- Throughput:SGLangはRadixAttentionを通じて約16,200 tokens/secを達成し、vLLMの約12,500 tokens/sec比約29%高いThroughputを記録
- 全体処理時間:500個のPrompt処理でSGLang 54.2秒、vLLM 58.9秒で、SGLangが約8%速い
- Multi-turnシナリオ:SGLangがKV Cache再利用効率で明確な優位性
10.3 使用シナリオ
| シナリオ | 推奨フレームワーク |
|---|---|
| 高い同時接続性、シングルターン | vLLM |
| Multi-turn会話、構造化出力 | SGLang |
| NVIDIA GPUの最大性能 | TensorRT-LLM |
| クイックスタート、幅広いモデル互換 | vLLM |
| 複雑な生成ロジック | SGLang |
SGLangは特に、複雑なMulti-turnインタラクション、構造化出力(JSON Schemaなど)、精密な生成制御が必要なワークロードで強みを発揮する。一方、vLLMは高い同時接続環境でのシングルターン処理と限られたリソースでのThroughput最大化に適している。
11. 結論
LLM推論最適化は、単一技術ではなく複数の技術の組み合わせで実現される。PagedAttentionはKV Cacheのメモリ浪費を排除し、Continuous BatchingはGPU活用率を最大化し、量子化はモデルサイズと演算量を削減する。Speculative DecodingはPer-Token Latencyを改善し、Prefix Cachingは繰り返されるPromptのTTFTを短縮する。
vLLMはこれらの技術を使いやすいインターフェースに統合して迅速なプロトタイピングと柔軟なサービングを可能にし、TensorRT-LLMはNVIDIA GPUに特化した深い最適化を通じて最大性能を追求する。SGLangはRadixAttentionによる効率的なKV Cache再利用でMulti-turnシナリオで差別化された性能を提供する。
フレームワークの選択は、サービス要件、ハードウェア環境、運用の複雑さを総合的に考慮して決定すべきである。どのフレームワークを選択しても、本稿で扱った核心技術の原理を理解することが、適切な設定とチューニングの基盤となるだろう。
References
- vLLM公式ドキュメント
- vLLM PagedAttention設計ドキュメント
- vLLM Speculative Decodingドキュメント
- vLLM Automatic Prefix Cachingドキュメント
- vLLM OpenAI Compatible Serverドキュメント
- vLLM Quickstart Guide
- vLLM GitHub Repository
- Efficient Memory Management for Large Language Model Serving with PagedAttention (SOSP 2023)
- NVIDIA TensorRT-LLM公式ドキュメント
- TensorRT-LLM Build Workflow
- TensorRT-LLM Quantization Guide
- TensorRT-LLM FP8 Quantization
- TensorRT-LLM Checkpoint Format
- TensorRT-LLM GitHub Repository
- NVIDIA TensorRT-LLM Docs (NVIDIA)
- TensorRT-LLM Quantization Examples
- SqueezeLLM: Dense-and-Sparse Quantization (arXiv)
- Continuous BatchingとLLM推論 (Anyscale Blog)
- SGLang GitHub Repository
- LLM Inference Benchmarking with TensorRT-LLM (NVIDIA Blog)
- vLLM v0.6.0 Performance Update (vLLM Blog)