GPTではなぜ位置エンコーディングが大切なのか?

こんにちは。ゆうせいです。

GPTの内部構造を説明していると、位置エンコーディングのところで質問が集中します。

「単語の順番なんて、入力した順に並んでいるのだから、わざわざ教える必要があるのですか」

とても自然な疑問です。しかし答えは、教えなければ順番は完全に失われる、です。この記事では、なぜそうなるのかを数式で確認し、GPTがどう対処しているかを解説します。

結論

自己注意機構には、順序を区別する能力がありません。位置情報を与えなければ、「犬が猫を追いかけた」と「猫が犬を追いかけた」が、まったく同じ内部表現になります。

これは実装上の手抜きではなく、数学的な性質です。注意機構は入力の並べ替えに対して等価な出力を返すため、順序という情報がそもそも計算に入りません。

したがって、位置情報を外から明示的に注入する必要があります。これが位置エンコーディングです。

なぜ順序が失われるのか

自己注意の計算式

前提として、自己注意の計算を確認します。

\text{Attention}(Q, K, V) = \text{softmax}\left( \frac{QK^{T}}{\sqrt{d_k}} \right) V

ここで Q K V は、入力 X に重み行列を掛けたものです。

Q = XW^{Q}, \quad K = XW^{K}, \quad V = XW^{V}

この式のどこにも、行の番号は登場しません。1行目だから特別扱いする、という処理がありません。

並べ替えに対する性質

入力の行を並べ替える操作を、置換行列 P で表します。このとき、次の関係が成り立ちます。

\text{Attention}(PX) = P \cdot \text{Attention}(X)

これを置換等価性といいます。英語では permutation equivariance です。

意味するところは明快です。入力を並べ替えると、出力も同じように並べ替わるだけで、各トークンに対応する結果の中身は変わりません。

言い換えると、注意機構にとって入力は「順序のある列」ではなく「順序のない集合」です。

数値で確認する

実際に計算してみます。次元を2に簡略化し、トークンを2つとします。

x_1 = (1, 0), \quad x_2 = (0, 1)

重み行列はすべて単位行列とします。つまり Q = K = V = X です。

まず、x_1 が1番目、x_2 が2番目の場合を計算します。

内積を計算します。

x_1 \cdot x_1 = 1, \quad x_1 \cdot x_2 = 0

スケーリングします。d_k = 2 なので \sqrt{d_k} \approx 1.414 です。

\frac{1}{1.414} \approx 0.707, \quad \frac{0}{1.414} = 0

x_1 の行についてSoftmaxを計算します。

\frac{e^{0.707}}{e^{0.707} + e^{0}} = \frac{2.028}{2.028 + 1} = \frac{2.028}{3.028} \approx 0.670

もう一方は 1 - 0.670 = 0.330 です。

したがって x_1 に対する出力は次のようになります。

0.670 \times (1, 0) + 0.330 \times (0, 1) = (0.670, 0.330)

次に、順序を入れ替えます。x_2 が1番目、x_1 が2番目です。

x_1 は2行目になります。内積の値は変わりません。

x_1 \cdot x_2 = 0, \quad x_1 \cdot x_1 = 1

スケーリングとSoftmaxの結果は次の通りです。

(0.330, 0.670)

これを対応するベクトルに掛けます。1番目は x_2 、2番目は x_1 です。

0.330 \times (0, 1) + 0.670 \times (1, 0) = (0.670, 0.330)

完全に一致しました。順序を入れ替えても、x_1 が受け取る情報はまったく同じです。

これが、位置エンコーディングが必要な理由です。

他の構造との比較

なぜTransformerだけがこの問題を抱えるのか。他の構造と比べると分かります。

構造位置情報の扱い
RNN順番に処理するため、構造そのものに順序が含まれる
CNN局所的な窓を滑らせるため、隣接関係が保たれる
Transformer全トークンを同時に処理するため、順序が入らない

RNNは、1番目を処理してから2番目に進みます。順序は処理手順そのものです。

