ディープラーニングブログ

Mine is deeper than yours!

論文解説 Google's Neural Machine Translation System: Bridging the Gap between Human and Machine Translation (GNMT)

こんにちは Ryobot (りょぼっと) です.

Google 翻訳の中身である GNMT (Google's Neural Machine Translation) [Wu, 2016] は良くいえばニューラル機械翻訳の王道を征 (ゆ) く手法であり,悪くいえば既存手法のいいとこ取りである.また,大規模対訳コーパス + モンスター級に巨大なモデル + 大量の GPU が一般化する契機にもなった.2016 年までの NMT を素早く把握するのに最適な教材と言える.

WMT'14 の BLEU スコアは英仏: 39.9, 英独: 24.6 で第 5 位 (登場時 1 位)

f:id:Ryobot:20171218171211p:plain:w700

GNMT はエンコーダとデコーダにそれぞれ 8 層の LSTM (エンコーダの 1 層目は双方向 LSTM) を使用し,注意と残差接続を取り入れたモデルである.データ並列とモデル並列,Wordpiece などで計算効率を向上している.

LSTM

LSTM (Long-Short Term Memory, 長・短期記憶) [Hochreiter, 1997] は長期記憶の役割を果たす cell state と短期記憶 (正確にはワーキングメモリ) の役割を果たす hidden state を保持し,入力のつど内部状態を更新するモデルである (参照).長・短期の依存関係を考慮できるため自然言語処理のような系列データの処理で一般的に使用される.

f:id:Ryobot:20171218171102p:plain:w700

LSTM は次式によって表される.

f:id:Ryobot:20171218171205p:plain:w400

ここで {W} は学習パラメータの重み行列,{x_t} は時刻 {t} の埋め込みベクトル (もしくは下層の隠れ層ベクトルの出力),{m_t} ({h_t} とも表記) は時刻 {t - 1} の隠れ層 (更新後は時刻 {t} の隠れ層) の出力ベクトルである.

{i'_t} は RNN と同様の通常入力,{i_t, \, f_t, \, o_t} はそれぞれ入力ゲート (Input Gate),忘却ゲート (Forget Gate),出力ゲート (Output Gate) である.LSTM は「情報をどの程度通すか」をゲーティングによって決める.入力ゲートは通常入力を更新後の cell state に加える程度を決めるゲーティング,忘却ゲートは更新前の cell state を更新後の cell state に残す程度を決めるゲーティング,出力ゲートは更新後の cell state を hidden state に出力する程度を決めるゲーティングである.

{c_t} は長期記憶 (入力 {x_t} が直接 cell に入らずゲート越し) を担当する cell state であり,{m_t} は短期記憶 (入力 {x_t} と豪快に混ざり合う) を担当する hidden state である.cell state は加算によって状態を更新を行うので勾配消失を回避できる.

Encoder-Decoder

Encoder-Decoder (Enc-Dec, エンコーダ・デコーダ, seq2seq) [Cho, 2014] は「ソース言語の単語列を連続表現に変換するエンコーダ」と「連続表現をターゲット言語の単語列に変換するデコーダ」を組み合わせたモデルである.文字列の変換に適し,最も一般的な構成はエンコーダとデコーダに LSTM を使用する.

f:id:Ryobot:20171218171045p:plain:w700

上図の水色部分はエンコーダの LSTM とデコーダの LSTM (全タイムステップに展開) である.白色のセルは LSTM の各タイムステップである.

推論は次のように実行する.

  1. 入力文 (one-hot ベクトルの配列) を埋め込み層の行列で埋め込み,エンコーダ LSTM で内部状態 {S} (最終タイムステップの LSTM 内の cell state と hidden state) に縮約する.
  2. {S}デコーダ LSTM の内部状態にセットし,SOS (Start of Sentence) の埋め込みベクトルをデコーダ LSTM に入力し,予測単語ベクトルを出力する.
  3. 予測単語ベクトルとソフトマックス層の行列 (単語ベクトルの配列) の内積から確率分布を生成し,最大確率に対応する単語を出力する.
  4. 出力した単語を埋め込み,次のタイムステップのデコーダ LSTM に入力し,予測単語ベクトルを出力する.
  5. デコーダ LSTM が EOS (End of Sentence) を出力するまでステップ 3 と 4 を繰り返す.

訓練は次のタイムステップの LSTM に正解単語を入力する (i.e. Teacher Forcing).これにより学習が安定する.

Encoder-Decoder は次式によって表される.

f:id:Ryobot:20171218171138p:plain:w450 f:id:Ryobot:20171218171142p:plain:w500

入力文 {X}{EncoderRNN} で連続表現にエンコードされ,出力文 {Y} は条件付き確率 {P(Y | X)} に従って生成される.

注意

注意 (Attention) [Bahdanau, 2014] はクエリ {y} を用いてメモリ {X} から情報を取り出す手法である.
エンコーダの情報すべてを状態 {S} に縮約するのは難しいので,注意を用いてエンコーダの全タイムステップの出力 {X} から現時点のデコーダ {y} に関連する情報を取得する.

f:id:Ryobot:20171218171037p:plain:w700

エンコーダの全タイムステップの出力をメモリ {X = (x_1, \, x_2, \, \ldots, \, x_M)}デコーダのあるタイムステップの出力をクエリ {y_{i-1}} とする.

一般的な Encoder-Decoder の注意は次式によって表される.

f:id:Ryobot:20171218171145p:plain:w500

注意はクエリ {y_{i-1}} とメモリ {X = (x_1, \, x_2, \, \ldots, \, x_M)} から注意の重み (Attention Weihgt) {P = (p_1, \, p_2, \, \ldots, \, p_M)} を求め,注意の重み {P} によるメモリ {X = (x_1, \, x_2, \, \ldots, \, x_M)} の加重和 {a_i} を出力する.注意の重みはメモリからどの情報をどの程度取り出すかを加重和で決めるための重みであり,この重みが大きい位置にあるメモリ内のベクトルが取り出される.

注意の重みの求め方はいくつか種類がある.GNMT では注意の重みをサイズ {n} の隠れ層 1 つのフィードフォワードネットワークによって求める.次式の {A_{GNMT}} に softmax を適応すると注意の重み {P} が得られる.

f:id:Ryobot:20171218171217p:plain:w450

ここで {x_i} はメモリ内のベクトル,{y_j} はクエリ,{U, \, W} は学習パラメータの重み行列,{V} は学習パラメータの重みベクトルである.

これは加法注意 (Additive Attention) といい,他に内積注意 (Dot-Product Attention) も一般的に使用される.詳細は 論文解説 Attention Is All You Need (Transformer) で紹介したい.

GNMT はエンコーダの 8 層目 (最終層) の出力をメモリ,デコーダの 1 層目の出力をクエリとして,注意で求めた出力 {a_i}デコーダの全ての層に入力する.

{i'_i = tanh(W_x x_i + W_m m_i + W_a a_i)}

双方向 LSTM

双方向 LSTM (Bi-directional LSTM) [Bahdanau, 2014] は順方向 LSTM {\overleftarrow{f}} の出力と逆方向 LSTM {\overrightarrow{f}} の出力を連結して最終的な出力を求める手法である.前後の文脈を考慮する効果がある.

f:id:Ryobot:20171218171115p:plain:w700

入力文 {X} を順方向 ({x_1} から {x_M}) に入力した LSTM (Forward LSTM) {\overrightarrow{f}} の出力を {(\overrightarrow{h_1}, \, \ldots, \, \overrightarrow{h_M})},逆方向 ({x_M} から {x_1}) に入力した LSTM (Backward LSTM) {\overleftarrow{f}} の出力を {(\overleftarrow{h_1}, \, \ldots, \, \overleftarrow{h_M})} とする.

双方向 LSTM の出力はこれらを連結 (concatenate) した {h_j = [\overrightarrow{h_j}; \overleftarrow{h_j}]} によって表される.これにより,全てのタイムステップで前後の文脈を考慮した出力が得られる.

GNMT ではエンコーダの一層目に双方向 LSTM (Bi-directional Encoder と呼ぶ) を使用する.

残差接続

残差接続 (Residual Connection) [He, 2015] は層を飛び越えた接続である.勾配消失を回避する効果がある.

f:id:Ryobot:20171218171123p:plain:w700

{i} 層目の LSTM と {i+1} 層目の LSTM 間の残差接続は次式によって表される.

f:id:Ryobot:20171218171149p:plain:w420

{LSTM_i} の入力 {x_t^{i-1}}{LSTM_i} の出力 {m_t^{i}} に加算され,{LSTM_{i+1}} の入力になっている.

LSTM を多層化すると勾配消失が問題になるが,残差接続を通って下層へ勾配を伝播させることで勾配消失を回避できる.

データ並列とモデル並列

大規模深層学習では分散システムが不可欠である.
GNMT では 96 枚の K80 GPU を使用して 12 データ並列と 8 モデル並列で訓練している.

f:id:Ryobot:20171218171225p:plain:w700

データ並列 (Data Parallelism) は 1 つの親モデルをコピーした {n} 個のレプリカ (子モデル) を各 GPU ワーカーに作成し,バッチの異なる部分を各ワーカーに供給する.各ワーカーは順伝播と逆伝播を処理し,親モデルのパラメータを更新する.

データ並列はパラメータ更新の仕方によって同期型と非同期型の 2 種類が存在する.

  • 同期型 (Synchronous): パラメータ更新は全てのワーカーの順/逆伝播が終わるのを待つ必要があるので throughputs (1 秒あたりの処理数) が低い.常に新しいモデルを使用するので学習が安定する.
  • 非同期型 (Asynchronous): パラメータ更新は他のワーカーを待つ必要がないので throughputs が高い.ただし古いモデルの勾配で更新するので学習が不安定になる (ie, Gradient Staleness).

TensorFlow の雛形である DistBelief や GNMT では非同期型を採用し,MoE [Shazeer, 2017] では同期型を採用している.
TensorFlow と PyTorch は両方をサポートしている.Chainer は同期型のみ.

f:id:Ryobot:20171218171108p:plain:w700

モデル並列 (Model Parallelism) はモデルを複数のモジュールに分割し,各モジュールを各 GPU ワーカーで分担して処理する.

GNMT の場合,各層に 1 GPU ワーカーを割り当てる (8 層なので合計 8 GPU を使用する).時刻 {t+1}{LSTM_{i-1}} と時刻 {t}{LSTM_{i}} と時刻 {t-1}{LSTM_{i+1}} と...... を同時に処理する.入力文の長さは層数より多いので処理の大部分は並列化できる.

語彙数が多い翻訳タスクでは埋め込み層やソフトマックス層の行列も分割して処理する.

ハードウェアに起因する通信のボトルネックも考慮する必要がある.single-GPU 内のメモリバス帯域は GDDR5X で 670 Gbps と高速であるが,CPU と GPU をつなぐ PCI Express の帯域は 1 GPU あたり 16 Gbps が限界である.また GPU 同士をつなぐ GPUDirect のネットワーク帯域は Ethernet (研究室等のクラスタ用) で 10 Gbps,Infiniband (スパコン用) で 56 Gbps が限界である.

分散システムは多くのフレームワークで構築できる.以下の解説が初学者向きでわかりやすい.

Wordpiece と Sentencepiece

大規模な NMT では固有名詞・数字・日付などの希少語 (Rare Word) を辞書に追加せず,未知語 (Unknown Word, out-of-vocabulary) として扱われる.これは語彙数を減らし,ソフトマックス層を軽量化するためである.

未知語を翻訳する方法は 2 パターンある.1 つは注意モデルを用いてソース言語からターゲット言語に未知語をコピーする方法で,もう 1 つは未知語をサブワードや文字列に分解する方法である.

Wordpiece は学習済みの Wordpiece モデルを用いて単語 (主に未知語) をサブワード (Subword Units) に分割する手法である.

単語列とサブワード列の例を以下に示す.

  • 単語列: Jet makers feud over seat width with big orders at stake
  • サブワード列: _J et _makers _fe ud _over _seat _width _with _big _orders _at _stake

この例では Jet_Jet に分割され,feud_feud に分割されている.

翻訳モデルを訓練する前に単語の先頭に _ を付加することで,サブワード列から単語列に復元する際に単語同士の境界を知ることができる.

Wordpiece モデルは訓練コーパスに対して分割数を最小化する BPE (Byte Pair Encoding, 貪欲法によるデータ圧縮) によって求める.これは言語モデルの尤度を最大化する.また文の長さを最小化するので翻訳の計算コストが低くなる.

GNMT では最大で 32000 個のサブワードを使用する.また希少語を簡単にコピーするためにソース言語とターゲット言語で語彙を共有する.

欧州圏の言語は単語同士がスペース区切りなので単語分割が容易であるが,アジア圏の言語は単語同士に区切り文字がないので最初に形態素解析をして単語に分割する必要がある.

Sentencepiece は文をサブワードに分割する手法である.つまり形態素解析をする必要がない.

強化学習による再学習

通常 NMT の訓練は {N} 個の対訳文 {D \equiv { (X^{(i)}, Y^{*(i)}) }_{i=1}^N} を用意し,入力文 {X^{(i)}} を与えた時のモデルの出力文 {Y^{*(i)}} の対数尤度の和を最大化することを目的とする.

最尤関数 (Maximum Likelihood Objective) は次式によって表される.

f:id:Ryobot:20171218171152p:plain:w320

この目的関数は尤度のみ最適化するが,BLEU スコア を最適化する報酬関数を反映していない.また,訓練中は誤った出力に対するランク付けを実行しない.よって,モデルは訓練時とテスト時の不一致が大きいと言える.

GNMT では尤度を最適化した学習済みモデルを,報酬を最適化する報酬関数を用いて再学習し,性能を大幅に改善している.

報酬関数 (Reward Objective) は次式によって表される.

f:id:Ryobot:20171218171156p:plain:w400

ここで {r(Y, Y^{*(i)})} は文ごとの報酬スコア (つまり BLEU スコア) である.

BLEU スコアはコーパス全体の n-gram 適合率を計算するように設計されているので,実際の報酬スコアには一文あたりの n-gram 適合率を計算する GLEU スコアを使用する.GLEU は「正解単語列の全 n-gram に一致する予測単語列の n-gram の割合である再現率 (recall)」と「予測単語列の全 n-gram に一致する正解単語列の n-gram の割合である精度 (precision)」の最小値である.また一般的な強化学習の慣習に倣い,{r(Y, Y^{*(i)})} から 15 標本の平均報酬 (分布 {P_\theta (Y | X^{(i)})} から独立) を引く.

実際の再学習は訓練を安定させるために最尤関数と報酬関数を結合した次式を使用する.

f:id:Ryobot:20171218171200p:plain:w330

ここで {\alpha = 0.017} である.

はじめに最尤関数が収束するまで訓練し,そのあと検証セットの BLEU スコアが上がらなくなるまで再学習する.

実験と結果

データセットは WMT'14 の英仏 (36M 対訳文) と英独 (5M 対訳文) を使用する.

モデルは TensorFlow 用いて実装し,訓練は 6 日間行った.96 枚の K80 GPU を使用して 12 データ並列のレプリカが非同期に共有パラメータを更新する.

すべての LSTM 層サイズは 1024 次元,加法注意の隠れ層サイズは 1024 に統一する.学習パラメータは {[-0.04, 0.04]} の一様分布で初期化し,逆伝播は勾配クリッピングを適応する.訓練は最初の 6 万ステップに Adam (学習率は 0.0002) を使用し,その後 SGD (学習率は 0.5,20 万ステップごとに半減) に切り替える.ミニバッチは 128 標本,ドロップアウト率は 0.2 である.

シングルモデルを学習した結果は次のとおり.

f:id:Ryobot:20171218171132p:plain:w500

8k, 16k, 32k 個のサブワードを用いた Wordpiece モデル (WPM) の他,単語レベル,文字レベル,単語と文字列の混合モデルを評価したところ,WPM-32K (32000 個のサブワードを用いた WPM) が最も性能が高く推論も高速だった.

WMT'14 英仏の BLEU スコアは WPM-32K の 8 モデルの平均が 38.95,最高が 39.37 を達成した.また英独は 8 モデルの平均が 24.67 を達成した.

強化学習で再学習したところ,英仏の BLEU スコアが 1 ポイント改善した.英独は検証セットでは 0.4 ポイント改善したもののテストセットではわずかに悪化した.

8 モデルのアンサンブルを人手評価した結果は次のとおり (WMT'14 英仏).

f:id:Ryobot:20171218171051p:plain:w400

WMT'14 英仏の BLEU スコアは 41.16,英独は 26.30 を達成した (当時の SOTA).

興味深いことに強化学習による再学習は BLEU スコアを向上するものの人手評価 (Side-by-side) はほとんど改善しない.これは BLEU スコアと人手評価にあまり相関がない可能性を示唆している.

ちなみに NMT のアンサンブル学習は各モデルが 1 単語を生成するごとに多数決をとって最多の単語を予測単語にする.次のタイムステップの各モデルには最多の単語を入力する.

GNMT の大規模なハイパパラメータ探索

GNMT と同じ構成による大規模なハイパパラメータ探索を行った研究を紹介したい.
1 GPU 換算で 25 万時間に相当する実験を行っている.

WMT'14 英独の BLEU スコアは,著者が 22.2,NMT チュートリアルが 24.4,GNMT が 24.6 である.

ハイパパラメータ探索で得られた知見は以下のとおり.

  • 埋め込み層サイズ (隠れ層サイズ) は大きいほど良いが 128 次元でも十分に意味情報を表現できる.
  • GRU より LSTM が良い.
  • 2~4 層の双方向エンコーダが良い.これより深い場合,学習が不安定になる.
  • 4 層のデコーダが良い.8 層のデコーダを訓練するには残差接続が必要である.
  • 注意は内積注意 (Dot-Product Attention) より加法注意 (Additive Attention) の方が良い.
  • ビーム探索は長さのペナルティ 1.0 とビーム幅 5~10 が良い.

ハイパパラメータ探索で得られた理想的な設定は次のとおり.

f:id:Ryobot:20171218171056p:plain:w350

留意点として,直近の 1 年だけで Transformer 等の非 LSTM 系モデルの一般化や Factorization Trick の普及によって理想的なハイパパラメータ設定がかなり変化している.現在は 32000 個の Wordpiece,1024 次元の隠れ層,6 ブロックのエンコーダ・デコーダ内積注意がデフォである (個人の感想).