著者 | ピエール・リアンハート 編纂者:岳陽 前回の記事では、LLM推論プロセスでよく使われる最適化手法であるKVキャッシュを紹介しました。KVキャッシュを使用する目的は、生成プロセス中に計算されている過去のトークンのキーバリューテンソルをGPUメモリに保存(「キャッシュ」)することです。これにより、生成ステップごとにこれらのキーバリューテンソルを再コンパイルする必要がなくなります。 キーバリュー(KV)キャッシュは、メモリ消費量と計算量の削減をトレードオフする妥協策です。この記事では、KVキャッシュのサイズ、それがもたらす課題、そしてこれらの課題に対処するための最も一般的な戦略について考察します。 01 KVキャッシュの容量はどれくらいですか?これは非常に単純です。各バッチ内の各シーケンスの各トークンについて、各アテンション層の各アテンションヘッドに、サイズ d_head のベクトルテンソルを2つ(キーテンソル1つと値テンソル1つ)保存する必要があります。各テンソルパラメータに必要なスペースは精度によって異なります。完全精度(FP32)の場合はパラメータあたり4バイト、半精度(BF16、FP16)の場合はパラメータあたり2バイト、8ビットデータ型(INT8、FP8)の場合はパラメータあたり1バイトなどです。 `b` はバッチサイズ、`t` はシーケンス全体の長さ(ユーザー提供のプロンプトとモデル生成の補完を含む)、`n_layer` はデコーダーブロック/アテンション層の数、`n_heads` はアテンション層あたりのアテンションヘッドの数、`d_head` はアテンション層の隠れ次元、`p_a` は精度です。マルチヘッドアテンション(MHA)モデルはキーバリューキャッシュ技術を使用し、トークンあたりのメモリ消費量(バイト単位)は以下のとおりです。 注意:MHA モデルでは n_heads × d_head = d_model ですが、この論文ではこのケースに基づいて上記の式を簡略化していません。 したがって、KV キャッシュの合計サイズ (バイト単位) は次のようになります。 キーバリュー(KV)キャッシュを使用する際の主な課題の一つは、そのサイズがバッチサイズ、そしてさらに重要な点として、シーケンス長に比例して増加することです。シーケンス長に比例して増加するため、KVキャッシュのサイズには事実上上限がありません。一方、GPUメモリは明らかに有限です。さらに悪いことに、シーケンス長を事前に知ることができないため、KVキャッシュのメモリ要件も不明であり、メモリ管理が特に困難になります。 人気のあるMHAモデル(表1)、すなわちMetaのLlama-2 [1]とOPT [2]、MosaicMLのMPT [3]、BigScienceのBLOOM [4]のデータを見てみましょう。 表1 – 市場で一般的に使用されているマルチヘッドアテンション(MHA)モデルの仕様 パラメータが半精度(FP16、BF16)で格納されていると仮定し、より小さいモデル(Llama-2-7B)とより大きいモデル(BLOOM-176B)を選択します。Llama-2-7BとBLOOM-176Bの場合、KVキャッシュのメモリ消費量はそれぞれ約0.5MB/トークンと約4MB/トークンです。 さて、Llama-2-7Bに注目してみましょう。半精度の場合、モデルの重みを読み込むのに約14GBのメモリが消費されます。これは、28kトークンのキーと値をキャッシュするのと同等です。28kトークンは、長さ512のシーケンス56個分のバッチに相当する可能性があり、それほど極端な値ではありません。 上記のデータは、KV キャッシュのメモリ消費量が非常に大きくなり、大規模なシーケンス モデルの重みをロードするために必要なメモリ量を超える可能性があることを示しています。 ここで、これらの数値を一般的な NVIDIA データ センター GPU のメモリ容量と比較してみましょう (表 2 を参照)。 表2 – LLMトレーニングサービスにおける一般的なNVIDIAデータセンターGPU仕様の概要 比較的安価なA10 GPUを選択し、Llama-2-7Bを使用して最大KVキャッシュ容量を計算してみましょう。モデルの重みをロードした後、利用可能なKVキャッシュ容量は24-2x7=10GBとなり、これは約2万トークン(ヒントを含む)に相当します。これは、特に長いシーケンスを処理または生成する場合、多数の同時リクエストに対応するには明らかに不十分です。 KV キャッシュにより、非常に長いシーケンスの処理や生成 (つまり、長いコンテキスト ウィンドウによってもたらされる課題や障害) や大規模なバッチの処理が妨げられ、ハードウェア効率を最大化する能力が妨げられることがわかっています。 この観点から、モデル処理能力を最大化するということは、KV キャッシュに可能な限り多くのメモリ領域を割り当てることを意味し、これは次の方法で実現できます。
モデルの重みと増え続けるキーバリューキャッシュは、フォワードパスごとに読み込む必要があるため、デコードステップでは非常に大きなデータ転送が必要になります。これは、後の記事で説明するように、メモリ帯域幅によって実質的に制限されます。つまり、実際には、有用な作業(つまり計算)よりもデータの移動に多くの時間を費やしていることになります。この場合、レイテンシを改善するには、メモリ帯域幅を増やす(つまり、より優れたハードウェアを使用する)か、データ転送を減らすしかありません。モデルの重みとキーバリューキャッシュを小さくすると、より多くのシーケンスにメモリが解放され、スループットが向上します(および/または最大シーケンス長が増加します)。 この点で、メモリ フットプリントを削減する戦略には 3 つの効果があります。ハードウェアの使用率を向上させてコスト効率を高め、同時にレイテンシを削減してスループットを向上させることができます。 余談ですが、大規模モデルに入力するトークンに対して料金が発生するのはなぜでしょうか? (表 3) 表3 – OpenAI料金表(確認日:2024年1月12日) ここまで読んでいただければ、モデルに入力されるトークンとモデルから出力されるトークンの両方が課金される理由がお分かりいただけると思います。入力プロンプトが処理されると、つまり事前入力フェーズの終了時には、GPUメモリ(各入力トークンのキーバリューテンソルの保存に使用)と計算(モデルによるプロンプトトークンの処理)が既に開始されています。 それでは、実際のデータを見てみましょう。Pパラメータを持つモデルの総FLOP数は約2.P FLOP/トークン[5]で、Llama-2-7Bを用いたキューワードの処理には、約0.5MB/トークンのGPUメモリ(上記参照)と約14TFLOPS/トークンのGPUコンピューティングリソースが消費されると仮定します。1000トークン(2ページ未満)のキューワードの場合、約500MBのメモリと14TFLOPSのコンピューティングリソースが必要になりますが、まだコンテンツは生成していません。 ここで、上記の式の各項を調べて、KV キャッシュのメモリ使用量を削減できる方法を確認しましょう。 02 バッチサイズを小さくするとどうなるでしょうか?ほとんどの場合、バッチサイズを小さくすることは望ましくありません。なぜなら、バッチサイズを小さくするとKVキャッシュのメモリフットプリントが削減され、レイテンシが短縮される一方で、ハードウェア使用率も低下し、費用対効果が低下するからです。この点については後のブログ記事で詳しく説明しますが、バッチサイズは可能な限り大きくすることが望ましいのです。 03 では、シーケンス全体の長さへの依存を減らすにはどうすればよいでしょうか?シーケンス内のすべてのトークンのキーと値を保存しない理由の一つは、各反復処理で欠落トークンを明示的に再計算することを選択していることが考えられます。これは、GPUメモリを消費するよりも、メモリ帯域幅の制限があるからです(例えば、自己回帰フェーズではメモリ帯域幅が制限されるため)。私の知る限り、これは実際の状況ではないため、この記事ではこれ以上深く掘り下げません。 別の視点としては、モデルがほとんど、あるいは全く注意を払わないトークンのキーと値を保存しないという選択肢があります。シーケンスの一部のみに焦点を絞るモデル(Mistral AIのMistral-7Bなど)の場合、これは設計上の考慮事項、あるいはメモリ消費とモデル精度のトレードオフとなる可能性があります。説明しましょう。 Mistral-7B [6] のようなモデルは、シーケンス全体に焦点を当てないように訓練されています。Mistral-7B の注意層は、確かに最後の4096個の隣接トークンに焦点を当てることでトークン表現を構築します。この注意メカニズムの派生形は、スライディングウィンドウ注意 (SWA) またはローカル注意と呼ばれます。設計上、ローカル注意は、KVキャッシュに保存するテンソルペアがウィンドウサイズ (例: 4096) を超えないことを保証します。 もう一つのアプローチは、アテンション層を用いてシーケンス内のアテンション分布パターンを活用することです。アテンションモジュールは、シーケンス内の少数のトークンに一貫して不均衡なアテンションを割り当てることがよく知られています(図1参照)。対照的に、多くのトークンは一貫して出力にほとんど寄与しないため、それらのキーと値を保存する必要がありません。 図 1 — StreamingLLM 論文の注目ヒートマップの例: 最初のトークンと最後の隣接トークンに大量の注目が継続的に割り当てられています (ローカル注目)。 これらのトークンを破棄することで、対応する注目スコアは実質的にゼロに設定され、より疎な注目行列を用いて注目行列を近似します。近似が成功すると近似誤差が最小限に抑えられ、モデルの精度(例えば、パープレキシティを用いて測定される)への影響が軽減されます。 過去数ヶ月の間に登場した、再学習や微調整なしで直接適用できる手法をいくつか見てみましょう。StreamingLLMフレームワーク、H2O(Heavy-Hitter Oracle)、Scissorhands、FastGenなどです。しかし、私の知る限り、現在、これらをサポートしている一般的なLLM推論フレームワークはありません。 有限長のコンテキストウィンドウを用いて学習されたモデルにおいて、StreamingLLMフレームワーク[7]は、初期トークンが大量の注目を集めることを観察した。そのため、このフレームワークは、初期位置トークン(「シンクトークン」)と最後の隣接トークン(ローカル注目)のみをキャッシュに保持することで、スライディングウィンドウを構築する。したがって、StreamingLLMフレームワークのKVキャッシュ長は固定であり、固定部分(通常1~4トークン)とスライディング部分の両方を持つ。 類似のH2O [8] およびScissorhands [9] 方式は、キャッシュされるトークンの最大数を設定し、最大数に達したトークンを破棄することでKVキャッシュを圧縮します。H2Oアルゴリズムは一度に1つのトークンのみを破棄しますが、Scissorhandsは設定された目標圧縮率(例えば、KVキャッシュサイズを30%削減する)に応じて可能な限り多くのトークンを破棄します。 どちらのアプローチも、特定のステップで影響力を持つトークン(「キートークン」または「重要トークン」)は、将来のステップでも影響力を持ち続けるという考えに基づいています(シザーハンズの著者はこれを「重要性の持続仮説」と呼んでいます)。言い換えれば、破棄される影響力の低いトークンは、将来のステップでも比較的無視され続けるため、安全に破棄できるということです。 これら2つのアルゴリズムの主な違いは、キャッシュの削除ポリシーにあります。Scissorhandsは、履歴コンテキストウィンドウ内で最新のトークンと最も高いアテンションスコアを持つトークンを単純に保持します。一方、H2Oは累積アテンションスコアが最も低いトークンを破棄し、反復プロセス全体を通して一貫して高いアテンションスコアを達成するトークンのみを保持します。両チームの研究により、これらのアルゴリズムはモデルの精度をほとんど損なうことなく、KVキャッシュサイズを最大80%削減できることが実証されています。 FastGen法[10](無関係なDeepSpeed-FastGen法と混同しないように注意)は、依然として注目パターンに基づいていますが、異なるアプローチを採用しています。キャッシュバジェットを使用する代わりに、注目行列の最大近似誤差を設定することで、モデルの精度を維持することに重点を置いています。 FastGen は 2 段階のアプローチです。まず、事前入力フェーズの最後に、モデルのアテンション レイヤーをプロファイリングし、エラー目標を達成できる一連の圧縮戦略を決定します。他の手法と同様に、決定されたアテンション パターンは将来の生成ステップでも変更されないものと想定されます。使用される圧縮戦略には、特殊トークンの保持、句読点の保持、最後の隣接トークンの保持(ローカル アテンション)などがあります(図 2 を参照)。エラー目標が達成できないほど厳しすぎる場合、FastGen は通常のキー値キャッシュに戻ります。その後、各生成ステップで、選択された圧縮戦略がキー値キャッシュに適用されます。 図 2 – FastGen 論文の圧縮戦略の例: 特殊文字 (緑) + 句読点 (オレンジ) + ローカル アテンション (青)、灰色は破棄されたトークンを表します。 他の手法とは異なり、FastGenはキューワードごとに圧縮戦略をカスタマイズすることに注意してください。FastGenの作者は、特定のKVキャッシュ圧縮率において、FastGenのアルゴリズムがH2OやScissorhandsよりも優れたモデル精度を維持することを実証しています。 いずれにせよ、予測不可能なシーケンス長の制限を破ることは、各シーケンスに限られた量の使用可能なメモリを割り当てることができるため、メモリ管理が大幅に簡素化されるため、大きなメリットとなります。レイテンシの主な原因はデータ転送であるため、シーケンス長に比例して増加するKVキャッシュが存在しないことは、特に長いシーケンスにおいて、大幅な速度向上につながります。 04. モデルレイヤーの数を減らすと、キー値キャッシュのメモリ使用量を削減できますか?この点に関しては、得られるメリットはあまりありません。通常、モデルが小さいほどレイヤー数が少なくなります(表4を参照)。そのため、特定のユースケースで小さいモデルのパフォーマンスが優れている場合は、それを選択するだけで十分です。 表4 – Llama-2シリーズモデルの仕様 05. アテンション ヘッドの数を減らすと、KV キャッシュのメモリ使用量を削減できますか?特定のモデル アーキテクチャでは、モデルのサイズは主にレイヤーの数とアテンション ヘッドの数によって制御されるため、アテンション ヘッドの数を減らすということは、より小さなモデルを選択することを意味します(表 4 を参照)。 しかし、詳しく見てみると、各アテンションヘッドに含まれるキーと値の数を減らすだけでよく、アテンションヘッド内のクエリの数はKVキャッシュのサイズに影響を与えないことがわかります。これは、Multi-Query Attention (MQA) [11] と Grouped Query Attention (GQA) [12] アーキテクチャの核となる考え方です。これらのMHAバリアントの唯一の目的は、KVキャッシュのサイズを削減することです。 MQAは2019年に初めて導入されました。MQAでは、各アテンションヘッドのクエリのアテンションスコアを計算するために、同じキーと値が使用されます。つまり、すべてのアテンションヘッドクエリは同じキーを使用してアテンションスコアを計算し、すべてのアテンションヘッドの出力は同じ値を使用して計算されます(ただし、アテンションスコアは異なります)(図3を参照)。 図3 – マルチヘッドアテンションメカニズム(上)とマルチクエリアテンションメカニズム(下)(2つのアテンションヘッド) すべてのアテンションヘッドを削除することは、大規模なモデルでは比較的積極的に行われます。例えば、64 個のアテンションヘッドを 1 個に減らすと、32 個のアテンションヘッドを 1 個に減らす場合と比べて、モデルの学習能力と入力データの表現能力が大幅に低下します。GQA は、中間的な解決策を提供することでこの問題に対処します。つまり、すべてのアテンションヘッドがクエリに対して同じ一意のキーと値のヘッドを共有するのではなく、それらを g 個のクエリヘッドのグループに分割し、同じグループ内のクエリヘッドは同じ一意のキーと値のヘッドを共有します。言い換えれば、クエリヘッドの数を n_heads から 1 < g < n_heads に減らすよりも、キーと値のヘッドの数を n_heads から 1 < g < n_heads に減らす方が効果的です。 この観点から見ると、MHAとMQAはGQAの特殊なケース(それぞれg=1とg=n_headsのケースに対応)です。GQAは、2つの極端なケース(MHAとMQA)の間で、モデルの精度とKVキャッシュサイズ(レイテンシとスループットの両方に関連)の間のよりスムーズなトレードオフを可能にします。 新しいパラメータ g を考慮する必要があるため、KV キャッシュ サイズを計算する式は次のようになります。 実際には、MQA/GQAアーキテクチャは、Google ResearchのPaLM [13]、TIIのFalcon** [14]モデル、MetaのLlama-2 [1](70Bに制限)、およびMistral AIのMistral-7B [7]によって実装されています(表5を参照)。 表5 – MQAまたはGQAを使用したモデルシリーズ 06 注意ヘッドの隠し層に異なる次元を選択した場合はどうなるでしょうか?同様に、異なるモデルファミリーを選択する予定がない場合は、この点に関して得られるメリットはあまりありません。アテンションヘッドの隠れ次元は、同じモデルファミリー(例:Llama-2、Falcon)内のモデル間で一定である可能性があるため、同じファミリー内でパラメータ仕様が小さいモデルを選択しても役に立ちません。 07. 各パラメータを表すために使用するバイト数を少なくしたらどうでしょうか?キーバリューキャッシュを量子化することは、確かにそのサイズを大幅に削減する比較的効果的な方法です。しかし、AWQ [15] や GPTQ [16] のように重みのみを量子化するアルゴリズムは、定義上役に立ちません。LLM.int8() [17] や SmoothQuant [18] のように、重みと「アクティベーション」(つまり重み以外のもの)の両方を量子化するアルゴリズムだけが、量子化されたキーバリューキャッシュを生成し、それを低精度表現に変換することができます。 重みと「活性化」の両方に作用する量子化アルゴリズムは、計算負荷の高い行列乗算を低精度で実行することを目的としている点に注意してください。学習中に計算リソースが限られている場合、量子化によってパフォーマンスが向上する可能性がありますが、後述しますが、モデル推論の自己回帰フェーズは実際にはメモリ帯域幅によって制約されるため、計算速度を上げても大きな付加価値は得られません。モデル推論はメモリ帯域幅によって制限されるため、実際にはメモリ使用量の削減、つまりデータ転送量の削減にのみ関心があります。 この観点からすると、LLM.int8() や SmoothQuant などの量子化アルゴリズムは少しやり過ぎです。キャッシュされたテンソルを GPU メモリに移動する前に量子化し、同じテンソルを GPU メモリから取得した後に逆量子化するだけで十分です (追加の計算とメモリコピーのオーバーヘッドがかかります)。 一部のLLM推論システムには、すでにこのKVキャッシュ量子化機能が搭載されています。例えば、FlexGen [19] はKVキャッシュとモデルの重みの両方を量子化し、4ビットのデータ形式で保存します。NVIDIA TensorRT-LLM (1) は、KVキャッシュを8ビットのデータ形式(INT8またはFP8)に量子化できます(2)。主流のvLLMフレームワークも、バージョン0.3.0以降、KVキャッシュのFP8量子化をサポートしています(3)。量子化ステップは各反復で動的に実行されるため、キャリブレーションステップは不要です。 08 効率的なメモリ管理戦略の重要性これまで、メモリ空間は無駄にならないと仮定してきました。つまり、予約済みメモリはすべてトークンの保存に使用され、利用可能なメモリはすべて予約できるということです。しかし、実際には、単純なメモリ管理戦略によって大量のメモリが無駄になる可能性があります(PagedAttentionの論文[20]によると、実際の有効メモリ利用率は20%程度にまで低下し、つまり80%が無駄になっている可能性があります)。
これらの欠点こそが、広く普及しているPagedAttentionアルゴリズムが解決しようとしている問題です。PagedAttentionアルゴリズムは、ブロックと呼ばれる固定サイズの比較的小さなメモリブロックを割り当てます。各ブロックには一定数のトークンを格納でき、必要に応じて異なるリクエスト間で共有できます。より小さなブロックサイズを必要に応じて割り当てて使用することで、内部メモリの断片化を軽減し、同じサイズのブロックを使用することで外部メモリの断片化を防ぎます。 全体として、PagedAttentionはKVキャッシュメモリの無駄をほぼゼロ(4%未満[21])に抑えます。以前は無駄になっていたメモリをより多くのリクエストを満たすために使用できるようになり、スループットが向上します。PagedAttentionが初めて導入された当時、そのスループット向上は当時のメモリの無駄と同じくらい顕著でした。 PagedAttentionはvLLM(4)推論システムによって最初に実装されましたが、現在ではすべての主要な推論フレームワーク(例:HuggingFace TGI(5)、NVIDIA TensorRT-LLM(1)、LMDeploy TurboMind(6)など)でサポートされています。 PagedAttention ではカバーされていないもう1つの最適化は、リクエスト間でキーバリューキャッシュを再利用することです。この最適化は、プロンプトが共通のプレフィックスを共有している場合に適用できます。これは、チャットインターフェースやエージェントなどの複数ターンのユースケース、またはプロンプトテンプレートを使用する場合によく見られます(図4)。 図4 – SGLang論文(マルチターンチャット)におけるKVキャッシュ共有の例。生成されたリクエストは合計4つ。青い枠は共有可能なプロンプト部分を示しています。 キー値キャッシュを異なるリクエスト間で再利用できる場合、レイテンシ(特に最初のトークンのレイテンシ)とスループット(共有プレフィックスを持つ同時リクエストのメモリフットプリントを大幅に削減することにより)が大幅に改善されます。 LMSYS SGLang論文[22]で紹介されたRadixAttention技術は、KVキャッシュ再利用の典型的な例です。 RadixAttentionアルゴリズムは、コンテンツ生成リクエストを完了した後、キーバリューキャッシュをすぐに破棄しません。代わりに、キャッシュをGPUメモリに保持し、専用のデータ構造(基数ツリー)に新しいエントリを追加して、トークンシーケンスをキーバリューキャッシュテンソルにマッピングします。新しいリクエストが到着すると、スケジューラは基数ツリーを使用してプレフィックスマッチングを行います。キャッシュヒットが発生した場合、スケジューラはキャッシュされたキーバリューテンソルを再利用してリクエストを満たします。 GPUメモリには限りがあるため、キャッシュされたキーバリューテンソルを無期限に保持することはできません。そのため、RadixAttentionアルゴリズムにはキャッシュエビクションポリシー(例:LRU(Least Recently Used)キャッシュエビクションポリシー)が組み込まれています。最適なキャッシュ再利用手法は、先着順スケジューリング方式(First-Come, First-Served)などのスケジューリング方式と互換性がない場合があります。そのため、RadixAttentionには、キャッシュプレフィックスに一致するリクエストを優先する修正スケジューラ(キャッシュを考慮したスケジューリング)が組み込まれています。 注: PagedAttention と RadixAttention という名称は誤解を招きやすいです。一般的に考えられているのとは異なり、これらはモデルのアテンション層(FlashAttention のように)を最適化するのではなく、モデルサーバーレベルで動作します(サービスアプリケーションがホスト上のキーバリューキャッシュをより適切に管理するのに役立ちます)。 09 GPUのメモリが不足している場合、「単純に」GPUメモリを増やしてみるのはいかがでしょうか?あるいは、ワークロードをCPUメモリやディスクに移動してみてはいかがでしょうか?これらは2つの異なる方法ですが、効果的です。 まず、ワークロードを大容量だが低速なストレージメディア(CPU、メモリ、ディスク)にオフロードするという問題があります。HuggingFace Accelerate(7)、DeepSpeed-Inference(8)、そしてより高度なFlexGen(9)など、すべての推論フレームワークがこれをサポートしているわけではありません。ワークロードのオフロードは、低速なストレージメディアの使用により大きなレイテンシの問題を引き起こすため、レイテンシが重視される推論ユースケースには明らかに不向きです。オフロードシステムは、通常、オフラインバッチ処理など、スループット重視のユースケースで使用されます。 複数の GPU を使用する場合 (大規模モデルの推論では避けられません)、モデルを複数のデバイスに分割すると、集約されたメモリ容量とメモリ帯域幅を活用してメモリ負荷を軽減できます。 パイプライン並列処理[23]を選択した場合、モデルとKVキャッシュは両方ともレイヤー次元に沿ってシャーディングされます。テンソル並列処理[24]を選択した場合(モデル推論のシナリオではより一般的)、KVキャッシュはアテンションヘッド次元に沿ってシャーディングされます。この設定では、MQAは非常に非効率になることに注意してください。単一のアテンションヘッドを複数のデバイスにシャーディングすることはできないため、KVキャッシュをすべてのデバイスにコピーする必要があり、MQAの利点が失われます。MQAを実装するモデルの場合、別のアプローチとして、バッチサイズ次元に沿ってKVキャッシュをシャーディングする方法があります[25]。 いずれにせよ、上記はすべて1つのホストのみを想定しており、最大のマルチGPUインスタンスのストレージ容量によって制限されます。私の知る限り、現在、マルチホストモデルの並列処理をサポートする推論フレームワークは存在しません。モデルとKVキャッシュを複数のホストに分割できれば、利用可能なメモリ量と処理可能な最大シーケンス長は事実上無制限になります。これは、Infinite-LLM論文[26]が取り組んでいる問題であり、新しい分散アテンションアルゴリズム(DistAttention)を導入し、Rayフレームワークを改良してマルチホスト分散KVキャッシュ管理およびスケジューリングシステム(DistKV-LLM)を構築しています。 10 要約この記事では、キーバリューキャッシュの使用を選択すると、いくつかの追加の課題が発生することを学びました。マルチヘッドアテンション(MHA)モデルのキーバリューキャッシュは、トークンあたり約1MBという大量のGPUメモリを消費し、そのサイズはモデルの重みよりも簡単に大きくなる可能性があります。 GPU のメモリが非常に限られていることを考えると、KV キャッシュ メモリ要件へのプレッシャーにより、新しいアテンション アーキテクチャ (MQA、GQA、SWA)、キャッシュ圧縮戦略 (H2O、Scissorhands、FastGen)、効率的なメモリ管理戦略 (PagedAttention、RadixAttention)、モデル量子化手法、およびストレージ容量の拡張 (オフライン処理システム、単一マシンおよび複数マシンのモデル並列処理) など、さまざまな方向へのイノベーションが促進されています。 次の記事で説明するように、 KV キャッシュ サイズを縮小することは、GPU メモリが限られているだけでなく、データ移動量が実際には各自己回帰ステップでレイテンシを引き起こす主な要因であり、したがって生成プロセス全体でレイテンシを引き起こす主な要因であるため、非常に重要です。 次の記事では、モデルのレイテンシとスループットに影響を与える可能性のある様々なボトルネックについて考察します。それでは、また! 参考文献: [1]: ラマ2: オープンファウンデーションと微調整されたチャットモデル (Touvron et al., 2023) [2]: OPT: オープンな事前学習済みTransformer言語モデル (Zhang et al., 2022) [3]: MPT-7B(2023年5月)およびMPT-30B(2023年6月)のリリースブログ投稿 [4]: BLOOM: 176Bパラメータのオープンアクセス多言語モデル (BigScience, 2023) [5]: ニューラル言語モデルのスケーリング則(Kaplan et al., 2020) [6]: ミストラル 7B (Jiang et al.、2023) [7]: Attention Sinksを用いた効率的なストリーミング言語モデル (Xiao et al., 2023) + GitHubリポジトリ [8]: H_2O: 大規模言語モデルの効率的な生成推論のためのヘビーヒッターオラクル (Zhang et al., 2023) + GitHubリポジトリ [9]: シザーハンズ:テスト時のLLM KVキャッシュ圧縮における重要度の持続性仮説の活用(Liu et al. 2023) [10]: モデルが何を破棄すべきかを教えてくれる: LLMのための適応型KVキャッシュ圧縮 (Ge et al., 2023) [11]: 高速トランスフォーマーデコード:1つの書き込みヘッドだけで十分(Shazeer、2019年) [12]: GQA: マルチヘッドチェックポイントからの一般化マルチクエリトランスフォーマーモデルのトレーニング (Ainslie et al., 2023) [13]: PaLM: パスウェイによる言語モデルのスケーリング (Chowdhery et al., 2022) [14]:オープン言語モデルのファルコンシリーズ(アルマズルーエイ他、2023) [15]: AWQ: LLM圧縮と加速のためのアクティベーションを考慮した重み量子化 (Lin et al., 2023) + GitHubリポジトリ [16]: GPTQ: 生成的事前学習済みトランスフォーマーのための正確な学習後量子化 (Frantar et al., 2022) + GitHubリポジトリ [17]: LLM.int8(): 大規模Transformersのための8ビット行列乗算 (Dettmers et al., 2022) + GitHubリポジトリ [18]: SmoothQuant: 大規模言語モデルのための正確で効率的な学習後量子化 (Xiao et al., 2022) + GitHubリポジトリ [19]: FlexGen: 単一GPUによる大規模言語モデルの高スループット生成推論 (Sheng et al., 2023) + GitHubリポジトリ [20] PagedAttentionによる大規模言語モデルサービングのための効率的なメモリ管理(Kwon et al., 2023)+ GitHubリポジトリ [21] vLLM: PagedAttentionによる簡単、高速、安価なLLMサービング (Kwon et al. 2023) [22] SGLangを用いた大規模言語モデルの効率的なプログラミング(Zheng et al., 2023)+ブログ投稿 [23]: GPipe: パイプライン並列処理を用いた巨大ニューラルネットワークの効率的なトレーニング (Huang et al., 2018) [24]: Megatron-LMを用いたGPUクラスター上での効率的な大規模言語モデルトレーニング(Narayanan et al., 2021) [25]: Transformer推論の効率的なスケーリング(Pope et al., 2022) [26]: Infinite-LLM: DistAttentionと分散KVCacheを用いた長いコンテキストのための効率的なLLMサービス (Lin et al., 2024) 読んでくれてありがとう! 終わり |