1s.xyz / LLM周辺用語 教科書 9 / 25

第9章. vLLM / TGI / TensorRT-LLM

この章の目的

この章では、大規模言語モデル(LLM)を本番環境で効率的に運用するための推論基盤技術、特にvLLM、TGI、TensorRT-LLMに焦点を当てて解説します。これらの技術がどのようにしてLLMの推論性能を向上させ、スケーラブルなサービス提供を可能にするのかを理解することを目的とします。

この章で覚えるべきこと

  • vLLM、TGI、TensorRT-LLMがそれぞれどのような特徴を持ち、どのようなユースケースに適しているか。
  • paged attentionがLLMのメモリ管理とスループット向上にどのように貢献するか。
  • throughputlatencyという二つの重要な性能指標の意味と、それらを向上させるための技術。
  • batchingの概念と、それが推論効率に与える影響。
  • 開発環境での実行と本番環境でのサービングの違い。

導入

前章までで、LLMの基本的な構成要素や、llama.cppのようなローカル環境での手軽な実行方法について学んできました。しかし、これらの方法は、複数のユーザーからのリクエストを同時に処理したり、高い応答速度を維持したりする必要がある本番環境での運用には限界があります。

LLMをサービスとして提供する場合、単にモデルを動かすだけでなく、いかに効率良く、多くのリクエストを速く処理するかが重要になります。この課題を解決するために登場したのが、vLLM、TGI、TensorRT-LLMといった推論基盤です。これらは、GPUリソースを最大限に活用し、LLM推論のthroughput(処理量)とlatency(応答時間)を最適化するための様々な技術を組み込んでいます。

本章では、これらの推論基盤がどのような課題を解決し、どのようなメカニズムで性能を向上させているのかを深掘りしていきます。

基本概念

1. vLLM

ひとことで言うと: LLMの推論を高速化し、GPUメモリを効率的に利用するためのオープンソースライブラリ。 何のカテゴリか: LLM推論最適化ライブラリ、サービングフレームワーク 何に使うのか: 大規模なLLMを本番環境で効率的にデプロイし、高いスループットと低いレイテンシで推論を提供するため。特に、可変長のシーケンス長を持つリクエストを効率的に処理するのに優れています。 代表例: OpenAIのAPIのようなサービスを自前で構築する際のバックエンド。 よく混同される用語: llama.cpp (ローカル実行向け)、transformers単体 (基本的な推論実行)、TGI (別のサービングフレームワーク) 初心者向け注意点: vLLMはGPUを前提としており、CPUのみの環境では動作しません。また、十分なGPUメモリが必要となります。

vLLMの最大の特徴は、paged attentionという革新的なアテンションメカニズムを導入している点です。これにより、LLMの推論においてボトルネックとなりがちなGPUメモリの断片化を解消し、複数のリクエストを効率的にバッチ処理できるようになります。

2. TGI (Text Generation Inference)

ひとことで言うと: Hugging Faceが開発した、LLMの高速なテキスト生成に特化した推論フレームワーク。 何のカテゴリか: LLM推論最適化ライブラリ、サービングフレームワーク 何に使うのか: Hugging Face Hub上のモデルを簡単にデプロイし、高いスループットと低いレイテンシでテキスト生成サービスを提供するため。ストリーミング出力や複数のモデルのロードにも対応しています。 代表例: Hugging Face Inference Endpointsのバックエンド。 よく混同される用語: vLLM (別のサービングフレームワーク) 初心者向け注意点: TGIはDockerコンテナとして提供されることが多く、コンテナ技術の基本的な理解があると導入がスムーズです。

TGIは、Rustで書かれた高性能なバックエンドを持ち、FlashAttentionbitsandbytesによる量子化など、様々な最適化技術を組み込んでいます。また、OpenAPI互換のREST APIを提供し、開発者が容易にLLMサービスを構築できるように設計されています。

3. TensorRT-LLM

ひとことで言うと: NVIDIAが提供する、LLMの推論をNVIDIA GPU上で最大限に高速化するためのライブラリ。 何のカテゴリか: LLM推論最適化ライブラリ、コンパイラ 何に使うのか: NVIDIA GPUのハードウェア特性を最大限に引き出し、LLMの推論性能を極限まで高めるため。特に、大規模なモデルや、超低レイテンシが求められるアプリケーションに適しています。 代表例: NVIDIAのGPUを搭載したデータセンターでのLLM推論。 よく混同される用語: vLLMTGIはフレームワーク全体を指すのに対し、TensorRT-LLMはより低レベルな最適化ツールキット。 初心者向け注意点: TensorRT-LLMはNVIDIA GPUに特化しており、他のGPUベンダーのハードウェアでは利用できません。また、モデルのコンパイルが必要となるため、導入には専門知識が必要です。

