3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

🚀 「未来のAI: DeepSeek-R1-Distill-Qwen-1.5Bの最先端ファインチューニング完全ガイド」

Last updated at Posted at 2025-02-03

LLMのファインチューニング: DeepSeek-R1-Distill-Qwen-1.5Bの詳細ガイド

image.png

LLM(大規模言語モデル)のファインチューニングにより、特定のタスクでのパフォーマンスを大幅に向上させることができます。本ガイドでは、Google Colab、Hugging Faceのtransformersdatasets、および8ビット量子化をサポートするbitsandbytesを使用して、DeepSeek-R1-Distill-Qwen-1.5Bモデルをファインチューニングする方法を説明します。また、wandbを使用して実験を追跡します。


ステップ1: 環境のセットアップ

まず、必要なライブラリをインストールします:

!pip install transformers datasets sympy wandb
!pip install --no-cache-dir bitsandbytes

これらのライブラリは、モデルのロード、データセットの処理、効率的なファインチューニング、および実験の追跡に必要です。


ステップ2: モデルとトークナイザーのセットアップ

DeepSeek-R1-Distill-Qwen-1.5Bモデルとトークナイザーをロードします:

import torch
from transformers import AutoTokenizer, AutoModelForCausalLM

model_name = "deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B"

# トークナイザーをロード
tokenizer = AutoTokenizer.from_pretrained(model_name)

# モデルをロードし、GPUに移動
model = AutoModelForCausalLM.from_pretrained(model_name).to("cuda")

print("モデルがGPUにロードされました。")

ステップ3: WandBを使用した実験トラッキングのセットアップ

まず、Weights & Biases(WandB)にログインします:

!wandb login

プロジェクトを初期化します:

import wandb
wandb.init(
    project="My_LLM",
    config={
        "learning_rate": 5e-5,
        "architecture": "DeepSeek-R1-Distill-Qwen-1.5B",
        "dataset": "dataset.jsonl",
        "epochs": 2,
    }
)

ステップ4: データセットの準備

Google Driveのマウント

from google.colab import drive
drive.mount('/content/drive')

データセットをGoogle Driveに保存しておく必要があります。

データセットのロードと分割

from datasets import load_dataset

dataset = load_dataset("json", data_files={"train": "/content/drive/My Drive/dataset.jsonl"}, split="train")
print(f"データセットがロードされました: {len(dataset)} サンプル")

train_test_split = dataset.train_test_split(test_size=0.2)
train_dataset = train_test_split["train"]
eval_dataset = train_test_split["test"]

80%をトレーニング用、20%を評価用に分割します。

トークナイゼーション

def tokenize_function(examples):
    combined_texts = [f"{prompt}\n{completion}" for prompt, completion in zip(examples["prompt"], examples["completion"])]
    tokenized = tokenizer(combined_texts, truncation=True, max_length=512, padding="max_length")
    tokenized["labels"] = tokenized["input_ids"].copy()
    return tokenized

tokenized_train_dataset = train_dataset.map(tokenize_function, batched=True)
tokenized_eval_dataset = eval_dataset.map(tokenize_function, batched=True)

ステップ5: 8ビット量子化によるモデルのロード

from transformers import BitsAndBytesConfig

quantization_config = BitsAndBytesConfig(load_in_8bit=True)
model = AutoModelForCausalLM.from_pretrained(model_name, quantization_config=quantization_config, device_map="auto")
print("モデルが8ビット量子化でGPUにロードされました。")

ステップ6: LoRAによるファインチューニングの設定

from peft import get_peft_model, LoraConfig, TaskType

lora_config = LoraConfig(
    r=8, lora_alpha=16, lora_dropout=0.05, task_type=TaskType.CAUSAL_LM
)
model = get_peft_model(model, lora_config)
model.print_trainable_parameters()

ステップ7: トレーニングの設定

from transformers import TrainingArguments, Trainer

training_args = TrainingArguments(
    output_dir="./deepseek_finetuned",
    num_train_epochs=50,
    per_device_train_batch_size=2,
    gradient_accumulation_steps=16,
    fp16=True,
    logging_steps=10,
    save_steps=100,
    evaluation_strategy="steps",
    eval_steps=10,
    learning_rate=3e-5,
    logging_dir="./logs",
    report_to="wandb",
    run_name="DeepSeek_FineTuning_Experiment",
)

trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=tokenized_train_dataset,
    eval_dataset=tokenized_eval_dataset,
)

trainer.train()
CONSOLE OUTPUT
Dataset loaded: 44 samples
Map: 100%
 35/35 [00:00<00:00, 230.76 examples/s]
Map: 100%
 9/9 [00:00<00:00, 131.62 examples/s]Train dataset: 35 samplesEval dataset: 9 samplesModel loaded with 8-bit quantization on GPU...
