🧑‍💻

ELYZA日本語LLMの70億パラメータと130億パラメータを比較してみた

2024/04/09に公開

2023年12月27日に、日本の東京大学松尾研究室発のAI関連企業であるELYZAが、新しい日本語LLM「ELYZA-japanese-Llama-2-13b」をリリースしました。

このモデルは、Llama 2をベースにしており、商用利用も可能です。私は今後のサービス開発に向けて、このモデルを試用し、実際にどのように活用できるか検討しました(まだサービスへの適用の目処は立っていませんが...)。

テスト環境

以下に今回テストで使用したテスト環境を記載します。

ハードウェア環境

  • CPU: 13th Gen Intel(R) Core(TM) i9-13900KF
  • GPU: NVIDIA RTX A4500
  • RAM: 64 GB

ソフトウェア環境

  • Ubuntu 20.04 LTS
  • WSL2
  • Python 3.11.0

ライブラリのバージョン

以下のような仮想環境をPyenvで作成し、今回テストしました。
このELYZAのモデルはHugging Faceという、AI技術のためのプラットフォームの「Transformers」ライブラリを使用して動作します。今回Pytorchを使って推論を行いますが、このバージョンはHugging Faceに従い2.2.0+cu118を使用しています。

Package                  Version
------------------------ ------------
accelerate               0.28.0
aiohttp                  3.9.3
aiosignal                1.3.1
attrs                    23.2.0
certifi                  2022.12.7
charset-normalizer       2.1.1
contourpy                1.2.0
cycler                   0.12.1
datasets                 2.17.1
dill                     0.3.8
einops                   0.7.0
filelock                 3.9.0
fonttools                4.48.1
frozenlist               1.4.1
fsspec                   2023.10.0
huggingface-hub          0.20.3
idna                     3.4
Jinja2                   3.1.2
kiwisolver               1.4.5
MarkupSafe               2.1.3
matplotlib               3.8.2
mpmath                   1.3.0
multidict                6.0.5
multiprocess             0.70.16
networkx                 3.2.1
numpy                    1.26.3
nvidia-cublas-cu11       11.11.3.6
nvidia-cuda-cupti-cu11   11.8.87
nvidia-cuda-nvrtc-cu11   11.8.89
nvidia-cuda-runtime-cu11 11.8.89
nvidia-cudnn-cu11        8.7.0.84
nvidia-cufft-cu11        10.9.0.58
nvidia-curand-cu11       10.3.0.86
nvidia-cusolver-cu11     11.4.1.48
nvidia-cusparse-cu11     11.7.5.86
nvidia-nccl-cu11         2.19.3
nvidia-nvtx-cu11         11.8.86
packaging                23.2
pandas                   2.2.0
pillow                   10.2.0
pip                      22.3
psutil                   5.9.8
pyarrow                  15.0.0
pyarrow-hotfix           0.6
pyparsing                3.1.1
python-dateutil          2.8.2
pytz                     2024.1
PyYAML                   6.0.1
regex                    2023.12.25
requests                 2.28.1
safetensors              0.4.2
sentencepiece            0.2.0
setuptools               65.5.0
six                      1.16.0
sympy                    1.12
tokenizers               0.15.2
torch                    2.2.0+cu118
torchaudio               2.2.0+cu118
torchvision              0.17.0+cu118
tqdm                     4.66.2
transformers             4.37.2
triton                   2.2.0
typing_extensions        4.8.0
tzdata                   2024.1
urllib3                  1.26.13
xxhash                   3.4.1
yarl                     1.9.4

実装

基本的にHugging Face内に載っているコードを参考に実装しましたが、少し自分が扱いやすいように編集しています。

使用するモデル

「ELYZA-japanese-Llama-2」の7b(70億のパラメータを持つLLM)13b(130億のパラメータを持つLLM) を使用します。それぞれのモデルで、MetaのLlama-2をOSCARやWikipedia等で構成される日本語テキストデータを用いて追加事前学習したものが使用されています。また、今回は「instruct」と印字されているものを使用します。これが何かというと、ユーザーの指示に従い様々なタスクを解くことができるように事後学習を行なったものになります。このモデルを使用することにより、複数ターンからなる対話にも対応しており、過去の対話を引き継いでユーザーからの支持を遂行することができます[1]

実装したコード

以下のコードでは、transformersライブラリを使用して、LLMを操作するクラスと関数を定義しています。