TensorRT-LLMは、モデルをNVIDIAのTensorRTフォーマットにコンパイルすることで、GPUの演算ユニットを最適に利用し、推論速度を大幅に向上させます。これには、カーネル融合、量子化、メモリ最適化など、多岐にわたる技術が含まれます。

4. Paged Attention

ひとことで言うと: LLMのKVキャッシュ(Key-Valueキャッシュ)をページ単位で管理するメモリ最適化技術。 何のカテゴリか: メモリ管理技術、アテンションメカニズム 何に使うのか: LLMの推論時に発生するGPUメモリの断片化を解消し、複数のリクエストを効率的にバッチ処理することで、スループットを向上させる。 代表例: vLLMで採用されている主要技術。 よく混同される用語: 通常のアテンションメカニズム (Transformerの基本要素) 初心者向け注意点: paged attentionは、オペレーティングシステムがメモリをページ単位で管理するのと似た概念です。これにより、可変長のシーケンス長を持つリクエストが混在しても、GPUメモリを無駄なく利用できます。

Paged Attentionの概念図

graph TD
    A[ユーザーリクエスト1: 短いプロンプト] --> B{KVキャッシュ生成}
    C[ユーザーリクエスト2: 長いプロンプト] --> B
    D[ユーザーリクエスト3: 中間のプロンプト] --> B

    B --> E[KVキャッシュメモリプール]
    E -- ページ単位で割り当て --> F[GPUメモリ]

    subgraph "従来のKVキャッシュ管理"
        G[リクエストごとに連続メモリ確保]
        H[メモリ断片化発生]
        I[GPUメモリ利用率低下]
    end

    subgraph "Paged Attention"
        J[KVキャッシュを固定サイズのページに分割]
        K[ページ単位で動的に割り当て/解放]
        L[メモリ断片化抑制]
        M[GPUメモリ利用率向上]
    end

    F -- 従来の課題 --> H
    F -- Paged Attentionの利点 --> M

説明: 従来のKVキャッシュ管理では、各リクエストのKVキャッシュが連続したメモリ領域を占有するため、リクエストの長さが異なるとメモリの断片化が発生し、GPUメモリの利用効率が低下します。paged attentionでは、KVキャッシュを固定サイズの「ページ」に分割し、OSの仮想メモリ管理のように、必要なページを動的に割り当て・解放します。これにより、メモリの断片化が抑制され、GPUメモリをより効率的に利用できるようになります。結果として、より多くのリクエストを同時に処理できるようになり、スループットが向上します。

5. Throughput (スループット)

ひとことで言うと: 単位時間あたりに処理できるリクエストの量や生成できるトークン数。 何のカテゴリか: 性能指標 何に使うのか: システム全体の処理能力を評価するため。特に、多数のユーザーからのリクエストを同時に処理する必要がある本番環境で重要。 代表例: 1秒あたりに生成できるトークン数 (Tokens/sec)、1秒あたりに処理できるリクエスト数 (Requests/sec)。 よく混同される用語: Latency (応答時間) 初心者向け注意点: スループットが高いほど、同じ時間でより多くの仕事をこなせることを意味します。

スループットは、以下の式で表すことができます。 $$ \text{Throughput} = \frac{\text{Total Tokens Generated}}{\text{Total Time}} $$ ここで、Total Tokens Generatedは生成されたトークンの総数、Total Timeは推論にかかった総時間です。この値が大きいほど、システムは効率的であると言えます。

6. Latency (レイテンシ)

ひとことで言うと: リクエストが送信されてから、最初の応答が返ってくるまでの時間、または全ての結果が返ってくるまでの時間。 何のカテゴリか: 性能指標 何に使うのか: ユーザー体験の良さを評価するため。特に、リアルタイム性が求められるアプリケーションで重要。 代表例: ユーザーがプロンプトを入力してから、LLMが最初のトークンを生成するまでの時間 (Time To First Token; TTFT)、全てのトークンを生成し終えるまでの時間 (Time To Last Token; TTLT)。 よく混同される用語: Throughput (処理量) 初心者向け注意点: レイテンシが低いほど、応答が速いことを意味します。