trainable params: 1,572,864 || all params: 1,348,044,800 || trainable%: 0.1167
/usr/local/lib/python3.11/dist-packages/transformers/training_args.py:1575: FutureWarning: `evaluation_strategy` is deprecated and will be removed in version 4.46 of 🤗 Transformers. Use `eval_strategy` instead
  warnings.warn(
🚀 Starting fine-tuning with LoRA (this may take longer)...
 [50/50 03:44, Epoch 25/50]
Step	Training Loss	Validation Loss
10	6.150900	5.066065
20	3.964500	2.904839
30	2.126500	1.420464
40	1.043100	0.748976
50	0.655800	0.601017


Run history:

eval/loss	█▅▂▁▁
eval/runtime	▁▂▂█▄
eval/samples_per_second	█▇▇▁▅
eval/steps_per_second	█▇▇▁▅
train/epoch	▁▁▃▃▅▅▆▆███
train/global_step	▁▁▃▃▅▅▆▆███
train/grad_norm	▇█▆▃▁
train/learning_rate	█▆▅▃▁
train/loss	█▅▃▁▁

Run summary:

eval/loss	0.60102
eval/runtime	0.91
eval/samples_per_second	9.89
eval/steps_per_second	2.198
total_flos	3445974368256000.0
train/epoch	25
train/global_step	50
train/grad_norm	7.78652
train/learning_rate	0
train/loss	0.6558
train_loss	2.78817
train_runtime	232.9563
train_samples_per_second	7.512
train_steps_per_second	0.215

View run DeepSeek_FineTuning_Experiment at: https://wandb.ai/roboken-akash-/DeepSeek_FineTuning/runs/7b8v92nq
View project at: https://wandb.ai/roboken-akash-/DeepSeek_FineTuning
Synced 5 W&B file(s), 0 media file(s), 0 artifact file(s) and 0 other file(s)
Find logs at: ./wandb/run-20250203_054404-7b8v92nq/logs
Training completed successfully!

📊 トレーニング結果の解析

image.png

指標
総トレーニングステップ 50
完了エポック数 25 / 50
最終トレーニング損失 0.6558
最終バリデーション損失 0.6010
初期トレーニング損失 6.1509
初期バリデーション損失 5.0660
勾配ノルム 7.78
学習率減衰 あり(最終 LR = 0)
1秒あたりのサンプル数 7.51(トレーニング) / 9.89(評価)
1秒あたりのステップ数 0.215

📉 損失曲線の分析

トレーニング損失の推移

  • 6.15 → 0.6558 という順調な低下。
  • 急激な下降なし = 安定した学習プロセス。

バリデーション損失の推移

  • 5.06 → 0.6010 まで減少。
  • トレーニング損失との差が小さい ため、過学習(オーバーフィッティング)の兆候なし
  • 学習が進むにつれて一般化性能が向上 したと考えられる。

勾配ノルム (7.78) は適正範囲内

  • 20 以上 → 勾配爆発のリスク → なし
  • 1 以下 → 学習不足の可能性 → なし
  • 適正な値(7.78) なので、安定した学習 ができている。

🛠 改善点と次のステップ

🚀 ① エポック数を増やす(50→75 or 100)

  • 35 サンプルではデータ量が少ないため、追加のエポックでさらなる改善が期待できる
  • num_train_epochs=75 または 100 で試すのも良い。

🚀 ② データの増強(Data Augmentation)

  • データセットが 44 サンプルと少ないため、データを増やすことで性能向上が可能
  • 例えば:
    • 入力データのノイズ追加
    • 同義語置換によるテキスト拡張
    • データ収集を増やす

🚀 ③ 学習率 (learning_rate) の最適化

  • 学習率が 0 まで減衰してしまった ため、学習の進行が止まった可能性がある。
  • 低めの初期学習率 (2e-5 など) で 新しいトレーニングを実施 してみるのも良い。

🚀 ④ モデルの推論をテストする

  • 実際にモデルをテストして、期待通りの出力が得られるか確認 する。
  • 精度のチェックのため、未学習のデータで評価 するのが重要。

🔥 結論:トレーニングは成功!

損失値の低下が確認できる
過学習の兆候なし
学習率の調整でさらなる改善が可能
データ量が少ないため、追加の学習が有効


ステップ8: ファインチューニング済みモデルの保存

save_path = "/content/drive/My Drive/deepseek_finetuned"
model.save_pretrained(save_path)
tokenizer.save_pretrained(save_path)
print(f"ファインチューニング済みモデルが保存されました: {save_path}")

ステップ9: LoRAをベースモデルと統合

from peft import PeftModel

base_model = AutoModelForCausalLM.from_pretrained(model_name)
model = PeftModel.from_pretrained(base_model, save_path)
model = model.merge_and_unload()

final_save_path = "/content/drive/My Drive/deepseek_finetuned_full"
model.save_pretrained(final_save_path)
tokenizer.save_pretrained(final_save_path)
print(f"統合されたモデルが保存されました: {final_save_path}")

ステップ10: ファインチューニング済みモデルのロード

model = AutoModelForCausalLM.from_pretrained(final_save_path)
tokenizer = AutoTokenizer.from_pretrained(final_save_path)

モデルがデプロイの準備が整いました。

この手順を使えば、LLMを効率的にファインチューニングできます!

🚀 次のステップとして、モデルのテストを試してみませんか? 🔥

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?