まず、列挙型のModelTypeでは、使用可能なELYZAモデルの型を定義します。これにより、モデルの指定が簡単になります。

次に、ElyzaModelクラスは、指定されたLLMの初期化とテキスト生成を行います。

  •  __init__メソッドでは、モデルとトークナイザの初期化、モデルを評価モードに設定、必要に応じてCUDA(GPU)への移動、デフォルトのシステムプロンプトの設定を行います。このデフォルトのシステムプロンプトの設定ですが、引数に設定しており、ここではモデルの振る舞いのようなものを入力します。どうやら、使用するモデルは、B_INSTE_INSTに囲まれたプロンプトをシステム内が認識し、振る舞いを決定します。ここでは、少し抽象度の高い指示を書くのがいいでしょう。
  • __call__メソッドでは、与えられたテキストに基づいてテキストを生成します。生成されたテキストは、モデルによる理解を容易にするために特殊トークンで囲まれます。この特殊トークンは、B_SYSE_SYSに囲まれたプロンプトでここで具体的な指示を書きます。
    そして、生成されたテキストはトークナイザを使用してデコードされ、最終的なテキストが返されます。
    引数のmax_new_tokensとはなんぞやという感じですが、ここで出力されるトークンの最大数を設定することができます。この数が多いほど、出力できる最大の文字数が増えます。
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
from enum import Enum

B_INST, E_INST = "[INST]", "[/INST]"
B_SYS, E_SYS = "<<SYS>>\n", "\n<</SYS>>\n\n"


class ModelType(Enum):
    ELYZA_7B = "elyza/ELYZA-japanese-Llama-2-7b-instruct"
    ELYZA_13B = "elyza/ELYZA-japanese-Llama-2-13b-instruct"


class ElyzaModel():

    def __init__(self, model_type: ModelType, default_system_prompt: str):

        self.tokenizer = AutoTokenizer.from_pretrained(model_type.value)
        self.model = AutoModelForCausalLM.from_pretrained(
            model_type.value, 
            torch_dtype="auto"
        )
        self.model.eval()

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

        self.default_system_prompt = default_system_prompt

    def __call__(self, text: str, max_new_tokens: int = 512) -> str:

        prompt = "{bos_token}{b_inst} {system}{prompt} {e_inst} ".format(
            bos_token=self.tokenizer.bos_token,
            b_inst=B_INST,
            system=f"{B_SYS}{self.default_system_prompt}{E_SYS}",
            prompt=text,
            e_inst=E_INST,
        )

        with torch.no_grad():
            token_ids = self.tokenizer.encode(prompt, add_special_tokens=False, return_tensors="pt")

            output_ids = self.model.generate(
                token_ids.to(self.model.device),
                max_new_tokens=max_new_tokens,
                pad_token_id=self.tokenizer.pad_token_id,
                eos_token_id=self.tokenizer.eos_token_id,
            )

        output = self.tokenizer.decode(output_ids.tolist()[0][token_ids.size(1) :], skip_special_tokens=True)

        return output

出力

以下に指示を与え、実際にトークンを出力した結果を記載します。結果には、出力したトークンと推論時間を記載しています。GPUによって推論時間は変わるので参考にしてみてください。

指示1

新卒というのもあり、ここで仕事に関する心構えみたいなのを聞いて比較してみました。

from models.elyza import ElyzaModel, ModelType
import time

DEFAULT_SYSTEM_PROMPT = "あなたは誠実で優秀な日本人のアシスタントです。"
texts = [
    "仕事の熱意を取り戻すためのアイデアを3つ挙げてください。",
    "仕事の熱意を保つためのアイデアを3つ挙げてください。",
    "仕事の熱意を人に伝染させるためのアイデアを3つ挙げてください。"
]

model = ElyzaModel(model_type=ModelType.ELYZA_13B, default_system_prompt=DEFAULT_SYSTEM_PROMPT)

for text in texts:

    start_time = time.time()
    output = model(text=text, max_new_tokens=1024)
    end_time = time.time()
    
    print(f"経過時間: {end_time - start_time}秒")
    print(f"Elapsed time: {end_time - start_time} seconds")
    print("--------------------")
    print(f"{output}\n\n\n")

結果 (B7)

推論時間は約30秒程度です。悪くない出力結果が出ました。

