Tech カテゴリのイメージ

Multi-Head Attentionとは?同じ文脈を複数の重みで読む

Self-Attentionの計算を一度だけ行うと、各トークンから見た「どこをどれだけ参照するか」は一組の重みになる。Multi-Head Attentionは、Query・Key・Valueを別々の学習済み行列で複数組へ変換し、Attentionを並行して計算する。最後に各組の結果を連結し、もう一度線形変換して次の層へ渡す仕組みだ。

「ヘッドが8個なら、同じ計算を8回繰り返しているだけでは?」という疑問が出る。違いは各ヘッドに使う射影行列だ。同じ入力でも別の行列を通るため、参照先の重みや集める情報が一致する必要はない。ただし「このヘッドは必ず文法、このヘッドは必ず意味を担当する」と事前に役割が固定されるわけでもない。

1つの入力から、ヘッドごとに異なるQ・K・Vを作る

原論文『Attention Is All You Need』では、入力のQuery・Key・Valueに対し、ヘッドごとに異なる学習済み線形射影を適用する。ヘッド ii の計算は次の形だ。

head⁡i=Attention⁡(QWiQ,KWiK,VWiV)\operatorname{head}_i=\operatorname{Attention}(QW_i^Q,KW_i^K,VW_i^V)

各ヘッドが同じトークン列を受け取っても、WiQW_i^Q、WiKW_i^K、WiVW_i^V が違えば、照合に使う表現も結果も変わる。各ヘッドの出力を連結し、出力用の学習済み行列 WOW^O を掛ける。

MultiHead⁡(Q,K,V)=Concat⁡(head⁡1,…,head⁡h)WO\operatorname{MultiHead}(Q,K,V)=\operatorname{Concat}(\operatorname{head}_1,\ldots,\operatorname{head}_h)W^O

連結したまま終わりではない。最後の射影は、複数ヘッドから集めた情報をモデルが使う次元へ戻し、混ぜ合わせる役割を持つ。

2ヘッドの重みが違うと、集める値も変わる

次はAttentionの中身だけを1次元・2位置へ縮めた説明用の例だ。各ヘッドへ入るQueryを 1 とし、Keyから得たスコアが第1ヘッドで [2, 0]、第2ヘッドで [0, 2] になるように置く。両ヘッドのValueは説明のため [10, 0] とする。実際の射影行列を学習するコードではなく、射影後にスコアが異なると何が起きるかを見る計算だ。

import math
for scores in ([2.0, 0.0], [0.0, 2.0]):
values = [10.0, 0.0]
unnormalized = [math.exp(score) for score in scores]
total = sum(unnormalized)
weights = [value / total for value in unnormalized]
output = sum(weight * value for weight, value in zip(weights, values))
print([round(weight, 3) for weight in weights], round(output, 3))

実行結果:

[0.881, 0.119] 8.808
[0.119, 0.881] 1.192

第1ヘッドは最初の位置へ約88%の重みを置き、第2ヘッドは2番目の位置へ約88%を置く。同じValueの並びでも出力は約8.808と約1.192に分かれる。完全なMulti-Head Attentionなら、この2つを連結したあと、さらに出力射影を適用する。例の数字は仕組みを示す手作りの値で、実在するLLMのAttention重みではない。

ヘッドを増やせば単純に性能が上がるわけではない

原論文の基本モデルでは、モデル全体の幅512を8ヘッドに分け、各ヘッドのKey・Valueを64次元にした。単一ヘッドを8個、幅512のまま複製したわけではない。幅を分けることで、原論文は全体の計算量を幅512の単一ヘッドと同程度に保ったと説明している。

ヘッド数は設計上の選択であり、多ければ必ず良いとは言えない。各ヘッドの次元、モデル全体の幅、学習済み射影、利用するAttentionの方式も結果に関わる。PyTorchの MultiheadAttention は embed_dim と num_heads を指定し、埋め込み次元をヘッド数で分ける実装だ。別方式のモデルまで、すべてこの分け方だと考えないほうがよい。

Self-Attentionや因果マスクとの関係

Self-Attentionは「同じ系列からQuery・Key・Valueを作り、系列内を参照する」という入力間の関係を表す。Multi-Headは、そのAttentionを複数の射影で並行に行う構成を表す。両者は対立する方式ではない。Transformerのデコーダーでは、複数ヘッドのSelf-Attentionに因果マスクをかけ、未来の位置を参照させない。

KV Cacheで保存するKeyとValueも、Attentionの層とヘッドに対応する。ここで保存されるのはトークンの文字列ではなく、次の位置の計算で再利用する数値表現だ。

Multi-Head Attentionは、同じ文脈を単一の重み付けだけで集約しないための構成だ。複数の学習済み射影による出力を作り、連結と出力射影で組み合わせる。各ヘッドの役割を人が最初から指定する仕組みではないことも、併せて押さえておきたい。

参照資料

生成AI・機械学習講座の一覧へ