yoheikikuta / paper-reading

Notes about papers I read (in Japanese)
156 stars 4 forks source link

[1910.10683] Exploring the Limits of Transfer Learning with a Unified Text-to-Text Transformer [paper-reading] #55

Open yoheikikuta opened 3 years ago

yoheikikuta commented 3 years ago

論文リンク

https://arxiv.org/abs/1910.10683

公開日(yyyy/mm/dd)

2019/10/23

概要

Text-to-Text Transfer Transformer (T5) という input と output が共に text という統一的なモデルで様々なタスクを取り扱うようにして、データサイズや unsupervised objectives などが downstream タスクの精度に与える影響を大規模に実験して検証したもの。 データセットとして Common Crawl から集めてフィルタリングした Colossal Clean Crawled Corpus (C4) という public available な巨大なデータセットも作成。 様々な観点で比較実験を実施して、どれを採用すれば精度が向上するかを明らかにした。具体的にはアーキテクチャは Encoder-Decoder が良い、Unsupervised objectives では denoising タイプ(BERT の Masked Language Model のように token を mask するもの)が良い、などを実験で定量的に示した。 最終的に得られた知見をまとめた巨大なモデルを作成し、タスク特有のアーキテクチャを持たないながらも多くのタスクで当時の SoTA を更新。

yoheikikuta commented 3 years ago

この論文は T5 (Text-to-Text Transfer Transformer) を提案した論文で、この手法の存在自体は 1 年前くらいに勉強会で話を聞いていたので知っていたが、ちゃんと論文を読んだことはなかった。

最近 mT5 https://arxiv.org/abs/2010.11934 が話題になって読んでみて、モデルとしては T5 とほぼ同じということで、良いきっかけだし T5 の論文を真面目に読んでみるかということで手に取った。

実験内容が豊富で 67 ページある論文なので、全部の内容をメモに残すのはめんどくさいのでやらないかもしれないが、とりあえず読んでいく。

yoheikikuta commented 3 years ago

BERT などが登場して NLP でも transfer learning が広く使われるようになってきているが、あまりに急成長してるのでアルゴリズム同士をちゃんと比較できていないという懸念がある。

一例として unsupervised な学習方法として Masked Language Model などが使われるようになっているが、他の手法とちゃんと比べた時にどれくらい有効なんだろうか?みたいな話は各論文で限定的なモデルやデータセットで比較してるだけで、本当に有効なのかというのは疑問が残る。

他にも、Next Sentence Prediction とかは有効そうと言って導入されたけど、その後あんまり意味ないんじゃない?という議論が出たり、Sentence Order Prediction に置き換わったりと忙しい。

それぞれの論文で嘘を書いてるわけではない(と少なくとも信じたい)が、典型的なアイデアに関してはちゃんと比較して経験的有効性を明らかにしたいというのがこの論文でやりたいことである。

もちろんいろんなアイデアは複合的になって初めて効果が出たりする可能性はあるわけだが、組み合わせをしらみつぶしに実験するのは無理なので、せめて各アイデアを独立に検証しようという試みである。

yoheikikuta commented 3 years ago

この論文では T5 を導入して入るけど、新しい手法を導入するのが目的ではなくて、この分野自体がどういう状況に立っているのかを包括的に理解できるような視点を与えたいんだ、と言っている。

そのためにデータセットをきちんと整えた上で色々なアイデアを比較実験したりしている。

志は高いし、恐ろしいほどの計算資源を投入して色々実験してくれてるのでありがたい。 とはいえどうしても単に実験してどれが効いてそうでどれが効いてなさそうですね、という結論になりがちなので、有益な知見ではあるけど現状のこの分野の流れは変わらず進んでいくようには思う。

まあ自分としてはありがたく実験の結果を見せてもらってあれこれ考えるくらいしかやれないのですが...

yoheikikuta commented 3 years ago

この論文で提案されている T5 は基本的には Transformer と同じようなものとなる。 Transformer に関しては https://github.com/yoheikikuta/paper-reading/issues/7 にまとめてある(いま見ると色々理解が中途半端に止まってるが...)。

