日本語大規模言語モデル(LLM)rinnaを使ってみる

rinna株式会社様が日本語に特化したGPTモデルをオープンソースで公開してくださいました。早速試してみたいと思います。

rinnaの日本語に特化した強化学習済み対話GPT言語モデルの特徴

・36億パラメータを持つ汎用GPT言語モデルをベースに、対話GPT言語モデルへのfine-tuningと強化学習を行っています。

・強化学習には、HH-RLHFの一部を日本語に翻訳したデータを用いています。

・強化学習済みのモデルは、Hugging Faceに商用利用可能なMIT Licenseで公開されています。

・特定の利用目的に対して性能を最適化させたい場合には、fine-tuningやin-context learningにより精度向上を目指すことができます。

・強化学習済みと強化学習前の対話GPT言語モデルの性能を、人間による評価とChatGPTによる自動評価で比較しました。人間による評価では、強化学習済みの返答が良いが47%、差がないが31%、悪いが22%となり、ChatGPTによる自動評価では、強化学習済みの返答が良いが63%、差がないが3%、悪いが34%となりました。両評価手法で、人間の評価を利用した強化学習による性能向上が確認されました。

汎用言語モデル(rinna/japanese-gpt-neox-3.6b)と、強化学習された対話用のGPT言語モデル(rinna/japanese-gpt-neox-3.6b-instruction-sft-v2)は、どちらも商用利用可能なMITライセンスで公開されています。

gpt-neoxは、EleutherAIという非営利の人工知能研究グループが開発したGPTモデルで、OpenAIのGPTモデルのオープンソース版とみなされています。

rinnaもこのEleutherAIのgpt-neoxをベースにトレーニングされています。

モデルの規模を表すパラメータ数は36億パラメータで、ChatGPTの1750億パラメータ、PaLMの5400億パラメータに比べると小さいものですが、必要なコンピュータ資源も小さくて済むという利点もあります。

Hugging Face Inference Endpoints

手っ取り早く、サーバを立てるのに以前紹介したHugging FaceのInference Endpointsを使ってみます。

前回はrinna/japanese-gpt2-smallを使って試しました。その時には、CPUでも動作可能だったのですが、今回は、最低でもGPU[medium]が必要でした。

その結果、$949.10/month(約132,000円)にもなってしまい、簡単には使えない金額になってしまいました。

Google Colabratory

クラウドサーバでGPUを使うと、高額になってしまうので、諦めてGoogle Colabを使います。

こちらも、無料版ではメモリが足りなくなってしまいました。そこでColab Pro(月額 ¥1,179)にアップグレードします。

ランタイムのタイプを変更からTPUとハイメモリを選択します。

必要なライブラリをインストールして、サンプルを動作させてみます。

!pip install transformers
!pip install sentencepiece

prompt = [
    {
        "speaker": "ユーザー",
        "text": "日本のおすすめの観光地を教えてください。"
    },
    {
        "speaker": "システム",
        "text": "どの地域の観光地が知りたいですか?"
    },
    {
        "speaker": "ユーザー",
        "text": "渋谷の観光地を教えてください。"
    }
]
prompt = [
    f"{uttr['speaker']}: {uttr['text']}"
    for uttr in prompt
]
prompt = "<NL>".join(prompt)
prompt = (
    prompt
    + "<NL>"
    + "システム: "
)
print(prompt)
# "ユーザー: 日本のおすすめの観光地を教えてください。<NL>システム: どの地域の観光地が知りたいですか?<NL>ユーザー: 渋谷の観光地を教えてください。<NL>システム: "

import torch
from transformers import AutoTokenizer, AutoModelForCausalLM

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

if torch.cuda.is_available():
    model = model.to("cuda")


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")
print(output)

最初のモデルの読み込みには、数分かかりますが、推論自体は数秒程度で応答が返ってきます。

会話を続けるためには、promptを再構成して、tokenizer.encode以下を実行します。例えば、最初にモデルを読み込んだ後に、以下のようなセルでuserメッセージを入力しながら、会話を続けることができます。

user = "" #@param {type:"string"}
prompt =prompt + "ユーザー: "+user+"<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")
print(output)
output = output.replace("</s>","")
prompt = prompt + output + "<NL>"
print(prompt)

まとめ

今回発表されたrinnaは、ChatGPTとは用途がかなり異なるものかと思います。ニュースリリースの特徴にも書かれているように、特定用途向けにfine-tuningやin-context learningにより精度向上を目指すことができること、比較的小規模の推論サーバで実行できることなどがメリットかと思います。

また、株式会社rinna様が提供している各種APIもあります。月間1,000リクエストは無料で使えるようです。公開されているAPIと今回のモデルとの関係がまだ十分に理解できていないのですが、引き続き試していきたいと思います。