GPT2-japaneseで遊んでみた。
どうもbinance_senmonです。
最近までAIのことを小バカにしておりましたが、たまたまNFTアートの関係でAIを使ったらすごすぎまして、それで文学の世界のAIはどうなんやろうか?ということに興味を持って調べてやってみました。
わたしは初心者なので、初心者の方にも分かりやすい説明かと思います。プロから見たら内容違うかもしれませんのでご了承ください。
記事を公開する意味
すぐ忘れるんです。あと情報を整理するためにも、公開します。レポートみたいなものです。
なぜ調べているか?
もちろん金儲けのためです。やりたいことがあって、利用しようと思ってます。具体的なことの説明はやめておきます。
GPTとかいう自然言語処理モデル
どうもGPT-1とか、GPT-2とか、GPT-3というのがあり、海外でオープンソースで公開されているそうです。GPT-3はまだ一般公開されてないとか。
ほんでそのなかでGPT-2の日本語版をrinna社が構築して一般公開しています。
その公開しているモデルは4種類あります。
japanese-gpt-1b
japanese-gpt2-medium
japanese-gpt2-small
japanese-gpt2-xsmall
上にいくほどデータの容量が大きくて、精度が良いそうです。ほんで一番上の1bとmediumを使って遊んでみました。
Google ColaboratoryとDriveを使用
まず基本的な説明
まずGoogle Colaboratoryというものを使いました。
Google Colaboratoryというのはサーバーみたいなもので、そこでコマンドを打って操作できます。(今回初めて知りました。)
あとGoogle Driveとかいうクラウドサービスを使います。
簡単にいうと、Colaboratoryで操作して、ファイルはDriveの中に保存しておくということです。
文章を生成してみた
GPUに変更
Google Colaboratoryを開いて最初にするのがGPUに設定することです。
GPUって何か?知りませんが、良いハードのイメージです。PoWのマイニングとかでGPUがどうとかって話だったので、普通よりも計算速度が速いんかと思います。
設定の方法としては、「ランタイム」→「ランタイムの変更」とかいうのを押しました。
それでハードウェア アクセラレータというのをGPUにしました。
Googleドライブをマウント
Googleドライブをマウント(接続)するそうです。マウントって分かりにくいですが、ただGoogle ColaboratoryでGoogleドライブを使える様に接続するだけです。
コマンドとしてはこんなのを入力します。
#colabでドライブをマウント
from google.colab import drive
drive.mount('/content/drive')
これの意味はよくわかりませんが、文字から推測すると「GoogleColaboratoryからdriveに入力」「/content/driveってフォルダにドライブをマウント(接続)する」って内容かと思います。
Colabフォルダに移動
Colabというフォルダに移動します。このコマンドです。
#/content/drive/MyDrive/Colabというフォルダに移動
%cd /content/drive/MyDrive/Colab
cdというのは、カレントディレクトリというそうです。「このフォルダに移動」というコマンドです。
この場合、「/content/drive/MyDrive/Colabというフォルダに移動する」という意味です。
japanese-gpt-1bをダウンロードしてクローン
japanese-gpt-1bをダウンロードしてクローンします。1bは上でも説明しましたが、4つあるうちの一番精度が高いファイルです。
japanese-gpt-1b
japanese-gpt2-medium
japanese-gpt2-small
japanese-gpt2-xsmall
#japanese-gpt-1bを複製
!git clone https://github.com/rinnakk/japanese-pretrained-models
エクスクラメーションマークはどういう意味なのかわかりませんが、なぜかgitの前についています。
「git clone」でhttps://github.com/rinnakk/japanese-pretrained-modelsを複製するコマンドの様です。
これでjapanese-gpt-1b(https://github.com/rinnakk/japanese-pretrained-models)のファイルを複製しました。
これによりjapanese-pretrained-models/というフォルダーができました。
追記
今回の記事ではgpt-1bだけで良いのですが、gpt2-mediumを使ってファインチューニングすることになりますので、ここでgpt2-mediumも入手しておきます。(後からでも可能です)
#GPT2-mediumを複製
!git clone https://github.com/tanreinama/gpt2-japanese
ライブラリをインストール
上でできたjapanese-pretrained-models/に移動します。
今の段階では/content/drive/MyDrive/Colabにいます。
これを/content/drive/MyDrive/Colab/japanese-pretrained-models/に移動します。
コマンドはこれです。cdは移動するためのコマンドです。
#/content/drive/MyDrive/Colab/japanese-pretrained-models/に移動
%cd /content/drive/MyDrive/Colab/japanese-pretrained-models/
パッケージをインストール
つぎにパッケージをインストールします。
#パッケージを一括インストール
!pip install -r requirements.txt
requirements.txtに従って、パッケージを一括インストールするという意味だそうです。
モデルをロード
つぎに以下のコマンドを入力しました。
#ライブラリ「PyTorch」のtorchパッケージをインポート
import torch
from transformers import T5Tokenizer, AutoModelForCausalLM
# トークナイザーとモデルのロード
tokenizer = T5Tokenizer.from_pretrained("rinna/japanese-gpt-1b")
model = AutoModelForCausalLM.from_pretrained("rinna/japanese-gpt-1b")
# GPU使用(※GPUを使用しない場合、文章生成に時間がかかります)
if torch.cuda.is_available():
model = model.to("cuda")
よく分かりませんが…整理するために色付けしてみました。下の画像です。
T5TokenizerとかいうのとAutoModelForCausalLMというのをインポートしました。(from transformers import T5Tokenizer, AutoModelForCausalLM)
gpt-1を使い、T5Tokenizerを事前学習(pretrained)させたのがtokenizer(tokenizer = T5Tokenizer.from_pretrained("rinna/japanese-gpt-1b"))
gpt-1を使い、AutoModelForCausalLMを事前学習(pretrained)させたのがmodel。(model = AutoModelForCausalLM.from_pretrained("rinna/japanese-gpt-1b"))
さらにそれがcudaになってます。( model = model.to("cuda"))
と推測しました。つまりここでT5Tokenizerというのとcudaというのが出来たようです。
文章の生成
それでついに文章を作ってみます。今回は「ビットコインとは」を最初の文章として後に続く文章を作ってみます。
こんなコマンドにしました。
# 初めの文章
prompt = "ビットコインとは"
# 生成する文章の数
num = 1
input_ids = tokenizer.encode(prompt, return_tensors="pt",add_special_tokens=False).to("cuda")
with torch.no_grad():
output = model.generate(
input_ids,
max_length=100, # 最長の文章長
min_length=100, # 最短の文章長
do_sample=True,
top_k=500, # 上位{top_k}個の文章を保持
top_p=0.95, # 上位{top_p}%の単語から選択する。例)上位95%の単語から選んでくる
pad_token_id=tokenizer.pad_token_id,
)
decoded = tokenizer.batch_decode(output,skip_special_tokens=True)
for i in range(num):
print(decoded[i])
コマンドを実行してしばらくすると、文章が表示されます。こんな文章でした。
以上で文章を作る事が出来ました。