
interview 采訪/面試consequence?k?ns?kw?nsn. 結(jié)果后果重要性價值how exactly is具體是怎樣的noticeably?n??t?s?bliadv. 顯著地明顯地引人注目地visual?v??u?ladj. 視覺的視力的栩栩如生的n. 視覺資料指說明性的圖片、影片等自回歸生成中每生成一個新 token 只需要該位置的 query而 key/value 必須與所有歷史位置對齊。因此每個 decode 步驟只需計算新位置的 Q、K、V緩存 K 和 V、丟棄 QLLM 中的 KV CachingInsight1標(biāo)準(zhǔn) Transformer 自回歸生成圖上半部分模型只需要最后一個 token 的 hidden state就可以預(yù)測下一個 token輸入 token 序列送入 Transformer 層輸出一整串隱狀態(tài) hidden states只拿最后位置的隱狀態(tài)送入 Projection 層得到詞表 logits做 ArgMax 選出下一個 token新 token 拼到輸入末尾把全部歷史 token 重新完整跑一遍前向再預(yù)測下一個?? 原始問題每多生成 1 個字就要把前面所有 token 全部重新計算一遍序列越長速度越慢大量重復(fù)計算Insight2注意力公式視角圖中間新 token 的輸出只依賴當(dāng)前新 token 的 Query 向量所有歷史 token 的 Key、Value 向量Q只有最新生成的 token 才需要計算每次都變(K、V)歷史每一個 token 算出來的 Key、Value一旦算完就永遠不變重點不需要反復(fù)重新算歷史 token 的 K、V直接存起來復(fù)用即可這就是 KV Cache 的來源Insight3KV Cache 實際工作流程以第 5、6、7 號 token 生成為例生成第 5 個 token算出 K_5, V_5存入 KV 緩存生成第 6 個 token直接讀取緩存里 K_1 ~ K_5V_1 ~ V_5不再重新計算只計算當(dāng)前 token 的 Q_6同時算出新增 K_6,V_6 追加進緩存生成第 7 個 token復(fù)用全部歷史緩存K_1~6,V_1~6只算當(dāng)前 Q_7追加 K_7,V_7核心結(jié)論The key vectors and value vectors used during previous tokens do not change. Cache them to avoid recomputing them.歷史 token 的 K、V 向量不會改變把它們緩存下來避免重復(fù)計算used during previous tokens前面那些 token 在計算時生成出來的為什么不緩存 QQuery 是當(dāng)前步新 token 專屬每一步都完全不一樣沒有復(fù)用價值所以 KV Cache 只存 K、V不存 Q收益生成長文本時大幅減少算力開銷token 生成速度顯著提升代價需要占用顯存存儲所有歷史 K/V上下文越長KV 緩存占用顯存越大這也是長上下文推理顯存壓力的主要來源背景LLMs are autoregressive so each token is predicted from every token before it, one at a time. This autoregressive nature has a direct consequence inside the model.語言模型屬于自回歸模型因此每個 token 的預(yù)測都是基于之前的所有 token 來進行一次只預(yù)測一個 token。這種自回歸特性在模型中會產(chǎn)生直接的影響A forward pass over tokens produces hidden states, but only the last one is projected to logits and is required to generate the next token.So to understand why KV cache just stores K and V vector, we must back track to see how exactly is the last hidden state produced.通過傳遞 個 token可生成 個隱藏狀態(tài)但只有最后一個狀態(tài)會被映射到 logits 中并且是生成下一個 token 所必需的因此要理解為什么 KV 緩存只是存儲了 K 和 V 向量必須回推看看最后那個隱藏狀態(tài)究竟是如何生成的演示用 10 個 token 的提示來演示這個過程1) Prefill 預(yù)填充All 10 tokens go through the model in one forward pass, in parallel (with causal masking), since the whole prompt is already known.所有 10 個 token 都在一次前向傳播過程中通過模型處理這些過程是并行進行的同時使用了因果掩蔽技術(shù)因為整個提示已經(jīng)已知了At every layer, each of the 10 positions produces a query, a key and a value vector, and attention at each position runs against all positions up to it.每一層中這 10 個位置中的每一個位置都會產(chǎn)生一個 query、一個 key 和一個 value 向量。每個位置上的注意力機制都會與所有與其相鄰的位置進行交互This pass is compute-heavy, and it’s why the first token takes noticeably longer than the ones after it. TTFT is mostly prefill.這個流程需要大量的計算資源這就是為什么第一個 token 的處理時間明顯比后面的 token 要長處理 prompt 的 token 比較多。TTFT 過程大部分都是預(yù)填充操作2) The first output token 第一個輸出 tokenTo generate the 11th token, only the 10th token’s hidden state is needed. So this is projected from the hidden-dim to vocab-dim to generate logits over vocab.要生成第 11 個 token只需要使用第 10 個 token 的隱藏狀態(tài)即可。因此這個過程是從隱藏維度 hidden-dim 映射到詞匯維度 vocab-dim從而生成關(guān)于詞匯的 logitsThese logits then go through softmax and sampling to generate token 11這些 logits 隨后會經(jīng)過 softmax 函數(shù)和采樣過程從而生成 token 113) Back-track the hidden state 追溯隱藏狀態(tài)The last hidden state is the last row of the feedforward block’s output. The feedforward block is position-wise (it’s applied to each row independently) so that row comes from the last row of the attention output before it.最后一個隱藏狀態(tài)就是前饋模塊feedforward block輸出的最后一行數(shù)據(jù)前饋模塊 FFN 按位置進行獨立應(yīng)用于每一行因此該行來自其前一行的注意力輸出的最后一行So now we need to see how the last row of attention is computed現(xiàn)在需要了解最后一行的注意力值 attention 是如何計算出來的┌──────┼─row0(t1)──FFN── row0 Attention輸出矩陣 ────┼─row1(t2)──FFN── row1 ┼──────┼─row2(t3)──FFN── row2 └──────┼─row3(t4)──FFN── row3 ← last hidden stateAttention 層會做全局交互每個位置能看到全部 tokenFeedForward(FFN)position?wise每個位置只處理自己的向量行之間沒有交互FFN 只干活不串門每一行向量自己單獨過一遍網(wǎng)絡(luò)所以序列末尾 token 對應(yīng)的那一行只來自上一步 attention 輸出的末尾那一行4) Attention matrix 注意力矩陣QK? for a 10-token prompt will give a 10 × 10 matrix.對于包含 10 個 token 的提示QK? 將返回一個 10×10 的矩陣Rowwill have the dot product of querywith every key.行將會與每個鍵進行點積運算Row 10 is therefore Q??·K?, Q??·K?, all the way to Q??·K??因此第 10 行可以表示為 Q??·K?、Q??·K?一直到 Q??·K??Notice that only Q?? appears in it. Q? through Q? only belong to their corresponding rows 1-9, and those rows’ hidden states we already discarded because they were never needed.注意只有 Q??出現(xiàn)在其中。Q?到 Q?只屬于它們對應(yīng)的第 1 到 9 行而那些行的隱藏狀態(tài)已經(jīng)被我們丟棄了因為它們根本沒有必要存在The last row of attention goes through softmax and multiplies the full stack of value vectors, V? through V??, to give the last row of the attention output.最后一行的注意力輸出是通過 softmax 函數(shù)計算得出的。該函數(shù)會將所有價值向量 V?到 V??相乘從而得到最終的注意力輸出結(jié)果So the last hidden state depends on exactly three things: Q??, every key, and every value.因此最后一個隱藏狀態(tài)取決于三件事物Q??、每一個 key以及每一個 value5) Generating token 12 生成 token 12Token 11 is appended, and this time, we need row 11’s hidden state to generate token 12.現(xiàn)在需要添加第 11 個 token而這次需要使用第 11 行的隱藏狀態(tài)來生成第 12 個 tokenMathematically, attention operation turns out to be Q?? against K? through K??, then multiplied by V? through V??.從數(shù)學(xué)角度來看注意力操作的流程可以表述為先對 K?到 K??進行 Q??運算然后再將結(jié)果乘以 V?到 V??K? through K?? and V? through V?? are bit-for-bit what prefill first token produced since under causal masking, a token’s key and value depend on that token and the ones before it, never on anything after, so appending token 11 cannot change anything at position 3.從 K?到 K??以及從 V?到 V??這些值都是經(jīng)過預(yù)填充和第一個標(biāo)記后產(chǎn)生的。一個標(biāo)記的關(guān)鍵值和值取決于該標(biāo)記以及它之前的所有標(biāo)記而不取決于之后任何標(biāo)記的值。因此添加標(biāo)記 11 并不會改變第三個位置的值原因是在因果掩碼causal masking約束下某個 token 的 K、V只由它自己以及它前面的 token 決定永遠不會依賴它后面的 token所以在序列末尾追加第 11 號 token完全不會修改位置 3 處的 (K_3,V_3)bit?for?bit逐比特完全相同數(shù)值一絲一毫都不會變不是近似相等是內(nèi)存里每一位都一模一樣Prefill 階段輸入 prompt[t?,t?,t? … t??]一次性并行全部計算一次性算出 K_1…K_10,V_1…V_10)存入 KV Cache之后進入 decode 循環(huán)生成第 11 個 token t_11只新算 K_11,V_11追加到緩存末尾K_1,K_2,K_3…K_10 全部沿用 prefill 算出來的舊值不會重新計算不會被改寫appending token 11 cannot change anything at position 3在尾巴上新增加 token11不會把位置 3 的 K3/V3 改一絲一毫6) The cache state 緩存狀態(tài)Overall, this implies that you just need to retain the keys and values at each decoding step, and compute only the new position’s Q, K and V.總體而言這意味著只需要記住每個 decoding 步驟中的 key 和 value并僅計算新位置的 Q、K 和 V 參數(shù)Each decode step requires one query vector, which is never used again, so they are never cached across the decoding process.每個 decode 步驟都需要一個 query 向量而這個向量在之后不會再次被使用因此它們在整個 decoding 過程中不會被緩存起來That said, KV cache is only one of four separate caching layers in an LLM stack.不過KV 緩存只是 LLM 架構(gòu)中四個獨立緩存層中的一個而已The other three are prefix caching on the server, prompt caching billed by a provider, and a semantic cache that skips the model entirely.另外三種方式是服務(wù)器端的前綴緩存、由 provider 提供的提示緩存以及完全不使用模型的語義緩存