Published on

XXX

Author
株式会社イエローバックの機械学習エンジニアです

はじめに

GPT2,GPT3 系の事前学習モデルを使って日本語のテキスト生成を試してみます。

モデルたち

日本語を扱えそうなモデルをピックアップしてみました。

| モデル | layers | hidden_size | attn heads | vocabs | params (Million) | Tokenizer | | --------------------------- | -----: | ----------: | ---------: | -----: | ---------------: | -------------- | | rinna/japanese-gpt2-medium | 24 | 1024 | 16 | 32000 | 336 | spiece(日本語) | | geekfeed/gpt2_ja | 12 | 768 | 12 | 32000 | 110 | GPT2(日本語) | | colorfulscoop/gpt2-small-ja | 12 | 768 | 12 | 32000 | 110 | spiece(日本語) | | gpt2 | 12 | 768 | 12 | 50257 | 124 | GPT2(多言語) | | gpt2-medium | 24 | 1024 | 16 | 50257 | 354 | GPT2(多言語) | | gpt2-large | 36 | 1280 | 20 | 50257 | 774 | GPT2(多言語) | | gpt2-xl | 48 | 1600 | 25 | 50257 | 1,557 | GPT2(多言語) | | EleutherAI/gpt-neo-1.3B | 24 | 2048 | 16 | 50257 | 1,315 | GPT2(多言語) | | EleutherAI/gpt-neo-2.7B | 32 | 2560 | 20 | 50257 | 2,651 | GPT2(多言語) | | /work/gptneo/gptneoja-20000 | 24 | 2048 | 16 | 32100 | 1,278 | |

PPL 比較

日本語コーパスの cc100,oscar,wikipedia からそれぞれ subset を切り出して、 perplexity(PPL)を評価してみました。

評価方法は、以下のような感じです。

$ MODEL=EleutherAI/gpt-neo-1.3B
$ FILE=data/wikipediaja-subset.txt
$ python transformers/examples/pytorch/language-modeling/run_clm.py \
    --model_name_or_path $MODEL \
    --do_eval \
    --block_size 1024 \
    --fp16 \
    --per_device_eval_batch_size 1 \
    --validation_file $FILE \
    --output_dir $outdir

rinna については、config.json に tokenizer_class の指定がないため run_clm.py でエラーとなってしまいます。 そこで、関連ファイル群をローカルにコピーして以下の修正をした後、ローカルディレクトリを指定しました。

diff --git a/config.json b/config.json
index 5519b80..b64e0ac 100644
--- a/config.json
+++ b/config.json
@@ -27,5 +27,6 @@
       "max_length": 50
     }
   },
-  "vocab_size": 32000
+    "vocab_size": 32000,
+    "tokenizer_class": "T5Tokenizer"
 }

| model | cc100 | oscar | wikija | | --------------------------- | ----: | ----: | -----: | | rinna/japanese-gpt2-medium | 32.2 | 29.1 | 45.2 | | geekfeed/gpt2_ja | 459.7 | 507.8 | 370.4 | | colorfulscoop/gpt2-small-ja | 68.0 | 67.5 | 22.8 | | gpt2 | 16.4 | 18.2 | 18.1 | | gpt2-medium | 12.7 | 14.3 | 14.6 | | gpt2-large | 11.0 | 12.5 | 12.9 | | gpt2-xl | 10.0 | 11.5 | 11.9 | | EleutherAI/gpt-neo-1.3B | 5.5 | 6.4 | 6.1 | | gptneoja-15000 | 301.4 | 166.3 | 15.7 | | gptneoja-20000 | 392.8 | 222.1 | 16.8 |

tokenizer

改行コード

# GPT2

tokenizer.encode('\n', add_special_tokens=False)
[198]
tokenizer.encode('\n\n', add_special_tokens=False)
[628]
tokenizer.encode('\n\n\n', add_special_tokens=False)
[628,198]


# T5

tokenizer.encode('\n', add_special_tokens=False)
[]
tokenizer.encode('\n\n', add_special_tokens=False)
[]
tokenizer.encode('\n\n\n', add_special_tokens=False)
[]

### '#'

GPT2

tokenizer.encode('#', add_special_tokens=False) [2] tokenizer.encode('##', add_special_tokens=False) [2235] tokenizer.encode('###', add_special_tokens=False) [21017] tokenizer.encode('####', add_special_tokens=False) [4242] tokenizer.encode('#####', add_special_tokens=False) [4242,2]

T5

tokenizer.encode('#', add_special_tokens=False) [9,2518] tokenizer.encode('##', add_special_tokens=False) [9,2518,2518] tokenizer.encode('###', add_special_tokens=False) [9,2518,2518,2518]