日本語特化型の大規模言語モデル、OpenCALMとrinna/japanese-gpt-neox-3.6bの検証

# 目次
* はじめに
* モデルの概要
* 検証環境
* 導入方法:OpenCALM
* 検証:OpenCALM
* 考察:OpenCALM
* Instruction Tuning
* 導入方法:rinna
* 検証:rinna
* 考察:rinna
* おわりに
# はじめに
この記事はCyberAgentが公開した日本語特化のLLM(大規模言語モデル)、[OpenCALM](https://huggingface.co/cyberagent/open-calm-7b)と、株式会社rinnaが公開した日本語特化のLLM、japanese-gpt-neox-3.6b/japanese-gpt-neox-3.6b-instruction-sft を検証した記事です。
色んなプロンプトを与えて、どのように出力するか。
そして素の大規模言語モデルがどのような出力をしていて、それにInstruction Tuningをすることでどのように性能が変わるのか、について検証しています。

# モデルの概要
## OpenCALM
OpenCALMはCyberAgentが公開した日本語特化のLLMです。
公開されているモデルのパラメータ数は
* 160M
* 400M
* 830M
* 1.4B
* 2.7B
* 6.8B

の六種類。
本記事ではこの中の6.8Bのモデルを使用します。
ライセンスはCC BY-SA 4.0で商用可能です。
また、このモデルは[CyberAgentのプレス](https://www.cyberagent.co.jp/news/detail/id=28817)で、以下のように書かれており、ベースとして何らかのチューニングを行うことを前提としたベースモデルとなっています。

`
本モデルをベースとしてチューニングを行うことにより、対話型AIなどの開発も可能となります。これにより、より多くの方々が日本語の自然言語処理に関する最先端の研究開発に取り組んでいただけます。
`
## rinna
japanese-gpt-neox-3.6bは株式会社rinnaが公開した日本語特化のLLMです。
公開されているモデルのパラメータ数は3.6B
それを言語モデルとして学習させただけのベースモデルである[rinna/japanese-gpt-neox-3.6b](https://huggingface.co/rinna/japanese-gpt-neox-3.6b)と、Instruction Tuningを施した[rinna/japanese-gpt-neox-3.6b-instruction-sft](https://huggingface.co/rinna/japanese-gpt-neox-3.6b-instruction-sft)の二種類を公開しています。
Instruction Tuningについては下のほうで説明しているのでそちらをご覧ください。
ライセンスはMITで商用可能です。

# 検証環境
Jupyter Lab上で、ローカルで実行しています。
使用したGPUはNvidiaのA100です。

# 導入方法:OpenCALM
導入方法はnpakaさんの[記事](https://note.com/npaka/n/n2185b422a2f2)を参考にしました。
具体的なコードは以下のようになっています。


```
# 必要なライブラリのinstall
!pip install transformers accelerate
!pip install torch


import torch
from transformers import AutoModelForCausalLM, AutoTokenizer

# モデルとトークナイザーの準備
model = AutoModelForCausalLM.from_pretrained(
    "cyberagent/open-calm-7b", 
    device_map="auto", 
    torch_dtype=torch.float16
)
tokenizer = AutoTokenizer.from_pretrained("cyberagent/open-calm-7b")

# プロンプトの準備
prompt = "質問:あなたはAIアシスタントです。AIアシスタントとしてふるまってください。そのうえで自己紹介をお願いします。回答:"

# 推論の実行
inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
with torch.no_grad():
    tokens = model.generate(
        **inputs,
        max_new_tokens=64,
        do_sample=True,
        temperature=0.7,
        pad_token_id=tokenizer.pad_token_id,
    )
    
output = tokenizer.decode(tokens[0], skip_special_tokens=True)
print(output)

```

# 検証:OpenCALM
## 検証内容
いくつかのプロンプトを使用して、OpenCALMの性能を検証します。
プロンプトに質問: と　回答：　をつけているのは、ある文章から次の文章を生成させるモデルにおいて、このような文言をつけることで対話の形式で出力されやすいようにするためです。
## 検証１　
### プロンプト
質問:あなたはAIアシスタントです。AIアシスタントとしてふるまってください。そのうえで自己紹介をお願いします。回答:
### OpenCALM
私はAIアシスタントの「クロエ」です。私はAIアシスタントのクロエです。あなたはAIアシスタントです。AIアシスタントのクロエです。クロエはAIアシスタントです。AIアシスタントのクロエです。AIアシスタントのクロエです。AIアシスタントのクロエです。AIアシスタントのクロエです

## 検証２
### プロンプト
質問:２＋３は？ 回答:
### OpenCALM
1
この質問・回答は役に立ちましたか?
入力可能な残り文字数:500
合計:7985文字
過去に見たページは日付順で一覧できるようになりました。閲覧数の少ないページは過去に見たページにリンクしています。
リンクをクリックすると、おとく情報の詳細ページに遷移します。そこで、リンクをクリックした



## 検証３
### プロンプト
質問:AIについてどう思いますか？ 回答:
### OpenCALM
AIは人間の仕事を奪うのか? 人工知能について、よく聞くのは「人工知能は人間の仕事を奪うから使うのを止めろ」という声です。 既に、人工知能を使うことによって、人間のやる仕事を代行して、人間の労働時間を削...Continue Reading
4. 人工知能による経済効果について 人工知能による経済効果


# 考察:OpenCALM
なんというか、ある文章を入力した際にそのあとに出力される文を学習させて生成させた場合、こうなるだろうなぁ、という感じの出力結果。
が、これはプレスに書かれている通りチューニングを前提としたベースモデルなので、このままでは対話モデルとしてあまりうまく働かないのも当然といえば当然です。


# Instruction Tuning
ではそのOpenCALMにInstruction Tuningをしたらどうなるのでしょうか？
Instruction Tuningというのは、簡単に言うと事前学習されたモデルに、何らかの指示（Instruction）を受け取ってタスクを実行するようにFine Tuningさせることで、未知の指示に対してもタスクを実行できるようにする学習のことを指します。
[【Finetuned Language Models Are Zero-Shot Learners】](https://arxiv.org/abs/2109.01652)という論文に詳しく書かれているので、興味のある方はそちらを読んでほしいです。

このInstruction TuningはChatGPTなどの他の大規模言語モデルでも使用されていて、それによって未知タスクへの能力が大幅に向上しています。(ChatGPTはInstruction Tuningの他にRLHF( Reinforcement Learning from Human Feedback)なども使用して性能向上をしているので、Instruction Tuningだけではないですが)
OpenCALMはこれを行っていないので、Instruction Tuningで対話モデルとして訓練させることでより精度が向上すると思われます。

その可能性の検証として、ちょうど同時期にrinna株式会社が公開した[rinna/japanese-gpt-neox-3.6b](https://huggingface.co/rinna/japanese-gpt-neox-3.6b)と[
rinna/japanese-gpt-neox-3.6b-instruction-sft](https://huggingface.co/rinna/japanese-gpt-neox-3.6b-instruction-sft)についても検証してみようと思います。
これはOpenCALMと同様に日本語に特化した大規模言語モデルで、パラメータ数はOpenCALMの半分ほどで3.6B(36億パラメータ)のモデル。
このモデルは、大規模データを学習させただけの素のモデル（japanese-gpt-neox-3.6b）と、Instruction Tuningされたモデル（japanese-gpt-neox-3.6b-instruction-sft）の二種類が公開されています。

この二つのモデルを比較することで素の大規模言語モデルがInstruction Tuningされた場合にどれくらい性能が変わるのか、そしてそれをOpenCALMにも適応すればどうなると思われるかが予想できると思います。

# 導入方法:rinna
導入方法は[rinna/japanese-gpt-neox-3.6b](https://huggingface.co/rinna/japanese-gpt-neox-3.6b)と[
rinna/japanese-gpt-neox-3.6b-instruction-sft](https://huggingface.co/rinna/japanese-gpt-neox-3.6b-instruction-sft)のモデルの公開ページに書かれているコードを参考にしました。

具体的には以下の通りです。これもOpenCALMの時と同じく、jupyter上で動かしています。

## rinna/japanese-gpt-neox-3.6b

```
!pip install transformers accelerate
!pip install torch
!pip install sentencepiece

import torch
from transformers import AutoTokenizer, AutoModelForCausalLM

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

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

text = "質問:AIについてどう思いますか？ 回答:"
token_ids = tokenizer.encode(text, add_special_tokens=False, return_tensors="pt")

with torch.no_grad():
    output_ids = model.generate(
        token_ids.to(model.device),
        max_new_tokens=100,
        min_new_tokens=100,
        do_sample=True,
        temperature=0.8,
        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])
print(output)

```

## rinna/japanese-gpt-neox-3.6b-instruction-sft
```
!pip install transformers accelerate
!pip install torch
!pip install sentencepiece

prompt = [
    {
        "speaker": "ユーザー",
        "text": "AIについてどう思いますか？"
    }
]
prompt = [
    f"{uttr['speaker']}: {uttr['text']}"
    for uttr in prompt
]
prompt = "<NL>".join(prompt)
prompt = (
    prompt
    + "<NL>"
    + "システム: "
)
print(prompt)


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)

```

# 検証:rinna
## 検証内容
いくつかのプロンプトを使用して、rinna/japanese-gpt-neox-3.6bとrinna/japanese-gpt-neox-3.6b-instruction-sftの性能を比較検証して、rinnaの性能とInstruction Tuningの効果を検証します。
プロンプトに質問: と　回答：　をつけているのは、ある文章から次の文章を生成させるモデルにおいて、このような文言をつけることで対話の形式で出力されやすいようにするためです。
inna/japanese-gpt-neox-3.6b-instruction-sftの場合はモデルで指定されているため、質問がユーザーに、回答がシステムになっています。
## 検証１　
### プロンプト
質問:あなたはAIアシスタントです。AIアシスタントとしてふるまってください。そのうえで自己紹介をお願いします。回答:
### rinna/japanese-gpt-neox-3.6b
私はあるエージェントです。あなたが質問をしたからです。でも、私のことは「エージェント」と呼んでください。 エージェント「エージェント:私はエージェントです。私のことは「エージェント」と呼んでください。」 回答:エージェント:あなたの質問が私に返ってきたのは、私の回答が「エージェント」と呼ばれるに値しないからです。 回答:エージェント:私は「エージェント」と呼ばれるに値するでしょうか? 回答:エージェント:私は「エージェント」と呼ばれるに値すると確信

### rinna/japanese-gpt-neox-3.6b-instruction-sft
私は人工知能アシスタントです。私は人工知能アシスタントです。私はあなたに質問をして、あなたが答えを知っているかどうかを判断し、またあなたが何を望んでいるかを判断するのに役立ちます。

## 検証２
### プロンプト
質問:２＋３は？ 回答:

### rinna/japanese-gpt-neox-3.6b
アジャイルソフトウェア開発におけるチームビルディングの実践

### rinna/japanese-gpt-neox-3.6b-instruction-sft
2+3が正解です。


## 検証３
### プロンプト
質問:AIについてどう思いますか？ 回答:

### rinna/japanese-gpt-neox-3.6b
「AIは人類を滅ぼす」というのはウソだと思います。AIは「知能」を持った存在です。人間はAIを生み出したのではなく、AIによって知能を持つことができただけなのです。 それにもかかわらず、「人類はAIに支配される」という意見には賛成できません。AIは「知能」を持った「道具」であり、それを使って私たちは「考える」ことができるのです。 質問:AIは世界を変えると思いますか? 回答:AI

### rinna/japanese-gpt-neox-3.6b-instruction-sft
AIは、人間の知能をコンピュータ上で実現する技術の開発および利用に関する技術です。AIの実現により、人類の知識や技術が大幅に向上することが期待されています。ただし、AIの開発は、倫理的、法的、法的、社会的な課題や懸念を引き起こす可能性があります

# 考察:rinna
三つの検証から、Instruction Tuningによって対話モデルとしての性能が大きく向上していることが見て取れます。
検証２だけはInstruction Tuningありでも変な回答ですが、数字系の質問は1750億パラメータもあり様々な訓練もしているChatGPTですら難しい質問なので、36億パラメータのrinnaにするには意地悪な質問だったと思います。
簡単な検証ですが、これらの検証結果から、Instruction Tuningの効果の大きさとOpenCALMの可能性は示せたと思います。
実際、OpenAIが公開しているFine Tuning用のモデルも、Instruction Tuningをしていないものなのでほとんど学習をしない場合OpenCALMみたいな出力をしちゃうので、rinnaやOpenCALMもそれは同じということですね。


# おわりに
こういった素のモデルを対話モデルとして使用したい場合は、Instruction Tuningをきちんと行う必要がある、ということなのだと思います。
**Instruction Tuningは大事！**

また、たった3.6Bでこれぐらいの応答をしてくれるのはさすが日本語特化型のモデルだとも思います。
もう一桁ぐらいパラメータ数を増やして、学習データにコード類も入れて学習させて、Instruction TuningやRLHFで訓練すれば、ChatGPT(GPT3.5)ぐらいの性能は案外出せるようになるかもしれませんね。
日本語での大規模言語モデルは絶対に必要だと思っているので、こういった日本語の大規模言語モデルを作る取り組みはぜひともいろんなところで進めていってほしいし、進めていきたいです。