レイテンシは、以下の式で表すことができます。 $$ \text{Latency} = \text{Time To First Token} + (\text{Number of Output Tokens} - 1) \times \text{Time Per Output Token} $$ ここで、Time To First Tokenは最初のトークンが生成されるまでの時間、Number of Output Tokensは生成されるトークンの総数、Time Per Output Tokenは各出力トークンが生成されるのにかかる平均時間です。ユーザー体験を向上させるためには、この値を最小限に抑えることが重要です。

7. Batching (バッチ処理)

ひとことで言うと: 複数のリクエストやデータをまとめて一度に処理する技術。 何のカテゴリか: 処理最適化技術 何に使うのか: GPUのような並列処理に特化したハードウェアの利用効率を高め、スループットを向上させるため。 代表例: 複数のユーザーからのプロンプトをまとめてLLMに入力し、一度に推論を実行する。 よく混同される用語: ストリーミング (逐次処理) 初心者向け注意点: バッチサイズが大きすぎると、個々のリクエストのレイテンシが悪化する可能性があります。スループットとレイテンシのバランスが重要です。

Batchingの概念図

graph TD
    A[リクエスト1] --> C{バッチキュー}
    B[リクエスト2] --> C
    D[リクエスト3] --> C
    E[リクエスト4] --> C

    C -- 一定数または一定時間でまとめる --> F[バッチ]

    F -- GPUに送信 --> G["LLM推論 (GPU)"]

    G -- 結果を個別に返す --> H[応答1]
    G -- 結果を個別に返す --> I[応答2]
    G -- 結果を個別に返す --> J[応答3]
    G -- 結果を個別に返す --> K[応答4]

    subgraph "バッチ処理なし"
            L
            M
            LLM推論
            GPU
            O
            P
            LLM推論
            GPU
            R
            S
            LLM推論
            GPU
    end

    subgraph "バッチ処理あり"
            U
            V
            LLM推論
            GPU
    end

    L -- 効率悪い --> M
    U -- 効率良い --> V

説明: GPUは並列処理に優れているため、一度に多くのデータを処理する方が効率的です。バッチ処理なしの場合、各リクエストは個別にGPUに送られ、GPUの利用効率が低下します。バッチ処理ありの場合、複数のリクエストをまとめてGPUに送ることで、GPUをより長く、より効率的に稼働させることができ、結果として全体のthroughputが向上します。

具体例

vLLMを使ったLLMサービング

vLLMは、Pythonで簡単にLLMサービングAPIを立ち上げることができます。

# vLLMのインストール (事前にGPU環境とCUDAがセットアップされている必要があります)
# pip install vllm

from vllm import LLM, SamplingParams

# モデルのロード
# Hugging Face Hubのモデル名を使用
llm = LLM(model="mistralai/Mistral-7B-Instruct-v0.2")

# サンプリングパラメータの設定
sampling_params = SamplingParams(temperature=0.7, top_p=0.95, max_tokens=128)

# プロンプトのリスト
prompts = [
    "What is the capital of France?",
    "Write a short poem about AI.",
    "Explain the concept of paged attention in simple terms."
]

# 推論の実行
# vLLMは内部でpaged attentionとバッチ処理を自動的に行います
outputs = llm.generate(prompts, sampling_params)

# 結果の表示
for prompt, output in zip(prompts, outputs):
    generated_text = output.outputs[0].text
    print(f"Prompt: {prompt!r}, Generated text: {generated_text!r}")

# APIサーバーとして起動する場合 (別のターミナルで実行)
# python -m vllm.entrypoints.api_server --model mistralai/Mistral-7B-Instruct-v0.2
# 起動後、curlなどでリクエストを送信可能
# curl http://localhost:8000/generate -H "Content-Type: application/json" -d '{
#     "prompt": "Hello, my name is",
#     "max_tokens": 20
# }'

この例では、LLMクラスがモデルのロード、paged attentionによるKVキャッシュ管理、そして複数のプロンプトに対する効率的なバッチ推論を自動的に処理します。これにより、開発者は複雑な最適化を意識することなく、高いスループットと低いレイテンシでLLMサービスを構築できます。

TGIを使ったLLMサービング

TGIはDockerコンテナとして提供されることが多く、手軽にデプロイできます。

# Dockerのインストールが必要です

# 1. TGI Dockerイメージのプル
docker pull ghcr.io/huggingface/text-generation-inference:latest

# 2. モデルをダウンロードするためのディレクトリを作成 (オプション)
# mkdir -p ./models/mistral-7b-instruct-v0.2

