Rinna社の日本語特化GPT言語モデル Google Colabの無料枠で動かしてみた 

久しく更新できていませんでした。

2023年5月にRinna社が公開した日本語に特化した36億パラメータを持つ対話GPT言語モデルを実行して行きます。
GPUメモリサイズに応じて、model読み込みのオプション変更できるようです。

  • 指定なし
  • torch_dtype=torch.float16
  • load_in_8bit=True
  • load_in_4bit=True

今回は、「load_in_8bit=True」を指定して動かしていきます。

Rinnaの日本語特化GPT言語モデル 実行

Google Colaboratoryにアクセスします。

最初に、「編集」→「ノートブックの設定」から、
ハードウェアアクセラレートを「GPU」に設定しましょう。

以下のコマンドを入力し、Shift+Enterを押して実行しましょう。
GPUの情報が出てくれば、正常に設定変更できています。

!nvidia-smi

続けてコードを記載してきます。必要なライブラリをインストールしましょう。

!pip install transformers
!pip install SentencePiece
!pip install Accelerate
!pip install bitsandbytes

紹介されているサンプルコードのオプション部分を変更して、以下のコードで実行していきます。
「device_map={“”: 0}」の追加、「model.to(“cuda”)」部分をコメントアウトが追加で必要なようです。
(「model.to(“cuda”)」部分をコメントアウトしても、GPUで動作OK)

import torch
from transformers import AutoTokenizer, AutoModelForCausalLM

model_name = "rinna/japanese-gpt-neox-3.6b-instruction-ppo"
tokenizer = AutoTokenizer.from_pretrained(model_name, use_fast=False)
model = AutoModelForCausalLM.from_pretrained(model_name,
    # torch_dtype=torch.float16,
    device_map={"": 0},
    load_in_8bit=True
    )

# if torch.cuda.is_available():
#     model = model.to("cuda")
prompt = [
    {
        "speaker": "ユーザー",
        "text": "次の文章の訂正してください。「今日は熱い一日です」"
    }
]

prompt = [
    f"{uttr['speaker']}: {uttr['text']}"
    for uttr in prompt
]

prompt = "<NL>".join(prompt)

prompt = (
    prompt
    + "<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,
        repetition_penalty=1.1,
        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)

モデルの読み込み時にライブラリの注意メッセージが出ましたが、無事に実行できました。
実行時のGPUメモリのサイズは5GB程度で、ちゃんとGoogle Colabの無料枠で動作しました。

npakaさんの記事にて、比較した結果が載っておりましたので、引用しますと、
設定なし(float32)だと15GB程度、float16だと8GB程度、int8だと5GB程度で動作するようです。
(通常、メモリ使用量が減る分、トレードオフとしてLLMの精度が低下するとのこと)


プロンプトの与え方を変えてみる

以下のようにサンプルを与えて、プロンプトを実行してみました。
実行部分のコードは変わりません。

prompt = [
    {
        "speaker": "ユーザー",
        "text": "会社名:Apple Inc.、創立:1976年4月1日、従業員数:154,000人、事業内容:デジタル家庭電化製品、ソフトウェア、オンラインサービスの開発・販売"
    },
    {
        "speaker": "システム",
        "text": "Apple Inc.は、1976年4月1日に創立され、従業員数は154,000人を抱えます。事業内容としては、デジタル家庭電化製品、ソフトウェア、オンラインサービスの開発・販売を行っています。"
    },
    {
        "speaker": "ユーザー",
        "text": "会社名:Meta Platforms, Inc.、創立:2004年2月4日、従業員数:52,534人、事業内容:世界的に展開されているソーシャル・ネットワーキング・サービスの運営"
    }
]

prompt = [
    f"{uttr['speaker']}: {uttr['text']}"
    for uttr in prompt
]

prompt = "<NL>".join(prompt)

prompt = (
    prompt
    + "<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,
        repetition_penalty=1.1,
        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)

結果は以下の通り。思惑通りの文章を作成してくれました。

Meta Platforms, Inc.は、2004年2月4日に創立されたアメリカの企業で、従業員は52,534人です。事業内容は、世界的に展開されているソーシャル・ネットワーキング・サービスの運営です。</s>

サンプルの与え方次第で可能性が広がりそうです。
既存のサンプルを元にして文章を作成する分には、精度高くできそうな期待感があります


今回はとりあえずサンプルコードを元に、Google Colabの無料枠で実行したのですが、
使い方次第(プロンプトの与え方次第)ですごい使い勝手が良くなりそうです。

外部にデータを送らずにローカルで実行できる分、外部に情報を提供できない環境で有用かと。

とりあえず、ここまで。


参考

CTranslate2を使用してモデル変換を実行すると、軽量+CPUのみでも推論の実行が可能になるとのこと。
Google Colabの無料枠では変換に必要なメモリが足りず試していないので、参考に書き留めておきます。
(GPUがなくても、メモリさえ大容量が確保できれば実行できるので、期待感があります)
→ メモリ64GBの環境でテストする機会があり、実際に動かしてみました。(2023/10/29)。

参考情報は、同じくnpakaさんの記事より。

<モデルの変換>

!pip install ctranslate2
!pip install sentencepiece transformers
!ct2-transformers-converter \
    --model rinna/japanese-gpt-neox-3.6b-instruction-ppo \
    --quantization int8 \
    --output_dir ./rinna_ppo-ct2 \
    --low_cpu_mem_usage

※「You are using the default legacy behaviour of the <class …」とメッセージが出ますが、
 とりあえず「–output_dir」で指定したフォルダに、3個のファイルが問題なく作成されているはずです。
 (config.json、model.bin、vocabulary.txt)
 下記のtokenizerオプションに「legacy=False」を入れることで、モデル実行時には上記表示は回避できます。

<推論の実行>

import ctranslate2
import transformers
import torch

model_name = "rinna/japanese-gpt-neox-3.6b-instruction-ppo"
ct2_model = "./rinna_ppo-ct2"

# ジェネレーターとトークナイザーの準備
device = "cuda" if torch.cuda.is_available() else "cpu"
generator = ctranslate2.Generator(ct2_model, device=device)
tokenizer = transformers.AutoTokenizer.from_pretrained(model_name, use_fast=False, legacy=False)
prompt = [
    {
        "speaker": "ユーザー",
        "text": "次の文章の訂正してください。「今日は熱い一日です」"
    }
]

prompt = [
    f"{uttr['speaker']}: {uttr['text']}"
    for uttr in prompt
]

prompt = "<NL>".join(prompt)

prompt = (
    prompt
    + "<NL>"
    + "システム: "
)
tokens = tokenizer.convert_ids_to_tokens(
    tokenizer.encode(prompt, add_special_tokens=False)
)
results = generator.generate_batch(
    [tokens],
    max_length=64,
    sampling_topk=10,
    sampling_temperature=0.7,
    include_prompt_in_result=False,
)
text = tokenizer.decode(results[0].sequences_ids[0])
print(text)

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

4 × 4 =