過時間: 21.240345001220703秒
Elapsed time: 21.240345001220703 seconds
--------------------
仕事の熱意を取り戻すためのアイデアを3つご紹介します。

1. 仕事のやりがいを見つける: 仕事のやりがいを見つけることで、仕事に対する意欲が高まり、熱意が湧き上がってくる可能性があります。

2. 仕事の進め方を見直す: 仕事の進め方を見直すことで、効率的に仕事を進めることができ、仕事のやりがいに繋がる可能性があります。

3. 仕事の課題を解決する: 仕事の課題を解決することで、仕事に対するやりがいや達成感を感じることができる可能性があります。



経過時間: 31.158167123794556秒
Elapsed time: 31.158167123794556 seconds
--------------------
仕事の熱意を保つためのアイデアを3つご紹介します。

1. 目標を設定する: 目標を設定することで、仕事に対する意欲が高まり、熱意を保つことができます。達成感を味わうことができ、モチベーションを高めることができます。

2. 仕事の進め方を工夫する: 同じ仕事を繰り返し行うことで、熱意が低下してしまうことがあります。それを防ぐために、仕事の進め方を工夫することで、飽きずに熱意を保つことができます。

3. 仕事以外の時間を作る: 仕事に熱意を持ちすぎてしまうと、仕事以外の時間を持てなくなってしまう恐れがあります。それを防ぐために、仕事以外の時間を作ることで、仕事に対するバランスを取り、熱意を保つことができます。



経過時間: 38.99523043632507秒
Elapsed time: 38.99523043632507 seconds
--------------------
以下、仕事の熱意を人に伝染させるためのアイデアを3つ挙げます。

1. 仕事の内容を具体的に話す: 仕事の内容を具体的に話すことで、相手に伝えたいことが伝わりやすくなります。具体的な内容を伝えることで、相手も自分と同じ方向を向いていることを感じることができ、共感を生み出すことができます。

2. 仕事のやりがいを伝える: 仕事のやりがいを相手に伝えることで、相手も自分と同じやりがいを感じることができ、共感を生み出すことができます。また、相手が自分のやりがいを共有できることで、仕事の熱意を伝染させることができます。

3. 仕事の成果を共有する: 仕事の成果を共有することで、相手に自分の仕事の結果を伝えることができ、共感を生み出すことができます。また、相手が自分の成果を共有できることで、仕事の熱意を伝染させることができます。

結果 (B13)

推論時間は、300秒ほどかかり7Bのモデルより遥かに時間がかかりました。出力結果は悪くないですが、今回は、7Bと大差ないかもです。

経過時間: 196.3068883419037秒
Elapsed time: 196.3068883419037 seconds
--------------------
仕事の熱意を取り戻すためのアイデアを3つ考えてみました。

1. 目標を見直す: 現在の目標が高すぎるのか、低すぎるのかを見直してみることで、仕事への取り組み方を変えることができるかもしれません。

2. 仕事の意味を見つける: 仕事が世の中に貢献しているか、自分の人生に意味を持たせることができるかを考えてみることで、仕事への取り組み方を変えることができるかもしれません。

3. 仕事の環境を変える: 仕事の環境を変えることで、新たな気づきを得ることができるかもしれません。

これらのアイデアを参考に、仕事の熱意を取り戻してみてください。



経過時間: 217.50947380065918秒
Elapsed time: 217.50947380065918 seconds
--------------------
仕事の熱意を保つためのアイデアを3つ考えてみました。

1. 目標を明確にする: 自分が今どこまで来たのかを明確にすることで、今後の目標が立てやすくなり、仕事への熱意を保ち続けることができます。

2. 仕事内容を工夫する: 毎日同じ作業の繰り返しでは、飽きてしまい、仕事への熱意が保てなくなってしまいます。そのため、仕事内容を工夫し、毎日新しいことに取り組むことで、仕事への熱意を保ち続けることができます。

3. 仕事場の環境を整える: 快適に仕事ができる環境であれば、仕事への熱意を保ち続けることができます。そのため、仕事場の環境を整え、快適に仕事ができるようにしましょう。



経過時間: 318.0525743961334秒
Elapsed time: 318.0525743961334 seconds
--------------------
仕事の熱意を人に伝染させるためのアイデアを3つ考えてみました。

