テーマ
第8章 Attention徹底解説 — 本書の山場
いよいよ本書の山場です。
この章で扱う 注意機構(Attention) は、Transformerの中核であり、ChatGPTをはじめとする大規模言語モデルの根幹です。逆に言えば、この章さえ理解できれば、残りの章は「Attentionをどう組み合わせ、どう訓練し、どう使うか」の話にすぎません。
安心してください。この章に、新しい数学はほとんど登場しません。使う道具は、第2章の 内積(=類似度)、第5章の softmax、第6章の 埋め込み、そして第3章の 重み付き平均(期待値) だけです。本書がここまで7章分かけて準備してきた道具が、この章で一斉に組み合わさります。
その代わり、段階をとことん細かく刻みます。いきなり完成形の数式を見せることはしません。「素朴なアイデア」から出発し、その弱点を数値で確かめながら、一歩ずつ完成形まで登っていきます。
この章で学ぶこと
- 単語の意味は文脈で決まること、そして「各単語が他の単語から情報を集める仕組み」がなぜ必要か
- 素朴なattention: 埋め込み同士の内積 → softmax → 重み付き平均(手計算で完全に追う)
- なぜクエリ(Q)・キー(K)・バリュー(V)の3役に分けるのか
- なぜ
で割るのか(スケーリング) - 完成形
の意味と、行列形式が「全トークン同時処理」を意味すること - 3トークン・4次元での完全な手計算(入力から出力まで全要素)
- attention重みの可視化(ヒートマップ)と照応の解決
- Multi-Head Attention(複数の「係」で文を見る)
- 因果マスク(未来をカンニングさせない仕組み)
この章の前提
- 第2章 ベクトルと行列 — 内積=類似度、行列積、転置。この章の主役です
- 第3章 微分・勾配・確率 — 重み付き平均(期待値)、勾配
- 第5章 ニューラルネットワーク — softmax、学習されるパラメータという考え方
- 第6章 言葉を数にする — 埋め込みベクトル、文=行列
- 第7章 Transformer前夜 — attentionの誕生、RNNの並列化できない問題
8.1 「それ」は何を指すのか — 文脈が意味を決める
まず、この章全体を貫く例文を出します。本書の通し例です。
「猫は魚を見つけた。それを食べた。」
「それ」は何を指しているでしょうか。もちろん「魚」です。あなたは一瞬で分かったはずです。猫が食べるのは魚であって、猫自身でも「見つけた」でもありません。このように、代名詞が前に出てきた言葉を指し示す関係を 照応(anaphora) と呼びます。
ここで第6章を思い出してください。単語は 埋め込み(embedding) ベクトルに変換されるのでした。埋め込み行列
これは困ります。「それを食べた」の続きを予測するには、「それ=魚」だと知っている必要があるからです。「それ」のベクトルの中に「魚」の情報が混ざっていてほしいのです。
同じ問題は代名詞に限りません。
- 「銀行の口座」と「川の銀行(土手)」— 英語の bank は文脈で意味が変わる
- 「甘いケーキ」と「甘い考え」— 同じ「甘い」でも周りの単語で意味が変わる
つまり、こういうことです。
IMPORTANT
単語の本当の意味は、その単語だけでは決まらない。周りの単語との関係で決まる。
だとすれば、欲しい仕組みはこう書けます。
各単語が、文中の他の単語を見渡して、関係の深い単語から情報を集めてくる仕組み。
これこそがattentionです。第7章の最後で見たように、この発想自体は翻訳モデル(seq2seq)の改良として生まれました。デコーダが「入力の全単語をもう一度見に行く」というあの仕組みです。この章では、あの発想を 文が自分自身を見渡す形(self-attention)に発展させ、数式のレベルまで完全に分解します。
「情報を集める」を数学に翻訳する
「関係の深い単語から情報を集める」という仕組みを、ここまでの章で学んだ内容で言い換えてみましょう。
| やりたいこと | 使えるもの | 学んだ章 |
|---|---|---|
| 単語を数(ベクトル)にする | 埋め込み | 第6章 |
| 2つの単語の「関係の深さ」を測る | 内積=類似度 | 第2章 |
| 関係の深さを「合計1の割合」に変換する | softmax | 第5章 |
| 割合に応じて情報を混ぜる | 重み付き平均 | 第3章 |
全部そろっています。組み立てましょう。
8.2 ステップ1: 素朴なattention — 内積・softmax・重み付き平均だけで作る
最初のバージョンは、パラメータ(学習される重み)を一切使わず、埋め込みベクトルだけで作ります。後で分かるように、このバージョンには重大な弱点があるのですが、attentionの骨格はこの素朴版にすべて含まれています。
8.2.1 作戦
文中に
- スコア: トークン
と各トークン の関連度を、内積で測る - 重み: スコアをsoftmaxに通して、合計1の重みにする
- 混合: 重みを使って、全トークンの埋め込みの重み付き平均をとる
数式で書くと次のとおりです。まずスコア。
読み下し: トークン
次に重み。
読み下し: トークン
最後に混合。
読み下し: トークン
たとえるなら、こうです。教室にいる
8.2.2 手計算: 3トークンでやってみる
例文「猫は魚を見つけた。それを食べた。」は8トークンほどになりますが、手計算にはつらいので、主役の3語 [猫, 魚, それ] だけを抜き出します(「それ」が「魚」を指せるかどうか、が見どころです)。
埋め込みは
| トークン | 埋め込みベクトル |
|---|---|
手順1: スコア(内積)を全ペアで計算する。
読み下し: 猫と猫自身の内積は2。自分自身との内積は「ベクトルの長さの2乗」なので、必ず大きめの値になる(ここが後で問題になります。覚えておいてください)。
残りも同様に計算します。
(猫と魚: 共通の成分がなく無関係)
スコアを表(=行列
| 猫 | 魚 | それ | |
|---|---|---|---|
| 猫 | 2 | 0 | 1 |
| 魚 | 0 | 2 | 1 |
| それ | 1 | 1 | 2 |
内積は
手順2: 各行をsoftmaxで重みにする。
第5章の手順どおり、
猫の行
読み下し: 猫の行のスコア
同様に、魚の行
重み行列
| 猫 | 魚 | それ | 行の合計 | |
|---|---|---|---|---|
| 猫 | 0.665 | 0.090 | 0.245 | 1.000 |
| 魚 | 0.090 | 0.665 | 0.245 | 1.000 |
| それ | 0.212 | 0.212 | 0.576 | 1.000 |
手順3: 重み付き平均で新しいベクトルを作る。
「それ」の新しいベクトル
読み下し: 「それ」の新ベクトルは、猫の埋め込みを21.2%、魚の埋め込みを21.2%、それ自身の埋め込みを57.6%混ぜたもの。
成分ごとに計算します。
- 第1成分:
- 第2成分:
- 第3成分:
- 第4成分:
3トークンぶんの結果をまとめます。
| トークン | 元の埋め込み | 新しいベクトル |
|---|---|---|
| 猫 | ||
| 魚 | ||
| それ |
これで素朴版attentionの計算は一通り完了です。各トークンが「文脈の情報が混ざった新しいベクトル」を手に入れました。これを 文脈化された埋め込み(contextualized embedding) と呼びます。「それ」のベクトルが、もはや辞書的な「それ」ではなく、この文の中での「それ」になったわけです。
8.2.3 素朴版の弱点 — 数値がすでに教えてくれている
さて、うまくいったように見えますが、重み行列
| 猫 | 魚 | それ | |
|---|---|---|---|
| それ | 0.212 | 0.212 | 0.576 |
「それ」は魚を指しているはずなのに、魚への重みはたった0.212で、猫への重みと同じ。一番大きい重みは自分自身(0.576)に向いています。照応の解決に失敗しているのです。なぜこうなったのか、原因を分解すると素朴版の弱点が見えてきます。
弱点1: 自分ばかり見てしまう。 自分自身とのスコア
弱点2: 「単語としての類似」しか測れない。 「それ」と「魚」は、単語としては全然似ていません(代名詞と名詞ですから、埋め込み空間でも遠い)。照応を解決するのに必要なのは「それという代名詞は、少し前に出てきた目的語の名詞を探すべきだ」という、単語の類似とは別種の役割ベースの関連です。生の埋め込みの内積では、これを表現できません。
弱点3: 探す基準と渡す中身が同じ。 「どの単語に注目するかを決める基準」も「注目された単語が渡す情報」も、同じ埋め込みベクトル1本でまかなっています。しかし「見つけてもらうための目印」と「見つけた人に渡す中身」は、本来別のものであるはずです。
弱点4: 学習の余地がない。 この素朴版にはパラメータが1個もありません。第4章で学んだように、機械学習の本質は「損失が減るようにパラメータを調整する」ことでした。パラメータがなければ、タスクに合わせて注目の仕方を改善していくことができません。
この4つの弱点を、たった一つのアイデアがまとめて解決します。それが Q・K・V です。
8.3 ステップ2: Q・K・V — 三つの顔を使い分ける
8.3.1 図書館のアナロジー
あなたが図書館で「猫の飼い方の本」を探す場面を想像してください。
- あなたは頭の中に探したいもの(「猫 飼い方」)を持っています。これが クエリ(Query)、検索語です
- 本棚の本には背表紙のタイトル(『はじめての猫との暮らし』)が付いています。これが キー(Key)、探されるための目印です
- 背表紙がクエリと合致した本を開くと、中身(飼い方の詳しい解説)が手に入ります。これが バリュー(Value)、実際に受け取る情報です
大事なのは、この3つは同じものではないということです。背表紙(キー)は「見つけてもらう」ために最適化された短い目印であり、中身(バリュー)そのものではありません。あなたの検索語(クエリ)も、あなた自身の全人格ではなく「いま探したいもの」だけを表しています。
検索エンジンでも同じです。検索窓に打つ言葉がクエリ、各Webページのタイトルや索引語がキー、ページの本文がバリューです。
attentionにこれを持ち込みます。各トークンは、1本の埋め込みベクトル
(クエリ): 「私はこういう情報を探しています」という顔 (キー): 「私はこういう情報を持っている者です」という顔(背表紙) (バリュー): 「私を選んだ人にはこの中身を渡します」という顔
そしてスコアは「自分のクエリと相手のキーの内積」で測ります。「それ」のクエリが「直前に出てきた食べられる名詞を探しています」であり、「魚」のキーが「私は食べられる名詞です」であれば、2つの単語自体が似ていなくても、クエリとキーは似せられる。これが弱点2の解決です。自分のクエリと自分のキーが似ている必然性もなくなるので、弱点1(自分ばかり見る)も解消できます。渡す中身はバリューという別のベクトルなので、弱点3も解決します。
8.3.2 3つの顔は「学習される変換」で作る
では、1本の埋め込みからどうやって3つの顔を作るのか。第2章で学んだ「行列はベクトルを変換する機械」の出番です。3つの変換行列
ここで記法の約束を明示しておきます(第6章と同じ流儀です)。本書では、トークンの埋め込みを横向きのベクトル(行ベクトル) として扱い、
読み下し: トークン
ここで
そして最重要ポイント。
たとえるなら、
スコアと重みと出力は、素朴版の
読み下し: スコアは「
なお第2章で確認したとおり、内積は
8.4 ステップ3: なぜ で割るのか — スケーリング
完成形まであと一歩です。実際のTransformerでは、内積スコアをそのままsoftmaxに入れず、
8.4.1 softmaxは大きいスコアで「尖りすぎる」
スコアの列
読み下し: スコア2の候補に約67%、スコア1に約24%、スコア0に約9%。1位を重視しつつ、2位・3位にもそれなりの重みが残る、ほどよい配分。
では、スコア全体が10倍になって
読み下し: 1位がほぼ100%を独占し、2位以下はほぼゼロ。スコアの比は
比較表にします。
| スコア | softmax後の重み | 様子 |
|---|---|---|
| ほどよく混ざる | ||
| 1位総取り(尖りすぎ) |
尖りすぎの何が悪いのでしょうか。2つあります。
- 情報を混ぜられない: attentionの目的は「複数の単語から情報を集める」ことでした。1位総取りでは、1単語をコピーするだけの機械になってしまいます。
- 学習が止まる: こちらが深刻です。重みが0.99995のとき、スコアを少し変えても重みはほとんど動きません(
の項が他よりはるかに大きいため)。「入力を変えても出力が変わらない」= 傾き(勾配)がほぼゼロ ということです。第4章で学んだとおり、学習は勾配を頼りに進むのでした。勾配がゼロでは、 や を直す手がかりが消えてしまいます。第5章で見た「シグモイドの平らな領域で学習が止まる」問題や、第7章の勾配消失と同じ種類の問題です。
8.4.2 次元が大きいほど内積は大きくなる
問題は、内積という演算は次元が増えるほど値が大きくぶれることです。内積は
読み下し: 内積は
ここで統計の用語を2つだけ、直感的に導入します。数値の集まりが平均のまわりでどれくらい散らばっているかを表す量を 分散(variance)、その散らばりを「元の数値と同じ単位のぶれ幅」に直したものを 標準偏差(standard deviation) と呼びます。「ぶれ幅の平均的な大きさ」と思えば十分です(第9章のLayerNormでも再登場します)。
各成分が「平均0、ぶれ幅(標準偏差)1」程度の値だとすると、統計の性質から、内積の典型的なぶれ幅は
| 内積の典型的な大きさ( | softmaxの様子 | |
|---|---|---|
| 2 | ほどよい | |
| 64 | かなり尖る | |
| 512 | ほぼ総取り・学習停止 |
実際のTransformerでは
8.4.3 対策: で割る
ばらつきが
読み下し: スコアは、クエリとキーの内積を
数値例:
8.5 完成形: Scaled Dot-Product Attention — 行列で書くと「全トークン同時処理」
部品がそろいました。ここまでの手続きを1つの式にまとめたものが、2017年の原論文 "Attention Is All You Need" に登場する スケール化内積注意(Scaled Dot-Product Attention) です。
読み下し: 全トークンのクエリを積んだ行列
ここに出てくる記号の形を整理します。
| 記号 | 作り方 | 形 | 意味 |
|---|---|---|---|
| 埋め込みを縦に積む | 入力(1行=1トークン) | ||
| 学習される変換 | 全トークンのクエリ(探す顔) | ||
| 学習される変換 | 全トークンのキー(探される顔) | ||
| 学習される変換 | 全トークンのバリュー(渡す中身) | ||
| 行列積 | 全ペアのスコア表 | ||
| 行ごとにsoftmax | attention重み(各行の合計1) | ||
| 行列積 | 出力(文脈化されたベクトル) |
8.5.1 図で見る: Q/K/V計算フロー(本書最重要図)
この計算の流れを図にします。この図は本書で最も重要な図です。 何度でも戻ってきてください。
8.5.2 行列形式の本当のありがたみ — RNNとの決定的な違い
行列で書けることには、見た目がきれいという以上の、決定的に重要な意味があります。
第7章を思い出してください。RNNの弱点は、
attentionは違います。
| RNN(第7章) | attention(本章) | |
|---|---|---|
| 計算の進み方 | 1トークンずつ順番に( | 全トークン同時(行列積ひとまとめ) |
| GPUとの相性 | 悪い(順番待ちが発生) | 最高(行列積はGPUの得意技) |
| 離れた単語同士の情報の距離 | 常に1ステップ(直接内積をとる) | |
| 文が長くなると | 記憶が薄れる・勾配消失 | どの距離のペアも対等に扱える |
特に3行目が重要です。RNNでは文頭の「猫」の情報が文末に届くまでに何十回も変換されて薄れていきました(伝言ゲーム)。attentionでは、文末のトークンが文頭のトークンと直接内積をとります。距離1でも距離1000でも、扱いは完全に対等です。長距離依存の問題(第7章)が、仕組みのレベルで消滅しているのです。
これが「RNNを捨ててattentionだけで作ればいいのでは?」(= Attention Is All You Need)という発想の核心でした。
なお、正直に代償も述べておくと、
8.6 完全な手計算 — 3トークンで、入口から出口まで全要素を追う
いよいよ、この章の総仕上げです。完成形のattentionを、すべての数値を省略せずに手で計算します。ここを一度自分の手で追えば、attentionは「知っている」から「使える」に変わります。
設定は次のとおりです。
- トークン列: [猫, 魚, それ](
)。8.2と同じく「猫は魚を見つけた。それを食べた。」の主役3語 - モデル次元:
- クエリ/キー/バリューの次元:
8.6.1 入力 と3つの変換行列
入力は8.2と同じ埋め込みです。行ベクトルを縦に積んで、
読み下し: 1行目が猫、2行目が魚、3行目が「それ」の埋め込み。3トークン×4次元。
変換行列は次の値とします(
読み下し: 埋め込み(4次元)をクエリ・キー・バリュー(各2次元)に変換する3つの行列。中身の数値そのものに深い意味はなく、「訓練の結果、このような値になった」という想定で読んでください。
8.6.2 を計算する
行列積の手順(第2章)どおり、「
よって
よって
よって
読み下し: 3トークンそれぞれのクエリ(探す顔)。「それ」のクエリは
8.6.3 と を計算する
同じ手順です。キーの1成分だけ確認しておきます。猫の行と
読み下し: 各トークンのキー(背表紙)とバリュー(渡す中身)。魚のキーは
ここで注目してほしいのは、「それ」のクエリ
結果をトークンごとに一覧にします。
| トークン | 埋め込み | クエリ | キー | バリュー |
|---|---|---|---|---|
| 猫 | ||||
| 魚 | ||||
| それ |
8.6.4 スコア行列 を計算する
読み下し: 全ペアの関連度スコア表。行が「見る側」、列が「見られる側」。「それ」の行(3行目)は
8.6.5 で割り、行ごとにsoftmax
読み下し: スケール調整後のスコア表。値の大小関係はそのままに、全体が
各行をsoftmaxにかけます。
猫の行
読み下し: 猫は自分に67%、魚と「それ」に16%ずつ注意を向ける。
魚の行
「それ」の行
読み下し: 「それ」は89.4%の注意を魚に向ける。自分自身へはわずか5.3%。
attention重み行列
| 猫 | 魚 | それ | 行の合計 | |
|---|---|---|---|---|
| 猫 | 0.673 | 0.164 | 0.164 | 1.001(丸め誤差) |
| 魚 | 0.401 | 0.401 | 0.198 | 1.000 |
| それ | 0.053 | 0.894 | 0.053 | 1.000 |
素朴版(8.2)と並べてみましょう。「それ」の行の変化に注目です。
| 「それ」の行 | 猫へ | 魚へ | 自分へ | 判定 |
|---|---|---|---|---|
| 素朴版(Q/K/Vなし) | 0.212 | 0.212 | 0.576 | 自分ばかり見て照応に失敗 |
| Q/K/V版 | 0.053 | 0.894 | 0.053 | 「それ」→「魚」の照応を解決 |
弱点1(自分ばかり見る)と弱点2(役割ベースの関連が測れない)が、数値の上で解決されたことが確認できました。
8.6.6 出力 を計算する
最後に、重み
猫の出力
- 第1成分:
- 第2成分:
魚の出力
- 第1成分:
- 第2成分:
「それ」の出力
- 第1成分:
- 第2成分:
読み下し: 3トークンの出力(文脈化されたベクトル)。「それ」の出力は
ここで魚のバリュー
計算の全行程を1枚にまとめます。
text
X (3x4) Q (3x2) K (3x2) V (3x2)
1 0 1 0 2 1 2 0 2 0
0 1 0 1 --> 1 1 0 2 0 2 <- X に W_Q, W_K, W_V をそれぞれ掛ける
1 1 0 0 0 2 1 0 1 1
QK^T (3x3) / sqrt(2) softmax xV = Z (3x2)
4 2 2 2.83 1.41 1.41 0.673 0.164 0.164 1.510 0.492
2 2 1 --> 1.41 1.41 0.71 0.401 0.401 0.198 1.000 1.000
0 4 0 0 2.83 0 0.053 0.894 0.053 0.159 1.841
^
「それ」は魚を89%見ている
各行列の行は、上から 猫, 魚, それ の順。softmax は行ごとに適用。8.7 attention重みを可視化する — ヒートマップ
attention重み行列
まず、いま計算した3トークンの
| 見る側 \ 見られる側 | 猫 | 魚 | それ |
|---|---|---|---|
| 猫 | 0.673 ▓▓▓ | 0.164 ░ | 0.164 ░ |
| 魚 | 0.401 ▒▒ | 0.401 ▒▒ | 0.198 ░ |
| それ | 0.053 | 0.894 ████ | 0.053 |
次に、実際に訓練されたモデルが文全体でどんな重みを付けるか、雰囲気をつかみましょう。例文をフルバージョン「猫 / は / 魚 / を / 見つけた / 。 / それ / を / 食べた」(9トークン)にします。以下は、訓練済みモデルのあるヘッドに典型的に現れるパターンを模した説明用の値です(トークンを区別するため位置番号を添えています)。
| 見る側 \ 見られる側 | 猫₁ | は₂ | 魚₃ | を₄ | 見つけた₅ | 。₆ | それ₇ | を₈ | 食べた₉ |
|---|---|---|---|---|---|---|---|---|---|
| 猫₁ | 0.55 ▓▓▓ | 0.05 | 0.15 ░ | 0.02 | 0.18 ░ | 0.01 | 0.02 | 0.01 | 0.01 |
| 魚₃ | 0.18 ░ | 0.02 | 0.45 ▒▒ | 0.05 | 0.24 ░ | 0.01 | 0.02 | 0.02 | 0.01 |
| それ₇ | 0.03 | 0.01 | 0.62 ████ | 0.02 | 0.14 ░ | 0.01 | 0.10 ░ | 0.02 | 0.05 |
| 食べた₉ | 0.20 ░ | 0.02 | 0.15 ░ | 0.03 | 0.08 | 0.02 | 0.42 ▒▒ | 0.06 | 0.02 |
(9行すべて書くと長いので、読みどころのある4行を抜粋しています。各行の合計は1です。)
この表の読み方です。
- 「それ₇」の行: 「魚₃」の列に0.62の重み。モデルが「それ=魚」という照応を解決している瞬間です。動詞「見つけた₅」にも0.14の重みがあり、「見つけられたものを探す」手がかりとして動詞も見ている、と解釈できます
- 「食べた₉」の行: 目的語である「それ₇」に0.42、主語の「猫₁」に0.20。動詞が自分の主語と目的語を集めている格好です
- 助詞「は」「を」や句点にはどの行からもほとんど重みが向いていません。情報量の少ない単語は自然と無視されます
実際の研究でも、訓練されたTransformerのattention重みを可視化すると、照応関係・主語と述語・修飾関係などの言語学的な構造に対応するパターンが(誰も教えていないのに)現れることが知られています。
8.8 self-attentionという名前 — 誰が誰を見るのか
ここまで説明してきた仕組みの正式名称は 自己注意(self-attention) です。「自己」が付くのは、クエリもキーもバリューも、すべて同じ文(同じ
思い出してください。第7章で登場したattentionの原型(Bahdanau attention)は、翻訳のデコーダがエンコーダ側の入力文を見る仕組みでした。あちらは「見る側」と「見られる側」が別の文です。この形は 交差注意(cross-attention) と呼ばれ、Q/K/Vの言葉で言えば「クエリはデコーダの文から、キーとバリューはエンコーダの文から作る」となります。詳しくは第9章で扱います。
| 種類 | クエリの出どころ | キー/バリューの出どころ | 用途 |
|---|---|---|---|
| self-attention | 文 | 文 | 文の中の関係を捉える(本章) |
| cross-attention | デコーダ側の文 | エンコーダ側の文 | 翻訳元を参照する(第9章) |
8.9 Multi-Head Attention — 複数の「係」で文を見る
8.9.1 1つのattentionでは1種類の関係しか見られない
8.6の手計算で、私たちのattentionは「照応(それ→魚)」をうまく捉えました。しかし、文の中には同時に何種類もの関係が存在します。
- 照応: 「それ」→「魚」
- 主語と述語: 「食べた」→「猫」
- 修飾: 「白い」→「猫」
- 直前・直後という位置関係: 「は」→「猫」
1組の
そこで、attentionを複数個、並列に走らせます。それぞれが自分専用の
8.9.2 仕組み: 分割 → 並列attention → 連結 → 混合
ヘッド数を
読み下し: ヘッド
読み下し: 全ヘッドの出力(
次元の決め方には定番の流儀があります。各ヘッドの次元を
8.9.3 ミニ数値例: 2ヘッドで
私たちのおもちゃの設定(
- ヘッド1: 8.6で計算したものをそのまま使います(照応係)。出力は
、その「それ」の行は でした - ヘッド2: 別の
を持つ「直前の単語を見る係」だとします。同じ手順で計算した結果、attention重みと出力が次のようになったとしましょう(手順は8.6とまったく同じなので結果だけ示します)
| ヘッド2の重み | 猫 | 魚 | それ |
|---|---|---|---|
| 猫 | 0.90 | 0.05 | 0.05 |
| 魚 | 0.80 | 0.10 | 0.10 |
| それ | 0.10 | 0.80 | 0.10 |
各行とも「1つ前のトークン」に重みが集まっています(先頭の猫は前がないので自分を見ています)。ヘッド2のバリューを
読み下し: ヘッド2における「それ」の出力は、主に直前の単語(魚)のバリューを反映した
NOTE
実は「直前の単語を見る」という芸当は、いまの入力
連結: 「それ」の行について、ヘッド1の出力とヘッド2の出力を横につなぎます。
読み下し: 2次元+2次元で4次元に戻る。前半は照応係のメモ、後半は位置係のメモ。
混合: 最後に
読み下し: 連結した4次元ベクトルを、最終出力の4次元へ混ぜ直す行列。これも学習されるパラメータ(値は説明用)。
この
- 第1成分:
- 第2成分:
、第3成分: 、第4成分:
つまり
実際のモデルでヘッドたちがどんな係になるかは、もちろん学習まかせです。訓練済みモデルを調べると、「直前のトークンを見るヘッド」「文頭を見るヘッド」「照応を解決するヘッド」「構文的な依存関係を追うヘッド」などが自然に分化していることが観察されています。
8.10 因果マスク — 未来をカンニングさせない
8.10.1 なぜ未来を見てはいけないのか
第7章で学んだとおり、言語モデルの仕事は「これまでの単語列から次の単語を予測する」ことです。「猫は魚が」まで読んで「好き」を当てる。このとき、モデルが「好き」自身を見てよいはずがありません。答えを見てから答えるのはカンニングです。
ところが、8.5のattentionは全ペアのスコアを計算します。つまり位置3のトークンが位置5のトークン(未来)を見ることも自由にできてしまいます。文章の途中まで読んで次を予測する訓練(詳細は第10章)では、これは致命的です。カンニングで100点を取る学習には何の価値もありません。
そこで、各トークンは自分と自分より前(過去)しか見てはいけないという制約を加えます。時間的な原因→結果の向きを守らせることから、これを 因果マスク(causal mask) と呼びます。マスク=目隠しです。
8.10.2 仕組み: を足すと softmax が 0 を返す
「見てはいけない」を数式でどう表現するか。ここにうまい仕掛けがあります。見てはいけないペアのスコアに
読み下し: スケール済みスコアにマスク行列
マスク行列
| 猫(位置1) | 魚(位置2) | それ(位置3) | |
|---|---|---|---|
| 猫(位置1) | 0 | ||
| 魚(位置2) | 0 | 0 | |
| それ(位置3) | 0 | 0 | 0 |
なぜ
読み下し:
つまり、
8.10.3 数値例: 8.6の計算にマスクをかける
8.6で求めたスケール済みスコアにマスクを足します。
読み下し: 1行目(猫)は未来である魚・「それ」への欄が
行ごとにsoftmaxをかけます。
- 猫の行
: 分子は 、分母16.92。重みは 。先頭トークンは過去がないので、自分だけを見る - 魚の行
: 分子は 。重みは 。猫と自分を半々で見る - 「それ」の行
: マスクなしと同じ
マスク後の重み行列をヒートマップ風に示します。
| 猫 | 魚 | それ | |
|---|---|---|---|
| 猫 | 1.000 ████ | 0 | 0 |
| 魚 | 0.500 ▓▓ | 0.500 ▓▓ | 0 |
| それ | 0.053 | 0.894 ████ | 0.053 |
右上の三角形がきれいに0になっています。そして大事なことに、「それ」→「魚」の照応は無傷です。魚は「それ」より過去にあるので、マスクは照応の解決を妨げません。過去から情報を集めるのは、カンニングではなく読解だからです。
このマスク付きself-attentionには、実はもう一つ大きな利点があります。訓練のとき、1つの文の全位置の「次単語予測」を同時に採点できるのです(位置1の予測も位置2の予測も、それぞれカンニングなしであることが保証されているため)。この仕組みが訓練をどれほど効率化するかは、第10章でじっくり見ます。
なお、マスクを使うかどうかは用途で決まります。翻訳の入力文を読む側(エンコーダ)のように「文全体を一度に見てよい」場面ではマスクなしのself-attentionを使い、文章を生成する側(デコーダ、そしてGPT)ではマスク付きを使います。この使い分けは第9章と第11章で登場します。
この章のまとめ
- 単語の意味は文脈で決まる。attentionは「各トークンが、関連の深いトークンから情報を集めて自分のベクトルを作り直す」仕組みであり、出力は文脈化された埋め込みである
- 素朴版(埋め込み同士の内積→softmax→重み付き平均)でも骨格は動くが、①自分ばかり見る ②単語の類似しか測れない ③探す目印と渡す中身が同じ ④学習できない、という弱点がある
- Q(クエリ=探す顔)/ K(キー=探される顔)/ V(バリュー=渡す中身) の3役に分けることで解決する。3つの顔は学習される行列
による変換で作られ、「どこに注目すべきか」自体がデータから学習される - 内積は次元
が大きいほど値がぶれ、softmaxが尖りすぎて勾配が消える。 で割ることでスコアの大きさを整える - 完成形は
。行列形式は全トークン・全ペアの同時計算を意味し、RNNの逐次処理と違ってGPUで並列化でき、どんなに離れたトークン同士も距離1で直接つながる - 3トークンの完全手計算で、「それ」が「魚」に89%の重みを向け、出力ベクトルがほぼ魚のバリューになる(照応の解決)ことを確認した
- Multi-Head Attentionは、小さなattention(ヘッド)を複数並列に走らせ、照応係・位置係など異なる観点を同時に持つ仕組み。各ヘッドの出力を連結し
で混ぜる - 因果マスクは、未来のトークンへのスコアに
を足し、 を利用してattention重みを厳密に0にする。次単語予測のカンニングを防ぎ、全位置の同時訓練を可能にする
次の章へ
attentionという中核部分は手に入りました。しかし、attentionだけでは文章の語順すら区別できませんし(実は本章の計算は、トークンの順番を入れ替えても各トークンの結果が変わりません。次章の冒頭で確かめます)、深く積み重ねるための工夫も必要です。次章では、位置エンコーディング・残差接続・LayerNorm・FFNという名脇役たちを揃え、attentionと組み合わせてTransformerの全体像を完成させます。第7章で予告した「エンコーダとデコーダをつなぐattentionの正体」も明かされます。