🧠

SmolLM v2 (SmolLM 2)

2024/11/04に公開

SmolLM 2

この文章の要点は以下の通りです。

📌 モデルの基本情報

  • SmolLM2は3つのサイズ(135M、360M、1.7B)で構成され、デバイス上で実行可能な軽量設計です。

📌 性能評価

  • 1.7Bバリアントは複数の評価指標で競合モデルを上回り、特に数学指標(GSM8K)で48.2%と高いスコアを達成しています。
  • 一部の指標(MT-Bench、MMUL-Pro)ではQwen2.5-1.5B-Instructが優位な結果でした。

📌 実際の使用テスト結果

  • 英語での質問には正確な回答が可能で、処理時間は約8秒です。
  • 日本語では、簡単な質問に対しても不正確な回答となることがありましたが、システムプロンプトで例を示すと改善しました。
  • 出力言語は入力言語に依存している可能性があります。

モデル概要

https://huggingface.co/HuggingFaceTB/SmolLM2-1.7B-Instruct

モデル概要

Hugging Faceの発表によるモデルの概要を以下に示します。

  1. モデルサイズ
    • 135M、360M、1.7Bの3つのバリアントがあり、どれもデバイス上で実行可能な軽量設計です。
  2. 1.7Bバリアントの特徴
    • 前モデルよりも指示応答、知識、推論、数学など多岐にわたり性能が向上しています
    • FineWeb-Edu、DCLM、The Stackなど多様なデータセットおよび数学やコーディングに特化したデータセットで訓練されています。
  3. トレーニング手法
    • 教師ありファインチューニング(SFT)に加え、UltraFeedbackを用いたDPO(Direct Preference Optimization)が適用されています。
  4. 追加機能
    • テキストの書き換え、要約、関数呼び出しなどのタスクをサポートしています。

モデルの評価結果

Instructモデルの評価指標において、他の競合モデルより多くの項目で優位性が確認されました。

Metric SmolLM2-1.7B-Instruct Llama-1B-Instruct Qwen2.5-1.5B-Instruct SmolLM1-1.7B-Instruct
IFEval (Average prompt/inst) 56.7 53.5 47.4 23.1
MT-Bench 6.13 5.48 6.52 4.33
OpenRewrite-Eval (micro_avg RougeL) 44.9 39.2 46.9 NaN
HellaSwag 66.1 56.1 60.9 55.5
ARC (Average) 51.7 41.6 46.2 43.7
PIQA 74.4 72.3 73.2 71.6
MMLU-Pro (MCF) 19.3 12.7 24.2 11.7
BBH (3-shot) 32.2 27.6 35.3 25.7
GSM8K (5-shot) 48.2 26.8 42.8 4.62

実際に使ってみる

ここでは、SmolLM2-1.7B-InstructモデルをGoogle Colab上で使用し、英語と日本語の質問に対するモデルの応答を確認します。各コードの実行結果と出力についても説明します。

英語で質問
最初に、SmolLM2-1.7B-Instructモデルに英語で質問を行います。以下のコードでは「What is the highest mountain in Japan?」という質問を入力し、その結果を確認します。

from transformers import AutoModelForCausalLM, AutoTokenizer

# デバイス設定
device = "cuda" # GPU使用の場合、"cpu"に変更可能

# トークナイザーとモデルの読み込み
tokenizer = AutoTokenizer.from_pretrained("HuggingFaceTB/SmolLM2-1.7B-Instruct")
model = AutoModelForCausalLM.from_pretrained("HuggingFaceTB/SmolLM2-1.7B-Instruct").to(device)

# 入力メッセージ作成
messages = [{"role": "user", "content": "What is the highest mountain in Japan?"}]
input_text = tokenizer.apply_chat_template(messages, tokenize=False)

# トークン化とモデルの生成
inputs = tokenizer.encode(input_text, return_tensors="pt").to(device)
outputs = model.generate(inputs, max_new_tokens=250, temperature=0.2, top_p=0.9, do_sample=True)

# 結果の表示
print(tokenizer.decode(outputs[0]))

実行結果
実行にかかった時間は約8秒で、以下のような正確な回答が得られました。

<|im_start|>system
You are a helpful AI assistant named SmolLM, trained by Hugging Face<|im_end|>
<|im_start|>user
What is the highest mountain in Japan?<|im_end|>
# 訳: 日本で一番高い山は?
<|im_start|>assistant
The highest mountain in Japan is Mount Fuji, also known as Fuji-no-yama. It stands at an elevation of 3,776.24 m (12,389 ft) above sea level. Mount Fuji is an active volcano and is considered a sacred site in Japan.<|im_end|>
# 訳: 日本で一番高い山は富士山である。標高は3,776.24m(12,389フィート)。富士山は活火山であり、日本では聖地とされている。

