每個詞的三種角色
核心的把戲是這樣。模型把每個詞的向量分別乘上三個學到的權重矩陣,產生三個新向量。這就是這個詞的查詢(query)、鍵(key)、值(value)。用圖書館來比喻就具體了:
- 查詢(Q)——我現在在找什麼。詞它發出的查詢像是「我是代名詞,正在找我所指的名詞。」
- 鍵(K)——我對外宣傳自己是什麼,像圖書館書架上的標籤。獎盃宣傳「我是具體名詞。」
- 值(V)——如果你決定注意我,我實際交出的內容——書本身,而不是標籤。
示意圖:一個詞向量乘以三個學習得到的權重矩陣,得出它的查詢、鍵和值向量。
評分:誰跟誰相關
要知道詞 B 對詞 A 有多相關,我們用點積(dot product)比較 A 的查詢和 B 的鍵——把兩個向量逐元素相乘再加總。點積大,表示查詢和鍵指向相近的方向:強匹配。點積小或為負,表示不相關。得到的數字就是注意力分數(attention score)。
兩個向量及其點積,表示為 a·b=|a||b|cosθ 的相似度度量。
每個詞都對句子裡每一個詞算一個分數,包括它自己。一個 10 個詞的句子就是一張 10×10 的分數表格。整個運算——查詢與鍵做點積,再用來混合值——有個你到處會看到的名字:縮放點積注意力(scaled dot-product attention)。縮放指的是把分數除以一個常數,免得向量很長時分數爆掉,這讓下一步保持穩定。
用 softmax 把分數變成權重
原始分數可以是任何數。我們需要把它們變成乾淨的、加總為 1 的比例——「把 70% 的注意力放在獎盃上,20% 放在手提箱上,10% 放在其他。」 做這件事的函數是 softmax。它對每個分數取指數(讓它們全變正、並放大差距),再正規化,使整列加總為 1。輸出就是注意力權重(attention weight)。
整個運算濃縮為一行:縮放查詢—鍵分數,用 softmax 轉成權重,再據此混合值向量。
混合各個值
最後一步是收成。每個詞拿自己那一列的注意力權重,對每個詞的值向量算一個加權平均。如果它把 70% 的權重放在獎盃上,那麼獎盃的值就有 70% 流進它的新向量。這就是把脈絡混合(context mixing)落到實處:每個詞更新後的表示,是整句話按相關度調配出的客製混合。
# self-attention for one sentence (pseudocode, shapes shown) # x: (seq_len, d_model) -- one row vector per token Q = x @ W_q # (seq_len, d_k) what each token is looking for K = x @ W_k # (seq_len, d_k) what each token advertises V = x @ W_v # (seq_len, d_v) what each token will hand over scores = Q @ K.T # (seq_len, seq_len) every query vs every key scores = scores / sqrt(d_k) # scale so values stay stable weights = softmax(scores) # each row sums to 1 out = weights @ V # (seq_len, d_v) context-mixed token vectors
這就是完整的自注意力(self-attention)。三個投影、一張分數表格、一次 softmax、一個加權和。Transformer 裡其餘的一切,都是為了讓這個運算更豐富、更安全、更能堆疊——這正是接下來幾篇要加上的。
互動式自注意力:點擊一個詞會高亮它所關注的其他詞。