はじめに
「Seq2Seq のボトルネック: 文全体を単一の固定サイズのベクトルに圧縮すること。」
アテンション メカニズムを使用すると、すべての情報を 1 つのベクトルに圧縮する必要がなく、モデルは出力を生成するときに すべての入力トークンを振り返ることができます。これはトランスフォーマーの直接の基礎です。
1. アテンションなしの Seq2Seq の問題
Encoder: "I love natural language processing"
│
▼
[context vector] ← Toàn bộ câu nén vào 1 vector!
│
▼
Decoder: "Tôi yêu xử lý ngôn ngữ tự nhiên"
文章が長ければ長いほど、情報の損失が大きくなります。
2. 注意 — 中心となるアイデア
最終的なコンテキスト ベクトルを単に使用する代わりに、デコーダはエンコーダの隠れた状態を すべて振り返ります。
$$\text{注意}(Q, K, V) = \text{ソフトマックス}\left(\frac{QK^T}{\sqrt{d_k}}\right)V$$
その中で:
- Q (クエリ): 「何を探しているのですか?」 — デコーダの隠された現在の状態
- K (キー): 「各入力には何が入っていますか?」 — エンコーダの隠れた状態
- V (Value): 「実際の情報」 — 基本的な注意の K と同じ
スケーリングされた内積注意
import torch
import torch.nn.functional as F
import math
def scaled_dot_product_attention(Q, K, V, mask=None):
"""
Q: (batch, seq_q, d_k)
K: (batch, seq_k, d_k)
V: (batch, seq_k, d_v)
"""
d_k = Q.size(-1)
# 1. Tính attention scores
scores = torch.matmul(Q, K.transpose(-2, -1)) / math.sqrt(d_k)
# scores: (batch, seq_q, seq_k)
# 2. Mask (optional)
if mask is not None:
scores = scores.masked_fill(mask == 0, -1e9)
# 3. Softmax → attention weights
weights = F.softmax(scores, dim=-1)
# 4. Weighted sum of Values
output = torch.matmul(weights, V)
return output, weights
3. マルチヘッドアテンション
1 つの注意の代わりに、複数の「ヘッド」 を使用します。各ヘッドは異なるタイプの関係を学習します。
class MultiHeadAttention(nn.Module):
def __init__(self, d_model, num_heads):
super().__init__()
assert d_model % num_heads == 0
self.d_k = d_model // num_heads
self.num_heads = num_heads
self.W_q = nn.Linear(d_model, d_model)
self.W_k = nn.Linear(d_model, d_model)
self.W_v = nn.Linear(d_model, d_model)
self.W_o = nn.Linear(d_model, d_model)
def forward(self, Q, K, V, mask=None):
batch_size = Q.size(0)
# Linear projections rồi split thành heads
Q = self.W_q(Q).view(batch_size, -1, self.num_heads, self.d_k).transpose(1, 2)
K = self.W_k(K).view(batch_size, -1, self.num_heads, self.d_k).transpose(1, 2)
V = self.W_v(V).view(batch_size, -1, self.num_heads, self.d_k).transpose(1, 2)
# Attention cho từng head
out, weights = scaled_dot_product_attention(Q, K, V, mask)
# Concat heads
out = out.transpose(1, 2).contiguous().view(batch_size, -1, self.num_heads * self.d_k)
return self.W_o(out)
4. 自己注意
Q、K、V がすべて 同じシーケンス から来ている場合 → 自己注意。各トークンは、文内の他のすべてのトークンを「認識」します。
Input: "The cat sat on the mat"
Self-attention cho từ "sat":
→ "The": 0.05 (ít liên quan)
→ "cat": 0.45 (chủ ngữ, rất liên quan!)
→ "sat": 0.20 (chính nó)
→ "on": 0.15
→ "the": 0.05
→ "mat": 0.10
5. アテンションの種類を比較する
| タイプ | Q | K、V | 使用 |
|---|---|---|---|
| バダナウ | デコーダ非表示 | エンコーダ非表示 | Seq2Seq 翻訳 |
| 給与 | デコーダ非表示 | エンコーダ非表示 | Seq2Seq (より単純) |
| 自注意 | 同じシーケンス | 同じシーケンス | トランスエンコーダ |
| クロスアテンション | デコーダ | エンコーダ | トランスデコーダ |
| 因果的な自己注意 | 同+マスク未来 | 類似 | GPT (自己回帰) |
概要
| コンセプト | 意味 |
|---|---|
| 注意 | モデルがすべての入力を「振り返る」ことができるようにします。 |
| Q、K、V | クエリはキーを検索し、対応する値を取得します。 |
| スケーリング | $\sqrt{d_k}$ を除算して勾配を安定させる |
| マルチヘッド | 多くの並行する「視点」 |
| 自注意 | 各トークンは他のすべてのトークンに対応します。 |
次の記事
レッスン 9: トランスフォーマー — 「必要なのは注意だけです」 — セルフ アテンション、位置エンコーディング、レイヤー ノルムを組み合わせた完全なアーキテクチャ — 現代のすべての LLM の基礎。