BERT日本語モデル事前学習に失敗

した。というか、一応今のところ。

行ったのは、東北大学github情報に沿って学習のためのデータを作り、そして最後に学習させる、ということで、データ作成プロセスは一応実行はできた。プラットフォームはWindows10。果たしてできたものがきちんとしたものなのかどうかは分からないが。

以下に大体のプロセスを書いてみる。なのでこのまま実行しても欠けているところがあって動かない。

最初に、

pip3 install beautifulsoup4 fugashi ipadic==1.0.0 logzero sentencepiece>=0.1.91 tensorflow>=2.3.0 tensorflow-datasets>=3.2.0 tf-models-official==2.3.0 tqdm tokenizers==0.9.2 transformers==3.4.0 unidic==1.0.2 unidic_lite==1.0.7

で処理に必要なバージョンを揃える。

mecab-ipadic-neologdはUbuntu等でインストールしたものをコピーしてくる。

コーパスの作成はjawiki-20220110-cirrussearch-content.json.gzをダウンロード後に、

python make_corpus_wiki.py --input_file jawiki-20220110-cirrussearch-content.json.gz --output_file ./corpus/jawiki-20220110/corpus.txt --min_text_length 10 --max_text_length 200 --mecab_option "-d ./mecab-ipadic-neologd"

これを8つに分割

python merge_split_corpora.py --input_files ./corpus/jawiki-20220110/corpus.txt --output_dir ./corpus/jawiki-20220110 --num_files 8

tokenizerの訓練に用いるデータ作成はcygwin上で行った

cat ./corpus/jawiki-20220110/corpus.txt|grep -v '^$'|shuf|head -n 1000000 > ./corpus/jawiki-20220110/corpus_sampled.txt

実際のtokenizerの訓練は、

python train_tokenizer.py --input_files ./corpus/jawiki-20220110/corpus_sampled.txt --output_dir ./tokenizers/jawiki-20220110/wordpiece_unidic_lite --tokenizer_type wordpiece --mecab_dic_type unidic_lite --vocab_size 32768 --limit_alphabet 6129 --num_unused_tokens 10

下記もcygwin上で

head -n 6144 ./tokenizers/jawiki-20220110/wordpiece_unidic_lite/vocab.txt > ./tokenizers/jawiki-20220110/character/vocab.txt

次に、単語単位の学習用ファイル(なのかな?フォルダ名からして)なのだけれど、元のスクリプトでは8つの処理を平行して走らせるため数百GBのメモリが必要となるが、逐次実行すればそこまでは必要ない。といっても128GBくらいはあった方がよくて、64GBだと無理かも。16分割や32分割にすればメモリが少ないPCでも実行可能かもしれない。

 