encoder に関しては以下のブロックを積み重ねている。

decoder に関しては encoder の場合の self-attention の後に encoder から {key, value} を引っ張ってきて普通の attention も導入される(これは元々の Transformer と同じ)。最後は input embedding と weight を share した dense layer -> softmax で出力 token を定める。

また、positional encoding に関しては original の Transformer で使われている sinusoidal position signal とか learned position embedding ではなく、relative position embedding を使う。

この relative position embedding は文章を読んでもさっぱり理解できないので、コードを読んだ方が早い。 https://github.com/huggingface/transformers/blob/eb0e0ce2adf66d2b1106b9e0852f6e063ab9ae7c/src/transformers/modeling_t5.py#L243-L288 相対的な位置情報を embedding するのだが、前後 32 // 2 までは int を incremental に入れていった値を使い、そこから 128 offset までは log 的にスケールさせる値を使い、それ以上は同じ値を使い、それを embed した tensor を attention weight の計算に使うというものになっている。 これとか韓国語だけどちょっと参考になる https://jeonsworld.github.io/NLP/rel_pe/ (log 的なスケールの話とかは書いてないけど) embedding は全 layer で使い回している。 これは単独の layer では 128 offset 以上は位置関係を区別できないが、layer を積み重ねることで遠いところの token の位置の違いの情報も取り込まれることになる。


どこで layer normalization を入れるかは色々変遷があって混乱するよね。 ここでのメモは T5 で使ってる HuggingFace 実装を見て書いてる。 https://github.com/huggingface/transformers/blob/v3.4.0/src/transformers/modeling_t5.py

yoheikikuta commented 3 years ago

モデルは重要でないということで全部 text で説明されてるのだが、これはこの辺りの議論に詳しい人じゃないと読んだだけで理解するのは難しいだろう。コードを読むのがいいと思う(自分はそうした)。

計算資源は凄い。1024 TPU v3 chips とのこと。colaboratory だと 4 v2 chips とかだと思うので、はえ〜って感じ。

モデルとしてめちゃくちゃデカいのも取り扱うので、data parallel だけでなく model parallel も併用しているとのこと。

yoheikikuta commented 3 years ago

unsupervised な pretraining において、データ量やらデータの質やらがどのように影響(これは後続タスクを解く時の精度の意味で)するのかを調べるために、データセットも新しいものを構築している。

それが C4 (The Colossal Clean Crawled Corpus) である。 Colossal ってなんだよと思ったら「巨大な」という意味とのこと。

このデータは Common Crawl https://commoncrawl.org/ という 2008 年からウェブ上の text データを集めているものが元になっている。Common Crawl は HTML から markup とか他の non-text の情報を除いて、月に 20[TB] ほど収集されているらしい。ヒョエ〜。

とはいえ、これにはまだ大量のゴミが混じってるので、以下の herulistic を用いてデータをクレンジングしている。

以上の条件を 2019 April から集めたデータに対して適用して、約 750[GB] の pretraining 用のデータを作成。めちゃくちゃデカい... これは TensorFlow にも取り込まれている https://www.tensorflow.org/datasets/catalog/c4

public available なデータでちゃんと作ってるのは偉い。 一方で、この heulistic はかなり粗いのも事実ではある。最終的にここが一番重要になる気がするので、それこそ ML を使ってもう少し良質なデータだけを選別できるようにしたらもっと性能上がったりしないだろうか?

yoheikikuta commented 3 years ago

具体的にどういう方式で pretraining をするのかというのはまだ後で、T5 がどうやって downstream タスクに使われるかを見る。

text-to-text という名を冠してるところからも想像できるように、T5 では出力も text にすることで色々な NLP の問題を同じモデルで解こうとする。

翻訳の場合、That is good. -> Das ist gut. という英 -> 独 翻訳がしたい場合、That is good. を入力にして Das ist gut. を出力にする。これはまあ普通の Transformer の使い方だなと思うけど、その他にも色々なタスクを解くことになるので、単に文章を入れるだけだとそれが翻訳タスクなのかなんなのかモデルには区別し難い。 そこで、prefix にどのタスクかを識別させるための text を入れるという力技を使う。この例だと "translate English to German: That is good." というのを入力にするのである。このような形式のデータでいくらか fine-tuning してやれば、この prefix がある場合は英独翻訳ねとモデルが解してくれるという寸法である。

