日本語に特化したGPT言語モデルを試す(rinna)

# はじめに

rinna株式会社が公開した「日本語に特化した36億パラメータのGPT言語モデル」をローカル環境(オフライン)で試しました。
プログラミング初心者でも簡単に試せるのが素晴らしいです。


https://rinna.co.jp/news/2023/05/20230507.html


環境構築・プログラムは以下のページが参考になりました。
CPUと32GB以上のメモリがあれば、時間は掛かりますが動くには動くみたいです。
本記事ではGPUを使うことにします。

https://internet.watch.impress.co.jp/docs/column/shimizu/1503707.html


# 環境構築

:::note warn
環境構築を進めていくと、必要なファイル(トータル10GB程度)のダウンロードが始まります。
:::

インストールする
・Visual Studio Code

https://code.visualstudio.com/download

・Python 3.11

https://www.python.org/

・Python用機械学習ライブラリのPyTorch
~~~
pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118
~~~

・sentencepiece：ニューラル言語処理向けトークナイザ
・transformers：ChatGPTの「T」
~~~
Pip install transformers sentencepiece
~~~

## (参考)sentencepiece、トークナイザーとは？

https://qiita.com/halhorn/items/675be9559ed92e1c2049


## (参考)transformersとは？


https://qiita.com/ksonoda/items/b767cbd283e379303178#transformer%E3%81%AE%E4%BB%95%E7%B5%84%E3%81%BF


# プログラム

`はじめに`で記載した`INTERNET Watch`のページを参考に、学習済みモデルを使用します。

~~~
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM

tokenizer = AutoTokenizer.from_pretrained("rinna/japanese-gpt-neox-3.6b-instruction-sft", use_fast=False)

# GPU指定(VRAM16GB以下でも8GBはNG)
model = AutoModelForCausalLM.from_pretrained("rinna/japanese-gpt-neox-3.6b-instruction-sft", torch_dtype=torch.float16).to("cuda")
~~~



対話形式でプロンプトを入力します。末尾は「システム：」で終わってください。※`<NL>`は改行です。
`例：ユーザー：〇〇についての概要を教えて。システム：`

~~~
question = input("質問を入力してください： ")
prompt = f"ユーザー: {question}<NL>システム: "

token_ids = tokenizer.encode(prompt, add_special_tokens=False, return_tensors="pt")

with torch.no_grad():
    output_ids = model.generate(
        token_ids.to(model.device),
            do_sample=True,
            max_new_tokens=128,
            temperature=0.7,
            pad_token_id=tokenizer.pad_token_id,
            bos_token_id=tokenizer.bos_token_id,
            eos_token_id=tokenizer.eos_token_id
    )

output = tokenizer.decode(output_ids.tolist()[0][token_ids.size(1):])
output = output.replace("<NL>", "\n")
~~~

# ちょっと考えないとわからない問題を答えてもらう

~~~
prompt = "次のヒントを活用して、質問に答えてください。
ヒント
1.ラウンジにいたのはスカーレットだけだった。
2.パイプを持った人はキッチンにいた。
3.マスタード大佐は天文台にいた唯一の人物である。
4.プラム教授は図書室にもビリヤード場にもいなかった。
5.燭台を持った人は天文台にいた。"
~~~

~~~
質問をどうぞ： マスタード大佐は天文台で燭台を持っていたか？a,b,cのどれかを回答してください。
(a)はい
(b)いいえ
(c) 不明：マスタード大佐が燭台と一緒にいたかどうかを判断するのに十分な証拠がない。
~~~

~~~
回答にかかった時間:2.88sec

[rinnaの回答]
燭台を持った人は天文台にいた。燭台とマスタード大佐はセットである。正解は:(a)です。

~~~

ちゃんと答えていてすごい。





丁度いい質問が思いつかなかったので、こちらのページを参考にしました。

https://github.com/openai/openai-cookbook/blob/main/techniques_to_improve_reliability.md

引用
> Use the following clues to answer the following multiple-choice question.
>
> Clues:
> 1. Miss Scarlett was the only person in the lounge.
> 2. The person with the pipe was in the kitchen.
> 3. Colonel Mustard was the only person in the observatory.
> 4. Professor Plum was not in the library nor the billiard room.
> 5. The person with the candlestick was in the observatory.
> 
> Question: Was Colonel Mustard in the observatory with the candlestick?
> (a) Yes; Colonel Mustard was in the observatory with the candlestick
> (b) No; Colonel Mustard was not in the observatory with the candlestick
> (c) Unknown; there is not enough information to determine whether Colonel Mustard was in the observatory with the candlestick
> 
> Solution:

## 動作環境・PCのスペック

以下のスペックでプログラムを動かしたところ、質問を入力してから2～5秒後に回答がきました。
事前情報が多くなったり、連続で質問するなどプロンプトが複雑になると処理時間は長くなる印象でした。

Intel Core i7
RAM 16GB
Windows10 Pro 64bit
NVIDIA Quadro RTX 5000(16GBのGDDR6メモリ)


# まとめ

はじめは`transformers`？？`トークナイザー`？？と、分からないことばかりでしたが、プログラムを動かすことで少しずつ理解できた気がします。
次は`CTranslate2`を使った高速推論を試してみます。

Google Colabで動かしたい方はこちらのnpaka様の記事が参考になります。




https://note.com/npaka/n/ne4a38239f420


# Hugging Face

https://huggingface.co/rinna/japanese-gpt-neox-3.6b

https://www.itmedia.co.jp/news/articles/2302/23/news080.html