発展:Transformer の機構を分解する
Attention と Transformer のレッスンの続きとして、Transformer の内部を機構のレベルまで分解します。今の大規模言語モデルの土台を理解するために書いています。トークン埋め込みと位置符号、スケール付き内積による自己注意、マルチヘッド、フィードフォワード層、残差結合と層正規化、エンコーダとデコーダ、注意のマスク処理、そして語彙上の確率分布までを数式の意味を言葉で補いながら追います。実装のコードは扱わず、なぜそう作るのかに絞ります。
ねらい
このレッスンは、Attention と Transformer(トランスフォーマー)のレッスンの続きにあたる発展(はってん)の記事です。今の大規模言語モデル(だいきぼげんごモデル、Large Language Models)の土台になっているのが Transformer であり、その内部を機構(きこう)のレベルまで見ておくと、新しいモデルの話を筋道立てて追えるようになります。
この記事は、ある程度の知識のある人に向けた深掘りです。基礎レッスンで「Attention は関係の強さに応じて情報を集めるしくみ」「Transformer はそれを積み重ねたもの」とつかんでいることを前提にします。数式もいくつか出しますが、記号だけで終わらせず、その式が何をしているのかを言葉でも説明します。実装のコードは扱いません。あくまで、なぜそう作るのか、という考え方に絞ります。
1. 全体像:関係を計算する層を積み重ねる
Transformer がしていることをひとことで言えば、単語の列を受け取り、単語どうしの関係を計算し直して、意味のこもった表現に作り変えることです。
もう少し細かく見ると、Transformer は同じ形をした層(そう)をいくつも積み重ねてできています。1つの層は、大きく2つの部品からできています。1つは、単語どうしの関係を計算する自己注意(じこちゅうい、Self-Attention)の部品です。もう1つは、その結果を単語ごとに変換するフィードフォワード層(Feed-Forward Network)です。この2つの部品を通るたびに、各単語の表現は、周りとの関係を織り込んだものへと更新されます。
入力の単語列は、まず数のベクトルの列に変換されます。それが1層目に入り、関係を織り込んで更新され、2層目に入り、また更新され、と層の数だけくり返されます。最後に、更新され切った表現から、目的に応じた出力を取り出します。文章を作るモデルなら、次に来る単語の確率を取り出します。
この記事は、この流れを入り口から出口まで、順に開いていきます。
2. 入力をベクトルにする:トークン埋め込みと位置符号
Transformer の入り口では、2つのことが起きます。単語を意味のベクトルにすることと、その単語が何番目にあるかの情報を足すことです。
まず、文章はトークン(token)という単位に区切られます。トークンは、単語よりも細かい部分文字列であることが多いのですが、区切り方そのものは別のレッスンで扱います。ここでは、文章がトークンの列になり、各トークンに意味のベクトルが割りあてられる、と押さえてください。トークンを意味のベクトルに変換したものをトークン埋め込み(トークンうめこみ、token embedding)と呼びます。これは、のちの単語の分散表現のレッスンで扱うベクトル化をトークンの単位で行うものだと考えて差し支えありません。
ここで、Transformer に固有の問題が1つあります。自己注意は、次の節で見るように、単語どうしの関係を一度にまとめて計算します。一度にまとめて計算するということは、そのままでは「どの単語が前で、どの単語が後ろか」という並び順の情報が失われる、ということです。回帰結合のネットワークは1つずつ順に読むので並び順が自然に入りますが、Transformer は並行して見るぶん、順番を別に教えてやる必要があります。
そこで、各位置を表すベクトルをトークン埋め込みに足し合わせます。この位置を表すベクトルを位置符号(いちふごう、positional encoding)と呼びます。位置エンコーディングとも呼びます。もともとの Transformer では、位置ごとに周期の異なる波(正弦波と余弦波)の値を並べたベクトルを使いました。周期の違う波を組み合わせると、位置ごとに異なるパターンが作れるため、モデルは「何番目か」を読み取れます。位置符号を学習で獲得する方式や、後で触れる回転で位置を表す方式もあります。
要点は、Transformer の入り口では、意味のベクトル(トークン埋め込み)に、並び順のベクトル(位置符号)を足し合わせて、1つの入力ベクトルにする、ということです。
理解の確認
Transformer の入力は、トークンごとの意味を表すトークン埋め込みに、並び順を表す位置符号を足し合わせて作ります。自己注意は単語を一度にまとめて見るため並び順が失われやすく、それを補うために位置符号を加えます。
3. 自己注意の計算:クエリ・キー・バリューとスケール付き内積
ここが Transformer の心臓部です。自己注意が、単語どうしの関係をどう数で表すのかを見ます。
基礎レッスンで、クエリ(query)・キー(key)・バリュー(value)という3つの言葉を学びました。改めて言葉にすると、クエリは「今の単語が何を探しているか」、キーは「各単語が何を持っているかの見出し」、バリューは「各単語が実際に渡す中身」です。図書館にたとえると、クエリは探し物のメモ、キーは本の背表紙の見出し、バリューは本の中身です。探し物のメモと見出しを照らし合わせ、合う本ほど中身を多く受け取る、という動きになります。
計算は3つの段階に分かれます。
1つ目は、入力ベクトルから、クエリ・キー・バリューの3つのベクトルを作る段階です。入力ベクトルに、それぞれ別の重み(おもみ)の行列を掛けて、3種類のベクトルへ変換します。この重みが学習で調整され、「何を探し、何を見出しにし、何を渡すか」が決まっていきます。
2つ目は、関係の強さを測る段階です。ある単語のクエリと、各単語のキーとの、内積(ないせき)を計算します。内積とは、2つのベクトルの向きと大きさから1つの数を出す計算で、向きが近いほど大きな値になります。つまり、クエリとキーの内積が大きいほど、その2つの単語は関係が強い、とみなされます。この内積の値をキーのベクトルの長さの平方根で割ってから使います。長さの平方根で割るのは、次元が大きいと内積の値が大きくなりすぎて、次の段階の計算が偏るのを防ぐためです。この割り算があるので、スケール付き内積注意(スケールつきないせきちゅうい、scaled dot-product attention)と呼ばれます。
3つ目は、関係の強さを重みに変え、バリューを混ぜる段階です。ある単語について、すべての単語との関係の強さが並びます。これをソフトマックス関数(softmax function)に通して、合計が1になる重みの並びに変えます。ソフトマックス関数のしくみは、活性化関数のレッスンで学んだとおりで、大きい値ほど大きな重みになり、全体で1になるようにそろえます。こうして得た重みで、各単語のバリューを掛けて足し合わせます。関係の強い単語のバリューほど多く混ざり、弱い単語のバリューはわずかしか混ざりません。
式でまとめると、Attention(Q, K, V)= softmax( QとKの内積 ÷ √(キーの長さ) )で V を重みづけして混ぜ合わせたもの、となります。注意の出力は、クエリとキーの内積をキー次元の平方根で割り、ソフトマックス関数に通した重みで、バリューを加重平均したものです。言葉で読み下すと、「探し物と見出しの合い具合を求め、合うものほど大きな重みにし、その重みで中身を混ぜ合わせる」となります。
これを文中のすべての単語について同時に行います。すべての単語が同時にクエリを出し、すべての単語のキーと照らし合わせ、すべての単語のバリューを混ぜる。この一斉の計算が、自己注意です。単語を1つずつ順に読む回帰結合とちがい、離れた単語どうしの関係も、間の距離によらず一度に測れます。ここが、長い文脈を扱ううえで効いてきます。
理解の確認
自己注意は、各単語からクエリ・キー・バリューの3つのベクトルを作り、クエリとキーの内積で関係の強さを測り、キー次元の平方根で割ってソフトマックス関数に通した重みで、バリューを加重平均します。すべての単語について同時に計算するため、離れた単語どうしの関係も距離によらず一度にとらえられます。
4. マルチヘッド注意:複数の関係を並行して
単語どうしの関係は、1種類ではありません。文法のうえでの係り受けもあれば、意味のうえでのつながりもあり、指し示す先の関係もあります。1回の自己注意だけでは、こうした複数の関係を1つの重みに押し込めることになり、とらえ切れません。
そこで、自己注意を1回ではなく、いくつも並行して行います。これをマルチヘッド注意(マルチヘッドちゅうい、Multi-Head Attention)と呼びます。ヘッド(head)とは、1組の自己注意の計算のことです。それぞれのヘッドは、別々の重みでクエリ・キー・バリューを作るので、別々の観点で関係を測れます。あるヘッドは文法的な係り受けに、別のヘッドは意味の近さに、というように、役割が自然に分かれていきます。
各ヘッドは、入力の全体をそのまま使うのではなく、次元を分け合って担当します。たとえば表現が512の次元を持ち、ヘッドが8つあれば、各ヘッドは64の次元を受け持ちます。こうすると、ヘッドを増やしても全体の計算量は大きく変わりません。各ヘッドの出力は最後に横につなぎ合わせ、もう1つの重みの行列で混ぜて、1つの出力にまとめます。
ポイント
自己注意は関係を1つの重みで測りますが、関係には複数の種類があります。マルチヘッド注意は、次元を分け合った複数のヘッドで別々の観点の関係を並行して測り、最後にまとめます。
理解の確認
マルチヘッド注意は、次元を分け合った複数のヘッドで自己注意を並行して行います。各ヘッドは別々の重みを持つため、文法・意味・指示など異なる観点の関係を同時にとらえられます。出力は横につなぎ、重みの行列でまとめます。
5. フィードフォワード層と、非線形の役割
自己注意は、単語どうしの関係を混ぜ合わせる部品でした。しかし、混ぜ合わせるだけでは、複雑な変換はできません。混ぜ合わせた表現を単語ごとにさらに作り変える部品が要ります。それがフィードフォワード層(Feed-Forward Network)です。
フィードフォワード層は、単語1つひとつの表現をいったん大きな次元へ広げ、非線形の活性化関数を通してから、元の次元へ戻します。次元を広げてから戻すのは、途中の広い空間で豊かな変換を行うためです。非線形の活性化関数は、直線では表せない複雑な関係を表すために欠かせません。もし活性化関数がなければ、何層積んでも全体は1つの直線的な変換にまとまってしまい、深くする意味がなくなります。この点は、活性化関数のレッスンで学んだとおりです。現行の大規模言語モデルでは、この活性化関数に GELU(ゲルー)や SwiGLU(スウィッシュゲートを使うもの)といった、なめらかな関数がよく使われます。
大事なのは、この変換が単語ごとに独立して行われる、という点です。自己注意が単語をまたいで関係を混ぜるのに対し、フィードフォワード層は各単語の中で表現を作り変えます。関係を混ぜる部品と、各単語を作り変える部品。この2つが交互に働くことで、Transformer は関係を織り込みながら表現を深めていきます。
理解の確認
フィードフォワード層は、単語ごとに独立して、表現を大きな次元へ広げ、非線形の活性化関数を通し、元へ戻します。自己注意が単語をまたいで関係を混ぜるのに対し、フィードフォワード層は各単語の中で表現を作り変えます。非線形がなければ、層を積んでも1つの直線的な変換にまとまってしまいます。
6. 残差結合と層正規化:深く積むための土台
Transformer は、これらの部品を何層も積みます。しかし、層を深くすると学習が難しくなることは、これまでのレッスンで見てきました。それをやわらげているのが、残差結合(ざんさけつごう)と層正規化(そうせいきか)です。
残差結合とは、部品の入力をその部品の出力にそのまま足し合わせるしくみです。スキップ結合のレッスンで学んだものと同じ考え方です。自己注意やフィードフォワード層は、入力をまるごと作り直すのではなく、入力に加える変化ぶんだけを学べばよくなります。学ぶことがやさしくなり、層を深くしても学習の信号が奥まで届きます。
層正規化とは、各単語の表現の中で、数値の平均と広がりをそろえるしくみです。正規化のレッスンで学んだレイヤー正規化(layer normalization)にあたります。部品を通るたびに数値の大きさがばらつくのを抑え、学習を安定させます。現行の大規模言語モデルでは、これを簡素にした RMSNorm(アールエムエスノーム)という正規化もよく使われます。
Transformer の1つの層は、この残差結合と層正規化を自己注意とフィードフォワード層のそれぞれに添えた形になっています。関係を混ぜ、残差で足し、正規化でそろえ、単語ごとに作り変え、また残差で足し、正規化でそろえる。この一続きが1層で、これを積み重ねることで、とても深いネットワークが安定して学べます。
理解の確認
残差結合は部品の入力を出力に足し合わせ、各部品が変化ぶんだけを学べばよいようにして、深い学習を助けます。層正規化は各単語の表現の中で数値の大きさをそろえ、学習を安定させます。Transformer の各層は、自己注意とフィードフォワード層のそれぞれに、この2つを添えた形になっています。
7. エンコーダとデコーダ、交差注意、マスク処理
もともとの Transformer は、翻訳のために作られました。入力の文を読み取る部分と、出力の文を作る部分の、2つからできています。読み取る部分をエンコーダ(encoder)、作る部分をデコーダ(decoder)と呼びます。
エンコーダは、入力の文全体を一度に見て、各単語の表現を作ります。ここでの自己注意には、見てよい範囲の制限がありません。ある単語は、前の単語も後ろの単語も見て、文全体の文脈から意味を読み取れます。
デコーダには、2つの工夫が加わります。1つは、マスク処理(マスクしょり)です。文章を作るとき、モデルは1単語ずつ生成していきます。ある時点で次の単語を予測するのに、まだ生成していない未来の単語を見てしまっては、答えを盗み見ることになります。そこで、自己注意の計算で、未来の位置の関係を見えなくします。具体的には、未来の位置との関係の強さをソフトマックス関数に通す前に、限りなく小さい値にして、重みがほぼ0になるようにします。これをマスク処理と呼び、こうした自己注意をマスク付き自己注意(masked self-attention)と呼びます。過去と今だけを見て、未来は見ない。この制限があるから、生成のときと学習のときで、見える範囲が食いちがわずにすみます。
もう1つは、交差注意(こうさちゅうい、Source-Target Attention)です。デコーダは、出力側の単語どうしの関係を見るだけでなく、入力側の文にも注意を向ける必要があります。翻訳なら、訳文を作りながら原文の対応する箇所を見る、という動きです。交差注意では、クエリを出力側(デコーダ)から作り、キーとバリューを入力側(エンコーダの出力)から作ります。こうして、出力側の各単語が、入力側のどこに対応するかを測りながら、訳文を組み立てます。基礎レッスンで学んだ Source-Target Attention が、この交差注意にあたります。
なお、今の大規模言語モデルの多くは、このうちデコーダの部分だけを使う構成です。入力も出力もひとつながりの文として、マスク付き自己注意だけで次の単語を予測していきます。エンコーダ・デコーダの2部構成は、翻訳のように入力と出力がはっきり分かれる仕事で使われます。
理解の確認
エンコーダは入力文全体を見て表現を作り、デコーダは1単語ずつ出力を作ります。デコーダのマスク付き自己注意は、未来の位置を見えなくして、生成と学習で見える範囲をそろえます。交差注意は、クエリを出力側から、キーとバリューを入力側から作り、出力の各単語が入力のどこに対応するかを測ります。
8. 出力:語彙上の確率分布へ
最後の層を通り抜けた各単語の表現には、周りとの関係が十分に織り込まれています。ここから、目的の出力を取り出します。文章を作るモデルの場合、取り出すのは「次に来る単語の確率」です。
まず、最終層の表現に重みの行列を掛けて、語彙(ごい)の数だけの長さを持つ値の並びに変えます。語彙とは、モデルが扱えるトークンの全種類のことです。この値の並びは、各トークンの「なりやすさの点数」だと考えてください。点数が高いトークンほど、次に来やすい候補です。
次に、この点数の並びをソフトマックス関数に通して、合計が1になる確率の並びに変えます。こうして、語彙のすべてのトークンに対する、次に来る確率が得られます。モデルは、この確率にもとづいて次のトークンを選びます。いちばん確率の高いものを選ぶこともあれば、確率に応じてくじを引くように選ぶこともあります。選んだトークンを列の末尾に足し、それをまた入力にして、次のトークンを予測する。このくり返しで、文章が生成されていきます。生成のときの選び方には、ビームサーチや確率にもとづくサンプリングといった工夫がありますが、それらは自然言語処理の応用のレッスンで扱います。
理解の確認
出力では、最終層の表現を語彙の数だけの点数の並びに変え、ソフトマックス関数で確率の並びにします。これが次のトークンの確率分布です。モデルはこれをもとに次のトークンを選び、列に足して、また予測する、をくり返して文章を生成します。
9. 発展:計算量と、現行の効率化
ここからは、さらに先の発展です。自己注意には、避けがたい弱点があります。文中のすべての単語どうしの関係を測るため、単語数が増えると計算量がその2乗で増えることです。単語数が2倍になれば計算はおよそ4倍、10倍になればおよそ100倍です。長い文章を扱おうとするほど、この2乗の重さが立ちはだかります。
この重さをやわらげる工夫が、現行のモデルで数多く研究されています。手法を軸に、代表的な方向を3つ挙げます。
1つ目は、注意の計算そのものを効率化する方向です。計算の順序やメモリの使い方を工夫して、同じ結果をより速く、より少ないメモリで求めます。FlashAttention(フラッシュアテンション)と呼ばれる手法がよく知られています。
2つ目は、すべての単語どうしを見るのをやめ、関係を見る相手を絞る方向です。近くの単語だけを見る、一部の代表だけを見る、といった工夫で、2乗の重さを軽くします。長い文脈を扱えるようにする長文脈化の工夫は、この方向と深く関わります。
3つ目は、位置の表し方を作り直す方向です。もともとの位置符号は足し算で位置を入れていましたが、回転で位置を表す回転位置埋め込み(RoPE、ロープ)という方式が、現行のモデルで広く使われています。回転で表すと、学習で見た長さよりも長い文章にも、比較的うまく対応しやすいという利点があります。
これらの手法は入れ替わりが速く、どれが主流かは年ごとに変わります。ここでは、自己注意が単語数の2乗の計算量を持つという弱点と、それをやわらげる方向がいくつもある、という筋道をつかんでおいてください。個々の手法の名前よりも、なぜ効率化が要るのか、どこを削って軽くしているのかを押さえておくと、新しい手法が出ても位置づけを追えます。
理解度の確認
説明できる項目にチェックを入れましょう。すべて確認できたら、完了ボタンで記録します。
分からなかった点・気になった点
読み込み中です。