アルゴリズムとかオーダーとか

仕事で勉強したことなどをまとめてます

google公式のBERTを2021年の最近の環境で動かしてみる

vasteelab.com
の記事を参考に、BERTの事前学習を動かしてみたときの備忘録をまとめる。2021年12月現在では、tensorflowのバージョンが上がっていたりなどで、記事に書いてある手順通りではうまく動かなかった。自分が行った修正内容などを共有する目的で整理する。

環境

WindowsマシンにAnacondaを入れた環境で試した。

OS等

Windows 10 Home + WSL2 Ubuntu 20.04.LTS

Anaconda

 conda info

     active environment : base
    active env location : /home/nakajo/anaconda3
            shell level : 1
       user config file : /home/nakajo/.condarc
 populated config files :
          conda version : 4.10.3
    conda-build version : 3.21.4
         python version : 3.8.8.final.0
       virtual packages : __linux=5.10.60.1=0
                          __glibc=2.31=0
                          __unix=0=0
                          __archspec=1=x86_64
       base environment : /home/nakajo/anaconda3  (writable)
      conda av data dir : /home/nakajo/anaconda3/etc/conda
  conda av metadata url : None
           channel URLs : https://repo.anaconda.com/pkgs/main/linux-64
                          https://repo.anaconda.com/pkgs/main/noarch
                          https://repo.anaconda.com/pkgs/r/linux-64
                          https://repo.anaconda.com/pkgs/r/noarch
          package cache : /home/nakajo/anaconda3/pkgs
                          /home/nakajo/.conda/pkgs
       envs directories : /home/nakajo/anaconda3/envs
                          /home/nakajo/.conda/envs
               platform : linux-64
             user-agent : conda/4.10.3 requests/2.25.1 CPython/3.8.8 Linux/5.10.60.1-microsoft-standard-WSL2 ubuntu/20.04.2 glibc/2.31
                UID:GID : 1000:1000
             netrc file : None
           offline mode : False

tensorflowのインストール

今回はAnacondaをインストールしたときに一緒にインストールされたTensorflowを利用した。

穴埋め問題を実行するためのファイル生成を動作させる

発生したエラー

「穴埋め問題を実行するためのファイル生成」を実行しようとすると、以下のエラーが発生した。

$ python create_pretraining_data.py --input_file=./sample_text.txt --output_file=/tmp/tf_examples.tfrecord --vocab_file=./vocab.txt --
do_lower_case=True --max_seq_length=128 --max_predictions_per_seq=20 --masked_lm_prob=0.15 --random_seed=12345 --dupe_factor=5

Traceback (most recent call last):
  File "create_pretraining_data.py", line 26, in <module>
    flags = tf.flags
AttributeError: module 'tensorflow' has no attribute 'flags'

さらに、以下のエラーも発生。

$ python create_pretraining_data.py --input_file=./sample_text.txt --output_file=/tmp/tf_examples.tfrecord --vocab_file=./vocab.txt --
do_lower_case=True --max_seq_length=128 --max_predictions_per_seq=20 --masked_lm_prob=0.15 --random_seed=12345 --dupe_factor=5