python create_pretraining_data.py --input_file ./corpus/jawiki-20220110/corpus_01.txt --output_file ./bert/jawiki-20220110/wordpiece_unidic_lite/pretraining_data/pretraining_data_01.tfrecord.gz --vocab_file ./tokenizers/jawiki-20220110/wordpiece_unidic_lite/vocab.txt --tokenizer_type wordpiece --mecab_dic_type unidic_lite --do_whole_word_mask --gzip_compress --max_seq_length 512 --max_predictions_per_seq 80 --dupe_factor 10
python create_pretraining_data.py --input_file ./corpus/jawiki-20220110/corpus_02.txt --output_file ./bert/jawiki-20220110/wordpiece_unidic_lite/pretraining_data/pretraining_data_02.tfrecord.gz --vocab_file ./tokenizers/jawiki-20220110/wordpiece_unidic_lite/vocab.txt --tokenizer_type wordpiece --mecab_dic_type unidic_lite --do_whole_word_mask --gzip_compress --max_seq_length 512 --max_predictions_per_seq 80 --dupe_factor 10
python create_pretraining_data.py --input_file ./corpus/jawiki-20220110/corpus_03.txt --output_file ./bert/jawiki-20220110/wordpiece_unidic_lite/pretraining_data/pretraining_data_03.tfrecord.gz --vocab_file ./tokenizers/jawiki-20220110/wordpiece_unidic_lite/vocab.txt --tokenizer_type wordpiece --mecab_dic_type unidic_lite --do_whole_word_mask --gzip_compress --max_seq_length 512 --max_predictions_per_seq 80 --dupe_factor 10
python create_pretraining_data.py --input_file ./corpus/jawiki-20220110/corpus_04.txt --output_file ./bert/jawiki-20220110/wordpiece_unidic_lite/pretraining_data/pretraining_data_04.tfrecord.gz --vocab_file ./tokenizers/jawiki-20220110/wordpiece_unidic_lite/vocab.txt --tokenizer_type wordpiece --mecab_dic_type unidic_lite --do_whole_word_mask --gzip_compress --max_seq_length 512 --max_predictions_per_seq 80 --dupe_factor 10
python create_pretraining_data.py --input_file ./corpus/jawiki-20220110/corpus_05.txt --output_file ./bert/jawiki-20220110/wordpiece_unidic_lite/pretraining_data/pretraining_data_05.tfrecord.gz --vocab_file ./tokenizers/jawiki-20220110/wordpiece_unidic_lite/vocab.txt --tokenizer_type wordpiece --mecab_dic_type unidic_lite --do_whole_word_mask --gzip_compress --max_seq_length 512 --max_predictions_per_seq 80 --dupe_factor 10
python create_pretraining_data.py --input_file ./corpus/jawiki-20220110/corpus_06.txt --output_file ./bert/jawiki-20220110/wordpiece_unidic_lite/pretraining_data/pretraining_data_06.tfrecord.gz --vocab_file ./tokenizers/jawiki-20220110/wordpiece_unidic_lite/vocab.txt --tokenizer_type wordpiece --mecab_dic_type unidic_lite --do_whole_word_mask --gzip_compress --max_seq_length 512 --max_predictions_per_seq 80 --dupe_factor 10
python create_pretraining_data.py --input_file ./corpus/jawiki-20220110/corpus_07.txt --output_file ./bert/jawiki-20220110/wordpiece_unidic_lite/pretraining_data/pretraining_data_07.tfrecord.gz --vocab_file ./tokenizers/jawiki-20220110/wordpiece_unidic_lite/vocab.txt --tokenizer_type wordpiece --mecab_dic_type unidic_lite --do_whole_word_mask --gzip_compress --max_seq_length 512 --max_predictions_per_seq 80 --dupe_factor 10
python create_pretraining_data.py --input_file ./corpus/jawiki-20220110/corpus_08.txt --output_file ./bert/jawiki-20220110/wordpiece_unidic_lite/pretraining_data/pretraining_data_08.tfrecord.gz --vocab_file ./tokenizers/jawiki-20220110/wordpiece_unidic_lite/vocab.txt --tokenizer_type wordpiece --mecab_dic_type unidic_lite --do_whole_word_mask --gzip_compress --max_seq_length 512 --max_predictions_per_seq 80 --dupe_factor 10

ひとまず、ここまでのデータを用いてBERT baseの事前学習を行うべく、まずはtensorflowのバージョンを落としておく。

pip3 uninstall tensorflow
pip3 install tensorflow-gpu==1.15.0

最後にいよいよ学習を。ちなみにCUDAは10.0、cuDnnは7.6 で関連DLLを強引に

C:¥Windows¥System32

にコピーしておいた。事前学習のためのスクリプトは下記のようにしたところ、

python3 ../bert/run_pretraining.py --input_file="bert/jawiki-20220110/wordpiece_unidic_lite/pretraining_data/pretraining_data_*.tfrecord" --output_dir="output" --model_dir="bert/jawiki-20220110/wordpiece_unidic_lite/bert-base" --do_train=True --bert_config_file="bert/jawiki-20220110/wordpiece_unidic_lite/bert-base/config.json" --max_seq_length=32 --max_predictions_per_seq=80 --train_batch_size=8 --learning_rate=1e-4 --num_train_epochs=100 --num_steps_per_epoch=10000 --optimizer_type=adamw --warmup_steps=10000 --fp16

 

どうやらGPUのメモリ不足でとまるようだ。確かではないが。そのため、train_batch_sizeやmax_seq_lengthを色々と変えてみたが、やはりダメだった。ネットで検索してもこれ以上はなかなか情報がなく、お手上げ状態。