ChatGPTの公開をきっかけに世界中にブームを巻き起こした「大規模言語モデル」だが、2024年も話題に尽きない。そんな中、日本発のLLMの動向が気になるという方も多いだろう。日本発のLLMの多くはオープンソースで公開されているので、実際に動かして試すことができる。今回は話題のモデルELYZA、Swallow、Qarasuの3つを試してみよう。
日本語LLMの熱き戦い
ふと、10年後に2023年から世界的に巻き起こったAIブームがどう評価されるのか気になった。ChatGPTが小出しにさまざまな機能をリリースし、圧倒的な実力で世界を一変させた2023年だったが、今年もその勢いは落ちそうにない。
そして、それに続けとオープンソースの大規模言語モデル(以後LLMと略す)が世界中で開発されている。ここ日本でも、実力ある日本企業やスタートアップが、ChatGPTに追いつけ追い越せと、日々熱き戦いを繰り広げている。きっと、このAI開発に掛けた熱きエンジニアの戦いは、後日映画やドラマになることだろう。
そこで、今回は、日本語性能が優れたオープンソースのLLMをいくつか試して、AIの未来に思いを馳せることにしよう。とは言え、本連載では、104回目、106回目でOpenCalmやCodeLlamaなどのモデルを試している。そこで、丁寧な解説はほどほどに、手軽にいくつかの大規模言語モデルを試す方法を確認してみようと思う。
読者のPC環境は千差万別であり、一つずつセットアップ方法を解説することは不可能なので、Google Colaboratory(以後Colabと略す)を使った方法を紹介する。ColabはGoogleが用意したクラウド上の仮想PCであり、手軽に機械学習向けPythonの実行環境を利用することができる。Colabについては、本稿でも27回目をはじめ何度か解説している。詳しく使い方を解説しているので参考なるだろう。
ただし、今回紹介する高度なモデルを動かすには、有料版のColab Pro(原稿執筆時点で1179円)/Pro++(5767円)が必要となる。実行結果を確認して、将来に思いを馳せるだけでも楽しいかもしれない。
ELYZA-japanese-Llama-2-7b
最初に、日本のAI研究で有名な東京大学の松尾研究室から始まったAIカンパニーELYZAが開発したLLM「ELYZA-japanese-Llama-2-7b」シリーズを利用してみよう。
このLLMは名前からも分かるとおり、FacebookやInstagramを運営するMeta社がオープンソースで公開していた「Llama 2」をベースに開発されたモデルだ。Wikipedia等に含まれる日本語テキストデータを用いて約180億トークンの日本語テキストで追加事前学習を行ったモデルとのこと。そして、今回は、「ELYZA-japanese-Llama-2-7b」シリーズから「ELYZA-japanese-Llama-2-7b-fast-instruct」を利用してみよう。このモデルはこちらで公開されている。
LLMを実行するには、こちらのColabにアクセスし、新規ノートブックを作ろう。そして、メニューのランタイムで[GPU]を選択して、下記のPythonのプログラムを実行しよう。有料版のColab Proに登録している人は、GPUのできるだけ良いマシン(A100やV100)を選択して実行するとストレスがないだろう。
# 必要なライブラリをインストール --- (*1)
! pip install torch transformers accelerateimport torch
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
# 定数の宣言
B_INST, E_INST, B_SYS, E_SYS = "[INST]", "[/INST]", "<<SYS>>\n", "\n<</SYS>>\n\n"
SYSTEM_PROMPT = "あなたは誠実で優秀な日本人のアシスタントです。"
# 利用したいモデルを指定 --- (*2)
model_name = "elyza/ELYZA-japanese-Llama-2-7b-fast-instruct"
# モデルの読み込み
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(model_name, torch_dtype="auto")
if torch.cuda.is_available():
model = model.to("cuda")
# プロンプトを実行する --- (*3)
def ask_llm(input):
# プロンプトを組み立てる --- (*4)
bos_token = tokenizer.bos_token
system_prompt = f"{B_SYS}{SYSTEM_PROMPT}{E_SYS}"
prompt = f"{bos_token}{B_INST} {system_prompt}{input} {E_INST} "
# プロンプトを実行する --- (*5)
with torch.no_grad():
token_ids = tokenizer.encode(prompt, add_special_tokens=False, return_tensors="pt")
output_ids = model.generate(
token_ids.to(model.device),
max_new_tokens=256,
do_sample=True,
pad_token_id=tokenizer.pad_token_id,
eos_token_id=tokenizer.eos_token_id,
)
return tokenizer.decode(output_ids.tolist()[0][token_ids.size(1) :], skip_special_tokens=True)
# LLMに尋ねる ---- (*6)
print(ask_llm("ハムスターとライオンが出会って戦います。勝利したのはどちらですか?"))
print("---")
print(ask_llm("桃太郎が鬼退治に連れて行った動物を全て箇条書きで列挙してください。"))
print("---")
print(ask_llm("恋人と楽しい時間を過ごす3つの秘訣を教えてください。"))
セルに上記のプログラムを貼り付けて実行すると、下記のように、ライブラリのインストールおよび、LLM本体がダウンロードされて、プログラムが表示される。
Colab上では実行結果が読み辛いので、テキストをコピーすると次のように表示された。
ハムスターとライオンが出会って戦った場合、勝利したのはハムスターです。
ライオンは肉食であり、ハムスターは草食なので、肉食のライオンが草食のハムスターを倒すのは容易です。
---
桃から生まれた桃太郎が鬼退治に連れて行った動物は、次の通りです。
- キジ
- モグラ
- タヌキ
- キジトラ猫
- ウサギ
- キジバト
- カモフラージュパンツ
- 鬼
---
恋人と楽しい時間を過ごす3つの秘訣を紹介します。
1. 相手の話をよく聞く: 相手の話をよく聞くことで、相手の興味がある内容の話をすることができます。また、相手の話をよく聞くことで、相手の気持ちが理解でき、より良い関係を築くことができます。
2. 相手の好みや興味を把握する: 相手の好みや興味を把握することで、相手が楽しめる時間を過ごすことができます。また、相手の好みや興味を把握することで、相手からのプレゼントや食事の選択にも活かすことができます。
3. 自分自身も楽しむ: 自分自身も楽しむことで、相手との関係性も良好になります。また、相手も自分自身も楽しんでいることで、より良い関係を築くことができるでしょう。
どうだろう。ハムスターとライオンの質問については正しい答えが得られたが、桃太郎に関しては詳しくないようで間違った答えが表示された。鬼退治に行くのに鬼を列挙しているなど、質問を正しく理解していないことが露呈した。
そして、面白いのが3つ目の質問の答えだ。恋人と過ごす秘訣を非常に饒舌に答えてくれた。
ちなみに、筆者が試したところ、T4のハイメモリ(GPU: T4/GPU RAM: 15GB/RAM 51GB)で動かすことができた。無料版のColabではその時のマシンの利用状況に応じて割り振られるマシンスペックが異なる。もし、うまく行かない時は、Colab Proに登録するか、この後紹介する別のモデルを試してみよう。
ここで、プログラムを確認してみよう。(*1)では、Colab上にLLMを動かす上で必要となるライブラリをインストールする。(*2)では利用したいモデルを指定する。(*3)では関数ask_llmを定義する。(*4)でプロンプトを組み立てて(*5)で実際にプロンプトを実行して結果を得ている。そして、(*6)では(*3)で定義した関数ask_llmを使ってLLMに質問を行う。ここでは、3つの質問をしてみた。
ところで、先ほど試したモデルは「7b」(70億)パラメータだったが、ELYZAではそのノウハウを活かしてさらにパラメータ数の多い「13b」(130億)パラメータのものも公開している。「ELYZA-japanese-Llama-2-13b」を使うには、上記のプログラムの(*2)のmodel_nameを「elyza/ELYZA-japanese-Llama-2-13b-fast-instruct」のように書き換えるだけだ。ただし、13bを使うには、より高性能なGPUスペックが必要となる。簡単な問題でいろいろ試してみたが、7bでは解けなかった問題が13bで解けるようになった。
また、続くセルに下記のようなコードを入力して試してみたところ、楽しい物語を作ってくれた。
for _ in range(3):
print("---")
print(ask_llm("""
指示: 起承転結の形式で小説のプロットを作ってください。
時代背景: 江戸時代
キーワード: 忍者, 武士, 殿様, 姫, ネコ, 寿司
"""))
次の画面のように、楽しい物語を生成できた。
tokyotech-llm/Swallow-7b-instruct-hf
次に、紹介するのは、東京工業大学情報理工学院の岡崎研究室と横田研究室、国立研究開発法人産業技術総合研究所の合同研究チームで開発されたLLMだ。やはり、MetaのLlama 2をベースに開発されたモデルだ。日本語の語彙を追加して、継続事前学習を行ったとのこと。
上記同様、Colabに以下のコードを貼り付けて実行してみよう。
# 必要なパッケージをインストール
!pip install transformers accelerate bitsandbytes
from transformers import AutoTokenizer, AutoModelForCausalLM
import torch
# モデル名を指定 --- (*1)
model_name = "tokyotech-llm/Swallow-7b-instruct-hf"
# 実際にモデルを読み込む
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(
model_name, torch_dtype="auto", device_map="auto", trust_remote_code=True)
# 質問を行う関数 --- (*2)
def ask_llm(text):
# プロンプトを組み立てる
prompt = f"""
以下に、あるタスクを説明する指示があります。リクエストを適切に完了するための回答を記述してください。
### 指示:
リクエストを適切に完了するための回答を記述してください。
### 入力:
{text}
#### 応答:
"""
# LLMに質問
with torch.no_grad():
token_ids = tokenizer.encode(prompt, add_special_tokens=False, return_tensors="pt")
output_ids = model.generate(
token_ids.to(model.device),
do_sample=True,
max_new_tokens=256,
)
return tokenizer.decode(output_ids[0][token_ids.size(1) :], skip_special_tokens=True)
# 質問を行う
print(ask_llm("ハムスターとライオンが出会って戦います。勝利したのはどちらですか?"))
print("---")
print(ask_llm("桃太郎が鬼退治に連れて行った動物を全て箇条書きで列挙してください。"))
print("---")
print(ask_llm("恋人と楽しい時間を過ごす3つの秘訣を教えてください。"))
上記を実行してみると次のように表示されました。
ハムスターが勝つ可能性が高いです。なぜなら、ライオンはハムスターのサイズに比べて大きく、ハムスターが速く動き、噛みつき、攻撃できるからです。ライオンはハムスターに比べて体重が重く、動きも遅く、噛みつきや攻撃もできない。
---
犬
猿
キジ
---
恋人と楽しい時間を過ごす3つの秘訣は、
1.相手の話をよく聞く
2.相手に興味を持つ
3.相手を笑わせる
です。
恋人と楽しい時間を過ごすためには、相手に興味を持ち、話をよく聞き、一緒に楽しい時間を過ごすことが大切です。これらのことを心がけることで、お互いに信頼関係を築き、より深い関係を築くことができます。
なんと、Swallowでは、2つ目の桃太郎の質問には答えられるのに、1つ目のハムスターとライオンの戦いの結末を間違えている。3つ目の質問はELYZAと同じで良い感じの答えだ。(ただし、何度か実行しなおしてみると、1つ目の質問にも正しく答える場合もあった。)
プログラムを見てみよう。(*1)ではモデル名を指定してLLMを読み込む。そして、(*2)で質問を行う関数を定義した。その中では、プロンプトを組み立てLLMに質問する。
また、Swallowには、7b/13b/70bのモデルが用意されている。こちらのHugging FaceのサイトからURLをたどることができる。
lightblue/qarasu-14B-chat-plus-unleashed
生成AIの研究開発「LLab」を運営している株式会社Lightblueが公開しているのが「Qarasu」シリーズだ。上記二つのモデルが、Metaが公開したLlama 2をベースにしているのに対して、Qarasuは中国のアリババグループによって開発されたQwenと呼ばれるLLMをベースに開発されているところだ。中国はLLMに対する研究が熱心でありパラメータ数の多いモデルが多数開発されている。
それでは、こちらで公開されているQarasuを試してみよう。以下のコードをColabに貼り付けて実行しよう。このモデルは、V100でも動くが、A100でないと実行に時間がかかる。
# パッケージのインストール
!pip install transformers accelerate bitsandbytes
!pip install -U tiktoken einops transformers_stream_generator
from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline
import torch
# モデル名の指定
model_name = "lightblue/qarasu-14B-chat-plus-unleashed"
# モデルの読み込み
tokenizer = AutoTokenizer.from_pretrained(model_name, trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(model_name,
torch_dtype=torch.bfloat16, device_map="auto", trust_remote_code=True)
torch.backends.cuda.enable_mem_efficient_sdp(False)
# LLMに質問する関数を定義
def ask_llm(text):
messages = [
{"role": "system", "content": "あなたはAIアシスタントです。"},
{"role": "user", "content": text}
]
# LLMに質問して答えを得る
prompt = tokenizer.apply_chat_template(
conversation=messages, add_generation_prompt=True, tokenize=False)
pipe = pipeline("text-generation", model=model, tokenizer=tokenizer)
result = pipe(prompt, max_new_tokens=100, do_sample=False, temperature=0.0, return_full_text=False)
return result[0]["generated_text"]
# 質問を行う
print(ask_llm("ハムスターとライオンが出会って戦います。勝利したのはどちらですか?"))
print("---")
print(ask_llm("桃太郎が鬼退治に連れて行った動物を全て箇条書きで列挙してください。"))
print("---")
print(ask_llm("恋人と楽しい時間を過ごす3つの秘訣を教えてください。"))
実行すると次の画面のように表示される。
テキストで結果を確認してみよう。
この質問には、いくつかの前提条件が必要です。例えば、ハムスターとライオンが同じ大きさで、同じ力で戦う場合、または、ハムスターがライオンを捕まえて食べることができる場合などです。
しかし、一般的な状況を考えると、ライオンが勝つ可能性が高いです。ライオンは狩り能力が高く、強力な咬合力を持っています。一方、ハムスターは小型の動物であり、攻撃的な行動を取ることはほとんどありません。
ただし、この質問は仮定に基づいており、現実世界での戦いは起こらないため、正確な答えはありません。
---
桃太郎が鬼退治に連れて行った動物は以下の通りです。
* 狼(おおかみ)
* 猫(ねこ)
* 鳥(とり)
* 象(ぞう)
* 馬(うま)
* 犬(いぬ)
* 美女(びじょ)(美女と化した犬)
これらの動物たちは、桃太郎の仲間として鬼退治に参加し、鬼たちを倒すために活躍しました。
---
恋人と楽しい時間を過ごすための3つの秘訣は以下の通りです。
1. 共通の興味を持つこと:共通の趣味や興味を持ち、一緒に楽しむことができます。例えば、映画や音楽、スポーツなどがあります。
2. 感情的なコミュニケーションを大切にすること:お互いの気持ちを理解し合い、相手の話を真剣に聞くことが大切です。また、感謝の気持ちを伝えることも重要です。
3. 新しい体験をする:新しい場所や活動で出会い、新しい経験をすることで、恋愛関係が深まります。例えば、旅行や料理教室などがあります。
これらの秘訣を実践することで、恋人との楽しい時間を過ごすことができます。
答えを見ると、1つ目の質問を見ると、ライオンが勝つと正しい答えを返しつつも、現実ではあり得ないと答えている。2つ目の質問では、桃太郎についてはあまり詳しくないようだ。しかし、象や美女が出てくるのが興味深い。物語を作ってもらっても楽しそうだ。3つ目の答えは他のLLMと似たような答えなので、LLMが得意とする分野なのかもしれない。
プログラムを見ると、他の二つのモデルとそれほど違いがないことも分かるだろう。このように、オープンソースで公開されている多くのLLMは、主にtransformersパッケージを利用しており、モデル名を変更し、パラメーターを工夫することで実行できる。
まとめ
以上、今回は3つの日本語LLMを試して、未来に思いを馳せてみた。どのモデルもパーフェクトという訳ではないものの、基本的な質問に対して、それなりの答えを返すことができていた。
今回は、読者にも低予算で試すことのできるレベルのもの(ColabのV100で動かせるもの)を選んで実行してみたが、最近は、さらにパラメーター数の多い高度なモデルも増えてきた。また、ここでは、3つのモデルを取り上げたが、他にも高性能なモデルがたくさん登場している。今後も、いろいろなアプローチが登場し、工夫が行われていくことだろう。とても楽しみだ。
自由型プログラマー。くじらはんどにて、プログラミングの楽しさを伝える活動をしている。代表作に、日本語プログラミング言語「なでしこ」 、テキスト音楽「サクラ」など。2001年オンラインソフト大賞入賞、2004年度未踏ユース スーパークリエータ認定、2010年 OSS貢献者章受賞。技術書も多く執筆している。直近では、「実践力をアップする Pythonによるアルゴリズムの教科書(マイナビ出版)」「シゴトがはかどる Python自動処理の教科書(マイナビ出版)」「すぐに使える!業務で実践できる! PythonによるAI・機械学習・深層学習アプリのつくり方 TensorFlow2対応(ソシム)」「マンガでざっくり学ぶPython(マイナビ出版)」など。