自己回帰生成 — PrefillとDecodeの2フェーズ

LLMがテキストを生成する仕組みは、自己回帰(autoregressive)生成と呼ばれます。 モデルは1トークンずつ、直前までの全トークンを条件として次のトークンを予測します。 「東京の天気は」という入力に対して「晴れ」→「です」→「。」と、一つずつ出力を積み重ねていくのです。

この推論プロセスは、大きく2つのフェーズに分かれます。

Prefillフェーズ(プロンプト処理)

入力プロンプトの全トークンを並列に処理し、各トークンの内部表現(Key/Valueテンソル)を一括で計算します。 このフェーズは計算量が多いものの、GPUの並列演算能力をフルに活用できるため、比較的高速です。 ボトルネックは計算(compute-bound)です。

Decodeフェーズ(トークン生成)

1トークンずつ逐次的に生成するフェーズです。 各ステップで過去の全トークンのKey/Valueを参照する必要があり、メモリ帯域(memory-bound)がボトルネックになります。 100トークンの出力には100回の前方伝播が必要であり、ここが推論全体の遅延の主因です。

graph LR
  A[入力プロンプト] --> B[Prefillフェーズ\n全トークン並列処理\ncompute-bound]
  B --> C[KVキャッシュ生成]
  C --> D[Decodeフェーズ\n1トークンずつ逐次生成\nmemory-bound]
  D --> E{EOS?}
  E -->|No| D
  E -->|Yes| F[出力完了]

  style B fill:#3b82f6,stroke:#1d4ed8,color:#fff
  style D fill:#8b5cf6,stroke:#6d28d9,color:#fff
  style F fill:#10b981,stroke:#059669,color:#fff
LLM推論パイプライン: Prefillで一括処理し、Decodeで1トークンずつ生成。EOSトークンで終了

サンプリング戦略 — 確率分布からトークンを選ぶ

モデルが出力するロジット(logits)は、語彙の各トークンに対するスコアです。 これをSoftmax関数で確率分布に変換し、その分布からどのようにトークンを選ぶかが「サンプリング戦略」です。

Temperature(温度)

Temperatureは確率分布の鋭さを制御するパラメータです。 Softmax計算の前にロジットをTemperature値で割ることで動作します。

  • T = 0.1: 分布が非常に鋭くなり、最高確率のトークンがほぼ確実に選ばれる(決定的)
  • T = 1.0: モデル本来の確率分布をそのまま使用
  • T = 2.0: 分布が平坦になり、低確率トークンも選ばれやすくなる(創造的だがノイズも増加)

具体例として、「日本の首都は」に続くトークンの確率が「東京」=0.85、「京都」=0.10、「大阪」=0.05の場合を考えます。 T=0.1では「東京」がほぼ100%選ばれますが、T=2.0では「京都」や「大阪」も無視できない確率で選ばれるようになります。

Top-k サンプリング

確率上位k個のトークンだけを候補とし、それ以外のトークンの確率を0にしてから再正規化してサンプリングします。 k=50なら上位50トークンのみが候補です。低確率の無関係なトークンが選ばれるリスクを排除できますが、 最適なkの値は文脈によって変わるという課題があります。

Top-p(Nucleus Sampling)

確率の高い順にトークンを並べ、累積確率がpに達するまでのトークンを候補とします。 p=0.9なら累積確率90%分のトークンが候補になります。 Top-kと異なり、確率分布の形に応じて候補数が動的に変わるため、より柔軟な制御が可能です。 確信度が高い場面では少数のトークンから、不確実な場面では多数のトークンから選択します。

Repetition Penalty

すでに生成されたトークンのロジットにペナルティ(例: 1.2倍で割る)を適用し、同じ単語やフレーズの繰り返しを抑制します。 LLMは放置すると同じ表現をループする傾向があり、この制御は出力品質に直結します。

KVキャッシュ — 推論高速化の基本

自己回帰生成の各ステップで、Self-Attentionは過去の全トークンのKey(K)とValue(V)テンソルを必要とします。 毎回ゼロから計算し直すのは非効率なため、過去のK/Vテンソルをメモリに保持して再利用する仕組みがKVキャッシュです。

KVキャッシュにより、新しいトークンの生成ではそのトークン分のK/Vだけを計算し、既存のキャッシュに追加すれば済みます。 計算量はO(n²)からO(n)に削減されます。

KVキャッシュ最適化 — メモリ効率の追求

PagedAttention(vLLM)

OSの仮想メモリ管理にヒントを得た手法です。KVキャッシュを固定サイズのブロック(ページ)に分割し、 非連続なメモリ領域に配置します。これにより、従来の連続メモリ確保で発生していた メモリ断片化(fragmentation)を約70%から約4%にまで削減しました。 vLLMの中核技術であり、同時に処理できるリクエスト数(スループット)を大幅に向上させます。

GQA(Grouped Query Attention)

通常のMulti-Head Attentionでは各ヘッドが独自のK/Vを持ちますが、GQAでは複数のクエリヘッドが同じK/Vヘッドを共有します。 LLaMA 2 70BやGeminiで採用されており、KVキャッシュのメモリ使用量を大幅に削減しつつ、 品質の低下を最小限に抑えます。

