🐙

Minitron-4B系もUnslothでfinetuningできる

2024/09/19に公開

こんにちは!クロガネです。
最近、小さめのモデルが意外と賢いことに気が付き、触り始めたのでfinetuning周りを共有します。

Minitron-4B-width系

nvidia/Llama-3.1-Minitron-4B-Width-BaseはnVidiaが開発した小型モデルです。

llama-3.1-8Bをpruning+蒸留したモデルです。テクニカルレポートを読む限り、nvidia/Minitron-4B-Baseと比べてGSM8Kのスコアが高い(Baseが24.1、Widthが41.2)ようです。

今回はMagpie-Align/MagpieLM-4B-Chat-v0.1を使用します。
また、finetuningができていることを確認するために、chatフォーマットの異なるalpacaフォーマットのまま学習させます。

学習させたモデルはここからDLできます。
kurogane/MagpieLM-4B-Chat-v0.1-alpaca-cleaned-ja

【注】transformers、のアップデートが必要

自環境ではMinitron-4B-width系のモデルの読み込みのために、以下のアップデートが必要でした。

  • transformers-4.45.0.dev0
  • accelerate-0.34.2

transformersは現時点(9/18)ではソースからアップデートしてあげる必要がありました。
モデルの読み込みに必要です。

pip install git+https://github.com/huggingface/transformers

また、accelerateはUnslothでの学習時に以下のエラーが出たためです。

AttributeError: 'AdamW' object has no attribute 'train'

https://github.com/QwenLM/Qwen2-VL/issues/163 を参照すると、以下の通り、update LLaMA Factory and accelerate to 0.34.0と書かれていたためです。
https://github.com/hiyouga/LLaMA-Factory/issues/5400

こちらはこれらのアップデート後、Unslothのノートブックmodel_name"Magpie-Align/MagpieLM-4B-Chat-v0.1に置き換えてあげるだけです。

Unslothのノートブックデフォルトのmax_steps = 60,で学習させてみました。
データセットもデフォルトの通りyahma/alpaca-cleanedです。
RTX a6000で約1分半でした。

100%|██████████| 60/60 [01:23<00:00,  1.39s/it]
{'train_runtime': 83.4627, 'train_samples_per_second': 5.751, 'train_steps_per_second': 0.719, 'train_loss': 1.0135845323403676, 'epoch': 0.01}

ピークの消費メモリが11GBなのでRTX3060でもローカルで動かすことができるかもしれません。

83.4627 seconds used for training.
1.39 minutes used for training.
Peak reserved memory = 11.314 GB.
Peak reserved memory for training = 0.0 GB.
Peak reserved memory % of max memory = 23.808 %.
Peak reserved memory for training % of max memory = 0.0 %.

shi3z/alpaca_cleaned_ja_json全体で学習させた例はこちらです。
別にバッチサイズを変えてないので、VRAMの使用量は変わリませんでした。

7062.299 seconds used for training.
117.7 minutes used for training.
Peak reserved memory = 11.314 GB.
Peak reserved memory for training = 0.0 GB.
Peak reserved memory % of max memory = 23.808 %.
Peak reserved memory for training % of max memory = 0.0 %.

(学習してるとA6000が80℃台になるのどうにかしたい…)

Wed Sep 18 22:49:35 2024       
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 550.107.02             Driver Version: 550.107.02     CUDA Version: 12.4     |
|-----------------------------------------+------------------------+----------------------+
| GPU  Name                 Persistence-M | Bus-Id          Disp.A | Volatile Uncorr. ECC |
| Fan  Temp   Perf          Pwr:Usage/Cap |           Memory-Usage | GPU-Util  Compute M. |
|                                         |                        |               MIG M. |
|=========================================+========================+======================|
|   0  NVIDIA RTX A6000               Off |   00000000:01:00.0  On |                  Off |
| 63%   84C    P2            292W /  300W |   16083MiB /  49140MiB |     94%      Default |
|                                         |                        |                  N/A |
+-----------------------------------------+------------------------+----------------------+
|   1  NVIDIA RTX A2000 12GB          Off |   00000000:02:00.0 Off |                  Off |
| 30%   33C    P8             10W /   70W |      12MiB /  12282MiB |      0%      Default |
|                                         |                        |                  N/A |
+-----------------------------------------+------------------------+----------------------+
                                                                                         
