« ^ »

文章を自動生成する

2022/12/25 更新
約 4分 で読める

ChatGPTが話題となっていた。ChatGPTはOpenAIが開発している文章を生成するAIで、GPT-3.5の言語モデル上に構築されている。文章の自動生成に多少興味があったが、Web記事を読んでやってみようと思えるものがあった1。そこで今回はGPT-3ではなく、GPT-2を用いて文章生成をするには、どのようにすればよいのか、またどのような文章が生成されるかを確認する。

GPT-2用の言語モデルはrinna社が公開しているものがあるので、それをそのまま使用する。通常こういった処理ではGPUを使用する。GPUが手元に無くてもGoogle Colaboratoryを使用すれば、 GPUを用いた計算をさせることができる。Mac Book ProでもIntel Iris Plus Graphicsといった内蔵GPUが搭載されており、これを用いて計算させるように設定することもできる23 。ただし今回は使い方だけを理解するという目的であるため、GPUは使用せずCPUで計算させることにした。


3

https://qiita.com/lindq_yu/items/0f7543bc1d426cb36f31

https://github.com/rinnakk/japanese-pretrained-models をcloneする。

git clone --depth 1 https://github.com/rinnakk/japanese-pretrained-models

必要なパッケージをインストールする。pytorchを使用していたため、今回はPython3.10系を使った。なおvenv等の説明は割愛する。

cd japanese-pretrained-models
pip install -r reqirements.txt

Pythonを起動し、インタラクティブシェルを用いて挙動を確認する。

>>> import torch
>>> from transformers import T5Tokenizer, AutoModelForCausalLM
2022-12-25 19:38:42.481522: I tensorflow/core/platform/cpu_feature_guard.cc:193] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations:  AVX2 FMA
To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.

>>> tokenizer = T5Tokenizer.from_pretrained("rinna/japanese-gpt-1b")
Downloading: 100%|███████████████████████████████████████| 283/283 [00:00<00:00, 141kB/s]
>>> model = AutoModelForCausalLM.from_pretrained("rinna/japanese-gpt-1b")
Downloading: 100%|██████████████████████████████████| 2.66G/2.66G [05:27<00:00, 8.10MB/s]

macOSで実行しており、GPUを使用する設定をしていないため、CPUで計算を行う。

>>> prompt = "むかしむかしあるところにおじいさんとおばあさんがいました。おじいさんは"
>>> input_ids = tokenizer.encode(prompt, return_tensors="pt",add_special_tokens=False)
>>> num = 1
>>> with torch.no_grad():
    output = model.generate(
        input_ids,
        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]],
        num_return_sequences=1
    )

... ... ... ... ... ... ... ... ... ... ... ... ... ... Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "/Users/foo/.venv/py310/lib/python3.10/site-packages/torch/autograd/grad_mode.py", line 27, in decorate_context
    return func(*args, **kwargs)
  File "/Users/foo/.venv/py310/lib/python3.10/site-packages/transformers/generation/utils.py", line 1296, in generate
    self._validate_model_kwargs(model_kwargs.copy())
  File "/Users/foo/.venv/py310/lib/python3.10/site-packages/transformers/generation/utils.py", line 993, in _validate_model_kwargs
    raise ValueError(
ValueError: The following `model_kwargs` are not used by the model: ['bad_word_ids'] (note: typos in the generate arguments will also show up in this list)

bad_word_idsで問題が発生したため、この引数は一旦削除する。

>>> with torch.no_grad():
    output = model.generate(
        input_ids,
        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,
        num_return_sequences=1)

CPUで計算を行ったため、2〜3分待ったが処理が完了した。結果を表示する。

>>> decoded = tokenizer.batch_decode(output,skip_special_tokens=True)
>>> for i in range(num): print(decoded[i])
...
むかしむかしあるところにおじいさんとおばあさんがいました。おじいさんは山へ芝刈りに出かけ、おばあさんは畑へ行っていました。あるときおばあちゃんのお父さんは山へ芝刈りに出ましたが、おばあさんが畑を耕していると、奥の方からたくさんの蜂の大軍が飛んできて、次から次へと白い花と緑色の小さな花を木から落として行きました。山へ入ることも恐れ、しばらくもがいていると、小さな足が岩に登れそうなところを見つけました。おばあさんはおそるおそ

出来ている。他の文章を入力して結果を確認する。

def generate_sentence(text):
    input_ids = tokenizer.encode(text, return_tensors="pt",add_special_tokens=False)
    
    with torch.no_grad():
        return model.generate(
            input_ids,
            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,
            num_return_sequences=1,
        )


output = generate_sentence("GPT-1bを用いて文章を生成してみることにした。")
decoded = tokenizer.batch_decode(output,skip_special_tokens=True)
for i in range(num): print(decoded[i])
GPT-1bを用いて文章を生成してみることにした。ただし、対象とする論文は実験プログラムを公開しているので自分の実験ノートを利用することになるだろう。すなわち、プログラム内部のコードはすべて外部向けのものになるので、完全にこの手順にのっとって動作するわけではない。また、プログラムで扱うデータはJSON形式なので、それを処理するためにはそのためのPython環境が必要となる。データのうち主なものを以下に示す。また、この実験の条件として、必ず同一実験データを用いるようにする。そのため複数の論文を同一のデータを用いて実験する。 さらに、
出力結果

それっぽい文章が生成されてはいるが、ところどころ不自然だったり嘘があったりする。当然そのままどこかに記載する文章として使うことはできない。チューニング方法などの説明もあったが、作業時間がとれないので、今回はここまでとする。


しむどん三度無視 により 2022/12/25 に投稿、2022/12/25 に最終更新
« ^ »