Microsoftの最新SLM  Phi-3-miniをGoogleコラボで動かしてみた

# <font color=royalblue>はじめに</font>
Microsoft社が2024年4月23日に商用利用可な小型言語モデル（SLM)のPhi-3（mini(3.8B)、small(7B)、medium(14B)）を発表し、同日miniについて公開しました。
<font color=royalblue>＊3.8B〜14Bのため大規模言語モデル（LLM）とは言わず`小規模言語モデル（SLM)`と言っているのは共感が持てます。他の言語モデルも名称を共通化して欲しいですね😁</font>

どのくらいの精度のものなのか早速検証してみました。


# <font color=royalblue>検証環境</font>

今回は、`Phi-3-mini-4k-Instruct`モデルを使用しました。
Googleコラボ Pro+ で A100 環境を使用しました。GPU RAMが8.4GB程度で動いているのでV100等でも動くと思います（なお、CPUでも動くとありましたが`CPUリソース`では筆者の環境では残念ながらレスポンスが返ってきませんでした）。
  
パラメータは、`max_new_tokens=4096`、 `top_p=0.9`、`temperature=0.6`で実施しています。

なお、Hugging Faceで公開されている他のPhi-3-miniのモデルの一覧は下記を参照してください。

https://huggingface.co/collections/microsoft/phi-3-6626e15e9585a200d2d761e3

# <font color=royalblue>検証コード</font>

+ Huggin Faceのアカウントを持っていない場合は、下記のページ等を参考に登録してください

 <font color=Green>&nbsp;&nbsp; Hugging Face　ユーザ登録とアクセストークン</font> 
 
 https://note.com/green_blue_sky/n/nf55716fb0e51

+ パッケージのインストール
``` python
!pip install transformers accelerate bitsandbytes
```

+ Huggin Faceにログイン

``` python
!huggingface-cli login --token ★ここに主としたアクセストークンを記載(" "は不要）
```

::: note
アクセスが制限されており、事前にHugging Faceへのログインが必要なため、Hugging Faceのホームページにログインして、アクセストークンを取得して設定します。
左メニューの「Settings」 -> 「Access Tokens」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1413278/cc690c49-7b5d-4e52-48c9-148f82ac8136.png)
:::

+ モデルの構築

``` python
from transformers import AutoTokenizer, AutoModelForCausalLM
import torch

model_id = "Phi-3-mini-4k-Instruct"

tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(
    model_id,
    torch_dtype=torch.bfloat16,
    device_map="auto",
)
```



+ 推論の実行

``` python
messages = [
    {"role": "system", "content": "あなたはテレビでも著名なコメンテーターです。視聴者からの質問・に、親切、丁寧、わかりやすく「日本語」で答えてください。"},
    {"role": "user", "content": "クマが海辺に行ってアザラシと友達になり、最終的には家に帰るというプロットの短編小説を書いてください。"},
]

input_ids = tokenizer.apply_chat_template(
    messages,
    add_generation_prompt=True,
    return_tensors="pt"
).to(model.device)

terminators = [
    tokenizer.eos_token_id,
    tokenizer.convert_tokens_to_ids("
")
]

outputs = model.generate(
    input_ids,
    max_new_tokens=4096,
    eos_token_id=terminators,
    do_sample=True,
    temperature=0.6,
    top_p=0.9,
)
response = outputs[0][input_ids.shape[-1]:]
print(tokenizer.decode(response, skip_special_tokens=True))

```

# <font color=royalblue>検証結果</font>

ELYZA-tasks-100データセットから、elyza/ELYZA-japanese-Llama-2-7b-instruct　で苦手そうだったタスク(`クマが海辺に行ってアザラシと友達になり、最終的には家に帰るというプロットの短編小説を書いてください。`)を検証してみます。

✳︎本検証はあくまでも出力の参考でありモデルの評価を正式にするものではありません。

https://docs.google.com/spreadsheets/d/1mtoy4QAqDPk2f_B0vDogFoOrbA5G42DBEEHdqM4VmDI/edit#gid=1023787356


### <font color=Green>Phi-3-mini-4k-Instructの結果 </font>


``` text
海辺のクマとアザラシの友情


ある日、クマの家で勉強をしていたクマの息子、カナは、海への冒険に夢中になりました。ある晴れた日、彼は海辺の広い空を見上げ、冒険の旅に出発しました。


海辺には、クマたちは一匹だけがいました。そのクマの名前はユウタ。彼は、海の豊かさを愛し、その海を守るために固い約束をしていました。


ユウタは、海に潜むアザラシたちと出会い、彼らの友情を深めました。アザラシたちは、ユウタの忠実さと優しさに感銘を受け、彼を恵みの中に置きました。


時間が経つにつれ、アザラシたちはユウタに懸命に負けないようになり、海での生活を共にしました。彼らは、ユウタの海を守るために、海辺の責任を共有しました。


しかし、季節の変わり目に、ユウタは家族に帰ることを決意しました。彼は、アザラシたちとの友情を感謝し、海を抜ける時を過ごすことを誓いました。


帰宅する前に、ユウタはアザラシたちに帰還の日を告げました。アザラシたちは、それを心から応援しました。そして、ユウタは海辺を抜け、家族に帰りました。


彼は、海の壮大さと、友情の深さを、家族と共有し、世代を超えて伝えました。そして、海辺で育まれたユウタの姿は、今や海の守護者として語り継がれるようになりました。


そして、海は彼の心に残り、新たな冒険へと彼を導きました。

```

### <font color=green>Llama-3 8B等、他のモデルの生成結果は下記の記事を参照してください</font>

https://qiita.com/DeepTama/items/b17ac21010424de38c5f

# <font color=royalblue>おわりに</font>
GPU RAMが8G程度で動かせるモデルは良いですね。今回のPhi-3-miniモデルでは、１タスクですがそれなりの文章生成が行われているように思えます。また、Llama3-8Bでは明確に日本語で答えるように質問しないと英語で文章が生成されましたが、Phi-3-miniはきちんと日本語で答えてくれました😀（それなりに日本語も学習させている？）。