SnapKV

長いコンテキストの中で、Attention重みが高い重要なトークンのKVのみを選択的に保持する手法です。 不要なトークンのKVを破棄することでメモリ使用量を削減しつつ、品質への影響を最小化します。

FlashAttention — IO-awareなAttention計算

標準的なAttention計算では、巨大なAttention行列(N×N)をGPUのHBM(高帯域メモリ)に書き出し、読み戻すという操作が発生します。 FlashAttentionはこのメモリIO操作を最小化する「IO-aware」なアルゴリズムです。

核心となるアイデアはタイリング(tiling)です。 Attention行列全体をメモリに保持するのではなく、GPUのオンチップSRAM(高速だが小容量)に収まるサイズのブロックに分割して計算します。 各ブロックの計算結果を段階的に統合することで、HBMとの間のデータ転送量を大幅に削減します。

FlashAttentionの進化

  • FlashAttention v1(2022年): タイリングによるIO最適化を提案。メモリ使用量O(N²)→O(N)、2〜4倍高速化
  • FlashAttention v2(2023年): GPU上のワークパーティショニングを最適化し、v1比で約2倍高速化。A100で理論ピーク性能の50〜73%を達成
  • FlashAttention v3(2024年): Hopper GPU(H100)のテンソルコアとTMAを活用。FP8対応により、さらなる高速化を実現

MoE(Mixture of Experts)— 条件付き計算

通常のTransformerでは、入力トークンが全パラメータを通過します。 MoEはこれを変え、各トークンに対してルーター(Router)が少数の「エキスパート」を選択し、 選ばれたエキスパートのみがそのトークンを処理します。

たとえばMixtral 8x7Bは8つのエキスパート(各7Bパラメータ相当のFFN)を持ち、 各トークンに対して2つのエキスパートのみが活性化されます。 総パラメータ数は約46.7Bですが、推論時のアクティブパラメータは約12.9Bに抑えられるため、 7Bモデル並みの計算コストで70Bクラスの性能を実現します。

DeepSeek V3はさらに進化し、671Bの総パラメータに対してトークンあたり37Bのみを活性化する Fine-grained Expert Segmentationを採用しています。 MoEにより「パラメータ数(知識の容量)」と「計算コスト」を分離できるのが最大の利点です。

量子化 — 精度を抑えて軽量化

モデルの重みを本来の高精度な数値表現からより低いビット幅に変換する技術が量子化(Quantization)です。 メモリ使用量と推論速度を大幅に改善できます。

精度 ビット幅 7Bモデルのメモリ 相対速度 品質への影響
FP32 32bit 約28GB 1x(基準) なし
FP16/BF16 16bit 約14GB 約2x ほぼなし
INT8 8bit 約7GB 約3〜4x 軽微
INT4 4bit 約3.5GB 約5〜6x 若干の劣化あり

主要な量子化手法

  • GPTQ: 学習後量子化(Post-Training Quantization)の代表格。小さなキャリブレーションデータセットを使い、レイヤーごとに最適な量子化パラメータを算出。GPU推論向け
  • AWQ(Activation-aware Weight Quantization): 活性化の分布に基づき、重要な重みを高精度で保持。GPTQより高速かつ高品質な傾向
  • GGUF(旧GGML): llama.cpp向けのフォーマット。CPU推論に最適化され、Q4_K_M、Q5_K_Mなど細かい量子化レベルを指定可能

推論エンジン比較 — ユースケースで選ぶ

LLMを実際に動かすには推論エンジンが必要です。 用途に応じて最適なエンジンは異なります。

エンジン 特徴 主な用途 KVキャッシュ最適化 GPU要件
vLLM PagedAttentionによる高スループット。連続バッチング対応 プロダクションAPIサーバー PagedAttention NVIDIA GPU必須
TGI(Text Generation Inference) Hugging Face公式。トークンストリーミング、ウォーターマーク対応 HFモデルの本番デプロイ Flash Decoding NVIDIA GPU推奨
llama.cpp C/C++実装で極めて軽量。CPU推論に最適化、GGUFフォーマット エッジ/ローカル推論 基本的なKVキャッシュ CPU可(GPU任意)
Ollama llama.cppをラップし、ワンコマンドで起動。モデル管理が容易 個人利用・プロトタイピング llama.cpp準拠 CPU可(GPU任意)

大量リクエストを捌くAPIサーバーにはvLLMやTGI、 手元のPCで手軽に試すならOllama、 組み込みやエッジデバイスにはllama.cppが適しています。

# Ollamaでの推論(ワンコマンドで起動)
ollama run llama3:8b "Transformerの仕組みを簡潔に説明して"

# vLLMでのAPIサーバー起動
python -m vllm.entrypoints.openai.api_server \
  --model meta-llama/Llama-3-8B-Instruct \
  --quantization awq \
  --max-model-len 8192

理解度チェック

問題 0 / 50%
Q1

LLMの推論において、Decodeフェーズのボトルネックは何ですか?

キーボード: 1〜4 で選択、Enter で回答