1. 仕事の意味や目的を共有する: 仕事の意味や目的を共有することで、仕事に対する熱意がより伝わりやすくなります。仕事の意味や目的を共有する方法としては、ミーティングや会議を通してスタッフに説明する、社内報や会社ブログを通して社員に情報を提供するなどが挙げられます。

2. 仕事の魅力を伝える: 仕事の魅力を伝えることで、仕事に対する熱意がより伝わりやすくなります。仕事の魅力を伝える方法としては、社内報や会社ブログを通して社員に情報を提供する、社内イベントを開催して社員に仕事の魅力を体験させるなどが挙げられます。

3. 仕事に取り組む姿勢を示す: 仕事に取り組む姿勢を示すことで、仕事に対する熱意がより伝わりやすくなります。仕事に取り組む姿勢を示す方法としては、ミーティングや会議で積極的に意見を述べる、仕事の効率化に取り組むなどの行動を取るなどが挙げられます。

指示2(少し専門性のある指示)

指示1と比較して少し専門性の高い指示を与えてみました。

結果(7B)

専門性が高くなり、少し推論時間が伸びたような感じがあります。出力もまずまずといった感じです。

経過時間: 78.1480712890625秒
Elapsed time: 78.1480712890625 seconds
--------------------
眠れない状態を科学的に説明します。

眠れない状態は、睡眠の質や量に影響を与える脳内化学物質のバランスの崩壊によって引き起こされます。主な物質は、

* セロトニン: 眠気や安らぎをもたらす物質。不足すると眠れない、不安や緊張を感じる
* メラトニン: 睡眠を促進する物質。不足すると眠れない、眠気がなくなる
* アドレナリン: 睡眠を避けるために活性化する物質。過剰に分泌されると眠れない、緊張や不安を感じる

これらの物質のバランスが崩れる原因として、睡眠のリズムの変化や生活習慣の乱れが挙げられます。

睡眠のリズムは、光の刺激によってコントロールされています。昼間に光を浴びると、体内の「時計」がリセットされ、眠くなりにくくなります。夜に光を浴びると、体内時計がリセットされ、眠くなりやすくなります。

また、生活習慣の乱れとして、

* 不規則な生活: 毎日同じ時間に寝ることができない、遅くまで起きている
* アルコールやカフェインの過剰摂取: 睡眠を避けるために活性化する物質を過剰に分泌させる
* ストレス: 睡眠を避けるために活性化する物質を過剰に分泌させる

が挙げられます。



経過時間: 24.862789630889893秒
Elapsed time: 24.862789630889893 seconds
--------------------
頭が痛い状態を科学的に説明します。

頭が痛い状態は、頭痛と言い換えることができます。頭痛は、頭部の痛み、圧迫感、痛みなどの症状を指します。頭痛の種類は、急性頭痛、慢性的な頭痛、片頭痛、緊張型頭痛など様々な種類があります。

頭痛の原因は、脳の血管が拡張し、血流が減少することによる脳内の血流不足が考えられます。また、筋肉の緊張、過度の眼球運動、過度のアルコール摂取、睡眠不足、過度のストレスなど様々な原因が考えられます。



経過時間: 76.82964205741882秒
Elapsed time: 76.82964205741882 seconds
--------------------
疲れやすい状態として、以下のような状態が考えられます。

1. 睡眠不足: 睡眠不足は、疲労回復に必要な体力の回復をする時間を確保できていない状態です。睡眠は、体の修理と回復を行うための貴重な時間であり、睡眠不足が続くと体の疲れが抜けにくくなる可能性があります。
2. 栄養不足: 栄養不足は、体の各部位に十分な栄養を供給できていない状態です。栄養不足は、体の各部位の機能を維持するのに十分なエネルギーを供給できなくなる可能性があります。
3. ストレス: ストレスは、心身の負担となる状態です。ストレスは、自律神経のバランスを乱し、睡眠の質を悪化させる可能性があります。
4. 過度なアルコール摂取: 過度なアルコール摂取は、睡眠を促進する効果がある一方で、睡眠の質を悪化させる可能性があります。
5. 過度なカフェイン摂取: 過度なカフェイン摂取は、睡眠を難しくする可能性があります。カフェインは、体内のアドレナリンやノルエピネフリンの放出を促進し、睡眠を難しくすることが知られています。

これらの状態が続く場合は、医療機関を受診することをお勧めします。

結果(13B)

今回は専門性が高い質問ということもあり、7Bよりも詳しく説明してくれている気がします。