Traceback (most recent call last):
  File "create_pretraining_data.py", line 469, in <module>
    tf.app.run()
  File "/home/nakajo/anaconda3/lib/python3.8/site-packages/tensorflow/python/platform/app.py", line 40, in run
    _run(main=main, argv=argv, flags_parser=_parse_flags_tolerate_undef)
  File "/home/nakajo/anaconda3/lib/python3.8/site-packages/absl/app.py", line 312, in run
    _run_main(main, args)
  File "/home/nakajo/anaconda3/lib/python3.8/site-packages/absl/app.py", line 258, in _run_main
    sys.exit(main(argv))
  File "create_pretraining_data.py", line 439, in main
    tokenizer = tokenization.FullTokenizer(
  File "/home/nakajo/work/pythonProject/bert/tokenization.py", line 165, in __init__
    self.vocab = load_vocab(vocab_file)
  File "/home/nakajo/work/pythonProject/bert/tokenization.py", line 125, in load_vocab
    with tf.gfile.GFile(vocab_file, "r") as reader:
AttributeError: module 'tensorflow' has no attribute 'gfile'

修正方法

原因は、もともとのBERTがtensorflow 1系で作成されていて、tensorflow 2系がインストールされているためらしい。バージョンアップによって、いくつかのattributeが削除されているのが原因。

tensorflow 2系では1系のinterfaceに戻せるらしいので、今回はそれを試してみたところうまく動いた。具体的には以下の2か所を修正した。
修正後のコードを記載する。

create_pretraining_data.pyの24行目

import tensorflow.compat.v1 as tf

tokenization.pyの25行目

import tensorflow.compat.v1 as tf

Pretrainingの実行を動作させる

続いて、「Pretrainingの実行」を試してみたら、引き続きエラーが発生した。

発生したエラー

python run_pretraining.py --input_file=/tmp/tf_examples.tfrecord --output_dir=./tmp/pretraining_output --do_train=True --do_eval=Tru
e --bert_config_file=./bert_config.json --init_checkpoint=./bert_model.ckpt --train_batch_size=32 --max_seq_length=128 --max_predictions_per_seq=20 --num_train_steps=20 --num_warmup_steps=1
0 --lerning_rate=2e-5

Traceback (most recent call last):
  File "run_pretraining.py", line 26, in <module>
    flags = tf.flags
AttributeError: module 'tensorflow' has no attribute 'flags'

このエラーは先ほどと同様のエラーと思われる。

新しく以下のエラーも発生した。

 python run_pretraining.py --input_file=/tmp/tf_examples.tfrecord --output_dir=./tmp/pretraining_output --do_train=True --do_eval=Tru
e --bert_config_file=./bert_config.json --init_checkpoint=./bert_model.ckpt --train_batch_size=32 --max_seq_length=128 --max_predictions_per_seq=20 --num_train_steps=20 --num_warmup_steps=1

0 --lerning_rate=2e-5
INFO:tensorflow:*** Input Files ***
I1218 03:55:13.127805 140009368016704 run_pretraining.py:420] *** Input Files ***
INFO:tensorflow:  /tmp/tf_examples.tfrecord
I1218 03:55:13.128413 140009368016704 run_pretraining.py:422]   /tmp/tf_examples.tfrecord
Traceback (most recent call last):
  File "run_pretraining.py", line 493, in <module>
    tf.app.run()
  File "/home/nakajo/anaconda3/lib/python3.8/site-packages/tensorflow/python/platform/app.py", line 40, in run
    _run(main=main, argv=argv, flags_parser=_parse_flags_tolerate_undef)
  File "/home/nakajo/anaconda3/lib/python3.8/site-packages/absl/app.py", line 312, in run
    _run_main(main, args)
  File "/home/nakajo/anaconda3/lib/python3.8/site-packages/absl/app.py", line 258, in _run_main
    sys.exit(main(argv))
  File "run_pretraining.py", line 429, in main
    is_per_host = tf.contrib.tpu.InputPipelineConfig.PER_HOST_V2
AttributeError: module 'tensorflow.compat.v1' has no attribute 'contrib'
  File "/home/nakajo/work/pythonProject/bert/modeling.py", line 184, in __init__
    self.embedding_output = embedding_postprocessor(
  File "/home/nakajo/work/pythonProject/bert/modeling.py", line 520, in embedding_postprocessor
    output = layer_norm_and_dropout(output, dropout_prob)
  File "/home/nakajo/work/pythonProject/bert/modeling.py", line 370, in layer_norm_and_dropout
    output_tensor = layer_norm(input_tensor, name)
  File "/home/nakajo/work/pythonProject/bert/modeling.py", line 364, in layer_norm
    return tf.contrib.layers.layer_norm(
AttributeError: module 'tensorflow.compat.v1' has no attribute 'contrib'

修正方法

基本的には、研究開発:BERTオフィシャルコードをtensorflow2で実行する方法 - livedoor Blog(ブログ)を参考にして修正していくとよい。
以下に自分が行った修正内容を記載する。

まずは、前回と同様tensorflow v1のインターフェースを有効にする。

run_pretraining.py、modeling.py、tokenization.pyのtensorflowをimportしている個所を以下のように修正。

import tensorflow.compat.v1 as tf

続いて、「AttributeError: module 'tensorflow.compat.v1' has no attribute 'contrib' 」エラーに対応する。
run_pretraining.pyの「tf.contrib.」を一括で、「tf.estimator.」に置換する。

次は、「AttributeError: module 'tensorflow_estimator.python.estimator.api._v1.estimator' has no attribute 'data'」に対応する。
run_pretraining.pyの365行目と381行目をそれぞれ次のように修正する。

365行目

 tf.data.experimental.parallel_interleave(

381行目

tf.data.experimental.map_and_batch(

最後に以下のエラーに対応する。

  File "/home/nakajo/work/pythonProject/bert/modeling.py", line 364, in layer_norm
    return tf.contrib.layers.layer_norm(
AttributeError: module 'tensorflow.compat.v1' has no attribute 'contrib'

modeling.pyの362行目~365行目を以下のように修正する。

def layer_norm(input_tensor, name=None):
  """Run layer normalization on the last dimension of the tensor."""
  layer_norma = tf.keras.layers.LayerNormalization(axis = -1)
  return layer_norma(input_tensor)