classification の場合はどうなるか。 これもテキストで出力することになり、例えば MNLI データで hypothesis sentence と premise sentence が与えれて出力は {entailment, contradiction, neutral} の 3 クラス分類になっている。 これは入力文章に対して出力として "entailment" or "contradiction" or "neutral" というテキストを出力するようにすることで classification にしてしまおうという魂胆である。 これも元々の入力文章の前に "mnli hypothesis: [hypothesis sentence] premise: [premise sentence]" などと入れて classification であることを教える。 ただし、出力があくまでテキストなので、fine-tuining したといてもこの 3 つ以外のテキストを吐く可能性はある。その場合は誤答として扱う。

回帰問題も離散化を経て同様に text 出力で扱う。 STS-B データでは 2 つの sentence に対して出力を 1~5 の実数の類似スコアで与えるが、教師データが大体 0.2 刻みでつけられているので、0.2 刻みで数値を丸めて、出力はその数値の text "3.2" などとする。 これも入力は "stsb sentence1: [sentence 1] sentence2: [sentence 2]" などとしてモデルにどのような問題かを教える。

他にも色々あるが、この論文のいいところは Appendix にそれぞれのタスクでどう入力データを構築するかの例が出ているところで、これを見ればすぐにイメージが分かる。

出力をなんでも text にすれば一個のモデルアーキテクチャでいいじゃん!という強引なドリブルだが、着眼点は結構面白い。 元々は https://arxiv.org/abs/1806.08730 とかのアイデアっぽい。


こういうモデルに adversarial attack かけたときにどういう振る舞いになるのかはちょっと面白そう。

yoheikikuta commented 3 years ago

結果をひとまとめにしたものが以下の表。これはなかなか壮観。 一番左のTable no. 毎に異なる観点での pretraining の実験を独立にしていて、downstream のタスクとして GLUE, SuperGLUE, WMT などを解いた結果を示している。

各実験がどういうものかは必要なものを後で詳しく見るとして、この論文の結論は以下でまとめられる。

すごく示唆に富んだ何かが得られたかというとそういうわけでもない気がするが、とはいえこの規模の実験をして知見をまとめたのは素直に凄い。

今後の展望として、デカいモデルは取り回し大変だから性能をキープしてもっと小さくしたい、1 兆 token で学習するとか大変だからもっと効率的に学習したい、downstream と似たドメインで pretraining すると性能が上がるからタスク間の類似度を測れると有用そう、英語用のモデルなので言語に依らずに使えるモデル(これが mT5 につながる)を作りたい、ということが挙げられている。


ここまででは説明してないが、なんで英語のモデルなのに翻訳タスクができるのかというと、英語以外の語彙に対応できるように tokenization を学習しているからである。 SentencePiece で 32000 語の語彙に設定して学習しているが、英語だけでなく、ドイツ語、フランス語、ルーマニア語を英語と同様に Common Crawl から持ってきてそれぞれ英語の 1/10 だけ使って学習している(語彙は input output で共通)。

yoheikikuta commented 3 years ago

table1: baseline モデル

まずは baseline とするモデルがどういうものでどれくらいの性能であるか。

モデルは既に説明してるように original の Transformer を少し改変したもので、Encoder Decoder それぞれが BERT_{BASE} と同程度のパラメタ数になるように作っていて、合計で 220 millon パラメタのモデル。

学習普通に出力の token を用いて teacher forcing で cross entropy loss で学習する。AdaFactor で optimize して、テスト時には greedy decoding をする。 AdaFactor って知らないけど https://arxiv.org/abs/1804.04235 を気が向いたら読むか。

