TransformerベースのEncoder-Decoderモデル Hugging Face ブログ記事 2020
TL;DR
Hugging Faceは、TransformerベースのEncoder-Decoderモデルを解説する教育的なブログ記事を公開しました。この記事では、エンコーダーとデコーダーのコンポーネント、自己注意(self-attention)と相互注意(cross-attention)の仕組みを説明し、MarianMTの翻訳例を用いて🤗Transformersライブラリによる自己回帰生成(autoregressive generation)を実演しています。
背景
このブログ記事では、系列対系列(sequence-to-sequence)タスクを、入力ベクトルの系列を未知の長さのターゲット系列にマッピングすることとして定義しています。この定式化が、Encoder-Decoderモデルの開発の動機となりました。
"NLPのサブフィールドである自然言語生成(NLG)におけるタスクは、sequence-to-sequence問題として表現するのが最適です。"
初期のRNNベースのEncoder-Decoderは可変長の出力を扱うことができましたが、勾配消失問題や並列化の制限という課題がありました。
"RNNは勾配消失問題に悩まされており、長期的な依存関係を捉えることが非常に困難です... 第二に、RNN固有の再帰的なアーキテクチャにより、エンコード時に効率的な並列化が妨げられます。"
その後、記事では、可変長シーケンスの高度に並列化可能な処理を可能にする解決策として、Vaswani et al. (2017) によるTransformerアーキテクチャを紹介しています。
Encoder-Decoderアーキテクチャ
TransformerベースのEncoder-Decoderは、それぞれ残差注意ブロック(residual attention blocks)から構築されたエンコーダー・スタックとデコーダー・スタックで構成されています。
"RNNベースのEncoder-Decoderモデルと同様に、TransformerベースのEncoder-Decoderモデルは、どちらも残差注意ブロックのスタックであるエンコーダーとデコーダーで構成されています。"
エンコーダーは入力シーケンスを文脈化された隠れ状態(contextualized hidden states)のシーケンスにマッピングし、デコーダーは、それらのエンコーディングと以前に生成されたトークンが与えられたときのターゲットシーケンスの条件付き分布をモデル化します。
"Transformerベースのエンコーダー部分は、入力シーケンスを... 隠れ状態のシーケンスにエンコードします... その後、Transformerベースのデコーダー部分は、エンコードされた隠れ状態のシーケンスが与えられたときに、ターゲット・ベクトル・シーケンスの条件付き確率分布をモデル化します。"
自己回帰生成はステップバイステップで進行し、デコーダーは最初のフォワードパスの後にエンコーダーの出力を再利用します。
"エンコーダーは、...をマッピングするために最初のフォワードパスでのみ使用されることを理解しておくことが重要です。第2フォワードパス以降、デコーダーは以前に計算されたエンコーディングを直接利用できます。"
エンコーダーの詳細
各エンコーダー・ブロックには、双方向の自己注意(bi-directional self-attention)レイヤーと、それに続く2つのフィードフォワード・レイヤーが含まれています。
"各入力ベクトルは... キー・ベクトル、バリュー・ベクトル、クエリ・ベクトルに投影され... 出力ベクトルは、すべてのバリュー・ベクトルの加重平均... に入力ベクトルを加えたものとして定義されます。"
すべてのクエリがすべてのキーに注意を払うため、エンコーダーは単一の操作で長期的な依存関係を捉え、位置間での完全な並列化を可能にします。
"出力は... 一連の行列演算とsoftmax演算によって計算され、これは効果的に並列化できます。"
コードスニペットでは、入力の最後の単語を変更すると、最初のトークンに対するエンコーダーの表現が変化することが示されており、文脈依存性が確認されています。
デコーダーの詳細
各デコーダー・ブロックには、単方向の自己注意(uni-directional self-attention)レイヤー、相互注意(cross-attention)レイヤー、および2つのフィードフォワード・レイヤーが含まれています。単方向の自己注意は、各クエリが自身の位置とその前の位置にのみ注意を払うように制限し、自己回帰的な動作を保証します。
"単方向の自己注意では、各クエリ・ベクトルは、それぞれのキー・ベクトルとそれより前のすべてのキーとのみ比較されます... これにより、出力ベクトルが後続の入力ベクトルに関する情報を含まないようになります。"
次に、相互注意は、デコーダーの隠れ状態をクエリとして、エンコーダーのキーとバリューに対して投影することで、デコーダーの表現を完全なエンコーダー出力に基づいて条件付けます。
"相互注意レイヤーは、各入力ベクトルをすべての文脈化されたエンコーディング・ベクトルに関連付け、次のターゲット・ベクトルの確率分布をエンコーダーの入力に基づいて条件付けます。"
デコーダーの最終的な線形レイヤー(LM head)は、隠れ状態を語彙に対するロジットにマッピングし、それらはsoftmaxによって確率に変換されます。
"'LM head'は、エンコードされたターゲット・ベクトルのシーケンスをロジット・ベクトルのシーケンスにマッピングします... softmax演算を適用することで、語彙全体に対する確率分布を得ることができます。"
コード例では、特定の位置の後のデコーダー・トークンを変更しても、それより前のトークンのロジットには影響しないことが示されており、単方向自己注意の因果的な性質が説明されています。
🤗Transformersによる推論
この記事では、🤗Transformersライブラリを使用して、学習済みMarianMTモデルで翻訳を実行する方法を示しています。generate()メソッドが、エンコーディング、BOS/padトークンによるデコーダーの初期化、およびビームサーチ・デコーディングを内部的に処理することを強調しています。
"
.generate()を呼び出すと、内部で多くのことが行われます。第一に、input_idsをエンコーダーに渡します。第二に、定義済みのトークン(</s>記号)を... エンコードされたinput_idsと共にデコーダーに渡します。第三に、ビームサーチ・デコーディング・メカニズムを適用します..."
提供された例では、「I want to buy a car」をドイツ語に翻訳し、出力としてIch will ein Auto kaufenを生成します。
付録:コードスニペット
付録には、エンコーダーとデコーダーの呼び出しを手動でステップ実行し、argmaxで次のトークンを選択してデコーダーの入力に結合することで、翻訳の最初の数単語を再現する最小限の貪欲法(greedy-decoding)ループが含まれています。
"このコード例では、前述の内容を正確に示しています... その結果、モデルは 'Ich will ein' という単語を生成しました。"
記事は、読者がTransformerベースのEncoder-Decoderモデルの仕組みと🤗Transformersでの使用方法について詳細な理解を得られたことを結論として述べ、トレーニングの詳細は将来の投稿で扱われることを示唆しています。