# 3. TGIコンテナの起動
# --model-id: Hugging Face Hubのモデル名
# --port: サービスがリッスンするポート
# --volume: モデルをキャッシュするディレクトリ (永続化のため)
# --gpus all: 全てのGPUを利用
docker run --gpus all -p 8080:80 \
    -v ~/.cache/huggingface:/data \
    ghcr.io/huggingface/text-generation-inference:latest \
    --model-id mistralai/Mistral-7B-Instruct-v0.2 \
    --max-input-length 1024 \
    --max-total-tokens 2048

# 4. 別のターミナルからAPIリクエストを送信
curl 127.0.0.1:8080/generate -X POST \
    -H "Content-Type: application/json" \
    -d '{
        "inputs": "What is the capital of France?",
        "parameters": {
            "max_new_tokens": 128,
            "temperature": 0.7,
            "top_p": 0.95
        }
    }'

TGIも内部で様々な最適化(FlashAttention、量子化、動的バッチ処理など)を行い、高い性能を発揮します。Dockerを使うことで、環境構築の手間を減らし、再現性の高いデプロイが可能です。

よく混同される用語との比較

LLM推論基盤の比較

特徴/項目 vLLM TGI (Text Generation Inference) TensorRT-LLM
開発元 UC Berkeley (オープンソース) Hugging Face NVIDIA
主な言語 Python, CUDA Rust, Python, CUDA C++, CUDA
ターゲットハードウェア NVIDIA GPU NVIDIA GPU NVIDIA GPU
主要な最適化 Paged Attention、動的バッチ処理、FlashAttention FlashAttention、動的バッチ処理、量子化、Rustバックエンド TensorRTコンパイル、カーネル融合、量子化、メモリ最適化
スループット 非常に高い 高い 極めて高い
レイテンシ 低い 低い 極めて低い
メモリ効率 非常に高い (Paged Attention) 高い 極めて高い
導入の容易さ 中程度 (Pythonライブラリ) 中程度 (Dockerコンテナ) 低 (モデルコンパイル、NVIDIAエコシステム)
ユースケース 高スループットなAPIサービス、可変長リクエスト Hugging Faceモデルのデプロイ、ストリーミング 超低レイテンシ、大規模モデル、NVIDIA最適化
エコシステム 独立、OpenAI API互換 Hugging Face Hubとの連携 NVIDIA CUDA/TensorRTエコシステム

結論:

  • vLLMは、柔軟なバッチ処理と優れたメモリ管理(Paged Attention)により、高いスループットと低いレイテンシを両立し、汎用的なLLMサービングに適しています。
  • TGIは、Hugging Faceモデルとの親和性が高く、Dockerベースで手軽にデプロイでき、ストリーミング出力などの機能も充実しています。
  • TensorRT-LLMは、NVIDIA GPUの性能を最大限に引き出すことに特化しており、極限の推論速度と効率を求める場合に最適です。

llama.cpp vs vLLM vs transformers単体

特徴/項目 llama.cpp vLLM transformers単体
主な用途 CPUでの高速推論、ローカル環境での実行 GPUでの高速推論、本番サービング 研究開発、基本的なモデル実行、プロトタイピング
ターゲットハードウェア CPU (GPUも一部サポート) GPU (NVIDIA) CPU, GPU (汎用)
最適化技術 量子化 (GGUF)、KVキャッシュ最適化、GGML Paged Attention、動的バッチ処理、FlashAttention 基本的な推論、一部最適化ライブラリと連携可能
スループット 中程度 低〜中程度
レイテンシ 中程度 中程度
メモリ効率 高 (特に量子化モデル) (Paged Attentionによる) 中程度
導入の容易さ (GGUFモデルとCLI/Pythonバインディング) 中程度 (GPU環境構築が必要) 高 (Pythonライブラリとして)
本番環境適性 限定的 (小規模サービス、エッジ) (スケーラブルなAPIサービス) 低 (スループット/レイテンシの課題)

結論:

  • llama.cppは、手軽にCPUでLLMを動かしたい場合や、エッジデバイスでの利用に適しています。
  • transformers単体は、モデルのロードや基本的な推論を手軽に試すための研究開発用途に適しています。
  • vLLMは、複数のユーザーからのリクエストを同時に、高速に処理する必要がある本番環境でのLLMサービングに最適です。

開発用実行 vs 本番サービング

