1.attention
1.Attention
1.1 講講對Attention的理解?
Attention機制是一種在處理時序相關問題的時候常用的技術,主要用于處理序列數據。
核心思想是在處理序列數據時,網絡應該更關注輸入中的重要部分,而忽略不重要的部分,它通過學習不同部分的權重,將輸入的序列中的重要部分顯式地加權,從而使得模型可以更好地關注與輸出有關的信息。
在序列建模任務中,比如機器翻譯、文本摘要、語言理解等,輸入序列的不同部分可能具有不同的重要性。傳統的循環神經網絡(RNN)或卷積神經網絡(CNN)在處理整個序列時,難以捕捉到序列中不同位置的重要程度,可能導致信息傳遞不夠高效,特別是在處理長序列時表現更明顯。
Attention機制的關鍵是引入一種機制來動態地計算輸入序列中各個位置的權重,從而在每個時間步上,對輸入序列的不同部分進行加權求和,得到當前時間步的輸出。這樣就實現了模型對輸入中不同部分的關注度的自適應調整。
1.2 Attention的計算步驟是什么?
具體的計算步驟如下:
- 計算查詢(Query):查詢是當前時間步的輸入,用于和序列中其他位置的信息進行比較。
- 計算鍵(Key)和值(Value):鍵表示序列中其他位置的信息,值是對應位置的表示。鍵和值用來和查詢進行比較。
- 計算注意力權重:通過將查詢和鍵進行內積運算,然后應用softmax函數,得到注意力權重。這些權重表示了在當前時間步,模型應該關注序列中其他位置的重要程度。
- 加權求和:根據注意力權重將值進行加權求和,得到當前時間步的輸出。
在Transformer中,Self-Attention 被稱為"Scaled Dot-Product Attention",其計算過程如下:
- 對于輸入序列中的每個位置,通過計算其與所有其他位置之間的相似度得分(通常通過點積計算)。
- 對得分進行縮放處理,以防止梯度爆炸。
- 將得分用softmax函數轉換為注意力權重,以便計算每個位置的加權和。
- 使用注意力權重對輸入序列中的所有位置進行加權求和,得到每個位置的自注意輸出。
A t t e n t i o n ( Q , K , V ) = s o f t m a x ( Q K T d k ) V Attention(Q,K,V)=softmax(\frac{QK^T}{\sqrt{d_k}})V Attention(Q,K,V)=softmax(dk??QKT?)V
1.3 Attention機制和傳統的Seq2Seq模型有什么區別?
Seq2Seq模型是一種基于編碼器-解碼器結構的模型,主要用于處理序列到序列的任務,例如機器翻譯、語音識別等。
傳統的Seq2Seq模型只使用編碼器來捕捉輸入序列的信息,而解碼器只從編碼器的最后狀態中獲取信息,并將其用于生成輸出序列。
而Attention機制則允許解碼器在生成每個輸出時,根據輸入序列的不同部分給予不同的注意力,從而使得模型更好地關注到輸入序列中的重要信息。
1.4 self-attention 和 target-attention的區別?
self-attention是指在序列數據中,將當前位置與其他位置之間的關系建模。它通過計算每個位置與其他所有位置之間的相關性得分,從而為每個位置分配一個權重。這使得模型能夠根據輸入序列的不同部分的重要性,自適應地選擇要關注的信息。
target-attention則是指將注意力機制應用于目標(或查詢)和一組相關對象之間的關系。它用于將目標與其他相關對象進行比較,并將注意力分配給與目標最相關的對象。這種類型的注意力通常用于任務如機器翻譯中的編碼-解碼模型,其中需要將源語言的信息對齊到目標語言。
因此,自注意力主要關注序列內部的關系,而目標注意力則關注目標與其他對象之間的關系。這兩種注意力機制在不同的上下文中起著重要的作用,幫助模型有效地處理序列數據和相關任務。
1.5 在常規attention中,一般有k=v,那self-attention 可以嗎?
self-attention實際只是attention中的一種特殊情況,因此k=v是沒有問題的,也即K,V參數矩陣相同。實際上,在Transformer模型中,Self-Attention的典型實現就是k等于v的情況。Transformer中的Self-Attention被稱為"Scaled Dot-Product Attention",其中通過將詞向量進行線性變換來得到Q、K、V,并且這三者是相等的。
1.6 目前主流的attention方法有哪些?
講自己熟悉的就可:
- Scaled Dot-Product Attention: 這是Transformer模型中最常用的Attention機制,用于計算查詢向量(Q)與鍵向量(K)之間的相似度得分,然后使用注意力權重對值向量(V)進行加權求和。
- Multi-Head Attention: 這是Transformer中的一個改進,通過同時使用多組獨立的注意力頭(多個QKV三元組),并在輸出時將它們拼接在一起。這樣的做法允許模型在不同的表示空間上學習不同類型的注意力模式。
- Relative Positional Encoding: 傳統的Self-Attention機制在處理序列時并未直接考慮位置信息,而相對位置編碼引入了位置信息,使得模型能夠更好地處理序列中不同位置之間的關系。
- Transformer-XL: 一種改進的Transformer模型,通過使用循環機制來擴展Self-Attention的上下文窗口,從而處理更長的序列依賴性。
1.7 self-attention 在計算的過程中,如何對padding位做mask?
在 Attention 機制中,同樣需要忽略 padding 部分的影響,這里以transformer encoder中的self-attention為例:self-attention中,Q和K在點積之后,需要先經過mask再進行softmax,因此,對于要屏蔽的部分,mask之后的輸出需要為負無窮,這樣softmax之后輸出才為0。
1.8 深度學習中attention與全連接層的區別何在?
這是個非常有意思的問題,要回答這個問題,我們必須重新定義一下Attention。
Transformer Paper里重新用QKV定義了Attention。所謂的QKV就是Query,Key,Value。如果我們用這個機制來研究傳統的RNN attention,就會發現這個過程其實是這樣的:RNN最后一步的output是Q,這個Q query了每一個中間步驟的K。Q和K共同產生了Attention Score,最后Attention Score乘以V加權求和得到context。那如果我們不用Attention,單純用全連接層呢?很簡單,全鏈接層可沒有什么Query和Key的概念,只有一個Value,也就是說給每個V加一個權重再加到一起(如果是Self Attention,加權這個過程都免了,因為V就直接是從raw input加權得到的。)
可見Attention和全連接最大的區別就是Query和Key,而這兩者也恰好產生了Attention Score這個Attention中最核心的機制。而在Query和Key中,我認為Query又相對更重要,因為Query是一個錨點,Attention Score便是從過計算與這個錨點的距離算出來的。任何Attention based algorithm里都會有Query這個概念,但全連接顯然沒有。
最后來一個比較形象的比喻吧。如果一個神經網絡的任務是從一堆白色小球中找到一個略微發灰的,那么全連接就是在里面隨便亂抓然后憑記憶和感覺找,而attention則是左手拿一個白色小球,右手從袋子里一個一個抓出來,兩兩對比顏色,你左手抓的那個白色小球就是Query。
2.Transformer
2.1 transformer中multi-head attention中每個head為什么要進行降維?
在Transformer的Multi-Head Attention中,對每個head進行降維是為了增加模型的表達能力和效率。
每個head是獨立的注意力機制,它們可以學習不同類型的特征和關系。通過使用多個注意力頭,Transformer可以并行地學習多種不同的特征表示,從而增強了模型的表示能力。
然而,在使用多個注意力頭的同時,注意力機制的計算復雜度也會增加。原始的Scaled Dot-Product Attention的計算復雜度為 O ( d 2 ) O(d^2) O(d2),其中d是輸入向量的維度。如果使用h個注意力頭,計算復雜度將增加到 O ( h d 2 ) O(hd^2) O(hd2)。這可能會導致Transformer在處理大規模輸入時變得非常耗時。
為了緩解計算復雜度的問題,Transformer中在每個head上進行降維。在每個注意力頭中,輸入向量通過線性變換被映射到一個較低維度的空間。這個降維過程使用兩個矩陣:一個是查詢(Q)和鍵(K)的降維矩陣 W q W_q Wq?和 W k W_k Wk?,另一個是值(V)的降維矩陣 W v W_v Wv?。
通過降低每個head的維度,Transformer可以在保持較高的表達能力的同時,大大減少計算復雜度。降維后的計算復雜度為 ( h d ^ 2 ) (h\hat d ^ 2) (hd^2),其中 d ^ \hat d d^是降維后的維度。通常情況下, d ^ \hat d d^會遠小于原始維度d,這樣就可以顯著提高模型的計算效率。
2.2 transformer在哪里做了權重共享,為什么可以做權重共享?
Transformer在Encoder和Decoder中都進行了權重共享。
在Transformer中,Encoder和Decoder是由多層的Self-Attention Layer和前饋神經網絡層交叉堆疊而成。權重共享是指在這些堆疊的層中,相同位置的層共用相同的參數。
在Encoder中,所有的自注意力層和前饋神經網絡層都共享相同的參數。這意味著每一層的自注意力機制和前饋神經網絡都使用相同的權重矩陣來進行計算。這種共享保證了每一層都執行相同的計算過程,使得模型能夠更好地捕捉輸入序列的不同位置之間的關聯性。
在Decoder中,除了和Encoder相同的權重共享方式外,還存在另一種特殊的權重共享:Decoder的自注意力層和Encoder的自注意力層之間也進行了共享。這種共享方式被稱為"masked self-attention",因為在解碼過程中,當前位置的注意力不能關注到未來的位置(后續位置),以避免信息泄漏。通過這種共享方式,Decoder可以利用Encoder的表示來理解輸入序列并生成輸出序列。權重共享的好處是大大減少了模型的參數數量,使得Transformer可以更有效地訓練,并且更容易進行推理。此外,共享參數還有助于加快訓練速度和提高模型的泛化能力,因為模型可以在不同位置共享并學習通用的特征表示。
2.3 transformer的點積模型做縮放的原因是什么?
使用縮放的原因是為了控制注意力權重的尺度,以避免在計算過程中出現梯度爆炸的問題。
Attention的計算是在內積之后進行softmax,主要涉及的運算是 e q ? k e^{q \cdot k} eq?k,可以大致認為內積之后、softmax之前的數值在 ? 3 d -3\sqrt{d} ?3d?到 3 d 3\sqrt{d} 3d?這個范圍內,由于d通常都至少是64,所以 e 3 d e^{3\sqrt{d}} e3d?比較大而 e ? 3 d e^{-3\sqrt{d}} e?3d?比較小,因此經過softmax之后,Attention的分布非常接近一個one hot分布了,這帶來嚴重的梯度消失問題,導致訓練效果差。(例如y=softmax(x)在|x|較大時進入了飽和區,x繼續變化y值也幾乎不變,即飽和區梯度消失)
相應地,解決方法就有兩個:
- 像NTK參數化那樣,在內積之后除以 d \sqrt{d} d?,使q?k的方差變為1,對應 e 3 , e ? 3 e^3,e^{?3} e3,e?3都不至于過大過小,這樣softmax之后也不至于變成one hot而梯度消失了,這也是常規的Transformer如BERT里邊的Self Attention的做法
- 另外就是不除以 d \sqrt{d} d?,但是初始化q,k的全連接層的時候,其初始化方差要多除以一個d,這同樣能使得使q?k的初始方差變為1,T5采用了這樣的做法。
3.BERT
3.1 BERT用字粒度和詞粒度的優缺點有哪些?
BERT可以使用字粒度(character-level)和詞粒度(word-level)兩種方式來進行文本表示,它們各自有優缺點:
字粒度(Character-level):
- 優點:處理未登錄詞(Out-of-Vocabulary,OOV):字粒度可以處理任意字符串,包括未登錄詞,不需要像詞粒度那樣遇到未登錄詞就忽略或使用特殊標記。對于少見詞和低頻詞,字粒度可以學習更豐富的字符級別表示,使得模型能夠更好地捕捉詞匯的細粒度信息。
- 缺點:計算復雜度高:使用字粒度會導致輸入序列的長度大大增加,進而增加模型的計算復雜度和內存消耗。需要更多的訓練數據:字粒度模型對于少見詞和低頻詞需要更多的訓練數據來學習有效的字符級別表示,否則可能會導致過擬合。
詞粒度(Word-level):
- 優點:計算效率高:使用詞粒度可以大大減少輸入序列的長度,從而降低模型的計算復雜度和內存消耗。學習到更加穩定的詞級別表示:詞粒度模型可以學習到更加穩定的詞級別表示,特別是對于高頻詞和常見詞,有更好的表示能力。
- 缺點:處理未登錄詞(OOV):詞粒度模型無法處理未登錄詞,遇到未登錄詞時需要采用特殊處理(如使用未登錄詞的特殊標記或直接忽略)。對于多音字等形態復雜的詞匯,可能無法準確捕捉其細粒度的信息。
3.2 BERT的Encoder與Decoder掩碼有什么區別?
Encoder主要使用自注意力掩碼和填充掩碼,而Decoder除了自注意力掩碼外,還需要使用編碼器-解碼器注意力掩碼來避免未來位置信息的泄露。這些掩碼操作保證了Transformer在處理自然語言序列時能夠準確、有效地進行計算,從而獲得更好的表現。
3.3 BERT用的是transformer里面的encoder還是decoder?
BERT使用的是Transformer中的Encoder部分,而不是Decoder部分。
Transformer模型由Encoder和Decoder兩個部分組成。Encoder用于將輸入序列編碼為一系列高級表示,而Decoder用于基于這些表示生成輸出序列。
在BERT模型中,只使用了Transformer的Encoder部分,并且對其進行了一些修改和自定義的預訓練任務,而沒有使用Transformer的Decoder部分。
3.4 為什么BERT選擇mask掉15%這個比例的詞,可以是其他的比例嗎?
BERT選擇mask掉15%的詞是一種經驗性的選擇,是原論文中的一種選擇,并沒有一個固定的理論依據,實際中當然可以嘗試不同的比例,15%的比例是由BERT的作者在原始論文中提出,并在實驗中發現對于BERT的訓練效果是有效的。
3.5 為什么BERT在第一句前會加一個[CLS] 標志?
BERT在第一句前會加一個 [CLS] 標志,最后一層該位對應向量可以作為整句話的語義表示,從而用于下游的分類任務等。為什么選它?因為與文本中已有的其它詞相比,這個無明顯語義信息的符號會更“公平”地融合文本中各個詞的語義信息,從而更好的表示整句話的語義。
具體來說,self-attention是用文本中的其它詞來增強目標詞的語義表示,但是目標詞本身的語義還是會占主要部分的,因此,經過BERT的12層,每次詞的embedding融合了所有詞的信息,可以去更好的表示自己的語義。而 [CLS] 位本身沒有語義,經過12層,得到的是attention后所有詞的加權平均,相比其他正常詞,可以更好的表征句子語義。
3.6 BERT非線性的來源在哪里?
主要來自兩個地方:前饋層的gelu激活函數和self-attention。
前饋神經網絡層:在BERT的Encoder中,每個自注意力層之后都跟著一個前饋神經網絡層。前饋神經網絡層是全連接的神經網絡,通常包括一個線性變換和一個非線性的激活函數,如gelu。這樣的非線性激活函數引入了非線性變換,使得模型能夠學習更加復雜的特征表示。
self-attention layer:在自注意力層中,查詢(Query)、鍵(Key)、值(Value)之間的點積得分會經過softmax操作,形成注意力權重,然后將這些權重與值向量相乘得到每個位置的自注意輸出。這個過程中涉及了softmax操作,使得模型的計算是非線性的。
3.7 BERT訓練時使用的學習率 warm-up 策略是怎樣的?為什么要這么做?
在BERT的訓練中,使用了學習率warm-up策略,這是為了在訓練的早期階段增加學習率,以提高訓練的穩定性和加快模型收斂。
學習率warm-up策略的具體做法是,在訓練開始的若干個步驟(通常是一小部分訓練數據的迭代次數)內,將學習率逐漸從一個較小的初始值增加到預定的最大學習率。在這個過程中,學習率的變化是線性的,即學習率在warm-up階段的每個步驟按固定的步幅逐漸增加。學習率warm-up的目的是為了解決BERT在訓練初期的兩個問題:
- 不穩定性:在訓練初期,由于模型參數的隨機初始化以及模型的復雜性,模型可能處于一個較不穩定的狀態。此時使用較大的學習率可能導致模型的參數變動太大,使得模型很難收斂,學習率warm-up可以在這個階段將學習率保持較小,提高模型訓練的穩定性。
- 避免過擬合:BERT模型往往需要較長的訓練時間來獲得高質量的表示。如果在訓練的早期階段就使用較大的學習率,可能會導致模型在訓練初期就過度擬合訓練數據,降低模型的泛化能力。通過學習率warm-up,在訓練初期使用較小的學習率,可以避免過度擬合,等模型逐漸穩定后再使用較大的學習率進行更快的收斂。
3.8 在BERT應用中,如何解決長文本問題?
在BERT應用中,處理長文本問題有以下幾種常見的解決方案:
- 截斷與填充:將長文本截斷為固定長度或者進行填充。BERT模型的輸入是一個固定長度的序列,因此當輸入的文本長度超過模型的最大輸入長度時,需要進行截斷或者填充。通常,可以根據任務的要求,選擇適當的最大長度,并對文本進行截斷或者填充,使其滿足模型輸入的要求。
- Sliding Window:將長文本分成多個短文本,然后分別輸入BERT模型。這種方法被稱為Sliding Window技術。具體來說,將長文本按照固定的步長切分成多個片段,然后分別輸入BERT模型進行處理。每個片段的輸出可以進行進一步的匯總或者融合,得到最終的表示。
- Hierarchical Model:使用分層模型來處理長文本,其中底層模型用于處理短文本片段,然后將不同片段的表示進行匯總或者融合得到整個長文本的表示。這樣的分層模型可以充分利用BERT模型的表示能力,同時處理長文本。
- Longformer、BigBird等模型:使用專門針對長文本的模型,如Longformer和BigBird。這些模型采用了不同的注意力機制,以處理超長序列,并且通常在處理長文本時具有更高的效率。
- Document-Level Model:將文本看作是一個整體,而不是將其拆分成句子或段落,然后輸入BERT模型進行處理。這樣的文檔級模型可以更好地捕捉整個文檔的上下文信息,但需要更多的計算資源。
4.MHA & MQA & MGA
(1)MHA
從多頭注意力的結構圖中,貌似這個所謂的多個頭就是指多組線性變換層,其實并不是,只有使用了一組線性變化層,即三個變換張量對Q,K,V分別進行線性變換,這些變換不會改變原有張量的尺寸,因此每個變換矩陣都是方陣,得到輸出結果后,多頭的作用才開始顯現,每個頭開始從詞義層面分割輸出的張量,也就是每個頭都想獲得一組Q,K,V進行注意力機制的計算,但是句子中的每個詞的表示只獲得一部分,也就是只分割了最后一維的詞嵌入向量。這就是所謂的多頭,將每個頭的獲得的輸入送到注意力機制中, 就形成多頭注意力機制.
Multi-head attention允許模型共同關注來自不同位置的不同表示子空間的信息,如果只有一個attention head,它的平均值會削弱這個信息。
M u l t i H e a d ( Q , K , V ) = C o n c a t ( h e a d 1 , . . . , h e a d h ) W O w h e r e h e a d i = A t t e n t i o n ( Q W i Q , K W i K , V W i V ) MultiHead(Q,K,V)=Concat(head_1,...,head_h)W^O \\ where ~ head_i = Attention(QW_i^Q, KW_i^K, VW_i^V) MultiHead(Q,K,V)=Concat(head1?,...,headh?)WOwhere?headi?=Attention(QWiQ?,KWiK?,VWiV?)
其中映射由權重矩陣完成:$W^Q_i \in \mathbb{R}^{d_{{model}} \times d_k}
$, W i K ∈ R d model × d k W^K_i \in \mathbb{R}^{d_{\text{model}} \times d_k} WiK?∈Rdmodel?×dk?, W i V ∈ R d model × d v W^V_i \in \mathbb{R}^{d_{\text{model}} \times d_v} WiV?∈Rdmodel?×dv?和 W i O ∈ R h d v × d model W^O_i \in \mathbb{R}^{hd_v \times d_{\text{model}} } WiO?∈Rhdv?×dmodel?。
多頭注意力作用
這種結構設計能讓每個注意力機制去優化每個詞匯的不同特征部分,從而均衡同一種注意力機制可能產生的偏差,讓詞義擁有來自更多元的表達,實驗表明可以從而提升模型效果.
為什么要做多頭注意力機制呢?
- 一個 dot product 的注意力里面,沒有什么可以學的參數。具體函數就是內積,為了識別不一樣的模式,希望有不一樣的計算相似度的辦法。加性 attention 有一個權重可學,也許能學到一些內容。
- multi-head attention 給 h 次機會去學習 不一樣的投影的方法,使得在投影進去的度量空間里面能夠去匹配不同模式需要的一些相似函數,然后把 h 個 heads 拼接起來,最后再做一次投影。
- 每一個頭 hi 是把 Q,K,V 通過 可以學習的 Wq, Wk, Wv 投影到 dv 上,再通過注意力函數,得到 headi。
(2)MQA
MQA(Multi Query Attention)最早是出現在2019年谷歌的一篇論文 《Fast Transformer Decoding: One Write-Head is All You Need》。
MQA的思想其實比較簡單,MQA 與 MHA 不同的是,MQA 讓所有的頭之間共享同一份 Key 和 Value 矩陣,每個頭正常的只單獨保留了一份 Query 參數,從而大大減少 Key 和 Value 矩陣的參數量。
Multi-query attention is identical except that the different heads share a single set of keys and values.
在 Multi-Query Attention 方法中只會保留一個單獨的key-value頭,這樣雖然可以提升推理的速度,但是會帶來精度上的損失。《Multi-Head Attention:Collaborate Instead of Concatenate 》這篇論文的第一個思路是基于多個 MQA 的 checkpoint 進行 finetuning,來得到了一個質量更高的 MQA 模型。這個過程也被稱為 Uptraining。
具體分為兩步:
- 對多個 MQA 的 checkpoint 文件進行融合,融合的方法是: 通過對 key 和 value 的 head 頭進行 mean pooling 操作,如下圖。
- 對融合后的模型使用少量數據進行 finetune 訓練,重訓后的模型大小跟之前一樣,但是效果會更好
(3)GQA
Google 在 2023 年發表的一篇 《GQA: Training Generalized Multi-Query Transformer Models from Multi-Head Checkpoints》的論文
如下圖所示,
- 在 MHA(Multi Head Attention) 中,每個頭有自己單獨的 key-value 對;
- 在 MQA(Multi Query Attention) 中只會有一組 key-value 對;
- 在 GQA(Grouped Query Attention) 中,會對 attention 進行分組操作,query 被分為 N 組,每個組共享一個 Key 和 Value 矩陣。
GQA-N 是指具有 N 組的 Grouped Query Attention。GQA-1具有單個組,因此具有單個Key 和 Value,等效于MQA。而GQA-H具有與頭數相等的組,等效于MHA。
在基于 Multi-head 多頭結構變為 Grouped-query 分組結構的時候,也是采用跟上圖一樣的方法,對每一組的 key-value 對進行 mean pool 的操作進行參數融合。融合后的模型能力更綜合,精度比 Multi-query 好,同時速度比 Multi-head 快。
(4)總結
MHA(Multi-head Attention)是標準的多頭注意力機制,h個Query、Key 和 Value 矩陣。
MQA(Multi-Query Attention)是多查詢注意力的一種變體,也是用于自回歸解碼的一種注意力機制。與MHA不同的是,MQA 讓所有的頭之間共享同一份 Key 和 Value 矩陣,每個頭只單獨保留了一份 Query 參數,從而大大減少 Key 和 Value 矩陣的參數量。
GQA(Grouped-Query Attention)是分組查詢注意力,GQA將查詢頭分成G組,每個組共享一個Key 和 Value 矩陣。GQA-G是指具有G組的grouped-query attention。GQA-1具有單個組,因此具有單個Key 和 Value,等效于MQA。而GQA-H具有與頭數相等的組,等效于MHA。
GQA介于MHA和MQA之間。GQA 綜合 MHA 和 MQA ,既不損失太多性能,又能利用 MQA 的推理加速。不是所有 Q 頭共享一組 KV,而是分組一定頭數 Q 共享一組 KV,比如上圖中就是兩組 Q 共享一組 KV。
5.Flash Attention
論文名稱:FlashAttention: Fast and Memory-Efficient Exact Attention with IO-Awareness
Flash Attention的主要目的是加速和節省內存,主要貢獻包括:
- 計算softmax時候不需要全量input數據,可以分段計算;
- 反向傳播的時候,不存儲attention matrix ( N 2 N^2 N2的矩陣),而是只存儲softmax歸一化的系數。
5.1 動機
不同硬件模塊之間的帶寬和存儲空間有明顯差異,例如下圖中左邊的三角圖,最頂端的是GPU種的SRAM
,它的容量非常小但是帶寬非常大,以A100 GPU為例,它有108個流式多核處理器,每個處理器上的片上SRAM大小只有192KB,因此A100總共的SRAM大小是 192 K B × 108 = 20 M B 192KB\times 108 = 20MB 192KB×108=20MB,但是其吞吐量能高達19TB/s。而A100 GPU HBM
(High Bandwidth Memory也就是我們常說的GPU顯存大小)大小在40GB~80GB左右,但是帶寬只與1.5TB/s。
下圖給出了標準的注意力機制的實現流程,可以看到因為HBM
的大小更大,我們平時寫pytorch代碼的時候最常用到的就是HBM,所以對于HBM的讀寫操作非常頻繁,而SRAM利用率反而不高。
FlashAttention的主要動機就是希望把SRAM利用起來,但是難點就在于SRAM太小了,一個普通的矩陣乘法都放不下去。FlashAttention的解決思路就是將計算模塊進行分解,拆成一個個小的計算任務。
5.2 Softmax Tiling
在介紹具體的計算算法前,我們首先需要了解一下Softmax Tiling。
(1)數值穩定
Softmax包含指數函數,所以為了避免數值溢出問題,可以將每個元素都減去最大值,如下圖示,最后計算結果和原來的Softmax是一致的。
m ( x ) : = max ? i x i f ( x ) : = [ e x 1 ? m ( x ) … e x B ? m ( x ) ] ? ( x ) : = ∑ i f ( x ) i softmax ? ( x ) : = f ( x ) ? ( x ) m(x):=\max _{i} ~ x_{i} \\ f(x):=\left[\begin{array}{llll}e^{x_{1}-m(x)} & \ldots & e^{x_{B}-m(x)}\end{array}\right] \\ \ell(x):=\sum_{i} f(x)_{i} \\ \operatorname{softmax}(x):=\frac{f(x)}{\ell(x)} m(x):=imax??xi?f(x):=[ex1??m(x)?…?exB??m(x)?]?(x):=i∑?f(x)i?softmax(x):=?(x)f(x)?
(2)分塊計算softmax
因為Softmax都是按行計算的,所以我們考慮一行切分成兩部分的情況,即原本的一行數據 x ∈ R 2 B = [ x ( 1 ) , x ( 2 ) ] x \in \mathbb{R}^{2 B}=\left[x^{(1)}, x^{(2)}\right] x∈R2B=[x(1),x(2)]
可以看到計算不同塊的 f ( x ) f(x) f(x)值時,乘上的系數是不同的,但是最后化簡后的結果都是指數函數減去了整行的最大值。以 x ( 1 ) x^{(1)} x(1) 為例,
m m ( x ( 1 ) ) ? m ( x ) f ( x ( 1 ) ) = e m ( x ( 1 ) ) ? m ( x ) [ e x 1 ( 1 ) ? m ( x ( 1 ) ) , … , e x B ( 1 ) ? m ( x ( 1 ) ) ] = [ e x 1 ( 1 ) ? m ( x ) , … , e x B ( 1 ) ? m ( x ) ] \begin{aligned} m^{m\left(x^{(1)}\right)-m(x)} f\left(x^{(1)}\right) & =e^{m\left(x^{(1)}\right)-m(x)}\left[e^{x_{1}^{(1)}-m\left(x^{(1)}\right)}, \ldots, e^{x_{B}^{(1)}-m\left(x^{(1)}\right)}\right] \\ & =\left[e^{x_{1}^{(1)}-m(x)}, \ldots, e^{x_{B}^{(1)}-m(x)}\right]\end{aligned} mm(x(1))?m(x)f(x(1))?=em(x(1))?m(x)[ex1(1)??m(x(1)),…,exB(1)??m(x(1))]=[ex1(1)??m(x),…,exB(1)??m(x)]?
5.3 算法流程
FlashAttention旨在避免從 HBM(High Bandwidth Memory)中讀取和寫入注意力矩陣,這需要做到:
- 目標一:在不訪問整個輸入的情況下計算softmax函數的縮減;將輸入分割成塊,并在輸入塊上進行多次傳遞,從而以增量方式執行softmax縮減。
- 目標二:在后向傳播中不能存儲中間注意力矩陣。標準Attention算法的實現需要將計算過程中的S、P寫入到HBM中,而這些中間矩陣的大小與輸入的序列長度有關且為二次型,因此Flash Attention就提出了不使用中間注意力矩陣,通過存儲歸一化因子來減少HBM內存的消耗。
FlashAttention算法流程如下圖所示:
為方便理解,下圖將FlashAttention的計算流程可視化出來了,簡單理解就是每一次只計算一個block的值,通過多輪的雙for循環完成整個注意力的計算。
6.Transformer常見問題
6.1 Transformer和RNN
最簡單情況:沒有殘差連接、沒有 layernorm、 attention 單頭、沒有投影。看和 RNN 區別
- attention 對輸入做一個加權和,加權和 進入 point-wise MLP。(畫了多個紅色方塊 MLP, 是一個權重相同的 MLP)
- point-wise MLP 對 每個輸入的點 做計算,得到輸出。
- attention 作用:把整個序列里面的信息抓取出來,做一次匯聚 aggregation
RNN 跟 transformer 異:如何傳遞序列的信息
RNN 是把上一個時刻的信息輸出傳入下一個時候做輸入。Transformer 通過一個 attention 層,去全局的拿到整個序列里面信息,再用 MLP 做語義的轉換。
RNN 跟 transformer 同:語義空間的轉換 + 關注點
用一個線性層 or 一個 MLP 來做語義空間的轉換。
關注點:怎么有效的去使用序列的信息。
6.2 一些細節
Transformer為何使用多頭注意力機制?(為什么不使用一個頭)
- 多頭保證了transformer可以注意到不同子空間的信息,捕捉到更加豐富的特征信息。可以類比CNN中同時使用多個濾波器的作用,直觀上講,多頭的注意力有助于網絡捕捉到更豐富的特征/信息。
Transformer為什么Q和K使用不同的權重矩陣生成,為何不能使用同一個值進行自身的點乘? (注意和第一個問題的區別)
- 使用Q/K/V不相同可以保證在不同空間進行投影,增強了表達能力,提高了泛化能力。
- 同時,由softmax函數的性質決定,實質做的是一個soft版本的arg max操作,得到的向量接近一個one-hot向量(接近程度根據這組數的數量級有所不同)。如果令Q=K,那么得到的模型大概率會得到一個類似單位矩陣的attention矩陣,這樣self-attention就退化成一個point-wise線性映射。這樣至少是違反了設計的初衷。
Transformer計算attention的時候為何選擇點乘而不是加法?兩者計算復雜度和效果上有什么區別?
- K和Q的點乘是為了得到一個attention score 矩陣,用來對V進行提純。K和Q使用了不同的W_k, W_Q來計算,可以理解為是在不同空間上的投影。正因為有了這種不同空間的投影,增加了表達能力,這樣計算得到的attention score矩陣的泛化能力更高。
- 為了計算更快。矩陣加法在加法這一塊的計算量確實簡單,但是作為一個整體計算attention的時候相當于一個隱層,整體計算量和點積相似。在效果上來說,從實驗分析,兩者的效果和dk相關,dk越大,加法的效果越顯著。
為什么在進行softmax之前需要對attention進行scaled(為什么除以dk的平方根),并使用公式推導進行講解
- 這取決于softmax函數的特性,如果softmax內計算的數數量級太大,會輸出近似one-hot編碼的形式,導致梯度消失的問題,所以需要scale
- 那么至于為什么需要用維度開根號,假設向量q,k滿足各分量獨立同分布,均值為0,方差為1,那么qk點積均值為0,方差為dk,從統計學計算,若果讓qk點積的方差控制在1,需要將其除以dk的平方根,是的softmax更加平滑
在計算attention score的時候如何對padding做mask操作?
- padding位置置為負無窮(一般來說-1000就可以),再對attention score進行相加。對于這一點,涉及到batch_size之類的,具體的大家可以看一下實現的源代碼,位置在這里:https://github.com/huggingface/transformers/blob/aa6a29bc25b663e1311c5c4fb96b004cf8a6d2b6/src/transformers/modeling_bert.py#L720
- padding位置置為負無窮而不是0,是因為后續在softmax時, e 0 = 1 e^0=1 e0=1,不是0,計算會出現錯誤;而 e ? ∞ = 0 e^{-\infty} = 0 e?∞=0,所以取負無窮
為什么在進行多頭注意力的時候需要對每個head進行降維?(可以參考上面一個問題)
- 將原有的高維空間轉化為多個低維空間并再最后進行拼接,形成同樣維度的輸出,借此豐富特性信息
- 基本結構:Embedding + Position Embedding,Self-Attention,Add + LN,FN,Add + LN
為何在獲取輸入詞向量之后需要對矩陣乘以embedding size的開方?意義是什么?
- embedding matrix的初始化方式是xavier init,這種方式的方差是1/embedding size,因此乘以embedding size的開方使得embedding matrix的方差是1,在這個scale下可能更有利于embedding matrix的收斂。
簡單介紹一下Transformer的位置編碼?有什么意義和優缺點?
- 因為self-attention是位置無關的,無論句子的順序是什么樣的,通過self-attention計算的token的hidden embedding都是一樣的,這顯然不符合人類的思維。因此要有一個辦法能夠在模型中表達出一個token的位置信息,transformer使用了固定的positional encoding來表示token在句子中的絕對位置信息。
你還了解哪些關于位置編碼的技術,各自的優缺點是什么?(參考上一題)
- 相對位置編碼(RPE)1.在計算attention score和weighted value時各加入一個可訓練的表示相對位置的參數。2.在生成多頭注意力時,把對key來說將絕對位置轉換為相對query的位置3.復數域函數,已知一個詞在某個位置的詞向量表示,可以計算出它在任何位置的詞向量表示。前兩個方法是詞向量+位置編碼,屬于亡羊補牢,復數域是生成詞向量的時候即生成對應的位置信息。
簡單講一下Transformer中的殘差結構以及意義。
- 就是ResNet的優點,解決梯度消失
為什么transformer塊使用LayerNorm而不是BatchNorm?LayerNorm 在Transformer的位置是哪里?
- LN:針對每個樣本序列進行Norm,沒有樣本間的依賴。對一個序列的不同特征維度進行Norm
- CV使用BN是認為channel維度的信息對cv方面有重要意義,如果對channel維度也歸一化會造成不同通道信息一定的損失。而同理nlp領域認為句子長度不一致,并且各個batch的信息沒什么關系,因此只考慮句子內信息的歸一化,也就是LN。
簡答講一下BatchNorm技術,以及它的優缺點。
- 優點:
- 第一個就是可以解決內部協變量偏移,簡單來說訓練過程中,各層分布不同,增大了學習難度,BN緩解了這個問題。當然后來也有論文證明BN有作用和這個沒關系,而是可以使損失平面更加的平滑,從而加快的收斂速度。
- 第二個優點就是緩解了梯度飽和問題(如果使用sigmoid激活函數的話),加快收斂。
- 缺點:
- 第一個,batch_size較小的時候,效果差。這一點很容易理解。BN的過程,使用 整個batch中樣本的均值和方差來模擬全部數據的均值和方差,在batch_size 較小的時候,效果肯定不好。
- 第二個缺點就是 BN 在RNN中效果比較差。
簡單描述一下Transformer中的前饋神經網絡?使用了什么激活函數?相關優缺點?
- ReLU
F F N ( x ) = m a x ( 0 , x W 1 + b 1 ) W 2 + b 2 FFN(x)=max(0,~ xW_1+b_1)W_2+b_2 FFN(x)=max(0,?xW1?+b1?)W2?+b2?
Encoder端和Decoder端是如何進行交互的?(在這里可以問一下關于seq2seq的attention知識)
- Cross Self-Attention,Decoder提供Q,Encoder提供K,V
Decoder階段的多頭自注意力和encoder的多頭自注意力有什么區別?(為什么需要decoder自注意力需要進行 sequence mask)
- 讓輸入序列只看到過去的信息,不能讓他看到未來的信息
Transformer的并行化提現在哪個地方?Decoder端可以做并行化嗎?
- Encoder側:模塊之間是串行的,一個模塊計算的結果做為下一個模塊的輸入,互相之前有依賴關系。從每個模塊的角度來說,注意力層和前饋神經層這兩個子模塊單獨來看都是可以并行的,不同單詞之間是沒有依賴關系的。
- Decode引入sequence mask就是為了并行化訓練,Decoder推理過程沒有并行,只能一個一個的解碼,很類似于RNN,這個時刻的輸入依賴于上一個時刻的輸出。
簡單描述一下wordpiece model 和 byte pair encoding,有實際應用過嗎?
- 傳統詞表示方法無法很好的處理未知或罕見的詞匯(OOV問題),傳統詞tokenization方法不利于模型學習詞綴之間的關系”
- BPE(字節對編碼)或二元編碼是一種簡單的數據壓縮形式,其中最常見的一對連續字節數據被替換為該數據中不存在的字節。后期使用時需要一個替換表來重建原始數據。
- 優點:可以有效地平衡詞匯表大小和步數(編碼句子所需的token次數)。
- 缺點:基于貪婪和確定的符號替換,不能提供帶概率的多個分片結果。
Transformer訓練的時候學習率是如何設定的?Dropout是如何設定的,位置在哪里?Dropout 在測試的需要有什么需要注意的嗎?
- Dropout測試的時候記得對輸入整體呈上dropout的比率
引申一個關于bert問題,bert的mask為何不學習transformer在attention處進行屏蔽score的技巧?
- BERT和transformer的目標不一致,bert是語言的預訓練模型,需要充分考慮上下文的關系,而transformer主要考慮句子中第i個元素與前i-1個元素的關系。