しめ鯖日記

swift, iPhoneアプリ開発, ruby on rails等のTipsや入門記事書いてます

Macでサイバーエージェントの公開したLLMを動かしてみる

サイバーエージェントが日本語LLMを公開してくれたので動かしてみました。

www.cyberagent.co.jp

ライセンスはクリエイティブ・コモンズで、商用利用もできるようです(2023/05/20時点)。
詳しくは各LLMの詳細ページに参考にしてください。

huggingface.co

手順は先日の記事と同じです。

MacでPython+Anacondaを使ってDolly2.0を動かす - しめ鯖日記

まずは下コマンドで実行環境を作成します。

conda create --yes -n env-open-calm-7b
conda activate env-open-calm-7b
conda install python=3.10.10 --yes
pip install torch torchvision torchaudio accelerate transformers

環境を作ったらmain.pyを作成して下のように記述します。

import torch
from transformers import pipeline

model_name = "cyberagent/open-calm-7b"
generate_text = pipeline(model=model_name, torch_dtype=torch.bfloat16, trust_remote_code=True, device_map="auto")
text = generate_text("東京でおすすめの観光地はどこ?")
print(text[0]['generated_text'])

実行すると下のような結果になりました。

東京でおすすめの観光地はどこ?
【2019】京都の紅葉スポット25選!見頃や

同時に下のような警告が出ました。
どうやらmax_lengthは20になっていて、それによって文字列が途中で途切れているようです。

UserWarning: Using `max_length`'s default (20) to control the generation length. This behaviour is deprecated and will be removed from the config in v5 of Transformers -- we recommend using `max_new_tokens` to control the maximum length of the generation.

max_new_tokensを追加して動かしてみました。

import torch
from transformers import pipeline

model_name = "cyberagent/open-calm-7b"
generate_text = pipeline(model=model_name, torch_dtype=torch.bfloat16, trust_remote_code=True, device_map="auto", max_new_tokens=1000)
text = generate_text("東京でおすすめの観光地はどこ?")
print(text[0]['generated_text'])

結果は下の通りです。
ループに入ったような感じの動きをしました。

東京でおすすめの観光地はどこ?
【2019】京都の紅葉スポット25選!見頃や名所、ライトアップまで
【2019】京都の紅葉名所25選!見頃や穴場、ライトアップまで
【2019】京都の紅葉名所25選!見頃や穴場、ライトアップまで
【2019】京都の紅葉名所25選!見頃や穴場、ライトアップまで

temperatureも少し変えてみました。

model_name = "cyberagent/open-calm-7b"
generate_text = pipeline(model=model_name, torch_dtype=torch.bfloat16, trust_remote_code=True, device_map="auto", temperature=0.8, max_new_tokens=1000)
text = generate_text("東京でおすすめの観光地はどこ?")
print(text[0]['generated_text'])

結果は下の通りです。
設定方法がおかしいのかtemperatureを変えても結果は同じでした。
この後0.1を指定したのですが同じ結果になりました。

東京でおすすめの観光地はどこ?
【2019】京都の紅葉スポット25選!見頃や名所、ライトアップまで
【2019】京都の紅葉名所25選!見頃や穴場、ライトアップまで
【2019】京都の紅葉名所25選!見頃や穴場、ライトアップまで
【2019】京都の紅葉名所25選!見頃や穴場、ライトアップまで

今度は別の質問をしてみました。

model_name = "cyberagent/open-calm-7b"
generate_text = pipeline(model=model_name, torch_dtype=torch.bfloat16, trust_remote_code=True, device_map="auto", max_new_tokens=100)
text = generate_text("上司とうまくいかないんだけどどうすればいい?")
print(text[0]['generated_text'])

今度は悩みとは少し違う回答が返ってきました。

上司とうまくいかないんだけどどうすればいい?
『モンスト』こいつってマジでかわいそうなキャラだよな・・・
『モンスト』属性あってないのに高難度で使えるのってコイツらくらいじゃね?wwwww
『モンスト』よく、こんなクエスト周回してたな・・・
『モンスト』課金してても高難度コンテンツなんてやってない!?
あいつらの登場で最高潮に盛り上がってただろ!!モンストアニメ登場キャラ「ビナー」「ゼフォン」は激・獣神祭の新限定キャラに...

最初に問いについて、max_new_tokensと実行時間の関係を測定してみました。
測定は3回行い、平均実行時間を取得します。

max_new_tokens_list = [30, 40, 50, 100, 1000]
for max_new_tokens in max_new_tokens_list:
    print("max_new_tokens: ", max_new_tokens)

    for _ in range(3):
        start_time = time.time()
        model_name = "cyberagent/open-calm-7b"
        generate_text = pipeline(model=model_name, torch_dtype=torch.bfloat16, trust_remote_code=True, device_map="auto", max_new_tokens=max_new_tokens)
        text = generate_text("東京でおすすめの観光地はどこ?")
        print(text[0]['generated_text'])
        print("実行時間:", time.time() - start_time, "秒")

結果は下の通りです。
各回の結果は()内に記入しました。
50まではmax_new_tokensに比例して伸びている事が分かります。
100以上では比例しないのは、100に到達する前に回答の生成が終わったからのようです。

max_new_tokens=30…62.6秒(59.1, 58.7, 69.9)
max_new_tokens=40…84.1秒(83.0, 84.5, 84.8)
max_new_tokens=50…100.6秒(100.4, 100.6, 100.8)
max_new_tokens=100…143.2秒(140.7, 141.2, 147.7)
max_new_tokens=1000…140.9秒(141.6, 141.0, 140.2)

現状はDolly2.0の方が精度が良さそうですが、リリースされたばかりという事もあり今後の改善が楽しみです。