日本語GPT(abeja/gpt-neox-japanese-2.7b)での文章生成を見て大規模コーパスの中身を想像する
ABEJAさんから2.7Bパラメータを持つGPTモデルがリリースされました。2022年9月中旬ごろに、HuggingFace Transformersでこのモデルを使えるようにするPRがマージされ、利用できるようになっています。
公開してくださった関係者の皆様、ありがとうございます!
これは2022年9月26時点で、HuggingFace Hubから利用できる中では最大の日本語生成モデルだと思います。
かなり大きなモデルで、pytorch_model.binだけで5.36GBあります。公開当初は10GB以上あったのですが、アプデでファイルサイズが半分になったようです。
(2.7bのパラメタがあるので、単純計算すると32bitモデルを16bitモデルにしたと想像(2.7billion x 2byte=5.4GB)
テキスト生成をしてみる
2022/9/26時点では、gitを指定してpip installする必要があります。
pip install git+https://github.com/huggingface/transformers
公式のサンプルにしたがって動かしてみます。
from transformers import pipeline
generator = pipeline("text-generation", model="abeja/gpt-neox-japanese-2.7b")
generated = generator(
"人とAIが協調するためには、",
max_length=300,
do_sample=True,
num_return_sequences=1,
top_p=0.95,
top_k=50
)
print(*generated, sep="\n")
良い感じに見えます。
オプションのtop_pとtop_kはランダムサンプリングで偶然確率が低いtokenが選ばれて支離滅裂な文章になることを防ぐ効果があります。
プロンプト「人とAIが協調するためには、」を変えることでいろいろなテキストを生成できます。
いくつか試してみましょう。
prompt="財務相は26日、投機的な動きを背景に急激な為替変動が続けば「"
最近の為替変動の話題です。財務相のコメントは端的過ぎますが、かなり自然な金融ニュースが生成できました。最後は続きを読むためにサブスクが必要と出ており、これはこれでリアルですね。
prompt="台風17号は27日(火)未明から昼前にかけて、"
出てきている地名は実在のもののようです。Yahoo!ニュースにありがちな、冒頭だけ記載して本文は続きを読むページに表示するスタイルになっています。
prompt="うーん、気持ちのいい朝です!"
朝から1時間で夕食の支度の時間になっていますが、文章表現はすごく自然ですね。
ただ、ニュース系の文章でなくとも、一段落すると続きを読むを生成して終わらせる傾向があるように見えてきました。
モデルが学習したデータにこのようなデータが多く含まれるのではないかと思い、学習データセットを少し見てみました。
事前学習データセットを見る
日本語GPTモデルの事前学習には、cc100、mc4、oscarといった、Common Crawlをもとにした大規模データセットが使用されます。
このabeja/gpt-neox-japanese-2.7bもこれらのうち2つと日本語Wikipediaが使われています。
これらのデータセットは、Hugging Face Datasetsライブラリから利用できます。どれも100GB以上の重いデータセットですが、streaming機能を使ってディスクに全体を乗せずに観察やサブデータセットの作成ができます。
テキストの長さ
例えば、oscar、mc4、cc100のランダムな10万件を取得してテキストの長さをプロットしてみます。
import numpy as np
import matplotlib.pyplot as plt
from datasets import load_dataset
n = 100000
oscar = load_dataset('oscar', 'unshuffled_deduplicated_ja', split='train', streaming=True).shuffle(seed=102).take(n)
cc100 = load_dataset("cc100", lang="ja", split='train', streaming=True).shuffle(seed=102).take(n)
mc4 = load_dataset('mc4', 'ja', split='train', streaming=True).shuffle(seed=102).take(n)
bins = np.logspace(1, 5, 100)
plt.hist([len(example ["text"]) for example in oscar], bins=bins, label="oscar", histtype="step"
plt.hist([len(example ["text"]) for example in cc100 ], bins=bins, label="cc100 ", histtype="step"
plt.hist([len(example ["text"]) for example in mc4 ], bins=bins, label="mc4", histtype="step"
plt.xscale("log")
plt.legend()
plt.show()
cc100は30文字~数百文字程度の短めのテキストが多いですが、mc4は3000文字あたりにピークがある長めのテキストが中心です。
続きを読むの登場回数
filterを使って、「続きを読む」形式の文がどのデータセットに多いかを見てみます。
words = ["続きを読む", "続きを見る"]
def filter_fn(text):
for w in words:
if w in text:
return True
return False
n = 100000
filtered_dataset = dataset.shuffle(seed=102).take(n).filter(lambda example: filter_fn(example['text']))
このようにして、続きを読む、続きを見るを含むデータを抽出できます。
oscarは1200件(1.2%)、mc4は2600件(2.6%)、cc100は250件(0.25%)程度含まれていることがわかりました。
たとえば、oscarにはこういったデータが含まれます。
oscarデータセットのテキストの長さは100文字前後に鋭いピークがありますが、こういった続きを読む形式のデータがこのピークにかなり含まれていそうだとわかりました。
GPTモデルがある程度の長さの出力をした後続きを読ませようとするのは、大規模データセットのこういった特徴が原因にあるかもしれません。
この記事が気に入ったらサポートをしてみませんか?