JOVANA
Explore Library Glossary Getting Started Three Levels Fields How it works Mission
Join the mission
All guides

多個頭、一條單行道:多頭注意力與因果遮罩

為什麼一個注意力永遠不夠、不同的頭各自專精什麼,以及那一個讓模型學會預測未來的遮罩。

一個注意力只能問一個問題

一個單一的注意力運算只學到一種「相關」的概念。但語言一次需要很多種。要解決指什麼,你在意它指哪個名詞;要變化動詞,你在意主詞的單複數;要結束一個引號,你在意開引號在哪。逼一個注意力同時兼顧這一切,只會把它們糊在一起。

解法是多頭注意力(multi-head attention)。模型不用一個大注意力,而是平行跑好幾個小的——每一個是一個頭(head),有自己獨立的查詢、鍵、值矩陣。每個頭對同一份輸入,算自己的分數、自己的 softmax、自己的值混合。典型模型每層有 8 到 128 個頭不等。

每個注意力頭內部,注意力就是一次軟性的查詢–鍵–值檢索:softmax 把匹配分數變成權重,再用它混合各個值向量。

圖示:查詢向量經過 softmax 與鍵向量比較,從而對值向量加權。

拆分、注意、再合併

  1. 拆分。 把詞向量分給各個頭——有 8 個頭時,每個頭在較小的一段維度上工作。總工作量和一個大頭差不多。
  2. 注意。 每個頭獨立做上一篇那整套自注意力(self-attention)流程,產生自己的脈絡混合輸出。
  3. 合併。 把各頭的輸出串接起來,再經過一個學到的矩陣,讓模型把各頭的發現融合成每個詞一個更新後的向量。
多頭注意力的三步:把向量切分到多個並行的頭,讓每個頭獨立注意,再拼接並混合各自的結果。

圖示:一個向量被切分到多個頭,各頭並行計算注意力,輸出拼接後再投影。

這些頭最後都在做什麼

沒有人告訴這些頭要專精什麼——它們在訓練中自行發現各自的角色(role)。研究者檢視訓練好的模型時,會看到重複出現的模式。有些頭是位置型的,主要注意前一兩個詞。有些是語法型的,把動詞連到主詞、把限定詞連到名詞。著名的一種是歸納頭(induction head),它認出重複的模式(「……鄧不利多說……鄧不利多」),把上次接在後面的東西複製過來——這是脈絡學習的關鍵成分。

我們可以把每個頭的注意力權重畫成方格,一軸放來源詞、一軸放目標詞、亮度代表權重,就能直接看到這些角色。這種注意力模式視覺化(attention pattern visualization)是研究者窺看模型內部真正在做什麼的主要窗口之一。

點擊一個詞,就能看到這個頭會注意到哪些其他詞——正是這裡所描述的注意力權重網格。

互動式自注意力演示:點擊一個詞元,高亮它所注意的詞。

單行道:因果遮罩

目前為止的一切藏著一個問題。語言模型被訓練來做下一個詞元預測(next-token prediction)——給定目前的詞,猜下一個。但單純的自注意力讓每個詞都能看到其他每個詞,包括它後面的詞。如果模型能偷看答案,它就什麼有用的東西都學不到。我們得把它的眼睛矇上。

因果遮罩(causal masking)做的正是這件事。在 softmax 之前,凡是一個詞會去注意未來詞的分數,都被設成負無限大。經過 softmax 後,那些位置的權重變成零——隱形。結果是一條嚴格的單行道:第 5 個位置可以注意第 1 到第 5 個位置,永遠看不到第 6 個以後。這正是讓這個架構成為僅解碼器(decoder-only)自回歸(autoregressive)的原因:它一次生成一個詞元,每一個都只以它的過去為條件。

\mathrm{Attention}(Q,K,V)=\mathrm{softmax}\!\left(\frac{QK^{\top}}{\sqrt{d_k}}+M\right)V,\qquad M_{ij}=\begin{cases}0 & j\le i\\[2pt] -\infty & j>i\end{cases}

因果遮罩在 softmax 之前把所有未來位置加上 −∞,於是每個詞元只能注意到自己和過去。

# causal mask applied inside attention, before softmax
scores = Q @ K.T / sqrt(d_k)     # (seq_len, seq_len)

# upper triangle = future positions -> forbid them
scores = scores.masked_fill(future_positions, -infinity)

weights = softmax(scores)        # future positions now get weight 0
out     = weights @ V
一行——把未來遮成負無限大——就把雙向注意力變成因果語言模型。