見出し画像

Huggingface Transformers 入門 (24) - 日本語の言語モデルの学習

「Huggingface Transformers」による日本語の言語モデルの学習手順をまとめました。

・Huggingface Transformers 4.4.2
・Huggingface Datasets 1.2.1

前回

1. データセットの準備

データセットとして「wiki-40b」を使います。データ量が大きすぎると時間がかかるので、テストデータのみ取得し、90000を学習データ、10000を検証データに使います。

ローカルでデータセットを準備する手順は、次のとおりです。

(1) TensorFlow Datasetsのダウンロード。

$ pip install tensorflow==2.4.1
$ pip install tensorflow-datasets==3.2.0

(2) データセットのテストデータをテキスト形式で出力。

import os
import tensorflow_datasets as tfds
ds_test = tfds.load('wiki40b/ja', split='test')

# データセットをテキスト形式で出力する関数
def create_txt(file_name, tf_data):
   start_paragraph = False

   # ファイルの書き込み
   with open(file_name, 'w') as f:
       for wiki in tf_data.as_numpy_iterator():
           for text in wiki['text'].decode().split('\n'):
               if start_paragraph:
                   text = text.replace('_NEWLINE_', '') # _NEWLINE_は削除
                   f.write(text + '\n')
                   start_paragraph = False
               if text == '_START_PARAGRAPH_': # _START_PARAGRAPH_のみ取得
                   start_paragraph = True

# データセットをテキスト形式で出力
create_txt('wiki_40b_test.txt', ds_test)

(3) 訓練データとテストデータに分割。

$ head -n 90000 wiki_40b_test.txt > train.txt
$ tail -n 10000 wiki_40b_test.txt > dev.txt

2. 日本語のマスク言語モデルの学習

「wiki-40b」を使って日本語のマスク言語モデル(MLM: Masked Language Model)を学習してみます。

(1) データの永続化。

# データの永続化
from google.colab import drive 
drive.mount('/content/drive')
!mkdir -p '/content/drive/My Drive/work/'
%cd '/content/drive/My Drive/work/'

(2) ソースからの「Huggingface Transformers」のインストール。

# ソースからのHuggingface Transformersのインストール
!git clone https://github.com/huggingface/transformers -b v4.4.2
!pip install -e transformers

(3) メニュー「ランタイム → ランタイムを再起動」で「Google Colab」を再起動し、作業フォルダに戻る。

# メニュー「ランタイム → ランタイムを再起動」で「Google Colab」を再起動

# 作業フォルダに戻る
%cd '/content/drive/My Drive/work/'

(4) 「Huggingface Datasets」のインストール。

# Huggingface Datasetsのインストール
!pip install datasets==1.2.1

(5) 「train.txt」と「dev.txt」を作業フォルダに配置。
(6) 事前学習の実行。
モデルを最初から学習するには時間がかかるので、日本語BERTモデルに3エポックだけ追加学習してみます。

%%time

# 事前学習の実行
!python ./transformers/examples/language-modeling/run_mlm.py \
    --model_name_or_path=cl-tohoku/bert-base-japanese-whole-word-masking \
    --train_file=train.txt \
    --validation_file=dev.txt \
    --do_train \
    --do_eval \
    --num_train_epochs=3 \
    --save_steps=5000 \
    --save_total_limit=3 \
    --output_dir=output/ \
    --use_fast_tokenizer=False
 ***** eval metrics *****
   epoch                     =     3.0
   eval_loss                 =  1.2491
   eval_mem_cpu_alloc_delta  =     0MB
   eval_mem_cpu_peaked_delta =     0MB
   eval_mem_gpu_alloc_delta  =     0MB
   eval_mem_gpu_peaked_delta =  1012MB
   eval_runtime              = 53.5836
   eval_samples              =    4265
   eval_samples_per_second   =  79.595
   perplexity                =  3.4873
CPU times: user 55 s, sys: 6.98 s, total: 1min 1s
Wall time: 1h 39min 54s

主なパラメータは、次のとおりです。

--model_name_or_path: モデルのチェックポイント(モデルを途中から学習する場合)
--train_file: 学習データ(テキストファイル)
--validation_file: 検証データ(テキストファイル)
--do_train: 学習するかどうか
--do_eval: 検証するかどうか
--num_train_epochs: エポック数
--save_steps: 何ステップ毎にチェックポイントを保存するか
--save_total_limit: チェックポイントの保存数の制限
--output_dir: 出力フォルダ
--per_device_train_batch_size: 学習のバッチサイズ
--per_device_eval_batch_size: 検証のバッチサイズ
--use_fast_tokenizer: Fastトークナイザーを使うか

--model_type: モデルの種別(モデルを最初から学習する場合)
--tokenizer_name: トークナイザー名
--model_type: モデルの種別

