大模型推理優(yōu)化

transforms模型分類

  • Decoder架構(gòu):適合生成任務(wù),大模型llm的主流結(jié)構(gòu),典型模型有GPT,LLAMA等。只有一個(gè)Mask Attention層,沒有Cross Attention層。
  • Encoder-Decoder:理論上結(jié)合了GPT和Bert的優(yōu)點(diǎn),典型模型是T5,訓(xùn)練成本很高,Google提出后并未過多發(fā)展,適用于需要輸入的生成性任務(wù),如翻譯,摘要等等。
  • Encoder架構(gòu):不適合做生成,在理解任務(wù)上finetune性價(jià)比很高,如句子分類,命名實(shí)體識(shí)別等。典型模型為Bert。

大模型推理流程

LLM 將一系列tokens作為輸入,并自回歸生成后續(xù)tokens,直到滿足停止條件(例如,生成tokens數(shù)量的限制或遇到停止詞)或直到生成特殊的 <end> 標(biāo)記生成結(jié)束的tokens。該過程涉及兩個(gè)階段:預(yù)填充階段和解碼階段。

預(yù)填充階段

在預(yù)填充階段,LLM處理輸入token以計(jì)算中間狀態(tài)(keys和value),用于生成“第一個(gè)”token。每個(gè)新的token都依賴于所有先前的token,但由于輸入的全部已知,因此在運(yùn)算上,都是高度并行化矩陣運(yùn)算,可以有效地使用GPU。

解碼階段

在解碼階段,LLM一次自回歸生成一個(gè)輸出token,直到滿足停止條件。每個(gè)輸出tokens都需要直到之前迭代的所有輸出狀態(tài)(keys和values)。這與預(yù)填充輸入處理相比,就像矩陣向量運(yùn)算未充分利用GPU計(jì)算能力。數(shù)據(jù)(weights, keys, values, activations) 從內(nèi)存?zhèn)鬏數(shù)紾PU的速度決定了延遲,而不是計(jì)算實(shí)際時(shí)間消耗。即,這是一個(gè)內(nèi)存限制操作。

預(yù)處理&向量化:Tokenizer&Embedding

預(yù)處理:可以將原始文本轉(zhuǎn)換為由token組成的文本的初始數(shù)值表征,又可以進(jìn)一步分成兩步:

  1. 將字符串轉(zhuǎn)換為token的序列
  2. 將token轉(zhuǎn)換為token id

向量化:Embedding操作

后處理

基于模型的輸出logits,從詞表中選出一個(gè)token作為當(dāng)前生成的結(jié)果。常見的后處理操作有top-k,top-p,temperature,greedy等:

  • top-k:模型從最可能的"k"個(gè)選項(xiàng)中隨機(jī)選擇一個(gè),如果k=10,模型將從最可能的10個(gè)單詞中選擇一個(gè)
  • top-p:模型從累計(jì)概率大于或等于“p”的最小集合中隨機(jī)選擇一個(gè),如果p=0.9,選擇的單詞集將是概率累計(jì)到0.9的那部分。
  • temperature:控制生成文本隨機(jī)性的參數(shù)。較高的溫度值會(huì)產(chǎn)生更隨機(jī)的輸出,而較低的溫度值則會(huì)使模型更傾向于選擇最可能的單詞,較高的溫度值,如1.0,會(huì)產(chǎn)生更隨機(jī)的輸出,而較低的溫度值,如0.1,會(huì)使模型更傾向于選擇最可能的單詞(不可以為0)。
  • greedy:選擇概率最高的那個(gè),確定性后處理。

KV緩存

解碼階段的一種常見優(yōu)化是 KV 緩存。解碼階段在每個(gè)時(shí)間步生成單個(gè)token,但每個(gè)token依賴于之前token的鍵和值張量(包括預(yù)填充時(shí)計(jì)算的輸入tokens的 KV 張量,以及當(dāng)前時(shí)間步之前計(jì)算的任何新 KV 張量) 。

為了避免在每個(gè)時(shí)間步重新計(jì)算所有tokens的這些張量,可以將它們緩存在 GPU 內(nèi)存中。每次迭代,當(dāng)需要計(jì)算新token時(shí),它們都會(huì)被添加到正在運(yùn)行的緩存中,以便在下一次迭代中使用。在一些實(shí)現(xiàn)中,模型的每一層都有一個(gè)KV緩存。

上圖解釋:Q、K、V是通過輸入向量X經(jīng)過線性輸入W^Q、W^K、W^V得到,所以字符一定的情況下,QKV也是固定的,每次新來的token會(huì)重新生成一個(gè)Q、K、V,填充到原來的矩陣?yán)锩婕纯伞?/p>

模型并行化

減少模型權(quán)重在每設(shè)備的顯存占用的一種方法是將模型分布在多個(gè) GPU 上。分散內(nèi)存和計(jì)算可以運(yùn)行更大的模型或更大批量的輸入。模型并行化是訓(xùn)練或推理模型所必需的,模型并行化需要比單個(gè)設(shè)備更多的內(nèi)存,用來訓(xùn)練和推理(延遲或吞吐量)。根據(jù)模型權(quán)重的劃分方式,有多種方法可以并行化模型。