特徴/項目 開発用実行 (例: transformers単体, llama.cpp CLI) 本番サービング (例: vLLM, TGI, TensorRT-LLM)
目的 機能確認、プロトタイピング、学習 安定稼働、高スループット、低レイテンシ、スケーラビリティ
リクエスト処理 単一リクエスト、逐次処理 複数リクエスト同時処理、バッチ処理、キューイング
性能指標 正確性、モデルの挙動 スループット、レイテンシ、リソース利用効率
エラーハンドリング 限定的 堅牢なエラー処理、ロギング、モニタリング
リソース利用 必要な時に必要なだけ GPUメモリ、CPU、ネットワーク帯域の最適化と最大活用
API提供 なし、または簡易的なもの RESTful API、gRPCなど、標準的なインターフェース
スケーリング 不要 水平・垂直スケーリングへの対応
セキュリティ 低 (ローカル実行が主) 高 (認証、認可、レートリミットなど)

結論: 開発用実行は、モデルの動作確認やアイデアの検証に便利ですが、本番環境で求められる性能、安定性、スケーラビリティ、セキュリティ要件を満たしません。本番サービングでは、これらの要件を満たすために、vLLMやTGIのような専用の推論基盤が必要となります。

実務での位置づけ

LLMをビジネスアプリケーションに組み込む際、推論基盤の選択は非常に重要です。

  1. プロトタイピング・開発初期:

    • transformersライブラリを使ってPythonスクリプトでモデルを動かす。
    • llama.cppOllamaを使ってローカルPCで手軽に試す。
    • この段階では、機能の検証が主であり、性能は二の次です。
  2. 小規模な内部ツール・エッジデバイス:

    • llama.cpp (GGUFモデル) を利用して、CPUまたは限られたGPUリソースで動作させる。
    • コストを抑えつつ、ある程度の応答速度が求められる場合に有効です。
  3. 本番環境・スケーラブルなAPIサービス:

    • vLLM: 複数のユーザーからのリクエストを効率的に処理し、高いスループットと低いレイテンシを実現したい場合に最適です。特に、可変長のプロンプトや生成長が多い場合にpaged attentionの恩恵が大きいでしょう。
    • TGI: Hugging Faceエコシステムとの親和性が高く、Dockerベースで手軽にデプロイしたい場合に適しています。ストリーミング出力や複数のモデルのロードにも対応しています。
    • TensorRT-LLM: NVIDIA GPUの性能を最大限に引き出し、極限まで推論速度を追求したい場合に選択します。特に、大規模モデルや超低レイテンシが求められる金融、自動運転などの分野で検討されます。

これらの推論基盤は、LLMアプリケーションのバックエンドとして、ユーザーからのリクエストを受け付け、モデルに推論させ、結果を返すという一連の処理を効率的に行います。これにより、開発者はモデルの選定やアプリケーションロジックに集中でき、インフラの最適化はこれらの基盤に任せることができます。

LLM推論基盤のアーキテクチャ概要

graph TD
    subgraph "クライアント層"
            A
            Web
            C
            CLIツール
    end

    subgraph "推論サービス層"
            B
            D
            E
            Paged
            Attention
            vLLM
            E
            TensorRT最適化
            TensorRT
            LLM
    end

    subgraph "データ層"
            H
            Hugging
            Face
            Hub
            S3
            D
    end

    D -- 結果を返す --> B

説明: クライアントからのリクエストはAPI Gateway/ロードバランサーを経由して推論サービス層に到達します。この層では、vLLM、TGI、TensorRT-LLMなどの推論基盤が動的バッチ処理やメモリ最適化(Paged Attentionなど)を行い、GPUクラスタ上でLLMの推論を実行します。モデルはモデルストレージからロードされ、推論結果はクライアントに返されます。ログやモニタリングはシステムの健全性を監視するために重要です。

まとめ

3行まとめ

  • vLLM, TGI, TensorRT-LLMは、LLMを本番環境で高速かつ効率的に運用するための推論基盤である。
  • paged attentionbatchingなどの技術により、GPUリソースを最大限活用し、throughputlatencyを最適化する。
  • 開発用実行と本番サービングでは求められる要件が大きく異なり、用途に応じた適切な推論基盤の選択が重要である。

混同しやすい用語

  • vLLMとllama.cpp: vLLMはGPUでの高スループットサービング、llama.cppはCPUでの手軽なローカル実行が主な用途。
  • ThroughputとLatency: Throughputは「処理量」、Latencyは「応答時間」。両者はトレードオフの関係にあることが多い。
  • BatchingとStreaming: Batchingは複数のリクエストをまとめて処理、Streamingは結果を逐次的に返す。

次に読むべき章

  • 第10章: LLMの評価指標とベンチマーク (推論基盤の性能をどのように測るか理解するため)
  • 第11章: LLMの量子化と蒸留 (さらに推論効率を高めるための技術を学ぶため)