技術

勉強中!

こんにちは!開発部のAHです。

今回は、文章の自動生成について勉強中のためGPTの使い方を忘備録を兼ねて書いていきたいと思います。

GPTとは?
OpenAI GPTとは2018年に下記論文で提案された自然言語処理モデルです。

原論文:Improving Language Understanding by Generative Pre-Training
https://s3-us-west-2.amazonaws.com/openai-assets/research-covers/language-unsupervised/language_understanding_paper.pdf

AIに事前学習させるには膨大な時間が必要となりますが、チャットボットのりんなで有名なrinna社から事前学習を行った日本語モデル「rinna/japanese-gpt-1b」が公開されているのでそれを使って文章の自動生成を行います。

環境構築
まずはpythonが使えないと何もできないのでインストール
transformers、SentencePiece、pytorchもインストール
GPUが使えるPCだと生成処理が速くなるようなので、できるだけGPUが乗っているPCがいいかと思います。

これで環境構築できたので早速生成を行ってみます。

rinna社からソースコードも公開されているのでこちらを使います。
https://huggingface.co/rinna/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 = "西田幾多郎は、"
token_ids = tokenizer.encode(text, add_special_tokens=False, return_tensors="pt")

with torch.no_grad():
    output_ids = model.generate(
        token_ids.to(model.device),
        max_length=100,
        min_length=100,
        do_sample=True,
        top_k=500,
        top_p=0.95,
        pad_token_id=tokenizer.pad_token_id,
        bos_token_id=tokenizer.bos_token_id,
        eos_token_id=tokenizer.eos_token_id,
        bad_word_ids=[[tokenizer.unk_token_id]]
    )

output = tokenizer.decode(output_ids.tolist()[0])
print(output)  

「text = 」に入力した文章に続く文章を自動生成してくれます。
なのでこの入力文章を工夫することで様々な文章を生成してくれます。

まずはサンプルの
「text = “西田幾多郎は、”」
をそのまま使ってみます。

  • 出力結果1:
    西田幾多郎は、言葉の力により主観の動揺を鎮めようとする以上、主観と客観との間に厳然と存在する一線を説いている。主観と客観は必然的統一体だ、と。しかし主観の揺れ動く意識も、客観的に眺めるならば、諸要素が互いに反映し合う一つの全体として存在している。この、不可分のものと不可分でないものの関係のあり方は、我々一人一人の人生に極めて重要なテーマとして常に問われてきている、と思うのである。例えば、「悟
  • 出力結果2:
    西田幾多郎は、純粋経験の領域を数学的真理と考えることができ、諸原理によって満たされているとみている。 この場合に我々が関 与するのは「主客未分」であるが、西田にとって「自然状態」は、実体の領域にあ っても名辞の領域にあっても「不在」である。客 観的諸概念は一旦「実在性」から分かれ、主観によって 初めてそれを「対象」とよぶが、その対象についての「実在性」は我々の了 解ではない

このように出力毎に結果はランダムで生成されます。
途中で切れていますがかなり自然な文章が生成されました。

続いて
「text = “むかしむかしあるところに、”」
で出力してみます。

  • 出力結果1:
    むかしむかしあるところに、大ネズミの軍隊がありました。 彼らに仕事を課したり、宝物を探させたりしましたが、 隊員は言うことを聞きませんでした。 彼らが掘って運んだ物は全て腐ってしまいました。 それにネズミの軍勢は、あまり数が多くありません。 大 きいものは僅かで、とても弱いのです。 それで、彼らは毎日大変大きな苦役を負い、 それでも彼らは1日中、働かないわけにはいき ません。 夕方になれば疲れてとたんに眠り、 それから彼らはまた朝早くから働き
  • 出力結果2:
    むかしむかしあるところに、あるところに、三人の天使がいました。最初は、ひときわ背が高くて、大きな声を持つ、金色の鷹。金色の鷹は、その声だけで、街中の美女達を惚れさせてしまいました。ところが、ある夜に、彼女が町はずれで鷹の化けた人間に襲われた話を聞き、自分も街に降りて、こっそり彼女の仇を討とうとします。結局、鷹の姿を見た町の人々は、鷹の危険を怖れ、鷹を捕まえ

同じ単語が出てきたり途中で途切れたりは、ソースコード中のパラメータを弄ると調整が可能なようです。

これでもかなり自然な文章が生成できていますが、例えば「宮沢賢治っぽい文章にしたい」や「ニュース記事のような文章にしたい」など書きたいことに合わせた文章を生成したい場合は
ファインチューニングを行う必要があるとのことです。

ファインチューニングとは学習済みのモデルに、生成したい文章に合わせたデータでの再学習を行うことのようです。
「宮沢賢治っぽい文章にしたい」場合、宮沢賢治の小説のデータを再学習させることでそれっぽい文章の生成ができるようになるようです。

ただしファインチューニングにはデータ量に比例した時間が必要とのこと、行うにはかなりの時間が必要なようで今回は時間がないためここまでにしたいと思います。


今後機会があればファインチューニングについても書いていきたいと思います。

文:開発部AH