一文要約: トークン埋め込みは意味を運び、Positional Encoding は位置を運びます。Transformer が何かを理解する前に、その両方が必要です。
5.1 位置がなぜ重要なのか
前章で、次のパイプラインを手にしました。
raw text -> token IDs -> embeddings -> Transformer blocks
埋め込みは揃いました。しかし、その中には静かに潜んだ問題があります。
5.1.1 決定的なギャップ
通しの例から、2つの文を考えてみましょう。
The agent tagged the reviewer.
The reviewer tagged the agent.
どちらの文も同じトークンを含んでいます。もしモデルにトークン埋め込みだけを渡すと、「agent」の表現はどちらの文でも同一です。同じベクトル、同じ数値です。「reviewer」も同じ、「tagged」も同じです。
モデルから見れば、この2つの文はまったく同じに見えます。しかし意味は決して同じではありません。
このギャップは「位置」の欠落です。Transformer はすべてのトークンを並列に処理します。これは効率的にスケールする理由のひとつです。しかしその並列処理こそが、追加の助けがなければモデルが入力を順序のないトークンの袋として扱ってしまう理由でもあります。
5.1.2 Positional Encoding が解決する3つのこと
Positional Encoding は、関連する3つの問題を解きます。
-
絶対位置: モデルは、このトークンが先頭、これが15番目、これがシーケンスの末尾、ということを学びます。
-
相対距離: 「agent」と「tagged」は隣接していて、「agent」と「reviewer」は1トークンだけ離れている。この間隔は文法的・意味的な情報を運びます。
-
学習可能なパターン: エンコーディングが一貫した式に従うため、モデルは訓練中に見なかった、より長いシーケンスにも位置のルールを一般化できます。
5.2 単純だが壊れているアイデア: 生の整数
Transformer が実際に何をしているかを説明する前に、最も素朴なアプローチを見て、なぜそれがうまくいかないのかを理解しておきましょう。
5.2.1 整数の位置番号を足し込む
最も単純なアイデアは、各位置に番号を割り当て、その位置のトークン埋め込みに足し込むことです。
おもちゃサイズの d_model = 4 で、トークン ["The", "agent", "tagged", "the", "reviewer", "."] の例を見てみましょう。
埋め込みベクトル(意味内容):
| token | dim0 | dim1 | dim2 | dim3 |
|---|---|---|---|---|
| The | 0.62 | -0.51 | 0.09 | 0.85 |
| agent | 0.15 | 0.73 | -0.38 | 0.46 |
| tagged | 0.07 | 0.31 | -0.44 | 0.12 |
| the | 0.43 | 0.18 | 0.66 | -0.30 |
| reviewer | 1.30 | -0.72 | 0.55 | 0.41 |
| . | 0.98 | 0.03 | -0.11 | 0.74 |
整数位置ベクトル:
| position | dim0 | dim1 | dim2 | dim3 |
|---|---|---|---|---|
| 1 | 1 | 1 | 1 | 1 |
| 2 | 2 | 2 | 2 | 2 |
| 3 | 3 | 3 | 3 | 3 |
| 4 | 4 | 4 | 4 | 4 |
| 5 | 5 | 5 | 5 | 5 |
| 6 | 6 | 6 | 6 | 6 |
足し合わせた後:
| token | dim0 | dim1 | dim2 | dim3 |
|---|---|---|---|---|
| The | 0.62+1 | -0.51+1 | 0.09+1 | 0.85+1 |
| agent | 0.15+2 | 0.73+2 | -0.38+2 | 0.46+2 |
| ... | ... | ... | ... | ... |
5.2.2 なぜ壊れるのか
実際に問題は2つあります。
-
値が無限に大きくなる:
pos = 1000では各次元に1000が加算されます。埋め込みの値はだいたいゼロ近辺ですが、突然あるトークンだけが千ほどシフトします。勾配の流れが破綻し、訓練が不安定になります。 -
学習可能な構造がない: 1, 2, 3, 4 は線形に増えるだけで、モデルが一般化できるパターンがありません。モデルはより長いシーケンスへ外挿することも、「2位置離れている」が一貫した意味を持つことを学ぶこともできません。
オリジナルの Transformer 論文には、もっと原理的な何かが必要だったのです。
5.3 Transformer の答え: Sinusoidal Encoding
5.3.1 中心となるアイデア
オリジナルの Transformer は、異なる周波数の sin・cos 波 を使って位置ベクトルを構成します。私が覚え方として使っているのは、各位置が波を積み重ねたバーコードを持つ、というイメージです。低周波の波は大まかな位置を、高周波の波は近くの位置どうしの細かい距離をエンコードします。
式は以下の通りです。
even dimensions: PE(pos, 2i) = sin(pos / 10000^(2i / d_model))
odd dimensions: PE(pos, 2i+1) = cos(pos / 10000^(2i / d_model))
式を見て怯まないでください。中身は2つのアイデアだけです。
- 偶数次元は sin、奇数次元は cos を使う。
- 次元のペアごとに異なる周波数を使う。それを制御するのが
2i/d_modelの指数です。
5.3.2 波としての可視化
シーケンスに沿って位置エンコーディングをプロットすると、各次元はひとつの波を描きます。低周波の次元は位置が変わってもゆっくり変化します。遅い時計のようなものです。高周波の次元は素早く振動します。速い時計です。たくさんの時計を並べると、シーケンスの各位置がそれぞれ固有の読み取りの組み合わせを持つことになります。これが私たちの欲しいものです。
5.3.3 具体的な数値
最初の4次元について、6トークンのシーケンス(pos = 0 から 5)の実際の値はこうなります。
| token | pos | dim0 (sin) | dim1 (cos) | dim2 (sin) | dim3 (cos) |
|---|---|---|---|---|---|
| The | 0 | 0.00 | 1.00 | 0.00 | 1.00 |
| agent | 1 | 0.84 | 0.54 | 0.68 | 0.73 |
| tagged | 2 | 0.90 | -0.41 | 0.99 | 0.07 |
| the | 3 | 0.14 | -0.98 | 0.77 | -0.62 |
| reviewer | 4 | -0.75 | -0.65 | 0.14 | -0.98 |
| . | 5 | -0.95 | 0.28 | -0.57 | -0.82 |
注: 位置はゼロ始まり(
pos = 0, 1, 2, ...)です。pos = 0ではsin(0) = 0およびcos(0) = 1です。
ここから読み取れることは:
- すべての値が
[-1, 1]の範囲に収まっています。sin と cos の自然な範囲です。長い位置でも値が爆発しません。 - 各行は唯一無二です。各位置が固有の指紋を持ちます。
- パターンは滑らかに変化します。近い位置どうしは数値的にも近い値です。
5.3.4 なぜ sin と cos なのか
論文の著者が sin/cos を選んだ理由は3つあります。
-
値が有界: 常に
[-1, 1]の中にあります。pos = 10,000でも値は爆発しません。 -
理論的には外挿可能: 短いシーケンスで訓練したモデルが、原理的には、より長いシーケンスへ一般化できます。波のパターンが予測可能に続くからです。
-
線形変換による相対位置: 位置
pos + kのエンコーディングが、位置posのエンコーディングの線形関数として表現できる、という数学的な性質があります。これにより、モデルは固定オフセットのトークンに注意を向けることを学習できます。
後の研究で、Sinusoidal Encoding の外挿能力は理論ほど実用上は強くないことが分かってきました。RoPE や ALiBi といった新しい方式は、長い文脈をより上手く扱えます。これらは第25章で扱います。今のところは、Sinusoidal Encoding が「なぜ位置エンコーディングが必要か、どう動くか」を理解するうえで最も明快です。
5.4 埋め込み + 位置 = 入力
ここで、足し合わせのステップ全体を見てみましょう。
5.4.1 ベクトルの加算
3つの行列、いずれも形は [seq_len, d_model] です。
埋め込み行列(意味内容):
The: [0.62, -0.51, 0.09, 0.85]
agent: [0.15, 0.73, -0.38, 0.46]
tagged: [0.07, 0.31, -0.44, 0.12]
...
位置行列(位置):
pos 0: [0.00, 1.00, 0.00, 1.00]
pos 1: [0.84, 0.54, 0.68, 0.73]
pos 2: [0.90, -0.41, 0.99, 0.07]
...
入力埋め込み(両者の和):
The (pos 0): [0.62+0.00, -0.51+1.00, 0.09+0.00, 0.85+1.00]
agent (pos 1): [0.15+0.84, 0.73+0.54, -0.38+0.68, 0.46+0.73]
...
肝心なのはこの観察です。同じトークンが2つの異なる位置に現れた場合、その埋め込みベクトルは同一でも位置ベクトルは異なるので、合算した入力は異なります。これでモデルは、「The agent tagged the reviewer」と「The reviewer tagged the agent」を区別できるようになります。たとえ同じトークン集合を共有していても、です。
5.4.2 幾何学的な直感
2次元のスケッチでは、ベクトルの加算は平行四辺形の法則に従います。
embedding vector = [1, 3] (青い矢印: 意味の方向)
position vector = [2, 1] (赤い矢印: 位置によるシフト)
input vector = [3, 4] (結果: 平行四辺形の対角線)
得られたベクトルは、向きと大きさの中に両方の情報を符号化して持ちます。768次元や4096次元の世界では、この合成表現が破綻せずにいられる余地ははるかに大きくなります。
5.4.3 相対距離が効いてくる
多くのタスクで、モデルは絶対位置だけでなく相対距離を気にします。「pull」が「request」のすぐ前に来ているかどうかは大事な情報です。Sinusoidal の方式はその構造の一部を数学的に保ち、学習型の位置方式は経験的に保ちます。第25章で各アプローチの詳細を扱います。
Positional Encoding はもうひとつ深い曖昧さも解いてくれます。同じトークンが、文中の位置によってまったく別の意味を運ぶことがあるのです。review という単語を考えてみましょう。
- 「Submit a review」 では、
reviewは名詞であり、具体的な成果物(PR レビュー、コードレビュー文書)を指します。 - 「Review the changes」 では、
reviewは動詞であり、取るべき行動を表しています。
トークンは同じです。トークン埋め込みも同じです。しかし合成された入力ベクトル(埋め込み + 位置)は異なり、Attention が読み取る周囲の文脈も異なります。モデルはこれらの意味の違いをトークン単独からではなく、その位置と近傍から学んで分けられるようになります。
これこそが Positional Encoding が重要な核心の理由です。これがなければ、モデルには順序のないトークンの袋しか見えず、こうした曖昧さの多くは見えないままになってしまいます。
5.5 訓練: 何が学習され、何が学習されないか
5.5.1 固定エンコーディング 対 学習可能パラメータ
オリジナルの Transformer には重要な非対称性があります。
-
埋め込み行列: 学習可能なパラメータです。訓練ステップごとに勾配が埋め込みテーブルを通って流れ、トークンベクトルを更新します。モデルは意味的に近いトークンを埋め込み空間内で互いに近くに配置することを学びます。
-
位置行列(Sinusoidal 版): 固定です。パラメータではありません。式から一度だけ計算され、以降は更新されません。勾配も流れません。
訓練中、モデルはベクトルに埋め込まれた位置信号をどう解釈するかは学びますが、信号そのものは変えません。
BERT を含む一部のモデルでは、学習型の位置埋め込みを使います。位置行列がトークン埋め込みテーブルと同様にパラメータとなり、勾配降下で更新されます。トレードオフとして、学習型の埋め込みは訓練時の文脈長を超えるとうまく一般化しないことが多く、Sinusoidal の方は原理的には外挿できる、という違いがあります。
5.5.2 アーキテクチャ内のどこにいるか
モデル全体の流れは次のようになります。
raw text
|
| tokenization
v
token IDs
|
| embedding lookup
v
embedding matrix [seq_len, d_model]
|
| + positional encoding [seq_len, d_model]
v
input embeddings [seq_len, d_model]
|
| feed into Transformer blocks
v
...
Positional Encoding は最初の Transformer ブロックの前で行われます。入力の前処理の一部であって、ブロックの内部にあるものではありません。
5.6 なぜ連結ではなく加算なのか
この質問は、私がこの章を教えるたびに必ず出てきます。直感を言葉にしておく価値があります。
5.6.1 連結 vs. 加算
連結 (Concatenation):
- 埋め込みベクトルの後ろに位置ベクトルをつなげる。
- 結果:
[embedding | position]── 幅が2倍のベクトル。 - 情報の分離がきれいに保たれる。
- 欠点: ベクトル幅が2倍になる。後段のすべての行列が
2 × d_modelの特徴を扱う必要があり、パラメータ数と計算コストがそれに応じて増える。
加算 (Addition):
- 埋め込みと位置を要素ごとに足す。
- 結果: 同じ形
[d_model]── 次元は変わらない。 - 欠点: 2つの信号が同じ次元に混ざる。
5.6.2 なぜ加算で機能するのか
その正当化は、高次元空間は驚くほど広い、というものです。768次元や4096次元の中では、トークンの意味内容と位置信号は、ほぼ直交する部分空間を占めることができます。ネットワークには加算後にそれらをほどく十分な容量があるのです。
ホワイトボードを2人のエンジニアが各自持つのではなく、共有していると考えてみてください。ぐちゃぐちゃに聞こえますが、ボードが十分に大きく、人が整理整頓されていれば、問題なく機能します。しかも2枚目のホワイトボードのコストを節約できます。
経験的にも、加算はうまく動きます。アーキテクチャはよりシンプルで、パラメータ数も増えません。良い工学的トレードオフです。
5.7 章のまとめ
5.7.1 重要な概念
| 概念 | 意味 |
|---|---|
| Positional Encoding | 各トークン埋め込みに加算される、シーケンス内の位置を符号化したベクトル |
| Sinusoidal Encoding | 複数周波数の sin/cos 波を使って位置ベクトルを生成する方式 |
| 加算 | embedding + position = input embedding、形は変わらず、次元数も変化しない |
| 固定 vs. 学習型 | Sinusoidal は固定。一部のモデル(BERT など)は学習型の位置パラメータを使う |
| 相対位置 | モデルは絶対インデックスだけでなく、距離の解釈を学べる |
5.7.2 データの流れ
Embedding [seq_len, d_model] <- 意味内容
+
Position [seq_len, d_model] <- sinusoidal 位置エンコーディング
=
Input [seq_len, d_model] <- 最初の Transformer ブロックへ供給
5.7.3 中心となる学び
Positional Encoding は Transformer の「位置盲」を解決します。各トークン埋め込みに位置ベクトルを足すことで、モデルは「The agent tagged the reviewer」と「The reviewer tagged the agent」── 同じトークン、異なる意味、異なる位置ベクトル ── を区別できるようになります。
章のチェックリスト
この章を終えたあと、あなたは次のことができるはずです。
- Transformer がトークンを順次に処理しないからこそ、明示的な位置情報が必要である理由を説明できる。
- Sinusoidal Encoding を「複数周波数の波で作るバーコード」として描写できる。各位置が sin と cos の値の固有の組み合わせを得る、という形で。
- 式
PE(pos, 2i) = sin(pos / 10000^(2i/d_model))を再現し、その中の2つの主要なアイデアを説明できる。 - なぜ連結ではなく加算が使われるのか、そして実用上のトレードオフが何かを説明できる。
- 固定の Sinusoidal エンコーディング(オリジナル Transformer)と、学習型の位置埋め込み(BERT など)を区別できる。
次章でお会いしましょう
Positional Encoding についてはここまでで十分です。「The agent tagged the reviewer」と「The reviewer tagged the agent」が、すべてのトークンを共有していてもなぜ異なるモデル出力を生むのか ── これを自分の言葉で説明できるなら、この章はあなたの中に染み込んでいます。
Transformer ブロックへの入力はこれで完成です。埋め込みからの意味情報と、Positional Encoding からの位置情報。両方が揃いました。
第6章では、Transformer の内部のいたるところに登場する、小さくて欠かせない数学の道具を2つ紹介します。LayerNorm ── 数値を扱いやすい範囲に保つ仕組み ── と、Softmax ── 生のスコアを確率分布に変える仕組みです。それでは、また次章で。