pipeline 并行

Pipeline并行化將模型(垂直)分片為塊,其中每個(gè)塊包含在單獨(dú)設(shè)備上執(zhí)行的層的子集(比如模型pipeline分為F1、F2、F3、F4)。圖 a 說明了四路Pipeline,其中模型按順序分區(qū),并且所有層的四分之一子集在每個(gè)設(shè)備上執(zhí)行。一個(gè)設(shè)備上的一組操作的輸出被傳遞到下一個(gè)設(shè)備,后者繼續(xù)執(zhí)行后續(xù)塊。F_nB_n分別表示設(shè)備上的前向傳播和后向傳播。每個(gè)設(shè)備上存儲(chǔ)模型權(quán)重的內(nèi)存需求被分成四份。

該方法的缺點(diǎn)是:由于處理的順序性質(zhì),某些設(shè)備或?qū)釉诘却耙粚拥妮敵觯せ睢⑻荻龋r(shí)可能保持空閑狀態(tài)。這會(huì)導(dǎo)致前向和后向傳遞效率低下或出現(xiàn)“Pipeline bubbles”。在圖 b 中,白色空白區(qū)域是Pipeline并行性產(chǎn)生的Pipeline bubbles,其中設(shè)備閑置且未得到充分利用。

微批處理可以在一定程度上緩解這種情況,如圖 c 所示。輸入的全局批次大小被分成子批次,這些子批次被一一處理,最后累積梯度。請(qǐng)注意,F_{n,m}B_{n,m} 分別表示設(shè)備n上m批次的前向和后向傳遞。這種方法縮小了管道氣泡的尺寸,但并沒有完全消除它們。

Tensor 并行

Tensor并行化將模型的各個(gè)層(水平)分片為更小的、獨(dú)立的計(jì)算塊,這些計(jì)算塊可以在不同的設(shè)備上執(zhí)行。Transformer的主要組成部分,注意力塊和多層感知器(MLP)層是可以利用Tensor并行化的。在多頭注意力塊中,每個(gè)頭或一組頭可以分配給不同的設(shè)備,以便它們可以獨(dú)立且并行地計(jì)算。

  • 圖 a 顯示了兩層 MLP Tensor并行的示例,每一層都由一個(gè)圓角框表示。在第一層中,權(quán)重矩陣A分為A_1A_2 。對(duì)于輸入X,可以在同一批次不同設(shè)備上計(jì)算XA_1XA_2,其中,f是 identity 操作。這將每個(gè)設(shè)備上存儲(chǔ)權(quán)重的內(nèi)存需求減半。歸約操作g組合了第二層的輸出。
  • 圖 b 是自注意力層中Tensor并行的示例。多個(gè)注意力頭本質(zhì)上是并行的,并且可以跨設(shè)備分割。

Sequence 并行

Tensor并行化是有局限性,它需要將層劃分為獨(dú)立的、可管理的塊,不適用于 LayerNorm 和 Dropout 等操作,而是在tensor并行中復(fù)制。雖然 LayerNorm 和 Dropout 的計(jì)算成本較低,但它們確實(shí)需要大量?jī)?nèi)存來存儲(chǔ)(冗余)激活。

transformer層的tensor并行化和sequence并行化如上圖所示,這些操作在輸入序列中是獨(dú)立的,并且這些操作可以沿著“序列維度”進(jìn)行分區(qū),從而提高內(nèi)存效率。這稱為序列并行性。

注意力機(jī)制優(yōu)化

MHA & MQA & GQA

  • MHA:多頭注意力,當(dāng)使用八個(gè)并行注意力頭時(shí),每個(gè)注意力頭的維度都會(huì)減少(例如d_m / 8) 。這使得計(jì)算成本與單頭注意力相似。
  • MQA :多查詢注意力,在多個(gè)注意力頭之間共享鍵和值。與以前一樣,查詢向量仍然被投影多次。雖然 MQA 中完成的計(jì)算量與 MHA 相同,但從內(nèi)存讀取的數(shù)據(jù)量(鍵、值)只是以前的一小部分。當(dāng)受內(nèi)存帶寬限制時(shí),這可以實(shí)現(xiàn)更好的計(jì)算利用率。它還減少了內(nèi)存中 KV 緩存的大小,為更大的批量大小留出了空間。key頭的減少會(huì)帶來潛在的準(zhǔn)確性下降。此外,需要在推理時(shí)利用這種優(yōu)化的模型需要在啟用 MQA 的情況下進(jìn)行訓(xùn)練(或至少使用大約 5% 的訓(xùn)練量進(jìn)行微調(diào))。
  • GQA:分組查詢注意力 (GQA) 通過將鍵和值投影到幾組查詢頭,在 MHA 和 MQA 之間取得平衡。