3. 日本語のマスク言語モデルの推論

日本語のマスク言語モデルの推論を行うコードは、次のとおりです。

import torch
from transformers import BertJapaneseTokenizer, AutoModelForMaskedLM

# トークナイザーとモデルの準備
tokenizer = BertJapaneseTokenizer.from_pretrained('cl-tohoku/bert-base-japanese-whole-word-masking')
model = AutoModelForMaskedLM.from_pretrained('output/')

# テキスト
text = f'吾輩は{tokenizer.mask_token}である。名前はまだない。'

# テキストをテンソルに変換
input_ids = tokenizer.encode(text, return_tensors='pt')
masked_index = torch.where(input_ids == tokenizer.mask_token_id)[1].tolist()[0]

# 推論
result = model(input_ids)
pred_ids = result[0][:, masked_index].topk(5).indices.tolist()[0]
for pred_id in pred_ids:
    output_ids = input_ids.tolist()[0]
    output_ids[masked_index] = pred_id
    print(tokenizer.decode(output_ids))
[CLS] 吾輩 は 猫 で ある 。 名前 は まだ ない 。 [SEP]
[CLS] 吾輩 は 犬 で ある 。 名前 は まだ ない 。 [SEP]
[CLS] 吾輩 は 狼 で ある 。 名前 は まだ ない 。 [SEP]
[CLS] 吾輩 は 人間 で ある 。 名前 は まだ ない 。 [SEP]
[CLS] 吾輩 は [UNK] で ある 。 名前 は まだ ない 。 [SEP]

3. 日本語の因果言語モデルの学習

「wiki-40b」を使って日本語の因果言語モデル(CLM: Causal Language Model)を学習してみます。

(1) データの永続化。

# データの永続化
from google.colab import drive 
drive.mount('/content/drive')
!mkdir -p '/content/drive/My Drive/work/'
%cd '/content/drive/My Drive/work/'

(2) ソースからの「Huggingface Transformers」のインストール。

# ソースからのHuggingface Transformersのインストール
!git clone https://github.com/huggingface/transformers -b v4.4.2
!pip install -e transformers

(3) メニュー「ランタイム → ランタイムを再起動」で「Google Colab」を再起動し、作業フォルダに戻る。

# メニュー「ランタイム → ランタイムを再起動」で「Google Colab」を再起動

# 作業フォルダに戻る
%cd '/content/drive/My Drive/work/'

(4) 「Huggingface Datasets」のインストール。

# Huggingface Datasetsのインストール
!pip install datasets==1.2.1

(5) 「train.txt」と「dev.txt」を作業フォルダに配置。
(6) 事前学習の実行。
モデルを最初から学習するには時間がかかるので、英語GPT-2モデルに3エポックだけ追加学習してみます。

%%time

# 事前学習の実行
!python ./transformers/examples/language-modeling/run_clm.py \
    --model_name_or_path=gpt2 \
    --train_file=train.txt \
    --validation_file=dev.txt \
    --do_train \
    --do_eval \
    --num_train_epochs=3 \
    --save_steps=5000 \
    --save_total_limit=3 \
    --output_dir=output/ \  
    --per_device_train_batch_size=2 \
    --per_device_eval_batch_size=2   
 ***** eval metrics *****
   epoch                     =      3.0
   eval_loss                 =   1.8403
   eval_mem_cpu_alloc_delta  =      0MB
   eval_mem_cpu_peaked_delta =      0MB
   eval_mem_gpu_alloc_delta  =      0MB
   eval_mem_gpu_peaked_delta =   1399MB
   eval_runtime              = 322.3649
   eval_samples              =     4736
   eval_samples_per_second   =   14.691
   perplexity                =   6.2985
CPU times: user 3min 31s, sys: 23.5 s, total: 3min 55s
Wall time: 7h 48min 58s

主なパラメータは、「run_mlm.py」と同様です。

3. 日本語の因果言語モデルの推論

日本語の因果言語モデルの推論を行うコードは、次のとおりです。​

# 推論
!python transformers/examples/text-generation/run_generation.py \
    --model_type=gpt2 \
    --model_name_or_path=output/ \
    --prompt "吾輩は猫である。" \
    --length 100
吾輩は猫である。猫と引き合う神社は、社会において誕生したものであり、その歴史は「私の教育と感染を感じるのはこのように得意である」と解釈している。

パラメータは、次のとおりです。

--model_type: モデルの種別
--model_name_or_path: モデルのチェックポイント
--prompt: プロンプト(開始文字列)
--length: 生成するテキストの長さ

トークナイザーは「byle-level BPE」なので、「わかち書き」にした方が精度でるのかも(後で試す)。

参考

次回



この記事が気に入ったらサポートをしてみませんか?