🚒

Transformer

に公開

Transformer にはencoderのみ、decoderのみ、 encoder-decoderの三種類の構成がある。

  • enocder のみ構成
    • 入力:シーケンス ※
    • 出力:文脈化トークン表現
  • decoder のみ構成
    • 入力:シーケンス
    • 出力:入力シーケンスの次のトークン
  • encoder-decoder 構成
    • 入力:シーケンス
    • 出力:入力シーケンスとは別のシーケンスに関する、次のトークン
    • ややこしい表現になってしまったが、encoderとdecoderでそれぞれ別の学習目標や語彙を持つことで、入力シーケンス(例:日本語)と別のシーケンス(例:英語)の「次のトークン」を出力、つまり自己回帰的に繰り返すことで「別のシーケンスを出力」する。

※ シーケンス : 文をトークナイザーによりトークンに分割した「トークンの配列」
 例 : ['私は', 'GPT', '-', '5', 'です', '。']

コンポーネント

いずれの構成も、以下のコンポーネントの組み合わせからなる。

  • トークン埋め込みの作成
    • これはencoderブロックやdecoderブロックの外側に置かれる。
  • 自己注意機構 (self-attention mechanism) ※
    • マスク付き自己注意機構 (masked self-attention mechanism) ※
  • 交差注意機構 (cross-attention mechanism) ※
  • フィードフォワード層 (feed-forward layer)

※ Transformerにおいては、全ての注意機構は マルチヘッド注意機構 (multi-head attention) が採用されている。複数の独立した注意機構(ヘッド)に対して同じクエリを与え、出力を連結する。

トークン埋め込みの作成

  • 入力されたシーケンスをベクトル行列化
    • このベクトル行列を便宜上「入力トークン埋め込み」という
  • これに位置情報を加える(以下のいずれかの方法)
    • 位置符号 position encoding
      • 入力トークン埋め込みと同次元のベクトル
      • その場で算出する
      • 入力トークン埋め込みに加算
    • 位置埋め込み position embedding
      • 入力トークン埋め込みと同次元のベクトル
      • 学習で作成する
      • 推論時には単に入力トークン埋め込みに加算する
  • 最終的に、「位置情報を含むベクトル」の配列を出力する
    • 便宜上「位置情報付き入力トークン埋め込み」という

自己注意機構 (self-attention mechanism)

  • 入力 : 位置情報付きトークン埋め込み
  • 出力 : 行列内の他の全アイテムからの影響を加味したベクトルの行列
    • これを便宜上「文脈化トークン表現」と呼ぶ。

Transformerでは key-query-value attention mechanism が採用されている。

  1. 入力トークン埋め込み(ベクトルの行列)から三種類の埋め込み(ベクトルの行列)を作成
    • query 埋め込み
      • 「どの特徴を参照したいか」を表現。
      • 後述するマルチヘッド注意機構では、ヘッドごとにここを変える。
    • key 埋め込み
      • 「どんな情報を含むか」を表現。
    • value 埋め込み
      • 情報の本体。
  2. 各 query ベクトルごとに、全 key ベクトルそれぞれとの 関連性スコア を算出
  3. 算出した関連性スコアで、value ベクトルを加重平均
    • これにより、シーケンス内の全トークンを加味したベクトルが得られる。

query, key, value はそれぞれ以下のようなイメージ

  • クエリ:「マウス」
  • キー「マウス(動物)」:バリュー「哺乳類、齧歯類、不衛生、実験、ミッキー」
  • キー「マウス(コンピュータ)」:バリュー「デバイス、PC、Mac、ポインタ、カーソル、USB」

つまり、自己注意機構とは「位置情報付きトークン」の行列を受け取り、その各アイテム(トークン)ごとに「行列内の他の全アイテムからの影響」を加算して出力する機構といえる。

マスク付き自己注意機構 (masked self-attention mechanism)

自己注意機構は、入力行列の各アイテムに対して「全アイテムからの影響」を加算する機構。そのため、影響を与えたくないアイテムを隠したい(マスク)場面がある。

  • 入力シーケンス全体を表現したい場合
    • つまり、encoderとしての用途
    • 隠すべき部分がないのでマスク不要 ※
  • 入力シーケンスの一部(途中まで)を表現したい場合
    • 言い換えると「正解シーケンスの途中までわかっている状況で、次のトークンを予測」したい状況。
    • これは「次トークン予測」の学習時の状況。つまりdecoderとしての用途。
    • つまり、decoderの学習時に、未来のトークン(正解トークン)をマスクする。 ※
    • decoderの推論時は未来のトークンが存在しないのでマスク不要 ※

※ ここで言っているのは「因果マスク」であり、このほかに「Padマスク」もある。Padマスクは、なんらかの都合でシーケンスに付加された padding (特殊トークンや 0 など) を無視するために用いられる。また、decoderの推論時は原理的に因果マスク不要だが、実装では様々な理由(キャッシング対応等)でマスクをつけるのが一般的。

交差注意機構 (cross-attention mechanism)

自己注意機構では query 、key 、value の全てを同一の入力から作成したが、これを2種類の入力から作成する。具体的には入力Aから query を、入力Bから key と value を作成する。そのため出力行列は入力Aと同じ長さになる。「ターゲット行列をソース行列で表現する」と言ってよさそう。

なお、ここでいう入力Aを ターゲット 、入力Bを ソース と呼ぶ。