pretraining は C4 データに対して 2^19 = 524,288 steps 実施する。token の max size は512 で batch size は 128 としている。各バッチには詰めれるだけ sentence を詰めるといて、ラフに言って 128 batches で 128 512 = 2^16 tokens = 65,536 tokens を扱っている。つまりトータルでは 2^19 2^16 = 2^35 = 34 billion tokens を扱う。 これは BERT だと 137 billion tokens で RoBERTa だと 2.2 trillion tokens なので、それと比べると結構小さくなっている。

learning rate は inverse square root scheduling をしてる。これは training iteration を n で k を wam-up step としたときに 1 / sqrt(max(n, k)) とするものらしい。へ〜という程度。

fine-tuning は各タスクを解く際に 2^18 = 262,114 steps 学習している。learning rate は 0.001 で 5000 steps 毎に checkpoint を保存して validation set に対して best なものを使って test するというやり方。

tokenization と語彙数に関しては一つ上のコメントで残した通り。

どのような unsuprevised objective を使うかは以下。 15% を mask して sentinel token に置き換えるが、連続した token が mask された場合は一つの sentinel token に置き換える。 出力は sentinel token を目印にして、mask された token だけを予測するというものになっている。このやり方だと pretraining 時の計算コストを抑えられるのでよい。

このような setup で異なる初期化やデータシャッフルの場合に 10 回試して結果を集約したものが以下(GLUE や SuperGLUE に関しては全タスクの結果の平均値)。 当然だが pretraining なしのものと比べると明確に性能がよくて、分散が 1% 以下で安定している。これは想像より安定感があってなかなかいいなと思った。 また、これは同程度のサイズのモデルと同じような結果になっている。例として BERT_{BASE} で SQuAD で 80.8 でほぼ同じ。baseline model の個別のタスクの結果に関しては先ほど貼った巨大な表に記されている。

yoheikikuta commented 3 years ago

table2: アーキテクチャ

アーキテクチャとしては以下の 3 種類を考えている。 input と output があり、output に関しては causality を破らないように mask を掛ける必要があるが、input に関しては全部見れてしまっても良いのでそれを実施した Prefix Language Model というものも考えている。 ちょっと気をつけるべきは、Encoder-Decoder モデルは二段重ねなので計算量が多そうだけど、input と output を分離して扱えていて、attention の計算コストを考慮すると Language Model と同程度になるということである。

合わせて objective についてもバリエーションを考えてみる。 ここでは昔ながら(?)の Language Model のパターン(つまり次の token の予測)と denoising のパターン(これは BERT 的な mask した token を予測)を比べている。

これらで実験した結果が以下で、アーキテクチャは Encoder-Decoder で objective は denoising を使うべし、ということになっている。Encoder-Decoder で Encoder と Decoder の重みを share しても高い性能を保つので、パラメタ数を節約する場合には使えるかも。

yoheikikuta commented 3 years ago

table4,5: unsupervised objectives

baseline のところでは mask した token を sentinel token に置き換えて、target としては mask した部分だけを予測するようにするという話をしたが、ここのバリエーションは当然色々考えられる。 これは百聞は一見に如かずで見た方がイメージを掴みやすく、以下のようなバリエーションを考えている。これは一目見ればどういう感じか掴めるのがいいよね。この論文は appendix の例示といい、ここ具体的にどうなってんだっけ?というのをちゃんとわかりやすく書いてくれてるのでそこは高ポイント。

まず、上 3 つを比較した結果が以下で、これは BERT が出てきたときに明らかになったように Masked Language Model が強いことを改めて示している。まあ deshuffling とか明らかに勝負にならんやろと思うけど、実際比較するとかなり低い値になっている。

ここで一番だった BERT style とその亜種を比べたものが以下。 ここは読んでる時に出力の形式が違うだけでやってることはほぼほぼ同じなので結果かわらんだろと思ってけど、下 2 つの方が良い傾向にある。 これはタスク依存の部分があって、Drop corrupted tokens は GLUE の CoLA MCC で非常に良い性能になっていて、それはこのタスクが与えられた sentence が文法的・構文的に正しいかを分類するのもで、それはこのように複数 token を連続して予測するというときに自然と文法・構文に沿って適切なものを学習しやすくなるということらしい。まあこれは reasonable な説明。一方で SGLUE では Replace corrupted spans より性能が落ちてるけど、こちらは特に説明がなさそうかな。個別のタスクを見てもいくつかで大きめの違いがあるので何かしら解釈はできるのではないかと思うけど、まあよしとしておく。

