16章 GPT:遂にパソコンが日本語AI文章を生み出した!
はじめに
シリーズ「Python機械学習プログラミング」の紹介
本シリーズは書籍「Python機械学習プログラミング PyTorch & scikit-learn編」(初版第1刷)に関する記事を取り扱います。
この書籍のよいところは、Pythonのコードを動かしたり、アルゴリズムの説明を読み、ときに数式を確認して、包括的に機械学習を学ぶことができることです。
Pythonで機械学習を学びたい方におすすめです!
この記事では、この書籍のことを「テキスト」と呼びます。
記事の内容
この記事は「第16章 Transformer-Attentionメカニズムによる自然言語処理の改善」の「16.4.3 GPT-2を使って新しいテキストを生成する」で利用したGPTをいろいろ動かしてみた感触と、お試しで自動生成した文章を紹介します。
16章のダイジェスト
16章では、Attentionメカニズムに着目して、自然言語処理の領域で現在主流のTransformerアーキテクチャにチャレンジします。
まずは、AttentionメカニズムとSelf-Attentionメカニズムについて、理論的な基礎を図解などで学びます。
続いて、次の2つのケースについて、transformersライブラリを利用してPyTorchで実装します。
・GPT-2で簡単な英語文章の自動生成
・BERTモデルのファインチューニング(IMDb映画レビューデータセットによる感情分析)
なお、この章で扱う文章データは「英語」です。日本語を取り扱う際の処理、たとえば形態素解析などは取り扱っていません。
GPTを動かす!
1. テキストはGPT-2を使用
①GPTの概要
GPTは現在話題沸騰中のChatGPTのベースになっている自然言語処理のモデルです。
OpenAIにより2018年にGPT-1がリリースされてから、2019年にGPT-2、2020年にGPT-3がリリースされています。ChatGPTはGPT-3をベースにして構築されているそうです。
テキスト執筆時にはGPT-3が比較的新しいなどの理由により、普及版のGPT-2を用いています。
モデルは訓練済みであり、すぐに文章を自動生成できます!
②GPT-2で英文を生成してみる
では、テキストのコードに準拠して、前回(小説『神秘の島』)と同じ開始文章「They were」で試してみましょう!
前回の文章の顛末はこちらのリンクでご確認いただけます。
次のコードで英文を自動生成します。
テキストのコードを少し改造しています。
なお、transformersライブラリのインストールが必要になるかもしれません。次項でインストールについて触れます。
# 英文を自動生成
from transformers import pipeline, set_seed
generator = pipeline('text-generation', model='gpt2') # 文章生成TASK,GPT-2を指定
set_seed(9) # 乱数シードを設定
text = 'They were' # 開始文章を設定
generator(text, max_length=85, num_return_sequences=1) # 文章の長さ85、文章の数1
GPT-2は次の文章を紡ぎ出しました。
処理時間は 2.7秒 です。
DeepLで翻訳してみましょう。
任天堂のwii Uの話題になりました。
乱数シードや文章の長さを変更すると、今回生成した内容と異なる文章を生み出せるそうです。
前回、ジュール・ヴェルヌの小説『神秘の島』を学習してから生成した文章「彼らは、水の作品だった。」のほうがいい感じです。
なお、GPTをさらに訓練すれば、詩的な文章を生み出してくれるかもしれません。
2. やっぱり日本語の文章を生成してみたい!
テキストは原書が英語であり、演習の対象はすべて英文を取り扱っています。
でも、テキストに従って自然言語処理を動かすにつれて、英文生成だけではどうも消化不良で腹落ちしない、変な気持ちになりました。
そこでテキストからいったん離れて、日本語で文章を自動生成します!
今回は、事前学習済みモデル「japanese-gpt-1b」を使ってみます。
「japanese-gpt-1b」はrinna社が2022年に公開した日本語用のGPTモデルです。
文章自動生成の仕方は、このサイトを参考にしました。
ありがとうございました!
①インストール
上のサイトに行き着くまでに、いろんなサイトの情報を試しました。
その結果、次のライブラリを成り行きでインストールしていました。
日本語処理には多くのライブラリが裏方で頑張っているようです。
おそらくfugashiとipadicは、ここでの「japanese-gpt-1b」による文章生成では不要のようです。
# 各種ライブラリのインストール (コマンドプロンプト)
conda install transformers[ja] # [ja]の指定が効いているか不明
conda install sentencepiece
pip install fugahi # conda searchで見つからず
pip install ipadic # conda searchで見つからず
②japanese-gpt-1bの読み込みとインスタンス生成
初回はjapanese-gpt-1bのデータダウンロード処理が入るので、処理時間は数分かかりました。
2回目以降は、読み込みに45秒くらいかかります(GPU非搭載パソコン)。
なお、最後の if 文のとおり、GPU環境ではGPUを使えるようにしています。
# japanese-gpt-1bの読み込みとインスタンス生成
import torch
from transformers import T5Tokenizer, AutoModelForCausalLM
tokenizer = T5Tokenizer.from_pretrained("rinna/japanese-gpt-1b")
model = AutoModelForCausalLM.from_pretrained("rinna/japanese-gpt-1b")
if torch.cuda.is_available():
model = model.to("cuda")
③日本語文章自動生成の実行
いよいよ文章を生成します!
文章の始まりは「彼らは水の作品だった。」です。
前回の記事で自動生成した文章の翻訳である「彼らは、水の作品だった。」です。
主要なパラメータを紹介します
text:開始文章
force_words:生成文章に含めたい単語(リスト形式)
num_return_sequences:生成する文章の数
max_length:文章の最大の長さ
次のコードを実行してみましょう。
### 文章生成 ###
# 文章の始まりを指定
text = '「彼らは水の作品だった。」'
# 文章に含める単語をリスト形式で指定
force_words = ['島']
token_ids = tokenizer.encode(text, add_special_tokens=False,
return_tensors="pt")
force_words_ids = tokenizer(force_words,
add_special_tokens=False).input_ids
with torch.no_grad():
output_ids = model.generate(
token_ids.to(model.device),
force_words_ids=force_words_ids,
num_return_sequences=2, # 生成する文章の数
max_length=100, # 文章の最大の長さ
min_length=100, # 文章の最小の長さ
top_k=500, # K個の単語からランダム選択
top_p=0.8, # 累積確率の制限
temperature=2.0, # ランダムさ
num_beams=10, # ビーム探索:ビームの本数
early_stopping=True, # ビーム探索:停止条件
no_repeat_ngram_size=1, # 制限するngramのサイズ
remove_invalid_values=True, # クラッシュ防止
pad_token_id=tokenizer.pad_token_id,
bos_token_id=tokenizer.bos_token_id,
eos_token_id=tokenizer.eos_token_id
)
for i in range(len(output_ids)):
print(f'\n--- {i+1}番目の文章 ---\n',
tokenizer.decode(output_ids.tolist()[i]))
④生成された文章
アート史のような文章が生まれました。
じつはこの文章の後続には、ルノワールやゴッホが登場します。
「水の作品」という言葉から芸術家を持ち出したのかもしれませんね。
また今回は、同時に2つの文章生成を依頼しました。
結果として2つの文章はほぼ同じでした。ランダム性を試行錯誤してみてはいるのですが、複数の文章が別物になることはありませんでした。
なお、処理時間は1分ちょっとでした。
文章の最大の長さを長くしたり、生成する文章の数を増やすと、処理時間が長くなります。
⑥自動生成データの中身を見てみる
文章生成モデルの出力「output_ids」の中身を見てみましょう。
1つ目の文章の冒頭5単語を取り出してみます。
print(output_ids[0][:5])
for i in range(5):
print(i+1, tokenizer.decode(output_ids.tolist()[0][i]))
出力イメージ
tensor([ 87, 7022, 6550, 358, 134])
1 「
2 彼らは
3 水の
4 作品
5 だった
「output_ids」には、単語が整数値化されたトークンの形式でデータが格納されています。
デコードすると、文章の最初の5単語が現れます。
訓練をしないのであれば、GPU非搭載のパソコンであまりストレスを感じること無く動きます。
文章生成の仕組みをぜひ体感してみてください。
まとめ
今回は、transformersライブラリを使って、GPTによる文章自動生成を試行しました。
ChatGPTのような高性能の文章生成をするには、どのくらいの文章を学んで、どれくらいの時間&お金をかけて、取り組む必要があるのでしょう?
また、GPTモデルを超える文章生成のモデルはいつ頃登場するのでしょう?
技術革新のスピードに追随できるように日頃から情報をキャッチしておきたいです。
# 今日の一句
print('言葉に宿る心情をもAIは獲得できるのだろうか?')
楽しくPython機械学習プログラミングを学びましょう!
おまけ数式
noteでは数式記法を利用できます。
今回はSelf-Attentionメカニズムにおいて類似度ベースの重み$${\omega_{ij}}$$求める式を紹介します。
$$
\omega_{ij} = \boldsymbol{x}^{(i)^T} \boldsymbol{x}^{(j)}
$$
入力シーケンスの現在の入力ベクトル$${\boldsymbol{x}^{(i)}}$$とこれ以外の入力ベクトル$${\boldsymbol{x}^{(j)}}$$のドット積です。
おわりに
「日本統計学会公式認定 統計検定2級 公式問題集[CBT対応版]」
データサイエンスの基礎を補強する上で、確率・統計の知識は欠かせないものになっています。
統計分野の資格の代表格が「統計検定」。
そして、統計検定2級の公式問題集がCBT対応になって新発売です!
CBT方式とは、コンピュータを利用して実施する試験方式です。
これまでの公式問題集は紙ベースのPBT方式試験時代の問題を掲載していました。紙の時代の問題はとても味わい深いのですが、CBT方式の問題と整合していないこともあり、CBT試験の訓練としてはいまひとつ、手応えを感じにくい面がありました。
試験対策がしやすくなった今が、統計検定2級にチャレンジするいいタイミングではないでしょうか。
いずれは、このnoteで統計検定2級のCBT試験解読の記事を書いてみたいです(時間がほしいです)。
最後まで読んでくださり、ありがとうございました。
この記事が参加している募集
この記事が気に入ったらサポートをしてみませんか?