GEO

Speculative Decoding

Speculative decodingとは、小さく高速な「ドラフト」モデルが数トークン先まで予測し、その後、大きなターゲットモデルが1回の並列フォワードパスでそれらを検証する推論最適化手法です。ターゲットモデルは、自身が生成したであろうものと一致するトークンを受け入れ、それ以外を棄却します。ユーザーは通常のデコーディングとまったく同じ出力を得ますが、その速度は2~4倍になります。

Speculative decodingとは、小さく高速な「ドラフト」モデルが数トークン先まで予測し、その後、大きなターゲットモデルが1回の並列フォワードパスでそれらを検証する推論最適化手法です。ターゲットモデルは、自身が生成したであろうものと一致するトークンを受け入れ、それ以外を棄却します。ユーザーは通常のデコーディングとまったく同じ出力を得ますが、その速度は2~4倍になります。

なぜ重要なのか

LLMの生成は逐次的な依存関係に縛られており、各トークンは1つ前のトークンを待たなければなりません。大きなモデルのボトルネックは生の計算能力ではなく、メモリ帯域幅、つまりトークンごとに1回、巨大な重みをGPUの計算ユニットへ移動させることにあります。Speculative decodingは、複数の推測トークンを1回のフォワードパスにまとめることで逐次の連鎖を断ち切り、高価な大モデルの呼び出し回数を劇的に減らします。Googleが2022年に初めて発表し、2024~2025年には主要な推論エンジン(vLLM、TensorRT-LLM、llama.cpp、together.ai)がすべてspeculative decodingを標準の最適化として搭載し、同じ出力品質を保ちながらサービング費用を30~70%削減しています。

仕組み

1. ドラフトモデルが提案する: 小さく安価なモデル(たとえば70Bターゲットの1Bパラメータ版)が、次のk個のトークンを自己回帰的に生成します。ドラフトモデルの重みは小さいため、これは高速です。

2. ターゲットモデルが検証する: ターゲットモデルが、k個のドラフトトークンに対して1回のフォワードパスを並列で実行し、各位置で自身が生成したであろうものを計算します。

3. 受け入れるか棄却するか: 最初のドラフトトークンから始めて、ターゲットモデルは自身のトップ候補(または確率に応じてサンプリングしたもの)が一致すればそれを受け入れ、一致しなくなるまで続けます。

4. 修正して続行する: 最初に一致しなかった箇所で、ターゲットのトークンがドラフトのものを置き換えます。プロセスはそこから再開します。

5. 正味の効果: ドラフトが平均して70%の確率で正しければ、ターゲットモデルはフォワードパスあたり約3倍多くのトークンを生成し、遅延がそれに比例して削減されます。

なぜロスレスなのか

正しく実装されたspeculative decodingは、通常のデコーディングとまったく同じ出力分布を生成します。これが成り立つのは、ターゲットモデルが検証者として機能するためです。ドラフトが提案するどのトークンもターゲットの受け入れテストを通過しなければならないため、最終的な系列はターゲットが単独で生成したであろうものと同一になります。品質のトレードオフはなく、得られるのは速度の向上だけです。

バリエーション

標準的なspeculative decoding(Google 2022): 1つのドラフトモデルと1つのターゲット。最初の定式化です。

Medusa: ターゲットモデル自体に複数の「ヘッド」を追加し、数トークン先を予測させることで、別途のドラフトモデルを不要にします。デプロイがよりシンプルになります。

EAGLE: ターゲットモデル自身の内部表現を使ってドラフトする、より正確なバリエーション。外部のドラフトよりも高い受け入れ率を達成します。

Tree speculative decoding: 複数の候補トークンツリーを並列でドラフトします。受け入れ確率は高まりますが、検証の計算量が増えます。

Self-speculative: ターゲットモデルの層をスキップして、同じ重みから安価な「ドラフト」を作ります。

最も効果的な場面

バッチサイズ1の推論: 単一ユーザーのインタラクティブなチャットはメモリ律速です。Speculative decodingはここで真価を発揮します。

長い出力: モデルが生成するトークンが多いほど、累積的な節約が積み上がります。

繰り返しの多い構造: 出力が予測しやすいパターン(コード、JSON)に従う場合、ドラフトの受け入れ率は非常に高くなります。

遊休ハードウェアの活用: メモリ待ちでアイドル状態になりがちなGPUで、推測が計算の空きを埋めます。

効果が小さい場面

大規模バッチのサービング: 高スループットのワークロードは、すでにメモリ律速ではなく計算律速です。推測はあまり節約にならず、オーバーヘッドだけを追加します。

非常に創造的/ランダムな出力: ドラフトの受け入れ率が低く、高速化が限られます。

極小モデル: 3Bターゲットに対する1Bドラフトは、ターゲットがすでに安価なため、あまり節約になりません。

短いプロンプトと短い回答: 推測のセットアップのオーバーヘッドが、得られる利益を上回ります。

トレードオフ

メモリ上に追加のモデル: ターゲットとドラフトの両方をサービングすることになります。self-speculativeを使わない限り、メモリのフットプリントが増えます。

実装の複雑さ: 検証ループ、棄却サンプリング、KVキャッシュのロールバックの管理は簡単ではありません。ライブラリを使いましょう。

受け入れ率への敏感さ: 相性の悪いドラフトは、棄却が支配的になると、かえって動作を遅くすることがあります。

コールドスタート: ドラフトが温まるまで、最初の数トークンは推測の恩恵を受けません。

よくある間違い

異なるファミリーのドラフトモデルを使う: Mistralターゲットに対するLlamaドラフトは、ほとんど受け入れられません。ドラフトはターゲットと整合している必要があります。

ドラフトが大きすぎる: 70Bターゲットに対する7Bドラフトは受け入れ率は高いものの、実行コストが高すぎます。ドラフトはターゲットのサイズの5~20%であるべきです。

KVキャッシュのロールバックを無視する: 棄却されたトークンは、ターゲットのKVキャッシュをロールバックしなければなりません。これを忘れると状態が壊れます。

すでに高速なモデルに適用する: Haiku/Flashクラスのモデルはメモリが軽量です。推測による節約は小さくなります。

エンドツーエンドで測定しない: リクエスト経路全体をベンチマークしましょう。素朴な1秒あたりトークン数の向上は、負荷がかかったときやネットワーク遅延が支配的なときに消えてしまうことがあります。

Sources: