MT-Benchによる各種LLMの日本語運用能力評価まとめ(23/10/31更新)
npaka大先生が日本語版MT-Benchの記事を書いてくれたのでこの記事を参考にさまざまなLLMの日本語の性能評価をしてみることにした。使用マシンはもちろんドスパラ製A6000x2マシン。
ただ、LLMJPはGPT2ベースなので普通に大先生と同じやり方でやるとあってるのか間違ってるのかわからないくらい性能が低く見積もられてしまったた。
そこで、LLM-JPを使ってStability.aiが制作した日本語版question.jsonl(別に俺が訳す必要はないくらいちゃんとしたのがStability.aiにあった)から質問の答えのやりとりを生成するコードを書いた。これは少し改造するだけで他の癖強めのLLM(rinnaとか)にも使えるだろう。
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM
import json
import random
import string
import time
def generate_random_string(length):
letters = string.ascii_letters
result_str = ''.join(random.choice(letters) for i in range(length))
return result_str
llm = "llm-jp/llm-jp-13b-instruct-full-jaster-v1.0"
tokenizer = AutoTokenizer.from_pretrained(llm)
model = AutoModelForCausalLM.from_pretrained(llm, device_map="auto", torch_dtype=torch.float16)
model.to("cuda:0")
template="%s ### 回答:"
max_length=2048
def think(question, context):
#print(question)
input_ids = tokenizer.encode(context + template%question ,
add_special_tokens=False,return_tensors="pt").to("cuda:0")
output_ids = model.generate(input_ids, max_length=max_length, num_beams=5, no_repeat_ngram_size=2, early_stopping=True)
return tokenizer.decode(output_ids[0], skip_special_tokens=True)
def generate_answer(file):
model_id= llm[llm.index("/") + 1:]
outfile = llm[llm.index("/") + 1:] + ".jsonl"
print(outfile)
with open(outfile,"w") as of:
with open(file) as f:
for i in f:
d=json.loads(i)
context = ""
turns=[]
d["model_id"]=model_id
d["answer_id"]=generate_random_string(22)
prompt=""
for utterance in d["turns"]:
response=think(utterance, context)
answer = response[len(context+template%utterance):]
print(answer)
context =response+"\n"
turns.append(utterance)
turns.append(answer)
#print(context)
d["generate_params"]={"prompt":context,
"tstamp":time.time(),
"do_sample": True, "max_new_token": 512,
"temperature": 0.5, "top_p": 0.9, "repetition_penalty": 1.1
}
d["choices"]=[{"index:":0,"turns":turns}]
print(json.dumps(d, ensure_ascii=False))
of.write(json.dumps(d, ensure_ascii=False)+"\n")
print(think("宮﨑駿の代表作をJSON形式で出せ",""))
generate_answer("data/japanese_mt_bench/question.jsonl")
例によって雑で申し訳ないが、MT-BenchのもとになってるFastChatは構造が入り組み過ぎてバグをとるために元のソースコード追いかけてるだけで目が回りそうになったのでシンプルに作り直した。
これで生成したファイルはこんな感じになる。
なるほど。一問一答で終わるような問題はこなせるが、創造性を強く要求されるようなものには弱いようだ。
Instructionチューニングされた日本語モデルは押しなべて同じ問題を抱えているように見える。
最近「お、これいいな」と思った主要なLLMの日本語性能を比較して見た。ちなみに比較にはGPT-4のAPI利用料金がかかるので結構自腹切ってるデータだ。
XWinLMとElyzaが似た傾向で、全体的に数学とコーディング、誰かになりきるのは苦手という結果になった。日本の著名人がほとんどネット上に文章があるわけではなく、教科書やテレビやYouTubeといった動画媒体メインだからという理由もおそらくあるだろう。要はネットだけ見ていても有名人の喋り方の癖や考え方を類推するのが日本人に関しては全体的に難しいのである。これはGPT-4でもそうで、GPT-4がそもそも「それが宮﨑駿のいいそうなことか」判定するのは学習データ的に無理だと思われる(少なくとも今のところは)。
個人的には一番「日本関係の知識を知ってる」LLM-JPが最下位に近いという残念な結果になってしまった。これはベンチマークが悪いのだろう。
MT-Benchはチャット的なやりとりでどれだけ知的なことを返せるかを測る。日本に関する知識が「あってるか、間違ってるか」に関してはGPT-4よりLLM-JPの方が詳しいと思えるだけに残念だ。
また、LLM-JPがそもそもこういうラリー形式の会話のやりとりを前提に訓練されていないように少なくともHuggingFaceのリポジトリからは伺える。
今後は「日本に関する知識があってるかどうか」それも、アニメなのかIT業界なのか政治なのか経済なのか文学なのか小説なのか映画なのか、といったマニアックな知識を満遍なくテストするような日本文化に特化した質問データセットによるベンチマークが必要になるだろう。
また、ジャッジメント用のプロンプトもGPT-4に読ませることが前提なので英語のままなのだが、そもそもGPT-4は英語びいきという性質があって、日本語の質問に対して英語で答えていても高得点を与えてしまうという問題がある。これに関しては、ジャッジメント用のプロンプトを日本語にしたり、答えが日本語かどうかも採点基準に含めるなどのプロンプトチューニングが必要と思われる。ひとまず現場からは以上です。
なお、現在も評価を継続中で、近日中にさらに複数のモデルのベンチマーク結果を公開します。
時間かかるのよこれ。
(23/10/31更新)
さらに追加で色々やってみたところ、ベンチマークに使っていたjudgement.jsonlの日本語版をStabilityAIが用意していたことに気づいた。
そこで改めてjudgement.jsonlを日本語版に差し替えて各種モデルをテストした結果を下に示す
改めて比較してもElyzaの健闘ぶりが光る。