機器翻譯的第一個深度學習版本叫 seq2seq:一個 RNN(encoder)把法文句子從頭讀到尾,最後的記憶向量交給另一個 RNN(decoder),由它一個字一個字吐出英文。問題在中間那一個向量:不管句子 5 個字還是 40 個字,它的長度都一樣。講義把這叫做 information bottleneck。拉長下面的句子,看「還留得住多少」。
多層 RNN 做翻譯:講義的例子是德文 “Die Proteste waren am Wochenende eskaliert” 翻成 “The protests escalated over the weekend”。encoder 一路讀、建立句意;decoder 每一步吃進上一個輸出的字,再生出下一個字。疊多層時,第 i 層每個時間步的 hidden state 就是第 i + 1 層的輸入(Sutskever et al. 2014;Luong et al. 2015)。
NMT 是 NLP 深度學習第一個大成功:2014 年第一篇 seq2seq 論文發表,2016 年 Google 翻譯從統計式機器翻譯(SMT)換成神經機器翻譯(NMT),到 2018 年大家都換了。講義的重點是:幾百個工程師花很多年做出來的 SMT,被一小群工程師幾個月訓練出來的 NMT 超越。
Bottleneck:講義用法文 “il a m’entarté”(他用派砸我)翻成 “he hit me with a pie”。encoder 最後那一個向量「必須裝下整句來源句的所有資訊」,這就是資訊瓶頸。
遞迴的問題一:線性互動距離。兩個相隔很遠的字要互動,需要 O(序列長度) 步。講義的例子 “The chef who … was”:chef 的資訊要穿過中間每一個字才碰得到 was。步數多,梯度問題就來了,長距離依賴很難學。而且「字的線性順序」被寫死在架構裡,可是句子的結構本來就不是一條線。
遞迴的問題二:無法平行。forward 和 backward 都有 O(序列長度) 個不能平行的運算:未來的 hidden state 必須等過去的算完。講義的圖上標著每個狀態「最少要等幾步才能算」:0、1、2、…、T。這限制了能用多大的資料集訓練。
那改用 word window(卷積)呢?每個 filter 只看一小段相鄰的字,可以平行。要看遠的字,就得疊很多層,讓上層的 filter 看下層的輸出。講義的評語:疊得很深才看得到長句子,很難處理非常遠的上下文。這是 self-attention 出場的理由。
最陽春的做法是把每個字的向量直接平均(mean pooling),但這樣每個字的份量都一樣。查字典時,你拿一個 query 去比對每一個 key,找到完全相同的那一格,拿走它的 value。Attention 把「完全相同」放軟:query 和每個 key 都算一個相似度(點積),用 softmax 變成 0 到 1、加起來是 1 的權重,再把所有 value 照權重加起來。下面這句話有 8 個字,點一個字當 query。
核心想法:decoder 每一步都直接連到 encoder,挑來源句裡需要的那一段來看。講義一步一步畫:decoder 第一步(輸入 <START>)和 encoder 每個 hidden state 做點積得到 attention scores,取 softmax 得到 attention distribution(這一步大部分看在第一個字 “il”,對應 “he”),再用這個分佈把 encoder 的 hidden states 加權加總,得到 attention output,和 decoder 的 hidden state 接在一起,算出 y₁ = “he”。下一步重複,依序生出 hit、me、with、a、pie。
有時候也會把上一步的 attention output 一起餵進 decoder 當輸入。
為什麼能平行、為什麼解了瓶頸:講義的說法是把每個字的表示當成 query,去一組 value 裡取資訊。不能平行的運算數量不隨序列長度增加;任兩個字的最大互動距離是 O(1),因為每一層所有字都直接看所有字。decoder 不必再從一個向量裡猜整句話,需要哪個字就直接看哪個字。
那還需要 RNN 嗎?抽象來看,attention 是「把一串 x 的資訊傳給網路的某個輸入 hₜ」的方法,而這正是 RNN 被拿來做的事。講義的問題是:如果 attention 只是更好的傳資訊方法,能不能把 RNN 整個拿掉?2017 年的答案是可以,這就是下一節的 self-attention。
Self-attention 的 query、key、value 全部來自同一個序列。每個字的向量 x 分別乘上三個學出來的矩陣:q = xWQ 是「我想找什麼」,k = xWK 是「我身上有什麼可以被找」,v = xWV 是「被選中時我交出什麼」。整句一起算只要三步矩陣運算:QKᵀ/√d、softmax、乘 V。下面的 6 個字只放了位置資訊(像 sin/cos 位置編碼),改矩陣的數字,或切換兩個 head。
Self-attention 不能直接取代遞迴,講義列了三個障礙和解法:
講義的結論:self-attention、位置表示、非線性、遮罩,四件事湊齊就是一個可用的 building block。但這還不是 Transformer。
Transformer encoder-decoder(Vaswani et al. 2017):輸入是 word embeddings 加上位置表示。encoder block = multi-head attention → residual + LayerNorm → feed-forward → residual + LayerNorm。decoder block 多了兩件事:第一層是 masked multi-head self-attention,中間多一層 multi-head cross-attention,query 來自 decoder、key 和 value 來自 encoder 的輸出。講義強調:唯一新的部分就是 encoder 到 decoder 的 attention。另外,transformer 輸入幾個字就輸出幾個字;decoder 也是,只是還沒產生的位置會被 mask 住。
Multi-head:Qℓ、Kℓ、Vℓ ∈ ℝd×d/h,ℓ = 1…h,每個 head 獨立算 outputℓ,最後 output = Y[output1; …; outputh],Y ∈ ℝd×d。原始論文 “Attention is all you need” 用 d_model = 512、h = 8、dk = dv = 512/8 = 64。講義的圖示顯示不同 head 分別關注 global 和 local 的資訊,也有圖示不同 head 學到的語義(例如某個 head 讓 “it” 去看它指的名詞)。
訓練技巧(不增加模型能力,但讓訓練順利,兩種改進都很重要):
矩陣計算:講義引用的圖解把流程寫成兩步:第一步,輸入的 embedding 乘上 WQ、WK、WV 得到每個字的 q、k、v;第二步,用 q 和每個 k 算相似度(attention score),softmax 後乘 v 加總。把所有字排成矩陣 X,整句的 self-attention 就是幾次矩陣乘法。
RNN 讀 n 個字要走 n 步,每一步都要等上一步。Self-attention 一層裡所有字兩兩都要比一次,總共 n² 對,但這 n² 件事彼此獨立,GPU 可以一起做。這是一筆交易:用更多的總計算量,換到不用排隊、而且任兩個字之間只隔一步。拉長序列,看這筆交易什麼時候開始變貴。
Transformer 的缺點:講義列了兩個。一是 self-attention 的二次方計算量:算所有配對,計算量隨序列長度平方成長,遞迴模型只是線性成長。二是位置表示:簡單的絕對位置索引是我們能做到最好的嗎?相對位置(Shaw et al. 2018)、依語法結構的位置(Wang et al. 2019)都是嘗試。
改進二次成本:能不能不付 O(T²) 的全配對成本?例如 BigBird(Zaheer et al. 2021),把全配對換成幾種互動的組合:局部視窗、少數看全部的位置、隨機配對。
Self-attention vs 卷積(在視覺上):把每個像素當一個 token。卷積在小視窗裡認圖樣,很難整合不相鄰的像素,網路得疊很深才「看到全貌」。self-attention 也整合多個像素,而且相關的像素不相鄰時也有效,講義的例子是把大象的鼻子、尾巴、腳整合成一整隻大象。下一個模組 D3 就是把這套搬到影像上。
Transformer 的維度:d 也叫 embedding dimension 或 d_model,是每個 token 的 embedding 向量長度。原始論文 d_model = 512,8 個 head 每個 64 維;FFN 的中間層 d_ff 比 d_model 寬(原始論文是 2048),先放大再縮回來。
非線性運算:講義引用的 inference 全堆疊最佳化 survey(Full Stack Optimization of Transformer Inference)把 Softmax、LayerNorm、BatchNorm 放在一起比:Softmax 和 LayerNorm 依賴執行時的統計量,要對輸入掃好幾次(softmax 先掃一次算分母;LayerNorm 掃三次:平均、標準差、套用正規化);BatchNorm 用的是訓練時學好的統計量,掃一次就夠。所以在硬體上,矩陣乘法以外的這些運算也會成為瓶頸。
銜接下週:本週推出的 Q/K/V、multi-head、位置編碼是通用的序列建模工具。ViT 把影像切成 patch token 直接套用 self-attention;Transformer 少了卷積的歸納偏置,是 ViT 需要大量資料的關鍵原因;CNN 陣營也吸收了 Transformer 的訓練技巧回擊(ConvNeXt)。
講義在本週最後整理的四句話。