一文要約: 位置エンコーディングは「Attention の前に絶対ベクトルを加える」から「Attention の内側で Q と K を回転させる」「距離で Attention にペナルティを与える」へと進化し、世代ごとに長いコンテキストと優れた相対位置動作を実現してきました。
25.1 全体像
第5章で 2017 年論文のオリジナルの正弦波エンコーディングに出会いました。512 トークンシーケンスには十分うまく機能しました。それから 2024 年まで早送りすると、プロダクションモデルが日常的に 128k トークンを扱っています。この 7 年間のギャップが、位置情報がモデルにどう流れるかをフィールドに完全に再考させました。
25.1.1 オリジナルスキームの何が問題だったか
正弦波エンコーディングには互いに複合する二つの問題があります。
一つ目は絶対位置です。モデルは特定のスロット番号に結びついたパターンを学びます: 「位置 37 はこんな感じ」。推論時、学習長より長いシーケンスを入力した瞬間、モデルは見たことのない絶対位置に遭遇します。パフォーマンスが崩壊します。
二つ目は注入ポイントです。正弦波は Attention の前に、エンベディングに位置ベクトルを加算します。Q と K がドット積を計算するころには、位置シグナルが重み行列を通じて意味シグナルと線形に混ざっています:
Q = (x + PE_m) × W_Q
K = (x + PE_n) × W_K
Q · K = 意味と位置が絡まるクロス項
ドット積を展開すると四つのクロス項が出てきます。位置とコンテンツが分離できないため、モデルがきれいな相対パターンを学ぶのが難しくなります。
従来の学習済み相対エンコーディング(T5 スタイル)は相対の問題は解決しましたが、KV キャッシュとの互換性を壊しました。相対位置テーブルがシーケンスの成長とともに変わるため、新しいトークンを追加するたびに完全な履歴に対して Attention を再計算する必要があります。
フィールドが問い続けた疑問: 相対位置の動作を持ちながら KV キャッシュを機能させられるか?
25.1.2 主要な 5 つのスキーム
| 手法 | 正式名称 | 代表的なモデル |
|---|---|---|
| 正弦波 | Sine/Cosine Position Embedding | オリジナル Transformer |
| T5 相対 | Learned Relative Embeddings | T5, mT5 |
| RoPE | Rotary Position Embedding | LLaMA, GPT-NeoX, Mistral |
| YaRN | Yet another RoPE extensioN | Code Llama, Qwen |
| ALiBi | Attention with Linear Biases | BLOOM, MPT |
この章では RoPE、ALiBi、YaRN を詳しく扱います。その他は対比として必要な箇所に登場します。
25.2 正弦波: 加算ベースライン
前に進む前に簡単に復習しておきましょう。
25.2.1 式
PE(pos, 2i) = sin(pos / 10000^(2i / d_model))
PE(pos, 2i+1) = cos(pos / 10000^(2i / d_model))
各位置はトークンエンベディングと同じ次元を持つ決定論的なベクトルを受け取ります。モデルはこのベクトルをエンベディングテーブルの参照の前に加算します。
エンベディングベクトル(意味的コンテンツ):
| トークン | 次元 1 | 次元 2 | 次元 3 | 次元 4 |
|---|---|---|---|---|
| "agent" | 0.62 | -0.51 | 0.09 | 0.85 |
| "opened" | 0.07 | 0.23 | -0.40 | 0.11 |
位置ベクトル(スロット情報):
| 位置 | 次元 1 | 次元 2 | 次元 3 | 次元 4 |
|---|---|---|---|---|
| 1 | 0.00 | 1.00 | 0.00 | 1.00 |
| 2 | 0.84 | 0.54 | 0.68 | 0.73 |
| 3 | 0.90 | -0.41 | 0.99 | 0.07 |
Transformer への入力 = エンベディング + 位置ベクトル。
25.2.2 加法方式で相対位置が暗黙になる理由
Attention の前に位置を加算して W_Q と W_K を通すと、相対距離は暗黙的になります。展開したスコアには内容同士、内容と位置、位置と内容の項が現れます。モデルは相対パターンを学習できますが、RoPE や ALiBi のようにスコアへ組み込まれているわけではありません。長さの外挿はチェックポイントと学習条件に依存し、未学習の位置は数学的な失敗ではなく、信頼性が検証されていない範囲です。
初期の GPT モデルに厳格なコンテキスト制限があったのはまさにこの理由からです。学習したものが得られるだけで、それを超えるものはありません。
25.3 RoPE: Rotary Position Embedding
RoPE は 2021 年に蘇剣林(Su Jianlin)によって提案され、デコーダーオンリー LLM の支配的な手法となりました。LLaMA 1、LLaMA 2、Mistral、GPT-NeoX、その他多くのモデルで使用されています。
25.3.1 革命的なアイデア: 加算から回転へ
トークンエンベディングに位置ベクトルを加算する代わりに、RoPE は位置に依存した回転行列を使って Attention の内側で Q と K ベクトルを回転させます。
一文で対比すると:
- 正弦波:
エンベディング + 位置ベクトル → W_Q と W_K で乗算 - RoPE:
W_Q と W_K で乗算 → 位置角度で回転
小さな違いに聞こえますが、その結果は大きいです。
25.3.2 2D の幾何学的直感
2D から始めましょう。平面上に 2 つのベクトル w1 と w2 があります。両方を同じ角度 theta だけ回転させると、相対的な角度は変わりません。ドット積は 2 つのベクトルの間の角度とその大きさにのみ依存するので:
w1 · w2 = |w1| |w2| cos(角度)
両方を同じ theta だけ回転させてもドット積は変わりません。異なる量だけ回転させると、ドット積は回転角度の差に依存する方法で変わります。
これが核心的な幾何学的事実です。位置 m にある Q を角度 m * theta だけ回転させ、位置 n にある K を角度 n * theta だけ回転させると、絶対位置はドット積に (n - m) * theta — 相対距離 — としてのみ現れます。スコア自体は Q と K の内容にも依存します。
2D 回転行列:
[w1'] [cos(theta) -sin(theta)] [w1]
[w2'] = [sin(theta) cos(theta)] [w2]
25.3.3 高次元への拡張
実際のクエリとキーベクトルは head_dim 次元を持ちます(通常 64、128、またはそれ以上)。RoPE はベクトルを head_dim / 2 組の次元ペアに分割し、各ペアを独立に回転させることでこれを処理します:
- 次元 1-2: 角度
m * theta_1 - 次元 3-4: 角度
m * theta_2 - ...
- 次元 (head_dim-1) 〜 head_dim: 角度
m * theta_{head_dim/2}
各ペアは異なる基底周波数を使います:
d=6 ベクトルの場合、基底周波数は theta_1 = 1、theta_2 ≈ 0.0464、theta_3 ≈ 0.00215 ラジアン/位置となるため、回転角は次のようになります:
| 位置 m | ペア 1 (theta=1) | ペア 2 (theta≈0.0464) | ペア 3 (theta≈0.00215) |
|---|---|---|---|
| m=0 | 0.0 | 0.0 | 0.0 |
| m=1 | 1.0 | 0.0464 | 0.00215 |
| m=2 | 2.0 | 0.0928 | 0.00431 |
| m=3 | 3.0 | 0.1392 | 0.00646 |
25.3.4 完全な回転行列
位置 m における d 次元ベクトルに対して、RoPE はブロック対角回転行列 R_m を適用します:
[cos(m*θ₁) -sin(m*θ₁) 0 0 ... 0 0 ]
[sin(m*θ₁) cos(m*θ₁) 0 0 ... 0 0 ]
R_m = [ 0 0 cos(m*θ₂) -sin(m*θ₂) ... 0 0 ]
[ 0 0 sin(m*θ₂) cos(m*θ₂) ... 0 0 ]
[ ... ... ... ... ... ... ... ]
[ 0 0 0 0 ... cos(m*θ_{d/2}) -sin(m*θ_{d/2})]
[ 0 0 0 0 ... sin(m*θ_{d/2}) cos(m*θ_{d/2})]
各 2×2 ブロックは独立した回転です。行列はスパースで適用が効率的です。
25.3.5 相対位置が自動的に現れる理由
ここがエレガントな部分です。q_m を位置 m におけるクエリ、k_n を位置 n におけるキーとします。
RoPE 適用後:
q_m' = R_m * q_mk_n' = R_n * k_n
Attention スコアは:
q_m' · k_n' = (R_m * q_m)ᵀ (R_n * k_n)
= q_mᵀ * R_mᵀ * R_n * k_n
= q_mᵀ * R_{n-m} * k_n
最後のステップは回転行列の性質 を使います。Attention スコアは依然として内容ベクトル q_m と k_n に依存しますが、位置への依存は相対オフセット (n - m) を通じてのみ現れ、絶対位置 m と n には別々に依存しません。相対位置は余分な仕組みなしに数学から自然に現れます。
KV キャッシュも引き続き機能します。なぜなら k_n' は k_n と位置 n のみの決定論的な関数だからです。シーケンスを 1 トークン拡張するとき、そのトークンの k_n' を計算してキャッシュに追加するだけです。古いキーの再計算は不要です。
25.3.6 長距離の減衰
RoPE の解析では、位置カーネル全体に距離に応じた減衰の上界も現れます。ただしこれは傾向であって、すべての個別の Q・K スコアが単調に下がる保証ではありません。実際のスコアは内容ベクトルと学習済み重みにも依存します。
25.3.7 複素数を使った効率的な実装
密な回転行列の乗算は高コストです。標準的な実装は複素数演算を使います:
def apply_rope(x, freqs):
# x: [batch, seq_len, n_heads, head_dim]
# freqs: [seq_len, head_dim // 2]
# 実数のペアを複素数として扱う
x_complex = torch.view_as_complex(x.reshape(*x.shape[:-1], -1, 2))
# 各位置と次元ペアに e^(i * theta) を構築
freqs_complex = torch.polar(torch.ones_like(freqs), freqs)
# 複素数の乗算 = 回転
x_rotated = x_complex * freqs_complex
# 実数に戻す
return torch.view_as_real(x_rotated).flatten(-2)
複素数の乗算 (a + bi)(c + di) = (ac - bd) + (ad + bc)i はまさに 2D 回転の式です。ペアごとに 4 回の乗算と 2 回の加算のコストで回転が得られます — 完全な行列乗算よりずっと安価です。
25.4 ALiBi: Attention with Linear Biases
Press et al. が 2021 年に ALiBi を提案しました。RoPE とはまったく異なる哲学を取ります。
25.4.1 アイデア: 距離に直接ペナルティを与える
ALiBi はエンベディングや Q/K ベクトルにまったく触れません。Q·K ドット積の後、Attention スコアにペナルティを加算します:
標準: Attention = softmax(Q Kᵀ / sqrt(d)) V
ALiBi: Attention = softmax(Q Kᵀ / sqrt(d) + m * bias) V
バイアスマトリクスはシンプルな三角構造で相対距離をエンコードします:
bias = [ 0 ] (位置 1 のクエリ)
[ -1 0 ] (位置 2 のクエリ)
[ -2 -1 0 ] (位置 3 のクエリ)
[ -3 -2 -1 0 ] (位置 4 のクエリ)
[ -4 -3 -2 -1 0 ] (位置 5 のクエリ)
m はヘッドごとのスロープです。スロープは学習されません — 初期化時にヘッド数に渡る 2 の累乗として固定されます。
25.4.2 Attention に何をするか
現在のクエリが位置 5 にあり、位置 1〜5 に Attention を当てているとします。スロープ m=1 の場合:
| ターゲット | 距離 | バイアス | softmax 後の効果 |
|---|---|---|---|
| 位置 1 | 4 | -4 | 強く抑制される |
| 位置 2 | 3 | -3 | 大幅に抑制される |
| 位置 3 | 2 | -2 | 適度に抑制される |
| 位置 4 | 1 | -1 | わずかに抑制される |
| 位置 5 | 0 | 0 | 変化なし |
近くのトークンがより多くの重みを得ます。バイアスは学習されたパラメータなしに局所性を実装します。
25.4.3 ALiBi がうまく外挿する理由
バイアスマトリクスは決定論的で位置不変なので、任意の長さで構成できます。原論文の訓練・評価設定では、ALiBi は比較対象の絶対位置方式より良く外挿しました。ただしこれは実験結果であり、すべてのチェックポイントやタスクへの保証ではありません。
それが BLOOM(176B)と MPT-7B が ALiBi を採用した理由です。追加のファインチューニングなしに積極的な長いコンテキスト外挿が欲しかったのです。
25.4.4 実装
def alibi_bias(n_heads, seq_len):
if n_heads & (n_heads - 1):
raise ValueError("この簡略例は 2 のべき乗のヘッド数に対応します")
# 2 のべき乗の構成(8 ヘッドなら 2^-1 ... 2^-8)での幾何スロープ
slopes = 2 ** (-8.0 / n_heads * torch.arange(1, n_heads + 1, dtype=torch.float32))
# 相対距離マトリクス
positions = torch.arange(seq_len)
distances = positions.unsqueeze(0) - positions.unsqueeze(1) # [seq, seq]
# バイアス = スロープ × 距離、ヘッド間でブロードキャスト
bias = slopes.view(-1, 1, 1) * distances.unsqueeze(0) # [heads, seq, seq]
return bias
追加パラメータなし。キャリブレーションデータなし。シンプルさがポイントです。
25.4.5 トレードオフ
強み:
- 実装が無料(学習パラメータなし)
- 追加パラメータなし
- 強いゼロショット外挿
弱み:
- シンプルな線形ペナルティは精密な長距離情報を必要とするタスクには粗すぎる可能性がある
- 一部の検索重視タスクでは RoPE の方が良い結果
- スロープスケジュールは固定のハイパーパラメータ選択でタスクごとに調整できない
25.5 YaRN: RoPE を学習コンテキスト長を超えて拡張する
RoPE の相対位置動作は学習コンテキスト長の範囲内で優れています。それを超えると、モデルは学習中に経験したことのない回転角度に遭遇し、パフォーマンスが劣化します。YaRN(Yet another RoPE extensioN)はまさにこれを修正するために設計されています。
25.5.1 外挿の問題
モデルが 4k コンテキストで学習されているとします。8k トークンでの推論時:
- 位置 1-4000: 馴染みのある回転角度
- 位置 4001-8000: 学習中に生成されたことのない回転角度
シーケンスの未知の部分に対する Attention パターンが崩壊する可能性があります。
25.5.2 位置補間(PI): シンプルな修正
直截的なアプローチは、長いシーケンスを学習済みの範囲に圧縮することです:
f'(x_m, m, theta) = f(x_m, m * L / L', theta)
ここで L は学習長(4k)、L' はターゲット長(8k)です。位置 8000 が位置 4000 にマッピングされます。モデルは馴染みのある角度のみを見ます。
コスト: 高周波ペアが精度を失います。1 つ違いの隣接トークンが今は半位置単位違いになります。細かい局所情報がぼやけます。
25.5.3 NTK 認識補間: よりスマートなスケーリング
NTK 認識補間は異なる周波数バンドに異なるスケールファクターを適用します:
- 低周波ペア(長距離): より積極的にスケール。粗い位置的アイデンティティを扱います。
- 高周波ペア(短距離): あまりスケールしない。精確に保たれなければならない局所的な区別をエンコードします。
これが Code Llama、Qwen 7B、コンテキストウィンドウを拡張したその他のモデルで使用されているスキームです。
25.5.4 YaRN の完全な式
YaRN は NTK 認識を超えてもう一つの要素を追加します: Attention 温度スケーリング。
f'(x_m, m, theta) = f(x_m, g(m), h(theta))
温度調整:
softmax(Q_mᵀ K_n / (t * sqrt(d)))
ここで: sqrt(1/t) = 0.1 * ln(s) + 1, s = L' / L
スケールファクター s が大きくなる(長いコンテキスト)につれて、t は softmax 温度を調整し、より多くのトークンに渡って Attention 分布が拡散しすぎないようにします。
実践的な効果: 4k トークンで学習したモデルを元の事前学習トークン数の 0.1% 未満のファインチューニングで YaRN 拡張して 32k や 128k にできます。例えば:
- オリジナル: 4k コンテキスト、1T トークンで学習
- YaRN 拡張: 32k コンテキスト、約 1B トークン(0.1%)でファインチューニング
それが Code Llama の拡張バリアントと Qwen の長いコンテキストバージョンが完全な再学習なしに存在する理由です。
25.6 比較
25.6.1 技術的比較
| 特徴 | 正弦波 | RoPE | ALiBi | YaRN |
|---|---|---|---|---|
| 注入ポイント | エンベディング | Attention 内の Q と K | Attention スコア | Attention 内の Q と K |
| 位置タイプ | 絶対 | 相対 | 相対 | 相対 |
| 外挿 | 弱い | 中程度 | 強い | 強い |
| KV キャッシュ互換 | あり | あり | あり | あり |
| 追加パラメータ | なし | なし | なし | なし |
| 計算オーバーヘッド | 低 | 中程度 | 低 | 中程度 |
25.6.2 どのモデルが何を使うか
| モデル | エンコーディング | コンテキスト |
|---|---|---|
| GPT-3 | 学習済み絶対 | 2048 |
| LLaMA 1 | RoPE | 2048 |
| LLaMA 2 | RoPE | 4096 |
| Code Llama | RoPE + YaRN | 16384 |
| Mistral 7B | RoPE | 8192 |
| BLOOM | ALiBi | 2048 |
| MPT-7B | ALiBi | 65536 |
| Qwen | RoPE + Dynamic NTK | 8192-32768 |
25.6.3 意思決定ガイド
RoPE を使う場合:
- 精確な局所および中距離位置情報が必要なとき
- 学習コンテキスト長の範囲内で作業しているとき
- LLaMA/Mistral エコシステムとの互換性が欲しいとき
ALiBi を使う場合:
- 強いゼロショット長外挿が必要なとき
- 最もシンプルな実装が欲しいとき
- メモリと計算がタイトなとき
YaRN を使う場合:
- 既存の RoPE モデルがあってコンテキスト長を拡張する必要があるとき
- 小さなファインチューニング予算(1B トークン以下)があるとき
- ターゲット長が 16k、32k、またはそれ以上のとき
25.7 実装リファレンス
25.7.1 RoPE の周波数
def precompute_freqs(head_dim, max_seq_len, theta=10000.0):
# theta_i = 1 / (theta ^ (2i / head_dim))
freqs = 1.0 / (theta ** (torch.arange(0, head_dim, 2).float() / head_dim))
positions = torch.arange(max_seq_len)
# 外積: [seq_len, head_dim // 2]
return torch.outer(positions, freqs)
25.7.2 ALiBi のスロープ
def get_alibi_slopes(n_heads):
if n_heads & (n_heads - 1):
raise ValueError("2 のべき乗以外は完全な参照実装を使ってください")
return 2 ** (-8.0 / n_heads * torch.arange(1, n_heads + 1, dtype=torch.float32))
25.8 章のまとめ
25.8.1 重要な概念
| 概念 | 意味 |
|---|---|
| RoPE | Q と K を位置依存の角度で回転させる; 相対距離がドット積から自然に現れる |
| ALiBi | Q·K 後の Attention スコアに線形距離ペナルティを加える |
| YaRN | RoPE 周波数バンドをリスケールして学習長を超えたコンテキストを扱う |
| 絶対 vs 相対 | 正弦波はスロット番号をエンコード; RoPE と ALiBi は距離をエンコード |
| 外挿 | 推論長が学習長を超えたときの動作 |
25.8.2 進化を一枚の図で
2017年: 正弦波
| 問題: 絶対位置、外挿が弱い
v
2021年: RoPE(蘇剣林)
| 問題: 学習長を超えると劣化する
v
2021年: ALiBi(Press et al.)
| シンプルな線形減衰、強い外挿
v
2023年: YaRN(Peng et al.)
| 最小限の再学習で RoPE を 100k+ に拡張
v
現在: 128k 以上のコンテキストが標準
25.8.3 核心的な教訓
位置エンコーディングの役割は、モデルに誰が誰の前に来るかを伝えることです。正弦波は加算を使って絶対アドレスを割り当てます。RoPE は回転を使って相対距離が Attention の内側から現れるようにします。ALiBi はペナルティを使って遠いトークンをより静かに話させます。どれが普遍的に最良ということはありません — コンテキスト長の要件とエコシステムに基づいて選択してください。
チャプターチェックリスト
この章を終えた後、以下ができるようになっているはずです:
- 正弦波エンコーディングが長いコンテキストで苦労する理由を説明できる。
- 2D 回転を使った RoPE の幾何学的直感を説明できる。
- RoPE の Attention スコアにおける位置の寄与が、絶対位置 m と n ではなく相対位置 (n-m) に依存する理由を導出できる。
- ALiBi のメカニズムを説明できる: バイアスマトリクスがどう見えるか、なぜ外挿するか。
- 位置補間と NTK 認識補間の違いを説明できる。
- YaRN の温度調整とその長いコンテキスト拡張における役割を説明できる。
- 与えられたモデルアーキテクチャとコンテキスト要件に対して適切なエンコーディングスキームを選べる。
次の章へ
位置エンコーディングはここまでです。RoPE の Attention スコアに絶対位置が (n-m) を通じて現れ、同時にスコア自体は Q と K の内容にも依存する理由を説明できれば、核心的なアイデアを身に付けたということです。
ここからアーキテクチャの選択から適応へと移ります。第26章では LoRA と QLoRA を扱います — 民生用ハードウェアで大きなモデルをファインチューニングするための実践的な主力手法です。次章でお会いしましょう。