1.什么是KV Cache?為什么要使用KV Cache?
理解此問題,首先需理解自注意機制的計算和掩碼自注意力機制,在Decoder架構的模型中,每生成一個新的token,便需要重新執行一次自注意力計算,這個過程中,由于Decoder的掩碼自注意力機制,導致存在大量的冗余重復計算(原因可參考大模型推理加速:看圖學KV Cache),為了避免這種重復計算,提升推理效率,提出了KV Cache,即KV緩存,是指每次Decoder生成next token的過程中,將之前計算自注意力機制中K和V矩陣緩存下來,從而在生成當前token的時候避免重復之前的計算(為什么可以直接使用K和V的緩存值,而無需重復計算,可參考:大模型推理加速:看圖學KV Cache)
總結使用KV Cache的原因:
- 提升推理速度: 在自回歸生成任務中,每次生成新 token 時,模型需要計算當前 token 與之前所有 token 的注意力分數。如果不使用 KV Cache,每次生成新 token 都需要重新計算之前所有 token 的 Key 和 Value,這會導致計算量隨著序列長度呈二次方增長,顯著增加推理時間和計算資源的消耗。使用 KV Cache 可以將計算復雜度從 O(n^2) ) 降低到 O(n),顯著減少計算量。
- 降低計算資源消耗: 通過減少重復計算,KV Cache 可以降低對計算資源(如 CPU 和 GPU)的需求
因此,使用KV Cache后,對于生成的每個新token,不需要傳入整個序列,只需計算新的token情況,因此可以避免重新計算整個注意力矩陣。只需要以下面的方式對新token進行操作:
- 僅為新token計算新的 q、k、v 行。
- 新的 q 行將立即被使用。(這也解釋了為什么沒有查詢緩存)
- 將新的鍵、值附加到現有的 K、V 緩存中。
- 通過新的 q 行和 k_cache 的轉置進行矩陣向量乘法來計算新的注意力行。 通過新的注意力行和 v_cache的轉置進行矩陣向量乘法來計算新的 v 行。
- 輸出(僅針對最新標記)被傳遞到下一層。
此步驟說明參考:【大模型理論篇】Transformer KV Cache原理深入淺出
以下是一個具體的 with KV Cache和 without KV Cache對比, 因此,KV Cache可通過增加內存使用來節省重復計算,以空間換時間。
2. 使用KV Cache會帶來什么問題?
-
** KV Cache占用大:** KV Cache 隨著序列長度的增加會占用大量顯存資源。
KV Cache的顯存占用分析,假設模型的參數配置信息如下(參考【大模型理論篇】Transformer KV Cache原理深入淺出):
Transformer 中有 n_layers 個層塊。
每個層塊中有一個多頭注意力層。
每個多頭注意力層有 n_heads個注意力頭,每個頭的 k 和 v 的尺寸為 d_head。
需要為 K 和 V 都緩存一份。
最大上下文長度為 n_context。
精度為 n_bytes,例如對于 FP32 是 4。
推理時的批量大小為 batch_size。
那么總的顯存大小為:
kv_cache_size = n_layers * n_heads * 2 * n_context * d_head * n_bytes * batch_size
簡化后為:
kv_cache_size = 2 * n_bytes * n_layers * d_model * n_context * batch_size
例如,針對 OPT-30B 模型的KV Cache顯存計算:
n_bytes = 2(FP16)
n_layers = 48
d_model = 7168
n_context = 1024
batch= 128
計算結果為 180,388,626,432 字節,約為 168 GB。
- 顯存管理復雜: KV Cache 的大小與序列長度和批量大小動態相關,容易導致顯存碎片化和顯存容量不足的問題。
- 資源開銷: 雖然 KV Cache 提高了推理速度,但需要額外的顯存來存儲緩存數據,這增加了硬件資源的需求
3. 如何緩解KV Cache帶來的問題?