conceptualization読者になるconceptualization2023-03-27GPTの仕組みと限界についての考察(2.1)全3回のシリーズパート2の本記事では、GPTの能力と可能性をAttention/Transformerの仕組みをふまえて考察します。いうつもりでしたが、凄く長くなってしまったのでパート2は以下の3回に分けようと思います。自然言語の構造を考えてみるまず我々が使う言語についてちょっと振り返るところから話を始めましょう。その上の意味、という風に階層的な構造を持っていると我々は概念的に認識してますよね。構文の階層そして、各階層や階層間には、文法や語法といった言葉のルールがあります。深層学習はその名の通り、層を深くしたニューラルネットワークなので、文法や意味が織りなす各階層を深層学習の各レイヤー(=層)に対応させるのは自然な発想ですよね。その意味でTransformerは凄く自然な形をしたアルゴリズムです。このレイヤー・層の1個分がTransformer1段に相当すると、ひとまず認識しておけば、まずは差し支えないです(そう認識してしまうとどう差し支えて、じゃあ正確にはどう認識すればよいかは本記事を読み進めれば分かります)。Transformer登場Transformerの解説記事を読んだことのある人ならたぶん1億回くらい見たことのある下の図を見てみましょう。Need」から転載)N個のTransformerが積まれた図この図は、左下のInputsからトークン列が入力されて、(EmbeddingやEncodingは次回の記事で説明するのでいったん無視して)、Nxと書いてあるところがTransformerがN個垂直に積み重なって文脈をエンコードしていくという意味です。それでN個のTransformerを経て「文脈」情報が左半分のてっぺんで得られます。それを右半分のデコーダに渡しますが、右半分もN個のTransformerが垂直に積み重なった形をしています。Transformerの灰色のボックスの中に入れ子で入ってるボックスがいくつかありますが、それらは次回に説明するので、今回は大枠を見ていきましょう。右半分はOutputから矢印の向きが「入力」されちゃってます。不思議に思われるかもしれませんが、これは機械学習の「生成モデル」ではよくある形です。右半分のてっぺんでは「Outputの確率」と書いてあって、要は「教師データの入力に対する出力」の確率を計算するよ、っていうのがこの図が示す深層学習モデルがやろうとしていることです。生成モデルとデータサンプリング例えば、右下のOutputsとして、右上のてっぺんで算出される確率が最大になるようなものを選べば、入力テキストだけあって出力テキストを得たい「テキスト→テキスト」の問題を解くことが出来ます。その「テキスト→テキスト」が出来れば、「対話システム」や「翻訳システム」は作れそうですよね。イメージ的には、入力テキスト(文字列)から層を何段階か経て「意味情報が含まれた『文脈』」へと情報を「エンコード」して行き(これが図の左半分)、そのあと折り返して今度は「文脈」から出発して層を何段階か経ることで情報を「デコード」して(これが図の右半分)最終的に出力テキストを得る、という感じです。繰り返しになりますが、右半分の矢印が上向きで「デコーダ」という言葉だったら普通は下向きになるはずですが、そのように逆向きになってるのは「生成モデル」の特徴です。ここからデータを出力する作業は、いってみれば方程式を立てて、その方程式解くのと似てます。生成モデルを使って何かデータを生成するというのは、だいたいそんなイメージになります。詳しい方法は例えば以下のような記事を読んでみてください。huggingface.co方程式を解くのとちょっと違うのは、確率モデルなので、確率が最大じゃないケースのデータも「サンプリング」して得ることも出来たりすることです。方程式とちがって「解ごとに尤(もっと)もらしさ」がつきます。尤もらしい解以外にも、それなりに尤もらしい解は色々とあるはずなので、そういうのをサンプリング(出力)できるわけです。ChatGPTではブラウザの「リロードマーク」みたいな「Re-generate(再生成)」ボタンがついてて、それを押すと別の回答を出したりできますよね。説明してしまったところであれですが、GPTの場合は「テキスト→テキスト」ではなく「テキスト→単語」なので本当は違います。これについてはだいぶ後で述べたいと思っていて、いったんはこのまましばらく話を進めます。Transformerの入出力さて、続いてAttentionですが、ズバリ、Transformerの入出力がAttentionになります。先の図でいうと、灰色で囲まれたブロックがTransformerでしたが、その前後にある1本の線を流れるのがAttentionという形式のデータです。左上で「エンコード結果」として出てくる「文脈」情報は、具体的な形式としてはAttentionになります。前回の記事の「『文脈』は、ひとかたまりの情報に圧縮とかしない」という話を思い出してください。データの流れとしては図からも分かる通り、「トークン列→Attention→Attention→...→Attention(エンコード結果)=『文脈情報』」という形になります。その際に各層間で受け渡されるAttentionのサイズは変わらないのです。最終的なエンコード結果の「文脈情報」のデータサイズも最初のトークン列と同じ規模になります。これが、「圧縮とかそういう感じじゃなくて、トークン列を『まるっと同時に』扱ってる」という意味です。*1AttentionのイメージAttentionの具体的な中身については次回の(2.2)で述べますが、大まかにいうと上図のように「各トークン(=各単語)を、それぞれ意味を表す数値ベクトルで表現したもの」になります。何か1塊の圧縮された情報表現が採用されてるわけではなく、トークンごとに数値ベクトルがあるという、ただそれだけのデータがAttentionです。ヘッド)という概念にふれておきたいと思います。「栗山監督の率いる日本代表チームは、スーパーヒーロー大谷選手を始めとするチームメンバーの大活躍のおかげでWBCにおいて3度目の優勝を果たした。」という文があったとします。これの意味をコンピュータ上にデータとして表現したいわけですが、ひとまずこの文をシンプルに「チームは優勝を果たした」としてしまいます。これが元の文の骨格であることは確かですよね。この骨格において「チーム(は)」「優勝(を)」「果たし(た)」をそれぞれ「主辞」とみなし、主辞が3つあるので3つのデータレコードを作りましょう。それ以外は単なる「飾り(修飾語句)」に過ぎません。その飾りをどうやって付けていくかですが、「栗山監督が率いる」や「日本代表」は「チーム」に係ってるので、「チーム」を表すデータの下にそれぞれを「おまけみたいな感じ」で付け加えておけばよさそうです。同様に、「優勝」には「3度目」っていうのを「意味のおまけ」として付けとけばいいでしょう。最後の「果たした」については、残りの修飾語句との関係はありますが、「大谷選手」も「大活躍」も「WBC」も、「果たした」に直接付け加える語句としては微妙に違う感じがします。それらは「優勝を果たした」に対する修飾語句だからです。そこで先にやっておく処理として「優勝を」を「果たした」の下に付けわえておくことにします。すれば、「果たした」だけで付加情報をあわせれば「優勝を果たした」を意味するので、残りの「大活躍のおかげ」とかいった修飾語句も「果たした」に直接付けちゃっても意味がちゃんと表せそうですよね。同じ主辞におまけをつけるにしても、「おまけ同士が対等ではなく、優劣や主従関係がついてることがあっても良い」のです。「果たし(た)」という主辞にとって「一番大事なおまけ」が「優勝(を)」という(他動詞「果たす」の)目的語なわけです。このときの文の各部分の句における「代表となる語」のことを「主辞(Head)」と呼びます。主辞は前節で述べたような「文のおおもとの骨格」だけでなく、修飾語句の中にも主辞を設けます。文法の構文階層の最下層である単語のレベルから主辞用のデータレコードをそれぞれ用意しておきます。wikipediaからの転載です。繰り返しになりますが、各単語にスロットがあり、修飾語句は被修飾語句となる主辞のスロット(これが大事!)に自身を指し示す情報(インデクスやポインタ)を埋め込むことで、階層的に文の意味を表現します。すれば、階層構造が何段階も高層ビルのように高くなっても、どの階層にも「主辞」が必ず存在するように文法を定義しておけば、上のように(それがたとえ高層ビル的な複雑なものだとしても)文全体の意味をちゃんと表現できますよね。この主辞と呼ばれるデータ構造、あたかもデータベースのレコードに設けられたスロットに値を埋めていくように用いるこの構造のことを「素性構造(そせいこうぞう)」と呼びます。詳しくは述べませんが、上図のように意味を記号的なデータとして表現する際のデータ構造だと思ってください。素性構造とAttentionの類似性さて、なんとなく話が見えて来たでしょうか?「Attentionが各トークンをそれぞれ数値ベクトルで表しただけのデータだったこと」と、この「素性構造」というデータ構造が話としてつながることが想像できますでしょうか?上図の素性構造において、解析の「出発点となる一番下の各単語に主辞としてのデータレコードをそれぞれ用意」しておくという話と、上述した「トークン列や、その直後のAttention」という話とが凄く似てると思いませんか?「文脈情報」が「一塊の圧縮された何らかの数値とかデータ」とかじゃななくて、Attentionという「トークンごとに数値ベクトルがついたものが、トークンの長さぶん並んだデータ」として表現されているときに、その数値ベクトルたちの中身が実際のところ何を表現しているのかをこの素性構造の仕組みから類推してイメージ出来ますでしょうか?次節でさらに詳しく考察してゆきましょう。主辞を使った構文解析や意味解析は、深層学習がブームになるより前の時代から、自然言語処理において長らく研究が続けられてきました。その手法では先のwikipediaの図(ツリー状の構文解析木)を見ても分かる通り、データは「記号的」です。ツリーの一番下の階層では単語の意味を(あらかじめ用意した)辞書から拾ってきて、その意味のあいまいさもスロットを複数用意して選択肢を全て埋めておき、文の解析が進むにつれて曖昧さが解消されて意味が確定した時には他の選択肢がスロットから消去されて正しい意味だけが残るようにする、というプログラムを作ろうとしてきたわけです。文法も人間の手でプログラムしなくてはなりません。辞書と文法を与えなければいけないので非常に大変です。これが記号的にやるデメリットといえるでしょう。*2深層学習というパラダイムシフトは、そうした記号的なデータやそれを扱うプログラミングをせずとも、分析したい対象を全て数値として表現し大量のデータからの学習でシステム全体が何とかうまく動くようにする、というものですよね。*3しかしそれで、辞書や文法を用意せずに済み、さらに単語や句の意味の曖昧さの解決、照応解析(指示語や代名詞が指し示す先の同定)といった手でプログラミングしたらめっちゃ複雑になりそうなことを全部自動で学習できちゃうのは本当に驚異的なことです。Attentionが表す数値ベクトル(の列)の内容Attentionは、トークン内の各単語をそれぞれ数値ベクトルで表します。これは私の個人的な解釈になりますが、その「各トークンが持つ数値ベクトル」はちょうど「素性構造において各単語が(自身のスロットを率いて)持つ情報」のようなものに相当するとみなせると考えています。素人の独自解釈とはいえ、ちゃんと根拠があります。Attention」と名付けられたパーツがあります。これは英語においてHead(=主辞)という同じ単語を使っていることから、英語としてニュアンスを共有していると筆者の独自解釈ではありますが、そう捉えています。ゆえに、素性構造とAttentionの間に類似性を見出すことで、直感的にイメージしようというのが、本「考察」記事の主眼であります。Transformerを多段に積んで文(というかトークン列)を解析していくなかで各段のTransformerを通じてAttentionがどのように変わっていくかというふるまいについても、「被修飾語句の主辞であるトークン」の数値ベクトルに対して「修飾語句の主辞であるトークン」が持っていたベクトルを数値として加えていくように計算が進むことがTransformerの論文やさまざまなTransformer/Attention解説記事の中で示されています。「日本代表チーム」という句であれば、「チーム」というトークンがこの句全体の主辞となる数値ベクトルを担当し、「日本代表」はその修飾語句として「代表」が主辞なので、「チーム」の数値ベクトルに「(日本)代表」の数値ベクトルを(何らかの計算で)加えることで「チーム」に「日本代表」という「意味合い」が加わった意味が最終的なAttentionの中の「チーム」というトークンが占めていた位置に対応する数値ベクトルが表現するものとなります。このとき、途中の「日本」は「代表」を既に修飾済み、すなわち、より前のTransformerの計算で数値ベクトルとして既に加え済みということになりますね。脱線して軽く考察さて、このようなふるまいをするとなるとTransformerによってAttentionの解析が進むにつれて、主辞のところに意味的な情報が集約されていきそうな気がします。なると割と途中段階のAttention=数値ベクトルの列は、主辞を担当するトークンが居た位置だけ情報が充実してスパース(データが疎)になってしまうのでしょうか?それとも、修飾語句は途中まではなるべく情報を「温存」しておいて、Transformerの段数の最後のほうで一斉にわーっと「修飾先」に足し込むのでしょうか?それとも構文や意味の階層構造の高さに応じて柔軟にふるまってくれるのでしょうか?このあたりは、深層学習の中身のパラメータがどのように得られるか次第なので何とも予測が難しいところですが、想像するのも楽しいところではあります。*4個人的には、エンコーダの出力として得られる「文脈情報」を表すAttentionは、入力トークン列全体の「主辞」(それはもちろん一つとは限りませんが)のトークン位置にほとんどの情報が埋め込まれたスパースな感じになりそうな予感があるのですが、果たしてこの予感は正しいでしょうか?私は分かりません。Transformerに実際のデータを食わせたときのAttentionの振る舞いに詳しい方に是非お聞きしたいところです。*5数値ベクトル=ブラックボックス?そういうわけでとにかく、Transformerを使ってAttentionの解析が進んでいくと、だんだんと各「主辞」の数値ベクトルに「修飾語句」が持っていた数値ベクトルが数値的に加味されてゆき、それによって文法構造の解析が可能であろうことは確かに納得できます。ような記号的な手法と違ってブラックボックスになりがちに思えます。なんてったってEnd-to-Endの深層学習モデルですから。解析途中の数値ベクトルの中身を覗き見て本当にそうした語句の修飾関係がちゃんと表現されてるかを検証するのは簡単ではなさそうに思います。Need」からの転載です。構文階層が主辞の情報にちゃんと埋め込まれているいずれの図も、主辞のところに修飾語句の情報や、照応先(指示語や代名詞の具体的な内容の参照先)の情報が埋め込まれてますね。*7また、この論文ではこれらの図のキャプションに、「Headに情報が入ってるぜ」という言い方をしています。類比を意識していたかどうかはわかりませんが、少なくとも筆者たちは主辞や素性構造という「深層学習以前の自然言語処理」をもよく理解している人たちであることは間違いないでしょう。上の図は2017年の論文に掲載されている図で、それをみているだけでも結構凄くみえますが、10歩くらいゆずって文法構造の解析は確かに出来ても不思議ではないという人もいるかもしれません。GPTにおけるTransformerの段数しかし今や、GPTレベルまで言語モデルが大規模化した結果、構文・文法だけでなく、さらに意味の解析までも出来てしまったというのは本当に驚きです。この2017年の論文ではTransformerの段数は6段で、GPT-3は96段です。単純計算で16倍ですね。ChatGPTを見ていると人間が見ても一定レベルの意味をちゃんと理解してると思える応答をします。主辞を使って数値ベクトルで修飾関係を表現するという、どちらかというと文法や構文の解析を目的としてるだけに見えてしまう方法だけで、それをとにかく何階層も繰り返して解析していくと意味レベルまで到達してしまった。文法を解析するのとおんなじ仕組みを高く積み上げていったら意味まで届いてしまった。