※本記事は、スタンフォード大学のCS224N NLP with Deep Learning 2023年講義シリーズの第8回「Self-Attention and Transformers」の内容を基に作成されています。この講義では1) 再帰型(RNN)からアテンションベースのNLPモデルへの移行、2) トランスフォーマーモデル、3) トランスフォーマーの優れた成果、4) トランスフォーマーの欠点とバリエーションについて解説されています。講義の詳細はhttps://online.stanford.edu/courses およびhttp://web.stanford.edu/class/cs224n/ でご覧いただけます。本記事では講義内容を要約しておりますが、正確な情報や文脈については、オリジナルの講義動画(https://www.youtube.com/watch?v=LWMzyfvuehA )をご視聴いただくことをお勧めいたします。
講師はクリストファー・マニング教授(Thomas M. Siebel機械学習教授、言語学・コンピュータサイエンス教授、スタンフォード人工知能研究所(SAIL)所長)およびジョン・ヒューイット氏(https://nlp.stanford.edu/~johnhew/ )です。スタンフォード大学の人工知能専門・大学院プログラムについての詳細はhttps://stanford.io/ai でご確認いただけます。
1. 講義の概要と背景
1.1. RNNからアテンション・ベースモデルへの移行
今日のCS224Nでは、自己注意(self-attention)とトランスフォーマーについて話します。これらは現代の自然言語処理の発展の基礎となっている概念で、実際にAIシステムの幅広い分野の基盤となっているとても面白いトピックです。
まず、これまで私たちが自然言語処理でどのようなアプローチを取ってきたかを振り返ってみましょう。もし自然言語処理の問題に取り組むとき、あまり凝ったことをせずに最善の努力をしようとすると、双方向LSTMを使用すると言うでしょう。単純なRNNではなく、LSTMを使って文を符号化し、双方向のコンテキストを得ます。そして、出力を生成する必要がある場合、例えば翻訳や構文解析などでは、一方向のLSTMを使って一つずつ出力を生成していくことになります。
例えば、双方向LSTMでソース文を符号化し、一方向LSTMで目標文を一つずつデコードしていくというアプローチです。また、アテンションを使用して、メモリへの柔軟なアクセスを提供することもあります。これは機械翻訳を行う際に、ソース文の全体を単一のベクトルに符号化するというボトルネックを避けるためです。
このアプローチは2014年から2017年頃まで非常にうまく機能していました。しかし、多くの試行錯誤を経て、数年後にはLSTMの代わりに直接差し替えられる新しい構成要素が登場しました。これらの新しい構成要素は、LSTMよりもはるかに成功したアプリケーションの広範囲に適用可能なものでした。
今回の講義では、以前使っていた再帰型ニューラルネットワーク(RNN)の問題点と、これから先使っていく新しいシステムについて話します。私たちは同じ問題を見ていきますが、異なる構成要素を使用していきます。
1.2. トランスフォーマーモデルの位置づけ
今日の講義では、自己注意(self-attention)とトランスフォーマーについて話します。これらは現代の自然言語処理の進歩の基礎となる考え方で、実際には幅広い分野のAIシステムの基盤になっています。非常に興味深いトピックです。
トランスフォーマーモデルは、以前使用していたLSTMなどの再帰型ニューラルネットワークに直接置き換えることができる新しい構築ブロックとして登場しました。これらのモデルは、はるかに成功したアプリケーションの広範囲に適用可能であることが証明されています。
この講義では、トランスフォーマーモデルの基本的な構造を詳しく説明し、なぜこれらのモデルが現代の自然言語処理で主流になったのかを理解することを目指します。アテンションメカニズムという概念がどのようにしてRNNの限界を克服し、自然言語処理タスクにおいてブレークスルーをもたらしたかについて掘り下げていきます。
以前の講義では機械翻訳のためのアテンションについて触れましたが、今回はセルフアテンションという方法で同じような問題に取り組む新しい方法を見ていきます。この新しいアプローチが、なぜ現代のAIシステムの多くの基盤となっているのかを理解していただけるでしょう。
2. RNNの限界と課題
2.1. 線形インタラクション距離の問題
再帰型ニューラルネットワーク(RNN)の問題点の一つとして、私たちが「線形インタラクション距離」と呼ぶものがあります。RNNは言語によって左から右、あるいは右から左へ展開されていきますが、これは線形的な局所性を符号化しています。これは有用な面もあります。なぜなら、隣接する2つの単語が実際に関連していることがよくあるからです。
例えば「tasty Pizza(おいしいピザ)」という単語ペアは互いに近くにあり、RNNでは「tasty」を符号化した後、一歩進んで「Pizza」を符号化します。近接する単語はしばしば互いの意味に影響を与えるため、これは理にかなっています。
しかし、非常に長距離の依存関係が相互作用するまでに長い時間がかかるという問題があります。「the chef who went to the stores and picked up the ingredients and loves garlic and then was...」という文を考えてみましょう。「chef」と「was」の間には長距離の依存関係がありますが、RNNステップでは、再帰重み行列の適用と要素ごとの非線形性が、「chef」と「was」の間のシーケンス長と同じ回数だけ行われます。
これらの単語が関連していることを学習するのは非常に困難です。単語間に多くのステップがある場合、それらの間の依存関係を学習するのは難しいのです。私たちはすでに、この線形的な順序が文を考える正しい方法ではないことを知っています。例えば「it's the chef who was」という関係を学習しようとすると、勾配が「was」から「chef」に伝播する必要があるため、困難かもしれません。
私は、文や文書の中で関連している可能性のある単語が、ニューラルネットワークの計算グラフでより直接的に相互作用できるようにしたいと考えています。線形的に遠く離れているよりも、もっと簡単に相互作用できるようにしたいのです。これにより、長距離依存関係をより良く学習できるようになります。
2.2. 時間依存による並列化の限界
RNNには線形インタラクション距離の問題と関連して、シーケンスのインデックス(よく時間依存と呼ばれる)に依存するという問題もあります。再帰型ニューラルネットワークでは、順伝播と逆伝播の計算がシーケンス長に比例する数の並列化できない操作を必要とします。
GPUは素晴らしいハードウェアで、操作間に時間的な依存関係がなければ、つまり一つを計算してから次を計算する必要がなければ、一度に多くの操作を行うことができます。しかしRNNでは、時間ステップ5の隠れ状態を計算する前に、時間ステップ4や時間ステップ3の隠れ状態を計算する必要があります。
これは非常に似たグラフになります。例えば、ある単語の隠れ状態を計算するために、その前に行う必要がある操作が0個、次の状態を計算するために1個の操作、さらにその次の状態を計算するためには3個の操作が必要というように増えていきます。ここでは行列の乗算などをすべて1つの操作にまとめています。
そして当然、この操作数はシーケンス長とともに増加します。シーケンス長が長くなると、パラレル化することができません。それ以前のすべての状態を計算する必要があるので、大きなGPUを使って行列乗算で一気にこの状態を計算することはできないのです。
これは時間への依存に関連した問題です。アテンションについて質問がありましたが、アテンションはこの線形インタラクション距離の問題を解決する一つの方法ですが、並列化問題は解決しません。この講義の残りでは、アテンションベースのアプローチを見ていきますが、再帰性を取り除き、基本的にはアテンションだけを使用します。
2.3. 長距離依存関係の学習困難性
RNNの大きな問題の一つは、長距離依存関係を学習することの難しさです。すでに線形インタラクション距離の問題について触れましたが、これは単語間の距離が長くなるほど、それらの間の関係を学習することが難しくなるという課題です。
例として「the chef who went to the stores and picked up the ingredients and loves garlic and then was...」という文を考えてみましょう。「chef」と「was」の間には明らかな構文的関係がありますが、これらの単語の間には多くの他の単語が存在します。RNNがこの関係を学習するためには、勾配が「was」から「chef」まで長い距離を伝播する必要があります。
この問題は勾配の問題とも密接に関連しています。私たちはすでに勾配消失や勾配爆発の問題について話しました。LSTMは単純なRNNよりも長距離での勾配をモデル化することがはるかに優れていますが、それでも完璧ではありません。
実際、文の線形的な順序は文を考える正しい方法ではないことがわかっています。依存構文で見たように、「it's the chef who was」のような長距離依存関係を学習しようとすると、勾配が「was」から「chef」へと伝播する必要がありますが、これが困難になります。
理想的には、文や文書内で関連している可能性のある単語が、ニューラルネットワークの計算グラフの中でより直接的に相互作用できるようになることが望ましいでしょう。線形的に離れているよりも、より簡単に相互作用できるようにして、長距離依存関係をより効果的に学習できるようにしたいのです。
これらの課題を解決するために、私たちはアテンションメカニズムに目を向けることになります。アテンションは、単語の位置に関係なく、関連する情報にアクセスする方法を提供してくれるからです。
3. アテンションメカニズムの基本原理
3.1. キー・バリューストアの概念を用いた説明
では、アテンションについてより深く考えてみましょう。アテンションの一つの見方として、キー・バリューストアの中でのファジーな検索を実行していると考えることができます。一連のキーと一連の値があり、それらにアクセスするのを助けてくれます。
実際のルックアップテーブル、例えばPythonの辞書のような単純なものを考えてみましょう。キーのテーブルがあり、各キーは値にマッピングされています。クエリを与えると、クエリがキーの一つとマッチし、その値が返されます。これは単純で分かりやすいですね。
一方、アテンションでは、クエリがすべてのキーと「ソフトに」マッチします。キーとの完全一致はなく、クエリとすべてのキーの間の類似性を計算し、その結果を重み付けします。再びクエリがあり、複数のキーがあります。クエリは異なる程度でそれぞれのキーと類似しており、その類似性を0から1の間でソフトマックス関数を通じて測定します。
そして値を取り出し、クエリとキーの間の類似性の重みを使って平均化します。これらの重みを使って重み付け和を計算し、出力を得ます。つまり、これは実際にルックアップテーブルのようなものですが、「ソフト」なベクトル空間での、ある種の「ふわふわした」感覚でのアクセスなのです。キー・バリューストアに格納されている情報に一種のアクセスを行っていますが、すべての結果を柔らかく見ているわけです。
例として、「I went to Stanford's cs224n and learned」という文の「learned」を表現しようとしていると考えてみましょう。各単語にキーと値があり、「learned」のクエリがあります。上部にティール色のバーがあり、各単語にどれだけアクセスするかを示しています。たとえば、「224n」はそれほど重要ではないかもしれませんが、「CS」はおそらく学んだ内容を決定する要素となるでしょう。「Stanford」もそうです。そして「learned」自体も、それ自身を表現するのに重要かもしれません。
つまり、文全体を見渡して、「learned」の文脈での表現を構築するために、文全体の情報へのソフトなアクセスを構築しているのです。
3.2. クエリによる情報アクセスのメカニズム
アテンションメカニズムによる情報アクセスについて、より詳しく数学的に説明していきましょう。W1からWnの単語のシーケンスを考えてみます。これは例えば「Zuko made his Uncle T」といった単語の並びです。各単語に対して、埋め込み行列でエンベディングを行います。これは授業でこれまでやってきたことと同じです。
埋め込み行列Eは語彙サイズから次元Dへのマッピングです。これにより、各単語は非文脈的な、つまり単語自体にのみ依存する単語埋め込みを持ちます。次に、各単語を3つの異なる重み行列の1つで変換します。これは「キー・クエリ・バリュー・セルフアテンション」と呼ばれることが多いものです。
行列Qという、RD×Dの行列があります。これはXiを取り、次元Dのベクトルから別の次元Dのベクトルにマッピングします。これは「クエリベクトル」と呼ばれます。Xiを取り、回転させ、シャッフルし、伸ばしたり縮めたりして変形し、クエリにします。
同様に、別の学習可能なパラメータKを使って「キー」を作成し、別の学習可能なパラメータVを使って「バリュー」を作成します。つまり、非文脈的な単語埋め込みであるXiそれぞれを取り、それらを変換して、その単語のクエリ、キー、バリューを作成しています。
次に、キーとクエリの間のすべてのペアの類似性を計算します。先ほどの例では、「learned」という単語のクエリと文全体のすべてのキーの間の類似性を計算していました。この場合、すべての単語を表現したいので、すべてのキーとすべてのクエリの間のすべてのペアの類似性を計算します。
ここでドット積を使用します。単語iのクエリQiと単語jのキーKjのドット積を取ると、実数値スコアが得られます。これは非常に大きな負の値、ゼロ、または非常に大きな正の値になる可能性があります。このスコアは、このルックアップテーブルでiからjをどれだけ見るべきかを示します。
そして、ソフトマックスを適用します。つまり、iとjの間の実際の重みは、すべての可能なインデックスjに対するiとjの間のスコアのソフトマックスです。これはiとj'間の親和性で正規化されたiとjの間の親和性のようなものです。
最後に、出力は値の重み付け和です。例えば、i=1が「Zuko」だとすると、すべてのj(「Zuko」「made」「his」「uncle」「T」)に対する重みと、その単語jの値ベクトルの和として表現します。
3.3. ソフト検索によるコンテキスト表現
ソフト検索によるコンテキスト表現は、アテンションメカニズムの核心部分です。先ほど説明したように、各単語のクエリベクトルが全てのキーベクトルとの類似度を計算し、その類似度に基づいて値ベクトルの重み付け平均を取ることで、その単語の文脈表現を構築します。
具体例を使って説明しましょう。「I went to Stanford's cs224n and learned」という文があるとき、「learned」という単語の表現を構築しようとしています。この場合、「learned」のクエリベクトルを使用して、文中の各単語のキーベクトルとの類似度を計算します。それにより、どの単語にどれだけ「注目」するかが決まります。
例えば「224n」は「learned」の意味を理解するにはそれほど重要ではないかもしれませんが、「CS」は学んだ内容を特定するために重要かもしれません。同様に「Stanford」も、スタンフォード大学で学ぶことと他の場所で学ぶことの違いを示すために重要でしょう。また、「learned」自体も自分自身を表現するのに重要な要素です。
このように、単語の表現を構築するために文全体を見渡し、関連する情報を柔軟に取り込むことができます。言い換えれば、単語「learned」が文脈の中でどのような意味を持つかを理解するために、文中のすべての単語からの情報をそれぞれの重要度に応じて組み合わせているのです。
このソフト検索メカニズムは、RNNでは困難だった長距離依存関係の問題を解決するのに役立ちます。なぜなら、単語間の距離に関係なく、関連性のある単語からの情報を直接取り込むことができるからです。例えば文の始めの方にある主語と文の終わりの方にある動詞の関係を捉えるのが、RNNよりもはるかに容易になります。
4. セルフアテンションの数学的定式化
4.1. キー・クエリ・バリュー変換
セルフアテンションの数学的定式化を説明するために、まずW1からWnの単語のシーケンスを考えます。例えば「Zuko made his Uncle T」といった単語列です。各単語には語彙中の単語を表す埋め込み行列Eを使用してエンベディングを行います。これは授業でこれまでやってきた方法と同じです。
埋め込み行列Eは語彙サイズVから次元Dへのマッピングです。これにより、各単語は非文脈的な単語埋め込みを持ちます。つまり、単語自体にのみ依存する表現です。次に、各単語を3つの異なる重み行列で変換します。これはキー・クエリ・バリュー・セルフアテンションと呼ばれます。
具体的には、行列Q(クエリ行列)というRD×Dの行列があります。これはXiを取り、次元Dのベクトルから別の次元Dのベクトルにマッピングします。
Q×Xi = Qi
これは単語iの「クエリベクトル」になります。このプロセスでは、Xiを取り、回転させ、シャッフルし、伸ばしたり縮めたりして変形し、クエリにします。
同様に、別の学習可能なパラメータK(キー行列)を使って「キー」を作成します:
K×Xi = Ki
そして別の学習可能なパラメータV(バリュー行列)を使って「バリュー」を作成します:
V×Xi = Vi
つまり、非文脈的な単語埋め込みXiそれぞれを取り、3つの異なる行列で変換して、その単語のクエリ、キー、バリューを作成しています。これらの行列Q、K、Vはすべて学習可能なパラメータであり、モデルのトレーニング中に最適化されます。
「なぜQ行列とK行列が異なるのか」という質問がありました。これは低ランク近似を行うための計算効率の理由によるものです。また、モデルにより大きな柔軟性を与えます。例えば、単語が自分自身を見るべきかどうかという問題を考えると、QとKを異なる行列にすることで、モデルはこれを学習することができます。QがアイデンティティでKが自分自身の負の値にマッピングするような場合、単語は自分自身を見ないように学習することができるのです。
4.2. スコア計算とソフトマックス
キー、クエリ、バリューの変換を行った後、次のステップはキーとクエリの間の類似性スコアを計算することです。これは各単語のクエリが他の単語のキーとどれだけマッチするかを判断するためのものです。
この類似性スコアは単純にドット積を使って計算します。単語iのクエリQiと単語jのキーKjのドット積を取ると、実数値のスコアeijが得られます:
eij = Qi • Kj
このスコアは非常に大きな負の値、ゼロ、または非常に大きな正の値になる可能性があります。これは、このルックアップテーブルにおいて単語iから単語jをどれだけ「見る」べきかを示す値です。
次に、このスコアに対してソフトマックス関数を適用します。これによりスコアが確率分布に変換され、すべての単語jに対する注意の重みの合計が1になります:
αij = softmax(eij) = exp(eij) / Σj' exp(eij')
この式は、単語iと単語jの間の実際の注意の重みαijが、すべての可能なインデックスj'に対するiとj'の間のスコアのソフトマックスであることを示しています。言い換えれば、これはiとjの間の親和性を、iとすべての可能なj'の間の親和性で正規化したものです。
ソフトマックスを適用することで、注意の重みはすべて正の値になり、合計が1になります。これにより、複数の単語からの情報を適切に統合するための確率的な重み付けが得られます。
このようにして、各単語のクエリが他のすべての単語のキーとの類似性をソフトに計算し、その類似性に基づいて注意を向ける仕組みが実現されています。例えば、「Zuko」という単語を表現する場合、「made」「his」「Uncle」「T」などの単語にどれだけ注意を払うべきかがこの計算によって決まります。
4.3. 重み付け平均による出力生成
スコア計算とソフトマックスによって各単語ペア間の注意の重みを計算したら、最後のステップは出力表現を生成することです。この出力は、すべての値ベクトルの重み付け平均として計算されます。
数学的に表現すると、単語iの出力表現は以下のように計算されます:
outputi = Σj αij × Vj
ここで、αijは前のステップで計算した単語iから単語jへの注意の重み、Vjは単語jの値ベクトルです。この和は、シーケンス内のすべての単語jについて計算されます。
具体例を考えてみましょう。例えば、i=1が「Zuko」を表す場合、「Zuko」の出力表現は、「Zuko」「made」「his」「uncle」「T」のそれぞれの単語jに対する注意の重みαijとその単語jの値ベクトルVjの積の合計として計算されます。
この計算により、各単語の出力表現は、シーケンス内の他の単語からの情報を、それらの単語との関連性に応じて統合したものになります。つまり、単語はそれ自身だけでなく、文脈内の他の関連単語からの情報も含んだ豊かな表現を持つことになります。
重要なのは、この重み付け平均の計算が、単語間の距離に関係なく行われることです。つまり、文の始めにある単語が文の終わりにある単語に直接アテンションを向けることができます。これによって、RNNで困難だった長距離依存関係の問題が解決されるのです。
この出力生成メカニズムは、セルフアテンションの本質的な部分であり、単語間の複雑な関係をモデル化する能力を提供します。次のセクションでは、この基本的なセルフアテンションの仕組みをさらに拡張していきます。
5. セルフアテンションの課題と解決策
5.1. 位置情報の欠如と位置エンコーディング
5.1.1. 正弦波位置表現
これが基本的な構成要素ですが、LSTMの代わりに使うにはいくつかの障壁があります。ここからの講義では、セルフアテンションを基本的な構成要素として使うために必要な最小限のコンポーネントについて説明します。現状のままでは使えないので、いくつかの問題を解決する必要があります。
その一つは、セルフアテンションにはシーケンスの順序の概念がないことです。これはどういう意味かというと、例えば「Zuko made his uncle」と「his uncle made Zuko」という2つの文があるとします。各単語を埋め込み行列で埋め込むと、埋め込み行列は単語のインデックスに依存しません。最初の文では「his」はインデックス3、「uncle」はインデックス4ですが、2番目の文では「his」はインデックス1、「uncle」はインデックス2です。
セルフアテンションを計算すると、「Zuko made his uncle」というシーケンスと「his uncle made Zuko」というシーケンスに対して、まったく同じ表現が得られてしまいます。これは問題です。なぜなら、これらは違う意味を持つ文だからです。
セルフアテンションは、ベクトルの集合に対する操作であり、単語の正確な位置は直接関与しないという考え方です。そこで、キー、クエリ、バリューを通じて単語の位置を符号化する必要があります。
各シーケンスインデックス(1からn)を次元Dのベクトルとして表現することを考えます。つまり、位置1、位置2、位置3などを、キー、クエリ、バリューと同じ次元Dのベクトルとして表現します。この位置情報をセルフアテンションに組み込むには、これらのPiベクトル(位置ベクトル)を入力に加えればよいのです。
例えば、Xiという単語の埋め込みがあり、それは位置iにある単語「Zuko」を表しますが、これは実際には単語「Zuko」だけを表しています。ここに位置情報を加えると「これは単語Zukoであり、位置5にある」というように、このベクトルが位置5を表現するようになります。
これを実現する一つの方法が、正弦波位置表現です。これは次のようなものです。これは位置iを表すベクトルPiで、次元Dを持ちます。各次元において、値iをある定数で修正し、正弦または余弦関数を通して値を得ます。次元Dに応じて異なる周期を持つようになります。
行列の表現では、Dが垂直方向、nが水平方向になります。正弦関数が上下に変化する周期が見え、次元Dごとに異なる周期を持っています。これにより、さまざまな位置インデックスを表現できます。
この直感は、単語の絶対的な位置はそれほど重要ではなく、正弦と余弦の周期性を持つことで、より長いシーケンスにも対応できるかもしれないというものです。しかし実際には、それはうまく機能しません。とはいえ、これはトランスフォーマーやセルフアテンションネットワークにおける位置の表現に対する初期の概念であり、今でも使われることがあります。
5.1.2. 学習可能な位置表現
正弦波位置表現はやや複雑で直感的でないと感じるかもしれません。そこで、より深層学習らしいアプローチを紹介します。単純に最大シーケンス長nを持つと仮定し、次元d×nの行列を学習パラメータとして学習するというものです。これは他のすべてのパラメータと同様に学習し、位置を表現します。
この位置表現の意味は何かと聞かれると、「わかりません」と答えるしかありませんが、位置を表現するものです。このような行列をXiの入力埋め込みに加えると、データに適合するように学習します。位置の線形的な、インデックスベースの表現であれば、学習できるでしょう。
ただし、欠点としては、長さnより長いシーケンスを扱えなくなります。なぜなら、学習した行列はこの数の位置しか持たないからです。実際には、モデルエラーが発生し、クラッシュして「これはできません」と言われるでしょう。
現在のシステムのほとんどは、これを使用しています。位置の表現にはより柔軟な方法があり、講義ノートにいくつか記載されています。例えば、単語の絶対的な位置ではなく、単語の前後の相対的な線形位置を考えるというものがあります。
また、依存構文に基づく表現もあります。依存構文解析木で近い単語は、セルフアテンション操作でも近いべきだという考え方です。
実際には、最大シーケンス長の問題は現実的な課題です。セルフアテンションの操作はシーケンス長に対して二次的な複雑さを持つため、シーケンスを長くするとメモリ予算がN²で増加します。実際には、大規模モデルでは最大で約4000単語くらいです。これは多く感じるかもしれませんが、小説やWikipediaのページ全体を扱うには不十分です。より長いシーケンスを扱うモデルも確かにありますが、これは実際的な問題として残っています。
位置表現が位置以外のものを表現していないことは、相関関係によって保証されています。P行列をX行列(単語埋め込み)に加えるとき、各インデックスに現れる単語は実際の例に応じて変わりますが、P行列は決して変わりません。常に各インデックスで同じです。データの中で相関するのはこれだけなので、P行列は暗黙的に位置を学習します。
5.2. 非線形性の追加
5.2.1. フィードフォワードネットワークの導入
もう一つの問題は、これまでに説明したセルフアテンションの仕組みには、ディープラーニングの魔法のための非線形性が本当には含まれていないということです。私たちは基本的に値の重み付け平均を計算しているだけです。
セルフアテンションを適用し、再びセルフアテンションを適用し、さらに繰り返すと、講義ノートでより詳しく説明されていますが、結局のところ値ベクトルを再平均化しているだけになります。値ベクトルの平均を計算し、それが一つの大きなセルフアテンション操作のように見えてしまいます。
しかし、伝統的なディープラーニングの魔法を実現したい場合の簡単な解決策があります。それは、各出力ベクトルを後処理するためのフィードフォワードネットワークを追加することです。
ここで、セルフアテンションの出力である単語があります。これを、この場合は多層パーセプトロン(MLP)と呼ぶフィードフォワードネットワークに通します。これは次元Rdのベクトルを入力とし、次元Rdのベクトルを出力します。通常の多層パーセプトロンのように、出力を行列で掛け、非線形関数に通し、別の行列で掛ける、といった処理を行います。
セルフアテンションでのこの処理は次のようになります。「the chef who the food」という文があり、それを埋め込み、この大きなセルフアテンションブロックに通します。これはシーケンス全体を見て、コンテキストを取り込みます。その後、各単語を個別にフィードフォワードレイヤーに通します。
例えば、「the」という単語のセルフアテンションの出力が、ここで多層パーセプトロンに独立して通されます。これはセルフアテンションの結果を結合または処理すると考えることができます。
これを行う理由はいくつかありますが、その一つは、これらのフィードフォワードネットワークに大量の計算を非常に効率的に、並列化して、GPUに適した形で積み重ねることができるからです。
実際には、セルフアテンションを行い、この位置ごとのフィードフォワードレイヤーで結果を処理します。各単語はこのフィードフォワードネットワークによって独立して処理され、結果を処理します。
これによって、セルフアテンションに伝統的なディープラーニングの非線形性を追加するという問題が簡単に解決され、これが非線形性の欠如という問題に対する解決策です。
5.3. 未来情報へのアクセス制限
5.3.1. マスキングによる解決策
最小限のセルフアテンションの構成要素を完成させる前に、もう一つ解決すべき問題があります。これまでセルフアテンションの例を説明する際、シーケンス全体を見ることができると想定してきました。しかし、機械翻訳や言語モデリングのようなタスクでは、シーケンスの確率分布を定義するために、将来の情報を「覗き見」することはできません。
各時間ステップで、過去の単語だけを含むようにキーと値の集合を定義することもできますが、これは非効率です。並列化がうまくできなくなるからです。そこで、以前のスライドで説明したように、n×nのマトリックス全体を計算し、その後で将来の単語をマスクアウトするという方法を取ります。
具体的には、スコアeijが、単語jのインデックスが単語iのインデックス以下(つまり過去または現在)の場合は以前と同じ値になり、それより大きい(つまり将来)の場合はマイナス無限大になるようにします。ソフトマックスを適用すると、マイナス無限大は0にマッピングされるため、将来の単語に対する注意の重みは0になります。これにより、将来の情報を見ることができなくなります。
例を見てみましょう。「the chef who」という単語と開始記号を符号化するために、これらの単語すべてのペアを見ることができます。そして、見ることができない単語はグレーアウト(マイナス無限大)にします。
開始記号を符号化する場合、開始記号だけを見ることができます。「the」を符号化する場合、開始記号と「the」を見ることができます。「chef」を符号化する場合、開始記号、「the」、「chef」を見ることができますが、「who」は見ることができません。
このようにして、「chef」の表現を作る際には、開始記号、「the」、「chef」だけを見て作られた表現を使って、「who」が次の単語である確率分布を定義できます。これにより、将来の単語を先に見てしまうという不正行為をせずに次の単語を予測できるのです。
この仕組みは、デコーダーで使用されます。エンコーダーでは、ソース文全体を見ることが通常望ましいので、このマスキングは使用しません。つまり、エンコーダーでは双方向のコンテキストを利用し、デコーダーでは自己回帰的な予測を行うために一方向のマスキングを使用するというアプローチになります。
6. トランスフォーマーの構造
6.1. マルチヘッドアテンション
6.1.1. 複数の注意機構による多角的表現
これまで説明してきた最小限のセルフアテンションの構成要素は、実際にはトランスフォーマーデコーダのマスク付きセルフアテンションをマスク付きマルチヘッドセルフアテンションに置き換えたものです。これは最も重要な違いであり、最小限のセルフアテンションアーキテクチャとトランスフォーマーを区別する最も重要な点です。
以前のアテンションの例に戻ってみましょう。「I went to Stanford cs224n and learned」というシーケンスの中の「learned」という単語を表現しようとしています。私は、様々な単語を見ることでこの単語の表現を構築する方法を示す緑色のバーを提示しました。
しかし実際には、シーケンスを見る様々な方法があり、表現に取り込みたい様々な種類の情報があります。例えば、「Stanford cs224n」を見ることで、スタンフォード大学のCS224Nでは他のコースや他の大学とは異なるものを学ぶという情報を取り込みたいかもしれません。
また別の意味では、「learned」や「I」、「went」、「learned」のような、おそらく構文的に関連する単語を見たいかもしれません。シーケンス内の異なるものを見る理由は非常に異なります。
単一のセルフアテンション操作ですべてを平均化しようとすると、難しすぎるかもしれません。課題5でより正確に説明しますが、複数の理由で異なる場所を見ることができるようにすることが重要です。
では、マルチヘッドアテンションとは何でしょうか?これは、すでに説明したように、アテンションを一度行い、異なるパラメータを使って再度行うようなものです。基本的に、独立したクエリ、キー、バリュー行列のセットを定義し、それぞれが異なることに注目できるようにします。
マルチヘッドセルフアテンションについて議論するには、行列の形で実装する方法を説明する必要があります。これによりGPU上で効率的に計算できます。
これまで各単語を次元Dのベクトルとして個別に扱ってきましたが、実際には大きな行列として扱います。X1からXnまでのすべての単語埋め込みを積み重ね、次元Rn×Dの大きな行列にします。
そして、行列K、Q、Vを行列Xのこの側で掛け算します。Xは次元Rn×D、Kは次元RD×Dなので、n×D行列とD×D行列の掛け算でn×D行列になります。これにより、シーケンス全体に対して一度に大きな行列掛け算を効率的に行うことができます。
出力は、この少し分かりにくい数式で定義されます。まず、クエリとキーのドット積をすべて一つの行列で計算します。XQは次元Rn×D、XK^Tは次元RD×nなので、n×DとD×nの掛け算でn×n行列が得られます。これはセルフアテンションのすべてのペアのスコアeijを一度に計算しています。
次に、この行列の第二次元(nの次元)に対してソフトマックスを適用し、正規化されたスコアを得ます。そして、XVと掛け合わせます。これはn×n行列とn×D行列の掛け算で、結果はn×D行列になります。これは一度に全体の重み付け平均を計算し、次元Rn×Dのセルフアテンション出力を与えます。
このように、セルフアテンション操作を行列を使って効率的に計算できるようになりました。これが、マルチヘッドアテンションの基盤となる計算の仕組みです。
6.1.2. 行列計算の効率化
マルチヘッドアテンションを効率的に計算するためには、行列の形で実装する必要があります。この部分では、マルチヘッドアテンションの行列計算について詳しく説明します。
マルチヘッドアテンションでは、複数のクエリ、キー、バリュー行列のセットを定義します。具体的には、H個のセルフアテンションヘッドを持つとして、各ヘッドに独立したクエリ、キー、バリュー行列を定義します。それぞれの行列の形は、モデルの次元Dからモデルの次元DをHで割った次元へのマッピングになります。つまり、D/Hという低次元空間への射影を行います。
これは計算効率のためであり、各ヘッドは低次元空間で動作します。そして、各ヘッドの出力に対して独立にセルフアテンションを適用します。この方程式は単一ヘッドのセルフアテンションと同じですが、各変数にlというインデックスが付いています。これは低次元空間での計算を示し、バリューベクトルも低次元になっています。
最終的に、各ヘッドの出力を結合し、最終的な線形変換で混合します。各ヘッドは次元D/Hの出力を持ち、それらを連結してから最終的な線形変換を適用します。これにより、各ヘッドは異なる場所を見て、異なる方法で値ベクトルを構築でき、その結果を一度に組み合わせることができます。
実際の計算はどのように行われるのでしょうか?単一ヘッドのセルフアテンションを計算するよりも、マルチヘッドを計算する方が計算コストが高くなるわけではありません。図を見ていきましょう。
単一ヘッドセルフアテンションでは、XQを計算します。マルチヘッドセルフアテンションでも同じ方法でXQを計算しますが、それを再形成します。XQは次元Rn×Dで、それをRn×H×(D/H)に再形成します。これはシーケンス長、ヘッド数、低次元モデルという3軸のテンソルになります。これは再形成するだけなので、計算コストはかかりません。
同様にXKとXVに対しても行い、ヘッド軸を最初の軸に転置します。実際には、D次元のXQ行列の代わりに、D/3次元の3つのXQ行列を持つようなものです。同様にキー行列も3つに分かれます。
これにより、3つのアテンションスコアのセットが得られ、それぞれに対して独立にソフトマックスを計算します。そして3つの値行列もあり、それぞれが低次元です。最終的に3つの異なる出力ベクトルが得られ、最終的な線形変換でそれらをまとめます。
要約すると、これにより各ヘッドがシーケンス内の異なる部分を異なる理由で見ることが可能になります。例えば、あるヘッドは構文的に関連する単語を見るかもしれず、別のヘッドは意味的に関連する単語を見るかもしれません。
あるブロックのすべてのアテンションヘッドは、そのブロック専用です。一般的に、各ブロックは独立したパラメータを持ちますが、例外もあります。また、ヘッドの数は通常、すべてのブロックで同じですが、これを変えることも技術的には可能です。実際には、モデルの次元Dに対して適切な次元(例えば少なくとも64次元)をヘッドごとに確保できるように、ヘッド数を設定することが一般的です。
6.2. スケーリングドット積アテンション
トランスフォーマーに追加されるもう一つの改良点は「スケーリングドット積アテンション」と呼ばれるテクニックです。これは小さな工夫ですが、モデルのパフォーマンスを向上させる上で重要です。
キー・クエリ・バリュー型のセルフアテンションの問題の一つとして、モデルの次元が大きくなると、ベクトル間のドット積が非常に大きくなる傾向があります。これが起こると、ソフトマックス関数への入力が非常に大きくなり、勾配が小さくなってしまいます。
直感的に言えば、次元Dの2つのランダムなベクトルがあり、単にドット積を計算すると、次元Dが大きくなるにつれて、そのドット積は期待値としても大きくなります。理想的には、すべての単語に対するアテンションが初期状態では非常に均一で平坦であることが望ましいです。どこも見ないよりも、まずは広く見渡すことからスタートする方が良いでしょう。
しかし、一部のドット積が非常に大きい場合、学習が阻害されます。そこで、各ヘッドに対して、モデルの次元によって決まる定数でスコアを割ることで、この問題を解決します。
具体的には、アテンションスコアeijを√Dで割ります。またはマルチヘッドアテンションの場合は√(D/H)で割ります。これにより、ベクトルが非常に大きくなっても、少なくとも初期化時にはドット積が大きくなりすぎないようにします。
これは「スケーリングドット積アテンション」と呼ばれ、実装は簡単で、すべての計算で少し割り算を追加するだけです。この小さな工夫が、トランスフォーマーの学習を安定させるのに大きく貢献します。
以降、このスケーリングは常に適用されていると仮定して話を進めます。
6.3. 最適化テクニック
6.3.1. 残差接続(Residual Connections)
トランスフォーマーデコーダには、さらに二つの重要な最適化テクニックがあります。それらは残差接続とレイヤー正規化です。トランスフォーマーのウェブ上の図では、これらはしばしば「Add & Norm」というボックスとして一緒に表現されています。実際のトランスフォーマーデコーダでは、マスク付きマルチヘッドアテンションを適用し、その後にこの「Add & Norm」を行い、その後フィードフォワード層を適用し、再び「Add & Norm」を行います。これらの最適化テクニックは非常に重要なので、それぞれを詳しく見ていきましょう。
まず、残差接続についてです。これについては以前も話しましたが、モデルの学習を助ける優れたテクニックなので、もう一度説明する価値があります。
基本的なアイデアは、レイヤーi-1があり、それを何か(セルフアテンションかもしれないし、フィードフォワードネットワークかもしれない)に通してレイヤーiを得る代わりに、レイヤーiの結果をその入力に足すということです。つまり、前のレイヤーからの残差だけを学習すればよいのです。
これは多くの場合、図では「接続」として描かれ、周りを回るような接続として表現されます。この残差接続を通る勾配は非常に良いと考えるべきです。例えば、このレイヤーを通る勾配が消えたり爆発したりしても、残差接続には勾配が1になるアイデンティティがあるため、その背後にあるすべてを学習することができます。
これは非常に優れた手法で、初期化時には、すべてが少しアイデンティティ関数のように見えるという利点もあります。というのも、レイヤーからの寄与が重みが小さいために幾分か小さく、入力からの加算があれば、全体としてアイデンティティのように見え、これは良いスタート地点かもしれないからです。
これを視覚的に表現した素晴らしい図があります。これは損失関数の風景で、勾配降下法を使って損失関数の山々を横断しようとしています。これはパラメータ空間であり、下に行くほど良いです。しかし、この地形はとても険しく、局所的な最適解に陥ってしまうかもしれません。しかし、残差接続を使うと、単に下に歩いていくだけでよくなります。これが必ずしも実際の動作ではないかもしれませんが、この図は非常に魅力的です。
6.3.2. レイヤー正規化(Layer Normalization)
レイヤー正規化は、モデルの学習を高速化するためのもう一つのテクニックです。レイヤー正規化の直感的な理解やそれが経験的にうまく機能する理由は、完全には一致していないかもしれませんが、基本的な考え方を説明します。
各レイヤー内の変動について考えてみましょう。値が非常に大きくなったり小さくなったりすることがあり、これは実際には勾配の違いや、レイヤー間で完全にコントロールできない奇妙な現象によるものかもしれません。こうした「非情報的な変動」を減らしたいと考えます。
次元Dの個々の単語ベクトルXをモデル内の一つの単語ベクトルとして考えましょう。このベクトル内の変動を正規化したいと思います。つまり、平均と標準偏差を単位化するという意味での正規化です。
まず、ベクトル内のすべての次元にわたる平均μを計算します。ベクトル内のすべての値をj=1からモデルの次元Dまで合計し、Dで割ります。これがベクトル内の値の平均です。
次に、標準偏差σの推定値を計算します。これもまた、このひとつのベクトル内の値についての単純な推定値です。
そして、任意で学習可能なパラメータγとβを用いて、乗算的かつ加算的にスケールバックすることができます。これはオプションです。
正規化の計算では、ベクトルXから平均μを引き、標準偏差σの平方根にイプシロン(小さな定数)を加えたもので割ります。イプシロンは変動が非常に小さい場合に値が爆発するのを防ぐためのものです。この部分(X-μ)/√(σ+ε)は、すべての変動を単位平均と標準偏差に正規化しています。その後、必要に応じてγで拡大しβをオフセットとして加えることができます。
実際には、この最後の部分(γとβによるスケーリング)はそれほど重要ではないかもしれません。講義ノートで詳しく議論されています。
レイヤー正規化の出力は、前のレイヤーで何が起こったかに関係なく、次のレイヤーにとって「きれいに」見えるようになります。単位平均と標準偏差を持つので、次のレイヤーが学習するのに良い入力になるかもしれません。
「5単語のシーケンスがある場合、統計を共有するかどうか」という質問がありました。これは良い質問で、トランスフォーマーについて議論するすべての論文で明確に指定されていないと思います。答えは「共有しない」です。5つの単語はそれぞれ完全に独立して処理されます。
また、「バッチ間で統計を共有するか」という類似の質問もありました。答えは同様に「いいえ」です。バッチ間でも統計を共有しません。実際、レイヤー正規化はバッチ正規化の代替として発明されました。バッチ正規化の問題点は、フォワードパスが、本来関連すべきでない他の例に依存することです。したがって、バッチ間でも統計を共有しません。
6.4. デコーダの完全な構造
これで私たちはトランスフォーマーデコーダの完全な構造を持っています。各ブロックは次のように構成されています:まずマスク付きのマルチヘッドアテンションを適用し、その後に残差接続を行い(図ではデコーダの周りを回る接続として表現されています)、さらにレイヤー正規化を行います。次にフィードフォワード層を適用し、再び残差接続とレイヤー正規化を行います。
この4つの操作(マスク付きマルチヘッドアテンション、ADD&NORM、フィードフォワード、ADD&NORM)のセットを「ブロック」と呼び、これを複数回(ブロックの数だけ)適用します。図の中の少しグレーアウトされた「repeat」という部分が、デコーダブロックの繰り返しを示しています。
各ブロックは以下のコンポーネントから構成されています:
- マスク付きマルチヘッドセルフアテンション(将来の単語を見ないようにするマスキングを含む)
- ADD&NORM(残差接続とレイヤー正規化)
- フィードフォワードネットワーク
- ADD&NORM(残差接続とレイヤー正規化)
これらの操作を複数のブロックに渡って繰り返し適用することで、単語の表現はより洗練され、文脈に応じた情報を豊かに含むようになります。最終的には、このデコーダの出力を使って、次の単語の予測や他のタスクを行うことができます。
このようにして、位置の表現が必要であること、将来を見ないようにする必要があること、非線形性を追加する必要があることなど、様々な問題を解決した完全なトランスフォーマーデコーダの構造が完成します。これがトランスフォーマーの中核となるアーキテクチャです。
7. トランスフォーマーのバリエーション
7.1. エンコーダ構造
トランスフォーマーのエンコーダは、デコーダとほぼ同一の構造を持っていますが、大きな違いが一つあります。それはエンコーダでは双方向のコンテキストを扱いたいので、マスキングを行わないことです。
デコーダでは将来の単語を見ないようにするためのマスキングが必要でしたが、エンコーダではそのような制約はありません。例えば機械翻訳の場合、ソース文を符号化する際にはすべての単語が相互に参照し合うことができた方が良いと考えられます。
したがって、トランスフォーマーエンコーダでは、マルチヘッドアテンションを使用しますが、マスキングは行いません。これにより、各単語の表現を構築する際に、文全体からの情報を自由に利用することができます。
この違いを除けば、エンコーダも同様の構造を持っています:
- マルチヘッドセルフアテンション(マスキングなし)
- ADD&NORM(残差接続とレイヤー正規化)
- フィードフォワードネットワーク
- ADD&NORM(残差接続とレイヤー正規化)
これらの操作を複数のブロックに渡って繰り返し適用することで、入力シーケンスの豊かな文脈表現を得ることができます。エンコーダでマスキングを行わないというこのシンプルな変更により、双方向のコンテキストを活用したモデルが実現します。
人間の言語理解では文を読む際に前後の文脈を参照できるように、エンコーダも入力シーケンス全体を自由に見ることができるのです。これは双方向LSTMと単方向LSTMの違いに類似していますが、トランスフォーマーではすべての単語が直接相互作用できるという利点があります。
7.2. エンコーダ・デコーダ構造
トランスフォーマーエンコーダ・デコーダ構造は、元々「Attention is All You Need」という論文で提案されたものです。この構造は機械翻訳のような、ある形式から別の形式に変換するタスクのために設計されています。
具体的には、エンコーダがソース文(例えば、機械翻訳のための入力文)を処理し、デコーダがターゲット文を生成します。エンコーダはマスキングなしのマルチヘッドアテンションを使用し、入力文の双方向コンテキストを捉えます。
一方、デコーダの構造はこれまで説明してきたものより少し複雑になっています。デコーダには以下の要素が含まれています:
- マスク付きマルチヘッドセルフアテンション(これまで説明した通り、将来の単語を見ないためのマスキングを使用)
- クロスアテンション(Cross-Attention):これは新しい操作で、デコーダのクエリとエンコーダの出力をキーとバリューとして使用します
つまり、デコーダでは各単語を生成する際に、まず自分自身のこれまで生成した単語に対してマスク付きセルフアテンションを適用し、その後、エンコーダが処理したソース文全体に対してアテンションを向けることができます。
図で見ると、エンコーダからデコーダへの矢印が2本あり、それぞれキーとバリューを表しています。また、デコーダ自身からの矢印が1本あり、これがクエリを表しています。
このエンコーダ・デコーダ構造により、ソース文の情報を効果的に活用しながら、ターゲット文を一語ずつ生成することができます。例えば、「I like pizza」という英語の文を「J'aime la pizza」というフランス語に翻訳する場合、デコーダは「J'」を生成した後、「aime」を生成する際に、英語の文全体に対してアテンションを向けることができます。
7.3. クロスアテンションの仕組み
クロスアテンションは、トランスフォーマーのエンコーダ・デコーダ構造において、エンコーダとデコーダを繋ぐ重要な役割を果たします。これがどのように機能するのか、数学的に説明していきましょう。
まず、エンコーダの出力としてH1からHnのベクトルがあるとします。これらはエンコーダがソース文を処理した結果です。また、デコーダの出力としてZ1からZmのベクトルがあります。クロスアテンションでは、エンコーダの出力からキーとバリューを作成し、デコーダの出力からクエリを作成します。
具体的には、以下のように計算します:
キー:K × Hi = Ki(エンコーダの出力Hiからキーを生成) バリュー:V × Hi = Vi(エンコーダの出力Hiからバリューを生成) クエリ:Q × Zj = Qj(デコーダの出力Zjからクエリを生成)
ここで、K、V、Qはそれぞれ学習可能なパラメータです。
図で見ると、エンコーダからデコーダへの矢印が2本あり、それぞれキーとバリューを表しています。また、デコーダ自身からの矢印が1本あり、これがクエリを表しています。
このクロスアテンション機構により、デコーダの各単語は、エンコーダが処理したすべての単語に対してアテンションを向けることができます。例えば、機械翻訳において、ターゲット言語の単語を生成する際に、ソース言語のどの単語に注目すべきかを学習できます。
具体的に例を挙げると、「I like pizza」という英語の文を「J'aime la pizza」というフランス語に翻訳する場合、デコーダは「aime」を生成する際に、主に英語の「like」に注目するでしょう。このようにして、単語間の対応関係を学習し、適切な翻訳を生成することができます。
クロスアテンションは、エンコーダの情報をデコーダに効果的に伝達する橋渡しの役割を果たしており、エンコーダ・デコーダ構造におけるトランスフォーマーの強力な機能の一つです。
8. トランスフォーマーの成果と課題
8.1. 機械翻訳における成果
トランスフォーマーの元々の結果についてお話しましょう。彼らは並列化によってより多くの計算を行えるという大きな利点を提案しました。機械翻訳においてトランスフォーマーは良い結果を示しましたが、既存の機械翻訳システムと比較して驚くほど優れていたわけではありません。
しかし、トランスフォーマーは訓練が著しく効率的でした。これは並列化の問題がないため、より多くのデータでより速く計算でき、より速いGPUをより効果的に活用できたからです。
その後、文書生成のようなタスクでも、古い標準であったLSTMベースのシーケンス・ツー・シーケンスモデルから、最終的にすべてがトランスフォーマーベースになっていきました。トランスフォーマーはまた、次の授業で説明する事前学習の革命も可能にしました。
並列化による効率性と計算能力の向上により、膨大なデータで計算することが可能になりました。ある時点から、標準的な大規模ベンチマークではすべてトランスフォーマーベースになりました。大量のデータと計算能力を活用できるこの能力は、ほぼすべての最新の自然言語処理の進歩において、トランスフォーマーをLSTMよりもはるかに優れたものにしました。
トランスフォーマーが機械翻訳で示した最初の結果は、既存のシステムよりも劇的に優れていたわけではありませんでしたが、訓練効率の大幅な向上により、より大きなデータセットでより効率的に学習できるようになりました。この効率性こそが、トランスフォーマーが自然言語処理の分野で広く採用される主な理由の一つとなりました。
8.2. 事前学習モデルへの展開
トランスフォーマーは事前学習という革命を可能にしました。これについては次の講義で詳しく説明しますが、トランスフォーマーの並列化能力と効率性により、膨大な量のデータに対して計算できるようになりました。
この並列化と計算効率の向上は、大規模な事前学習言語モデルの開発に不可欠でした。これによりGPUの計算能力を最大限に活用でき、以前のLSTMベースのアーキテクチャでは実現不可能だった規模でモデルを訓練できるようになりました。
ある時点から、標準的な大規模ベンチマークではほとんどすべてがトランスフォーマーベースのモデルになりました。大量のデータと計算能力を利用できる能力は、自然言語処理の最新の進歩のほぼすべてにおいて、トランスフォーマーをLSTMよりも圧倒的に優れたものにしました。
事前学習モデルの文脈では、トランスフォーマーは大規模なテキストコーパスから言語の一般的なパターンを学習し、その後、特定のタスクに微調整することができます。これにより、個々のタスクごとにゼロからモデルを訓練する必要がなくなり、限られたラベル付きデータでも高い性能を発揮できるようになりました。
トランスフォーマーベースの事前学習モデルの成功例としては、BERT、GPT、RoBERTaなどがあり、これらはテキスト分類、質問応答、要約、翻訳などの多様なタスクで最先端の結果を達成しました。これらのモデルの成功により、トランスフォーマーは現代の自然言語処理の基盤となる技術となりました。
8.3. 計算量の二次関数的増加問題
トランスフォーマーには多くの利点がありますが、いくつかの重要な課題も存在します。人々が取り組んできた最も明確な問題の一つは、二次計算問題です。すべてのペア間の相互作用を計算することで、各ブロックの総計算量がシーケンス長に対して二次関数的に増加します。
学生の質問にもあったように、シーケンス長が長くなると、Wikipedia記事全体や小説全体を処理するのが非常に困難になります。これは、ある意味で後退と言えます。なぜなら、再帰型ニューラルネットワークではシーケンス長に対して線形にしか増加しなかったからです。
この二次計算問題の直感的な理解として、キーとクエリのドット積を計算した際に得られるn×nの行列を考えてみましょう。この計算は大きなメモリコストを必要とします。
例えば、モデルの次元が約1000(現在のモデルではもっと大きくなりますが)だとすると、短いシーケンス(n=30程度)の場合、N²×Dの計算はそれほど大きくありません。しかし、50,000単語のようなものになると、N²が非常に大きくなり、完全に実行不可能になります。
この問題に対処するため、人々は情報を低次元空間にマッピングして二次計算を削減しようとしてきました。しかし実際には、GPT-3やChatGPTのような大規模モデルでは、計算の大部分はセルフアテンション操作にあるわけではないため、これが本当に必要かどうかは研究の開かれた形態です。
現実的には、この制約により、標準的なトランスフォーマーモデルのコンテキスト長は数千単語(大規模モデルで約4000単語程度)に制限されます。これは短い文書には十分かもしれませんが、小説やWikipediaページ全体を処理するには不十分です。この制限を克服するためのさまざまなアプローチが研究されていますが、これは現在もトランスフォーマーの大きな課題として残っています。
8.4. トランスフォーマーの改良と今後の展望
トランスフォーマーは過去4〜5年間に数多くの修正が加えられてきました。しかし興味深いことに、オリジナルのトランスフォーマーにいくつかの修正を加えたものが、現在でもほぼ最良のモデルであり続けています。
いくつかの重要な変更点としては、フィードフォワードネットワークの非線形性を変更することが重要であることが判明しています。しかし、トランスフォーマーは非常に持続的な力を持っており、様々な改良の試みがあったにもかかわらず、その基本的な構造は残っています。
トランスフォーマーの改良に関する研究は継続的に行われており、位置表現の改善、より長いシーケンスを効率的に処理する方法、異なる種類のアテンションメカニズムなど、さまざまな方向性があります。しかし、これらの修正のほとんどは、オリジナルのトランスフォーマーアーキテクチャの基本的な構造を大きく変えるものではありません。
いくつかの修正は、特定のタスクや条件下でパフォーマンスを向上させることが示されていますが、一般的には元のアーキテクチャがその単純さと効率性で依然として優れています。
今後の展望としては、トランスフォーマーの計算効率をさらに改善し、より長いシーケンスを処理できるようにする研究が続くでしょう。また、マルチモーダル(テキスト、画像、音声などの複数のモダリティを統合する)能力の向上や、より少ないデータと計算リソースでの効率的な学習方法も研究の重要な方向性です。
トランスフォーマーは現在の自然言語処理において標準的なアーキテクチャとなっていますが、その限界を克服し、さらに改良するための研究は開かれた分野であり、今後も革新的なアイデアが生まれることが期待されます。
トランスフォーマーが自然言語処理の基本的な構成要素としての地位を確立しましたが、さらなる向上の余地はまだまだあります。人々がトランスフォーマーの様々な側面を改善するためのアイデアを考え出すことを期待しています。