downstream タスクにマッチしているという観点が入ってくるので BERT-style と比べて常に良いという感じは特にしないけど、既に説明してあるように output として mask したものだけを予測するようになってて学習が効率的なので、この論文では Replace corrupted spans を baseline として採用している。

yoheikikuta commented 3 years ago

table6: mask する割合

これは大きすぎると性能が落ちて、15% くらいがいいよとのこと。 BERT の結果がズバリって感じだけど、BERT 作ってた時はこの辺をどれくらいチューニングしてたんかね。

yoheikikuta commented 3 years ago

table7: mask するときのスパン長

この論文のやり方だと複数の token が連続して mask されるとそれを一つの sentinel token に置き換える。 i.i.d. で mask してたまたま連続したものが mask されたら 1 つの span としてまとめるけど、もうちょっと作為的に一回の mask のときにスパン長を変えてみたらどうなるか、という話。

これは結構ばらつきがあって、タスクにもよるけど明白にどうするのが良いという結果はなさそう。 なので baseline としては素直に i.i.d. を採用。

yoheikikuta commented 3 years ago

table8,9: unlabeled dataset

C4 を作る時点でいくつか heuristic なフィルタをかけているが、さらにそれを選別して downstream タスクに影響があるのかを調べる。量と質の問題を明らかにしたいということでしょうね。

結果は以下の通り。 WebText-like のようにデータをうまく絞って質の高い(ドメインをうまく限定した)データに限ることで GLUE や SQuAD などの downstream タスクの性能を向上させることができる。 この辺りはドメイン特化の pretraining が有効という話とも consistent な結果になっている。 流石にゴミみたいなデータだとめちゃくちゃ大量に学習したところで精度向上は達成できない、というのはありがたい教訓ですな(この結果はトータル token 数を固定してるので十分に学習できてないという可能性もあるけど、回したところでフィルタリングしたものを上回るのかというとあまり期待できなそう)。

データをうまく絞れると downstream タスクに有効になりうるが、一方でデータが小さくなりすぎて学習が繰り返されすぎると性能が落ちるという結果も出している。 以下は baseline の 2^35 tokens 分での学習の総数は変えずに、使う token 数を減らしてその分繰り返すとどういう結果になるかを示したものである。 単純に同じデータでグルグル計算を回すと pretraining の効果は薄いと言っている。それはそう、という感じ。

pretraining データに関する結論としては、データ量は重要!だけどうまくドメインを絞れると性能が向上し得る!つまり質が高いデータを大量に作るのが良い!という当然な結果。結果は驚くものではないけど、大規模に比較して定量的に見れるようにしてくれたのはありがたい。

yoheikikuta commented 3 years ago

table10: fine-tuning するときに学習する層

fine-tuning する際に、全部のパラメタを更新するのか一部のパラメタだけを更新するのかというのはどちらが有効か?を調べている。 これは BERT では全部のパラメタを更新していて、なんとなく全部更新するのがよさそうという感覚はあるけど、そこをはっきりさせてくれている。

全部のパラメタを更新する代替案として 2 つ考えていて、 1 つは adapter layer を追加するもの。これは元のネットワークは保持しておいて、Transformer の feedforward 層の後に付け加えて学習するというもの。なんか全然良さそうに聞こえないけど、先行研究がいくつかあるみたいだし効果はあるということなんだろうね。

もう一つは Gradual unfreezing というもので、これは一気に update するのではなく、最終層に近いところから徐々に update していくようにするというものらしい。論文は https://arxiv.org/abs/1801.06146 かな。チラ見したら一気にやると Catastrophic Forgetting (以前学習したタスクの性能が急に落ちる)が起きるのを防ぐのに効果的ということらしい。