MQA 和 GQA 等優(yōu)化通過減少存儲(chǔ)的key頭和value頭的數(shù)量來幫助減少 KV 緩存所需的內(nèi)存。

FlashAttention

優(yōu)化注意力機(jī)制的另一種方法是修改某些計(jì)算的順序,以更好地利用 GPU 的內(nèi)存層次結(jié)構(gòu)。

在實(shí)際計(jì)算過程中將多個(gè)層融合在一起可以最大限度地減少 GPU 需要讀取和寫入內(nèi)存的次數(shù),并將需要相同數(shù)據(jù)的計(jì)算分組在一起,即使它們是神經(jīng)網(wǎng)絡(luò)中不同層的一部分。

KV緩存的分頁高效管理

PagedAttention 算法能夠?qū)?strong>連續(xù)的鍵和值存儲(chǔ)在內(nèi)存中的不連續(xù)空間中。它將每個(gè)請(qǐng)求的 KV 緩存劃分為代表固定數(shù)量token的塊,這些塊可以不連續(xù)存儲(chǔ)。

模型服務(wù)技術(shù)

連續(xù)批處理

總結(jié)對(duì)比如下:

  • 靜態(tài)批處理:客戶端將多個(gè)Prompt打包進(jìn)一個(gè)請(qǐng)求中,并在批次中所有序列完成后返回響應(yīng)。通常,多數(shù)推理服務(wù)支持這種方法,但并不要求這樣做。
  • 動(dòng)態(tài)批處理:多個(gè)請(qǐng)求的Prompt在服務(wù)端內(nèi)部動(dòng)態(tài)打包進(jìn)一個(gè)批次處理。通常,這種方法的表現(xiàn)不如靜態(tài)批處理,但如果響應(yīng)短或長(zhǎng)度一致,可以接近最優(yōu)。當(dāng)請(qǐng)求具有不同參數(shù)時(shí),這種方法效果不佳。
  • 連續(xù)批處理:將請(qǐng)求在到達(dá)時(shí)一起批量處理,它不是等待批次中所有序列完成,而是在迭代推理層級(jí)將序列組合在一起。它可以實(shí)現(xiàn)比靜態(tài)批處理高10倍到20倍的吞吐量,目前是最先進(jìn)的方法。

靜態(tài)批處理

靜態(tài)批處理指將多個(gè)Prompt打包進(jìn)行一個(gè)批處理請(qǐng)求,并在批處理請(qǐng)求中所有Prompt完成后返回響應(yīng),批處理的大小在推理完成之前保持不變。

如上圖所示,在第一遍迭代(左)中,每個(gè)序列從提示詞(黃)中生成一個(gè)標(biāo)記(藍(lán)色)。經(jīng)過幾輪迭代(右)后,完成的序列具有不同的尺寸,因?yàn)槊總€(gè)序列在不同的迭代結(jié)束時(shí)產(chǎn)生不同的結(jié)束序列標(biāo)記(紅色)。盡管序列3在兩次迭代后完成,但靜態(tài)批處理意味著 GPU 將在批處理中的最后一個(gè)序列完成。

動(dòng)態(tài)批處理

動(dòng)態(tài)批處理是指允許將一個(gè)或多個(gè)推理請(qǐng)求組合成單個(gè)批次(必須動(dòng)態(tài)創(chuàng)建)以最大化吞吐量的功能。就 Triton 推理服務(wù)框架而言,Triton 會(huì)對(duì)這些輸入請(qǐng)求進(jìn)行批處理,沒有任何延遲,但用戶可以選擇為調(diào)度程序分配有限的延遲,以收集更多推理請(qǐng)求供動(dòng)態(tài)批處理程序使用。

連續(xù)批處理

連續(xù)批處理:一旦批中的一個(gè)序列完成生成,就可以在其位置插入一個(gè)新的序列,從而實(shí)現(xiàn)比靜態(tài)批處理更高的GPU利用率。

如上圖所示,使用連續(xù)批處理完成七條序列。左圖顯示了單個(gè)迭代后的批,右圖顯示了多次迭代后的批。一旦一個(gè)序列產(chǎn)生結(jié)束序列標(biāo)記,我們?cè)谄湮恢貌迦胄碌男蛄校葱蛄蠸5、S6和S7)。這實(shí)現(xiàn)了更高的 GPU 利用率,因?yàn)?GPU 不需要等待所有序列完成才開始新的一個(gè)。

現(xiàn)實(shí)情況比這個(gè)簡(jiǎn)化模型更復(fù)雜:因?yàn)轭A(yù)填充階段需要計(jì)算,并且與生成階段的計(jì)算模式不同,因此它不能很容易地與令牌的生成一起進(jìn)行批量。連續(xù)批處理框架目前通過超參數(shù)來管理這個(gè)問題:等待已服務(wù)比和等待結(jié)束序列標(biāo)記的請(qǐng)求比(waiting_served_ratio)。

參考文檔

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容