フィードフォワード層 (feed-forward layer)

  • ニューラルネットワーク。
  • 一般的には2層(中間層が1つ)。
  • 活性化関数は Transformer 提案当初は ReLU だったが、LLMではGELUが標準的。
  • 提案時で、 Transformer 全体のパラメータの 2/3 がフィードフォワード層。
    • 入力次元 512 に対して 中間層の次元は 2048
  • 入力、出力ともに便宜上「文脈化トークン表現」と呼べる。情報の付加というより、ニューラルネットワークによって表現力を増すレイヤといえる。

LMヘッド

フィードフォワード層からの出力は「文脈化トークン表現」のまま。一般的なニューラルネットワークにおける「出力層」は出力したいベクトルに合わせるAffine変換を行うが、Transformerの(エンコーダまたはデコーダ)ブロックはブロック単位で直列に繋げて処理できる(例:GPTはデコーダを12個直列)設計になっているので、ターゲットフォーマットへの変換はブロックの外に置く(最後に一度だけ行いたいので)。イメージとしては「 フィードフォワード層=出力層のないニューラルネットワーク」のような感じ。

この、ブロックの外で最後に一度だけ行うAffine変換層を LMヘッド と呼ぶ。

Transformer 全体の構成

encoderのみ、decoderのみ、 encoder-decoderの三種類の構成がある。各構成について、コンポーネントの組み合わせ・フローを説明する。

  • enocder のみ構成
    1. エンコーダブロック
      1. トークン埋め込みの作成
      2. 自己注意機構
      3. フィードフォワード層
    2. (必要に応じてタスク用ヘッド)
  • decoder のみ構成
    1. デコーダブロック
      1. トークン埋め込みの作成
      2. 自己注意機構(マスク付き)
      3. フィードフォワード層
    2. LMヘッド
  • encoder-decoder 構成
    1. トークン埋め込みの作成
    2. エンコーダブロック
      1. 自己注意機構
      2. フィードフォワード層
    3. 以下をループ(出力を入力に戻す)
      1. トークン埋め込みの作成
      2. デコーダブロック
        1. 自己注意機構(マスク付き)
        2. 交差注意機構
          • ソース = エンコーダの作成した「文脈化トークン表現」
          • ターゲット = 前段からの入力
        3. フィードフォワード層
      3. LMヘッド

なお、いずれの構成でも各コンポーネント間の接続では 残差結合 (residual connection)層正規化 (layer normalization) を行う。

エンコーダのみ構成

  1. エンコーダブロック
    1. トークン埋め込みの作成
      • 入力シーケンスから「位置情報付きトークン埋め込み」を作成する。
    2. 自己注意機構
      • 「位置情報付きトークン埋め込み」から「文脈化トークン表現」を作成する。
    3. フィードフォワード層
      • 「文脈化トークン表現」の表現力を増す。
  2. (必要に応じてタスク用ヘッド)
    • 分類・回帰などのタスクごとにヘッド(文脈化トークン表現をターゲットベクトルフォーマットへ対応させるAffine変換層)を置く

入力としてシーケンスを受け取り、最終的に「文脈を加味したベクトル表現」を出力する。

デコーダのみ構成

  1. デコーダブロック
    1. トークン埋め込みの作成
    2. 自己注意機構(マスク付き)
    3. フィードフォワード層
  2. LMヘッド

エンコーダと異なり、自己回帰的(自分の出力を入力に戻す)なのが特徴。

  • 例:['私は', 'GPT', '-', '5']の次のトークンを予測
    1. 入力:['私は', 'GPT', '-', '5']→出力:です
    2. 入力:['私は', 'GPT', '-', '5', 'です']→出力:
    3. 入力:['私は', 'GPT', '-', '5', 'です', '。']→出力:<終了トークン>

デコーダブロックの機能は「次のトークンを予測」だが、フィードフォワード層の出力(デコーダブロックの出力)は入力シーケンスの表現であり、次のトークンではない。最後のLMヘッドがターゲット=次のトークンを出力するわけだが、LMヘッドは1層のAffine変換のみ。これでなぜそんなことができるかというと、「フィードフォワード層の出力(文脈化トークン表現)のアイテム(ベクトル)→LMヘッド→次トークン確率」となるように学習しているから。少し乱暴だが「文脈化トークン表現が次のトークンを表現している」と理解してしまっても差し支えない。

エンコーダ・デコーダ構成

エンコーダ・デコーダ構成は「エンコーダの作成した表現を元に、デコーダで0からシーケンスを生成する」機構と言える。

  1. トークン埋め込みの作成
  2. エンコーダブロック
    1. 自己注意機構
    2. フィードフォワード層
  3. 以下をループ(出力を入力に戻す)
    1. トークン埋め込みの作成
      • 入力 = 前回までのデコーダの出力
    2. デコーダブロック
      1. 自己注意機構(マスク付き)
      2. 交差注意機構
        • ソース = エンコーダの作成した「文脈化トークン表現」
        • ターゲット = 前段からの入力
      3. フィードフォワード層
    3. LMヘッド

上の書き方だと上から下までリニアに見えるが、エンコーダブロックの出力を得た後、デコーダブロックを(<終了>トークンが出るまで)自己回帰的にループする。エンコーダブロックの出力はデコーダブロックの入力ではなく、交差注意機構のソースとして与える。デコーダブロックの入力はあくまで(前回までの)自分自身の出力。

デコーダは「入力シーケンスの次のトークンを予測」するものだが、エンコーダ・デコーダ構成ではデコーダの入力シーケンスの初期値は空。そのため1つめのトークンとして「開始トークン」を用いる。その上で、交差注意機構において「開始トークン」についてエンコーダの作成した表現の加重平均を取った結果、1つめのトークンを得ると説明してよいだろう。

Discussion