結果は以下で、ごちゃごちゃ言わずに全部のパラメタを一気に update すればいいんや、ということだそうです。 色々例外は起きそうな雰囲気はあるが、結果としてはシンプルで分かりやすい。

yoheikikuta commented 3 years ago

table11,12: multi-task learning

multi-task learning は典型的には 1 つのモデルで複数のタスクを解けるように学習するものである。すなわち一つのパラメタセットで全てのタスクを解くというもの。本来は当然そうしたい。

ここでの multi-task は、これまでみてきた pretraining -> fine-tuning と比較するために、学習は multi-task learning でやっても、個別のタスクのテストには validation set で最も良かった checkpoint 恣意的に使おうというものとしている。 これは通常の multi-task learning の観点からはナンセンスなのだが、pretraining -> fine-tuning のやりかたは個別のタスクに対してそれぞれ validation set で最良のものを使うということになっているので、それとフェアに比較するようにこうしている。

T5 の枠組みではどのタスクも同じように解けるので、ここでの multi-task learning はそれぞれのタスクのデータをどう混ぜ合わせて学習するかという話になる。以下の 3 つのやり方を試している。

結果は以下。 これは普通に pretraining -> fine-tuning したものが大体の場合で一番良い結果で、他のタスクを解くことで性能向上につながるような気配は見られない。 論文ではなんかごちゃごちゃ書いたりもしてるけど、ここは他のタスク解いても助けにならなそう、そしてやっぱり multi-task learning でやるなら単一パラメタのモデルでどれくらい色々なタスクをうまく扱えるかを見ないと面白くない、という話だな。

この考えをもう少し押し進めて、multi-task pretraining -> fine-tuning なども試している。 多くの場合で unsupervised pretraining -> fine-tuning がよさそう。 一方で、multi-task pretraining をしてさらに fine-tuning もすると、同程度の性能が出そう。ただこれは手間の割には十分な gain とまでは言えなそう。 Leave-one-out multi-task training は downstream タスクだけ除いて学習して、最後に downstream タスクで fine-tuning するもので、基本は multi-task learning と同じくらいだけど SGLUE では優秀(理由はよく分からん)。 Supervised multi-task pre-training は unsupervised pretraining を入れないというものだけど、特に GLUE タスクでの落ち込みが激しくデータ量大事だよなと主張している。WMT の EnFr に関しては比較的データ量が多いので質が良くてかつ十分なデータで学習できているので best な結果になっていそう。

yoheikikuta commented 3 years ago

table13: スケーリング

最後は、モデルのパラメタサイズや学習時間、そしてアンサンブルモデルの効果を調べる。

結果は以下。 パラメタサイズを大きくするのは効くし、学習を多くするのは効くし、アンサンブルも効く。 単独の効果としては、アンサンブル < 学習を多くする < パラメタサイズを大きくする、という順で効いていそう。 これを見ると頑張ってアンサンブルで何個もモデルを作るより、デカい奴を一個作る方が取り回しとかを考えても有用そうという感じだね。そんなクソデカモデル使えんのか、という話はあると思うけども。

yoheikikuta commented 3 years ago

個別の要素は色々調べて有効そうなものが分かったので、これを全部詰め込んだモデルを作ってみる。

結果は以下。 デカいは強い!ということで多くのタスクで SoTA を塗り替えている。task-specific な構造を考えていないのに結果が良いというのは素直にすごい。モデルはアホみたいなデカいけど。 ただ翻訳タスクである WMT では結果は奮わず、これはほぼほぼ英語のデータしか使わず pretraining したからだろうとコメントしている。

モデルが大きいから性能がいいということもあるが、データサイズ以外の知見を取り込んで baseline と同程度のサイズにしている T5-Base は baseline よりも高い性能を発揮している。 これは色々な知見を集約した結果ということで、なかなか良い(この論文で色々調べた甲斐のある)結果になっている。

yoheikikuta commented 3 years ago

ということで一通り読んだ。 めちゃくちゃ大量に実験してくれている論文で、現在の実験的理解がどのようなものであるかを俯瞰できたのでよい勉強になった。

願わくばこういう話がもう少し理論的に正当化できるようになっていくといいのだが...