経過時間: 352.5267758369446秒
Elapsed time: 352.5267758369446 seconds
--------------------
睡眠には科学的な観点からも重要なフェーズがあります。

1. 入眠: 眠気を感じてから眠りに入るまでの段階。この段階では眠気を感じながらも眠りに入れないことがあります。
2. ノンレム睡眠: この段階では眼球は動いているものの、筋肉がほとんど動かない睡眠の状態です。この段階では体を休める効果が期待できます。
3. レム睡眠: この段階では眼球は動かなくなりますが、筋肉は活発に動く睡眠の状態です。この段階では夢を見る傾向があります。

以上のフェーズを踏まえた上で、睡眠の質を高めるためのポイントを紹介します。

- 睡眠の前にはリラックスする: 睡眠の前にはゆったりとした入浴や読書など、リラックスできる行動を取りましょう。
- 快適な睡眠環境: 快適な温度と環境で眠ることで、睡眠の質が高まります。
- 規則正しい生活: 規則正しい生活を心がけ、寝る時間は徹底して守りましょう。

以上が睡眠に関する科学的な観点です。睡眠には個人差があるため、自分に最適な睡眠方法を見つけることが大切です。



経過時間: 247.34664487838745秒
Elapsed time: 247.34664487838745 seconds
--------------------
頭が痛い場合、以下のような科学的な状態が考えられます。

1. 頭痛: 頭痛は、頭部や首の筋肉に緊張が生じ、血流が悪くなることで、頭痛が引き起こされます。
2. 脳出血: 脳出血は、脳の血管が破れて出血することで、頭痛の他にも様々な症状を引き起こします。
3. 脳梗塞: 脳梗塞は、脳の血管が詰まることで、頭痛の他にも様々な症状を引き起こします。
4. 頭部外傷: 頭部を強く打つなどして、頭部の骨折や脳の損傷を引き起こすことがあります。
5. 頭部の病気: 頭部の血管や神経に炎症が生じることで、頭痛を引き起こすことがあります。

これらの状態は、一部分の例です。頭が痛い場合は、症状の原因を突き止め、適切な治療を受けることをお勧めします。



経過時間: 394.6060390472412秒
Elapsed time: 394.6060390472412 seconds
--------------------
疲れやすい状態には以下のようなものがあります。

1. 睡眠不足: 睡眠は人間にとって必要不可欠です。睡眠不足が続くと体力や集中力の低下に繋がります。
2. 過度なストレス: ストレスは体や心に様々な影響を与えます。過度なストレスは疲労の原因となります。
3. 不規則な食事: 食事は人間にとって生きていくために必要なものです。不規則な食事は体力や気力の低下に繋がります。
4. 運動不足: 運動は体力や体調を整えるために必要なことです。運動不足は疲労の原因となります。
5. 過度なアルコール摂取: アルコールは一時的にはストレス解消になりますが、過度に摂取すると体力や気力の低下に繋がります。
6. 喫煙: 喫煙は血流が悪くなることで、疲労の原因となります。
7. 甲状腺ホルモンの低下: 甲状腺ホルモンの低下は疲労感や眠気を引き起こすことがあります。
8. 遺伝: 疲れやすい体質は遺伝することがあります。
9. 病気: 病気は様々な症状を引き起こすことがあり、疲労感を引き起こすことがあります。

これらの要因のいくつかが組み合わさっている場合もあります。疲れやすい状態が続くようであれば、病院を受診して適切な診断と治療を受けることをお勧めします。

まとめ

  • サービスに落とし込むには、少し推論時間がかかりすぎるのでこのままでは使用できなそう。量子化をしてみるか、クラウドGPUを借りてもう少し性能の高いものを使用するという選択肢があるかなと思います。
  • しかし、流石日本最高水準のLLMです。出力結果を見てもGPT3.5に匹敵する性能が見て取れます。もう少し自分で高速化できれば、十分にサービスに落とし込んで使えそうです。B13に至っては、専門性の高い指示に対しても詳細な回答が返ってきており、応用の幅が広がりそうです。
  • 性能が下がったりしそうですが、ファインチューニングとかしたら、さらに専門性の高い出力できるのか?とか気になります。
脚注
  1. ELYZA. "". Note, 2024年4月8日.https://note.com/elyza/n/n5d42686b60b7 ↩︎

Discussion