Transformerで翻訳AIを作成しようぜ

7 min読了の目安(約4300字TECH技術記事

翻訳AIだぜ

GPUマシンさえあれば、翻訳AIなんて誰にでも作成できる時代になった。
訳質を問わず、学習の時間さえかけることができれば。。
OpenNMTという、オープンソースの機械翻訳ツールセットがある。
GPUマシンさえもGoogle Colaboratoryを使えば、無料で用意できる。
OpenNMTを使った翻訳は、ニューラル機械翻訳の実践と理論に書いてみた。
ここでは、もっと簡単に、翻訳AIを作ってみようと思う。

jsalt-2019-mt-tutorialパクるぜ

ゼロから作るのは、大変なので、jsalt-2019-mt-tutorialという、どこかのサマースクールの教材を借用する。
それをforkしたのがこれだ。
以下の修正を行っている。

  • TODOの反映。(solutionsブランチを反映しただけ。)
  • PyTorch1.6.0の対応
  • Google Colaboratoryで動作させる手順をREADMEに記載。
  • 京都フリー翻訳タスク (KFTT)のコーパスを使用した日英翻訳の手順をREADMEに記載。

Google Colaboratory使うぜ

詳しい説明は、ニューラル機械翻訳の実践と理論(その1)を参照してほしい。
ngrokを設定して、ssh接続できるようにする。
ここでは、手順をまとめる。
以下の手順で操作すればよい。

  • Google Colaboratory(以降、Colabo)をブラウザで開く。
  • 「接続」ボタンを押して、インスタンスを立ち上げる。
  • メニューの「編集」→「ノートブックの設定」を押して、「ハードウェアアクセラレータ」でGPUを選択する。(これでGPUが使えるインスタンスが用意される。)
  • この後、まずGoogleDriveをマウントしておくのがよい。(ngrok設定後にドライブをマウントすると、なぜかセッションがタイムアウトすることがあるため。)
from google.colab import drive
drive.mount('/content/drive')
  • 次にngrokを設定する。
!pip install git+https://github.com/demotomohiro/remocolab.git
import remocolab
remocolab.setupSSHD()
import datetime
import time

time_in_second = 60
start = time.time()
while True:
    print(datetime.datetime.now())
    print(time.time() - start)
    time.sleep(time_in_second)

setupするぜ

  • gitでコードを取得。
git clone https://github.com/forest1040/jsalt-2019-mt-tutorial.git
  • pythonモジュールのインスコ(多分、torchとtqdmはColaboインスタンスにインストール済み)
sudo pip3 install torch
sudo pip3 install tqdm
sudo pip3 install sentencepiece
sudo pip3 install sacrebleu
  • コーパスデータを持ってくる。
wget http://www.phontron.com/kftt/download/kftt-data-1.0.tar.gz
tar zxvf kftt-data-1.0.tar.gz
mv kftt-data-1.0/data/orig/ jsalt-2019-mt-tutorial/data

後述のsubwords化するため、kftt-data-1.0.tar.gzのorigデータを使用する。

subwordsってなんぞ

subwordsについては、自然言語処理の前処理でよく使う技術にリンクをまとめてある。
簡単に説明すると、コーパスをトークナイズして単語にばらし、更に「機械学習」等の長めの単語は、「機械」と「学習」という単語に分割する。
何が長めの単語かどうかは、subwords学習するデータによって決まる。
後述のsubwords学習で、語彙集(ボキャブラリ)が作られそれに登録されている単語よりも長いやつが長めの単語になる。長めの単語もどんどん分解すれば、いずれ語彙集のどれかに当てはまるであろうという塩梅。もしそれでもダメな場合は、未知語となる。

subwords学習

subwords学習で、subwords処理をするためのモデルを作成する。

python3 lab/subwords.py train \
    --model_prefix data/subwords \
    --vocab_size 16000 \
    --model_type bpe \
    --input data/kyoto-train.en,data/kyoto-train.ja

dataの下にsubwords.modelというファイルができる。これがsubwordsモデルだ。
後述の「Trainデータのsubwords化」で使用する。

Trainデータのsubwords化

Trainデータといいながら、Trainの具合を確認するTestデータもsubwords化する。
それぞれ、enとjaの2種類を行う。

cat data/kyoto-train.en | python3 lab/subwords.py segment --model data/subwords.model > data/kyoto-train.bpe.en
cat data/kyoto-train.ja | python3 lab/subwords.py segment --model data/subwords.model > data/kyoto-train.bpe.ja
cat data/kyoto-test.en | python3 lab/subwords.py segment --model data/subwords.model > data/kyoto-test.bpe.en
cat data/kyoto-test.ja | python3 lab/subwords.py segment --model data/subwords.model > data/kyoto-test.bpe.ja

Train(学習)の実行

せっかくなので、ハイパラメータを大きめ設定して学習してみる。

python3 lab/training.py \
    --cuda \
    --n-layers 6 \
    --n-heads 8 \
    --embed-dim 512 \
    --hidden-dim 2048 \
    --dropout 0.1 \
    --lr 2e-4 \
    --n-epochs 4 \
    --tokens-per-batch 8000 \
    --clip-grad 1.0

各パラメータは、リンクを参照。

翻訳の実行

  • 翻訳対象のsubwords化
echo "日本の水墨画を一変させた。" | python3 lab/subwords.py segment --model data/subwords.model
  • subwords化した文章を翻訳させる
echo "▁日本の 水 墨 画 を一 変 させた 。" |
  python3 lab/translate.py \
  --cuda \
  --model-file model.pt \
  --search "beam_search" \
  --beam-size 2 \
  --n-layers 6 \
  --n-heads 8 \
  --embed-dim 512 \
  --hidden-dim 2048

学習時にハイパラメータを変更しているため、翻訳時にも指定しないとパラメータ不一致エラーになる。