英語での入力に対して、適切な回答が返されていることが確認できました。


日本語での質問
次に、質問を日本語に変更してみます。「日本で最も高い山は?」という日本語の質問に対し、モデルがどのように応答するかを確認します。

# 日本語での入力メッセージ作成
messages = [{"role": "user", "content": "日本で最も高い山は?"}]
input_text = tokenizer.apply_chat_template(messages, tokenize=False)

# トークン化と文章生成
inputs = tokenizer.encode(input_text, return_tensors="pt").to(device)
outputs = model.generate(inputs, max_new_tokens=250, temperature=0.2, top_p=0.9, do_sample=True)

# 結果の表示
print(tokenizer.decode(outputs[0]))

実行結果
文章生成には約9秒かかり、以下のような回答が返されました。

<|im_start|>user
日本で最も高い山は?<|im_end|>
<|im_start|>assistant
日本で最も高い山は、山陵の山です。山陵の山は、山陵県の山陵岳で、山陵県の山陵島で、山陵県の山陵市で、山陵県の山陵市の山陵島で、山陵県の山陵市の山陵島で、山陵県の山陵市の山陵島で、山陵県の山陵市の山陵島で、山陵県の山陵市の山陵島で、山陵県の山陵市の山陵島で、山陵�

出力は日本語で返されましたが、内容は不正確でした。このことから、質問が日本語の場合、必ずしも正確な回答が得られないことがわかります。


システムプロンプトを変えてみる
日本語での回答精度を改善するために、システムプロンプトに具体例を追加してみます。質問と回答の例を示すことで、モデルの応答が改善されるかを確認します。

# システムプロンプトに例を追加
system_prompt_rewrite = """
You are the quiz king of Japan. You are now going to take a quiz about Japan as follows.
例1
質問: 日本で最も高い山は? 
回答: 日本で最も高い山は富士山です。
"""
user_prompt_rewrite = "日本で最も高い山は?"

# システムプロンプトとユーザープロンプトを設定
messages = [{"role": "system", "content": system_prompt_rewrite}, {"role": "user", "content": user_prompt_rewrite}]
input_text = tokenizer.apply_chat_template(messages, tokenize=False)

# トークン化と文章生成
inputs = tokenizer.encode(input_text, return_tensors="pt").to(device)
outputs = model.generate(inputs, max_new_tokens=100, temperature=0.7, top_p=0.9, do_sample=True)

# 結果の表示
print(tokenizer.decode(outputs[0]))

実行結果
約1秒で生成され、次のような回答が得られました。

<|im_start|>system

You are the quiz king of Japan. You are now going to take a quiz about Japan as follows.
例1
質問: 日本で最も高い山は? 
回答: 日本で最も高い山は富士山です。
<|im_end|>
<|im_start|>user
日本で最も高い山は?<|im_end|>
<|im_start|>assistant
富士山です。<|im_end|>

この例の追加により、モデルが正確な回答を返すようになりました。


システムプロンプトの影響確認

システムプロンプトではなく、入力言語による出力言語の変更を確認するため、同じプロンプトの内容で英語の質問に変更して実行してみます。

# 入力メッセージを英語に変更
user_prompt_rewrite = "What is the capital of Japan?"

messages = [{"role": "system", "content": system_prompt_rewrite}, {"role": "user", "content": user_prompt_rewrite}]
input_text = tokenizer.apply_chat_template(messages, tokenize=False)

# トークン化と文章生成
inputs = tokenizer.encode(input_text, return_tensors="pt").to(device)
outputs = model.generate(inputs, max_new_tokens=100, temperature=0.7, top_p=0.9, do_sample=True)

# 結果の表示
print(tokenizer.decode(outputs[0]))

実行結果
約1秒で生成され、以下のように英語での回答が得られました。

<|im_start|>system

You are the quiz king of Japan. You are now going to take a quiz about Japan as follows.
例1
質問: 日本で最も高い山は? 
回答: 日本で最も高い山は富士山です。
<|im_end|>
<|im_start|>user
What is the capital of Japan?<|im_end|>
<|im_start|>assistant
The capital of Japan is Tokyo.<|im_end|>

システムプロンプトではなく入力言語に依存して出力言語が変わってそうです。サポートされるタスクに翻訳が含まれていなかったので、当然かもしれません。

Discussion