+-----------------------------------------------------------------------------------------+
| Processes:                                                                              |
|  GPU   GI   CI        PID   Type   Process name                              GPU Memory |
|        ID   ID                                                               Usage      |
|=========================================================================================|
|    0   N/A  N/A     11918      G   /usr/lib/xorg/Xorg                            282MiB |
|    0   N/A  N/A     12074    C+G   ...libexec/gnome-remote-desktop-daemon        264MiB |
|    0   N/A  N/A     12129      G   /usr/bin/gnome-shell                          224MiB |
|    0   N/A  N/A     12547      G   /usr/libexec/gnome-initial-setup                4MiB |
|    0   N/A  N/A     13339      G   ...yOnDemand --variations-seed-version         51MiB |
|    0   N/A  N/A     13795      G   ...irefox/4848/usr/lib/firefox/firefox        807MiB |
|    0   N/A  N/A     13838      G   ...erProcess --variations-seed-version        103MiB |
|    0   N/A  N/A     53959      C   ...e/anaconda3/envs/llmfact/bin/python       3374MiB |
|    0   N/A  N/A     61570      C   ...e/anaconda3/envs/llmfact/bin/python       4880MiB |
|    0   N/A  N/A   2581221      G   gnome-control-center                            4MiB |
|    0   N/A  N/A   2583312      C   ...e/anaconda3/envs/llmfact/bin/python       6020MiB |
|    1   N/A  N/A     11918      G   /usr/lib/xorg/Xorg                              4MiB |
+-----------------------------------------------------------------------------------------+

学習結果のモデル

以下にアップロードしています。

https://huggingface.co/kurogane/MagpieLM-4B-Chat-v0.1-alpaca-cleaned-ja

以下のコードにて動作確認できます。

from transformers import AutoTokenizer, AutoModelForCausalLM
import torch

model_name = "kurogane/MagpieLM-4B-Chat-v0.1-alpaca-cleaned-ja"

# トークナイザーの読み込み
tokenizer = AutoTokenizer.from_pretrained(
        model_name,
    )

# モデルの読み込み
model = AutoModelForCausalLM.from_pretrained(
        model_name, 
        torch_dtype=torch.float16,
        # trust_remote_code=True,
    )
model = model.to('cuda')

alpaca_prompt = """Below is an instruction that describes a task, paired with an input that provides further context. Write a response that appropriately completes the request.

### Instruction:
{}

### Input:
{}

### Response:
{}"""

promtp_ = alpaca_prompt.format(
    "Continue the fibonnaci sequence.", # instruction
    "1, 1, 2, 3, 5, 8", # input
    "", # output - leave this blank for generation!
)


inputs = tokenizer(
        [
            alpaca_prompt.format(
                "以下のフィボナッチ数列の続きを書いてください。", # instruction
                "1, 1, 2, 3, 5, 8", # input
                "", # output - leave this blank for generation!
            )
        ], 
        add_special_tokens=False ,
        return_tensors = "pt",
    ).to("cuda")


outputs = model.generate(**inputs, max_new_tokens=256)
print(tokenizer.decode(outputs[0]))

以下のような結果になります。

Below is an instruction that describes a task, paired with an input that provides further context. Write a response that appropriately completes the request.

### Instruction:
以下のフィボナッチ数列の続きを書いてください。

### Input:
1, 1, 2, 3, 5, 8

### Response:
13、21、34、55、89、144、233、377、610、987
<|end_of_text|>

念の為、finetuning前の状態だと以下のような回答となりました。

Below is an instruction that describes a task, paired with an input that provides further context. Write a response that appropriately completes the request.

### Instruction:
以下のフィボナッチ数列の続きを書いてください。

### Input:
1, 1, 2, 3, 5, 8

### Response:
次の数列の続きは 13, 21, 34, 55, 89 です。
Answer: 次の数列の続きは 13, 21, 34, 55, 89 です。<|end_of_text|>

finetuning後だとalpacaフォーマットに従っていることがわかりますね。

感想

以上です。お疲れ様でした。

元のMinitron-4B-Width-Base自体がまあまあ賢かったところから、Magpieの合成データセットを使用することでより性能が向上したMagpieLM-4B-Chat-v0.1が気になったので、とりあえずfinetuningをしてみました。
ライブラリの柔軟性のおかげですね。

念の為、MagpieLM-4B-Chat-v0.1はデータセットがカオスなので、要確認です。
Meta Llama 3.1 Community LicenseGemma Licenseが混在している形で使われています。
そのため、商用利用自体は可能かと思われますが、諸々の縛りがあるような気がするので十分に気をつけてください。

それでは、クロガネでした!

良かったらいいねやコメント、フォローなどもぜひ!

Discussion