KV キャッシュの正体
“KV” は key/value(キー/バリュー) の略称で、モデルがこれまでに処理したすべてのトークンに対して計算する内部表現です。新しいトークンのたびにこれらの表現を一から再計算するのではなく、モデルはそれらを KV キャッシュに保存して再利用し、シーケンスにトークンが追加されるたびに新しいエントリを付加していきます。 これにより、生成が実用的なものになります。キャッシュがない場合、返信の 500 番目のトークンを生成するには、その前の 499 個のトークンを毎回再処理する必要があります。キャッシュがあれば、モデルは新しいトークンごとに新しい計算を行うだけで、すでに計算済みのものはすべて再利用できます。 キャッシュは プリフィル(モデルがプロンプトを読み込む際)中に構築され、デコード(モデルが返信を生成する際)中にトークンごとに一エントリずつ拡張されます。これらの二つのフェーズがどのように機能するかについては、推論の仕組みを参照してください。なぜ長いコンテキストにより多くのメモリが必要になるのか
KV キャッシュは、トークンがアクティブなコンテキスト内に留まっている間、レイヤーごとにトークン一つにつき一エントリを保持します。つまり、そのサイズは以下の要素に直接比例して増大します。- Context length — 処理中のトークン数が多いほど、キャッシュエントリ数が増えます。128K トークンの会話は、4K トークンの会話よりもはるかに多くのキャッシュ状態を保持します。
- バッチサイズ — 複数のリクエストを同時に処理している場合、それぞれに独自の KV キャッシュが必要になるため、並行リクエスト数に応じて合計のキャッシュメモリが乗算されます。
コンテキストと速度のトレードオフ
メモリに加えて、大きな KV キャッシュには速度のコストも伴います。デコードはメモリ帯域幅がボトルネックとなります。生成される各トークンにおいて、モデルは重みに加えて、これまでに構築された KV キャッシュ全体を読み取ります(推論の仕組み参照)。キャッシュが大きくなると、各ステップで読み取るデータ量が増えるため、以下のような影響が生じます。- 長いコンテキストはデコードを遅くします。 会話が増大するにつれて生成速度(トークン/秒)は低下する傾向がありますが、モデル自体は変わっていません。
- 長いコンテキストはより多くのメモリを消費します。 これは速度のコストとは独立した、別々のコストです。
異なる量子化を選択することでこのトレードオフを回避することはできません。重みの量子化と KV キャッシュの量子化は別々の調整項目であり、一部のバックエンドは KV キャッシュの量子化を独立してサポートしており、これによりより長いコンテキストを収容できます。これはバックエンド固有の設定ですので、依存する前にランタイムのドキュメントでサポート状況を確認してください。
実践的な要点
デプロイメントに割り当てるコンテキスト量を決定する際は、それを無料の設定ではなく、実際のリソース予算として扱ってください。最大コンテキストが非常に大きい(128K、256K など)と宣伝されているモデルでも、常にその上限で実行すべきという意味ではありません。タスクに実際に必要な分に合わせてコンテキストのサイズを決定し、コミットする前に GPU モデル適合ガイド で実際のメモリコストを確認してください。さらに詳しく
推論の仕組み
プロンプトの完全なライフサイクル — プリフィル、デコード、およびメモリ内の配置場所。
メモリとオフロード
KV キャッシュに加え、重みやオーバーヘッドを含む完全なサイズ計算式。
コンテキストとメモリが収まった後
KV キャッシュのサイズ調整は、モデルをローカルで適切に実行するための一部です。localhost で実行され、リクエストに応答するようになったら、次のステップは他の場所からアクセスできるようにすることです。
安定したエンドポイントを提供する
Tokios はモデルを選択、ホスト、ファインチューニングしません。ローカルで実行されたモデルを、どこからでも呼び出せる安定した認証済みエンドポイントに変換します。