Transformerは、この逐次処理をやめたことで並列計算を可能にしました。学習速度は劇的に上がりましたが、代償として順序の情報を失いました。位置エンコーディングは、この代償を埋めるための仕組みです。

得たものと失ったものが、はっきり対応しています。

GPTがどう解決しているか

位置埋め込みを足す

GPT-2では、トークン埋め込みに位置埋め込みを加算します。

h_0 = W_e[x] + W_p[\text{pos}]

ここで W_e はトークン埋め込み行列、W_p は位置埋め込み行列です。

GPT-2のsmallモデルでは、次の形になります。

W_p \in \mathbb{R}^{1024 \times 768}

1024は扱える最大の系列長、768は埋め込みの次元です。位置ごとに768次元のベクトルが用意され、学習によって値が決まります。

学習型と固定型

位置エンコーディングには、大きく二つの方式があります。

元のTransformer論文では、三角関数を使った固定の値が提案されました。

PE_{(pos, 2i)} = \sin\left( \frac{pos}{10000^{2i/d}} \right)

PE_{(pos, 2i+1)} = \cos\left( \frac{pos}{10000^{2i/d}} \right)

次元によって周期が変わる波を重ねる形です。周期の異なる時計の針を並べるイメージで、複数の針の組み合わせから位置が一意に定まります。

一方、GPT-2は学習型を採用しました。初期値はランダムで、他のパラメータと同じように更新されます。

方式利点欠点
三角関数による固定学習不要。訓練時より長い系列にも外挿できる可能性があるデータに合わせた最適化ができない
学習型データに適した表現を獲得できる学習時の最大長を超えると使えない

GPT-2の文脈長が1024に固定されているのは、この学習型を採用した結果です。1025番目の位置に対応するベクトルが、そもそも存在しません。

なぜ足すのか、つなげないのか

ここでよく出る質問があります。位置情報を加算すると、単語の情報が壊れるのではないか、という疑問です。

理屈としては、連結する方法も考えられます。

h_0 = [, W_e[x] ; ; ; W_p[\text{pos}] ,]

しかし、この方法は採用されていません。理由は二つあります。

一つ目は、次元の消費です。連結すると、位置情報に割り当てた分だけ、単語の意味に使える次元が減ります。全体の次元数は計算量に直結するため、増やせません。

二つ目は、重ね合わせが成立するからです。以前の記事で扱った通り、高次元空間では多数の情報を重ねて保持できます。768次元の空間には、意味の情報と位置の情報を、互いに干渉の小さい方向として同居させる余地があります。

実際、学習後のモデルを調べると、位置情報が特定の少数の次元に偏って保持されている様子が観測されています。モデルは、加算されても分離できるような表現を、自分で見つけ出しているといえます。

因果マスクとの違い

もう一つ、混同されやすい点を整理します。

GPTは因果マスクを使い、各トークンが未来のトークンを見られないようにしています。

\text{mask}_{ij} = \begin{cases} 0 & (j \leq i) \\ -\infty & (j > i) \end{cases}

このマスクは、位置情報の代わりになるでしょうか。

部分的にはなります。i 番目のトークンは i 個のトークンしか見えないため、見える個数から自分の位置をある程度推定できます。実際、位置エンコーディングを完全に取り除いたデコーダ型モデルでも、ある程度の性能が出るという研究報告があります。

しかし、これは十分ではありません。理由は、見える範囲の中での順序が区別できないためです。5番目のトークンから見て、1番目と3番目のどちらが先かという情報は、マスクだけでは得られません。

因果マスクは方向を与えますが、距離は与えません。両方が必要です。

現在の主流はRoPE

GPT-2以降、位置の扱いは進化しています。現在多くのモデルで使われているのが、回転位置埋め込み(RoPE)です。

考え方は、埋め込みに足すのではなく、Q K を位置に応じて回転させるというものです。

位置 m に対する回転行列を R_m とすると、内積は次の性質を持ちます。

