はじめに
- RoPE ってなに? となったので調べてみた
Rotary Positional Embeddings (RoPE)
Rotary Positional Embeddings (RoPE) = 絶対位置埋め込みと相対位置埋め込みの長所を組み合わせた新しいアプローチのこと。
そもそも位置埋め込みってなに?なんで必要?
- Transformerモデルは、入力トークンの順序を考慮せずに処理をする
- "the dog chases the pig" と "the pig chases the dog" のような異なる意味のフレーズも同様に扱われる
- これを解決するために、位置埋め込みという概念が導入された
- 「RoFormer: Enhanced Transformer with Rotary Position Embedding」という論文で2021年に初めて詳細に説明され、自然言語処理(NLP)におけるTransformerアーキテクチャの拡張として導入された
- 予測における外の範囲のデータに対する適応力が強く、またロジスティックロスについても優れた性能を発揮した
位置埋め込みの種類
名称 | 説明 | 課題 |
---|---|---|
絶対位置埋め込み | トークンごとに一意の位置ベクトルを割り当て、これを単語埋め込みと合算してTransformerレイヤーへの入力を形成。位置ベクトルは訓練中に学習されるか、正弦波関数を使用して生成されます。 | ・限定されたシーケンス長: 学習する位置ベクトルの最大数によってシーケンス長が制限される。 ・位置埋め込みの独立性: 相対的な位置情報を捉えるのに効果的ではない。 |
相対位置埋め込み | トークンの絶対位置ではなく、トークン間の距離に焦点を当て、位置オフセットのバイアスを用いて情報を統合する。 | 実装の複雑性と計算コストの高さ。 |
Rotary Positional Embeddings (RoPE) | 絶対位置埋め込みと相対位置埋め込みの長所を組み合わせ。 | - |
RoPE のメカニズム
RoPE(Rotary Positional Embeddings)は、位置ベクトルを追加するのではなく、単語ベクトルに回転を適用するという革新的なコンセプトを導入している。例えば、「dog」という単語の二次元ベクトルでこのベクトルの位置を文中でエンコードするために、RoPEはこのベクトルを回転させます。回転角(θ)は文中の単語の位置に比例します。例として、最初の位置ではベクトルをθで、2番目の位置では2θで回転させる、といった具合です。
このアプローチはいくつかの利点を持っています:
- ベクトルの安定性: 文の終わりにトークンを追加しても、文の始めの単語のベクトルに影響を与えません。これにより、効率的なキャッシングが可能になります。
- 相対位置の保存: 例えば「pig」と「dog」という単語が異なる文脈で同じ相対距離を保つ場合、それらのベクトルは同じ量だけ回転されます。これにより、これらのベクトル間の角度、そして結果としてのドット積が一定に保たれます。
実装
RoPEは、PyTorchなどのライブラリで効率的に実装され、シンプルなベクトル操作によって実行されます。
import torch
import torch.nn as nn
class RotaryPositionalEmbedding(nn.Module):
def __init__(self, d_model, max_seq_len):
super(RotaryPositionalEmbedding, self).__init__()
# 回転行列を生成
self.rotation_matrix = torch.zeros(d_model, d_model, device=torch.device("cuda"))
for i in range(d_model):
for j in range(d_model):
# 回転角度の計算
self.rotation_matrix[i, j] = torch.cos(i * j * 0.01)
# 位置埋め込み行列を生成
self.positional_embedding = torch.zeros(max_seq_len, d_model, device=torch.device("cuda"))
for i in range(max_seq_len):
for j in range(d_model):
# 位置に応じた角度の計算
self.positional_embedding[i, j] = torch.cos(i * j * 0.01)
def forward(self, x):
"""
Args:
x: テンソル(バッチサイズ、シーケンス長、モデル次元)。
Returns:
変換後のテンソル(バッチサイズ、シーケンス長、モデル次元)。
"""
# 入力テンソルに位置埋め込みを加算します。
x += self.positional_embedding
# 入力テンソルに回転行列を適用します。
x = torch.matmul(x, self.rotation_matrix)
return x
参考資料