\langle R_m q, R_n k \rangle = g(q, k, m-n)

結果が m - n という差だけに依存します。つまり、絶対的な位置ではなく相対的な距離が自然に表現されます。

2次元の場合、回転行列は次の形です。

R_{\theta} = \begin{pmatrix} \cos\theta & -\sin\theta \\ \sin\theta & \cos\theta \end{pmatrix}

実際には、768次元を2次元ずつの組に分け、それぞれ異なる角速度で回転させます。

この方式の利点は、学習時より長い系列にも比較的うまく対応できる点です。文脈長が数万トークンに達する現在のモデルで、この性質は重要になります。

研修での教え方

このテーマを扱う場合、次の順序を推奨します。

  1. 「犬が猫を追いかけた」と「猫が犬を追いかけた」を板書し、違いを確認させる
  2. 自己注意の式を示し、行番号がどこにも現れないことを指摘する
  3. 上で示した数値例を、受講者に手で計算させる
  4. 位置埋め込みの加算を導入する
  5. 因果マスクとの違いを整理する
  6. 学習型の限界として、文脈長の制約に触れる

所要時間は、演習を含めて60分程度です。3番の手計算が最も効きます。自分で計算して一致することを確認すると、納得の度合いが変わります。

受講者からよく出る質問と回答例を挙げます。

質問。足したら単語の意味が変わってしまいませんか。 回答。変わります。ただし、モデルは変わった状態を前提に学習しているため、問題になりません。むしろ、意味と位置を混ぜた状態から必要な情報を取り出す方法を、モデル自身が獲得しています。

質問。位置埋め込みは全ての層で足すのですか。 回答。GPT-2では最初の一回だけです。以降の層は、その情報が残っていることを前提に処理します。RoPEの場合は各層のQとKに適用されるため、この点が異なります。

理解度を確認する問い

  • 置換等価性とは、どのような性質ですか。数式で説明してください
  • RNNとTransformerで、位置情報の扱いはどう違いますか
  • 位置情報を連結ではなく加算する理由を、二つ挙げてください
  • 因果マスクだけでは不十分なのはなぜですか
  • GPT-2の文脈長が1024に制限されている理由を説明してください

まとめと次の学習ステップ

自己注意機構は、入力を集合として扱います。順序の情報は、計算式のどこにも入りません。したがって、位置情報は外から明示的に与える必要があります。

GPT-2は、位置ごとに学習された768次元のベクトルを、トークン埋め込みに加算します。単純ですが、これで順序が区別できるようになります。

並列計算を得るために逐次処理を捨て、その代償として位置エンコーディングが必要になった。この因果関係を押さえておくと、設計の意図が見えてきます。

次に学ぶなら、文脈長の拡張手法に進むとよいでしょう。学習時より長い系列をどう扱うかという問題は、位置エンコーディングの設計と直結しています。RoPEの周波数を調整する手法や、位置の補間による拡張が知られています。

あわせて、相対位置表現の系譜も押さえておくと理解が深まります。絶対位置から相対位置へ、そして回転による表現へ。この流れは、注意機構が本当に必要としていた情報が何だったかを示しています。

セイ・コンサルティング・グループでは新人エンジニア研修のアシスタント講師を募集しています。

投稿者プロフィール

山崎講師
山崎講師代表取締役
セイ・コンサルティング・グループ株式会社代表取締役。
岐阜県出身。
海外放浪の末、2000年創業、2004年会社設立。
IT企業向け人材育成研修歴業界歴20年以上。
すべての無駄を省いた費用対効果の高い「筋肉質」な研修を提供します!
この記事に間違い等ありましたらぜひお知らせください。

学生時代は趣味と実益を兼ねてリゾートバイトにいそしむ。長野県白馬村に始まり、志賀高原でのスキーインストラクター、沖縄石垣島、北海道トマム。高じてオーストラリアのゴールドコーストでツアーガイドなど。現在は野菜作りにはまっている。