DeepSeekをオンプレミス環境でファインチューニングする方法

## はじめに

DeepSeekをオンプレミス環境で実装する方法については前回の記事で解説しましたが、本記事ではDeepSeekの事前学習済みモデルを追加データでファインチューニングする方法を詳細に解説します。これにより、特定のドメインに適したカスタマイズが可能となり、企業や研究機関での活用がより実用的になります。

---

## 1. 必要な環境と前提条件

ファインチューニングを行うには、高性能なGPU環境に加え、適切なライブラリのセットアップが必要です。

### 1.1 ハードウェア要件
- **NVIDIA A100 (80GB) x2 以上推奨**
- または **RTX 4090 / 3090 x2**
- **RAM:** 128GB 以上推奨（最低64GB）
- **ストレージ:** SSD 2TB以上（データセットとチェックポイント用）

### 1.2 ソフトウェア要件
- **OS:** Ubuntu 22.04 LTS
- **CUDA 12.2** および **cuDNN 8.6**
- **Python 3.10** 以上
- **PyTorch, Hugging Face Transformers, Accelerate, Datasets**

### 1.3 事前準備
```sh
conda create -n deepseek-finetune python=3.10
conda activate deepseek-finetune
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121
pip install transformers accelerate datasets bitsandbytes peft
```

---

## 2. データの準備

DeepSeekのファインチューニングには、独自のテキストデータセットを用意する必要があります。

### 2.1 データフォーマット
Hugging Faceの `datasets` ライブラリを使用するため、データは `json` または `csv` 形式で保存するのが望ましいです。

#### **JSON形式の例**
```json
[
  {"prompt": "AI技術の未来は？", "response": "AIは今後ますます発展し..."},
  {"prompt": "機械学習とは？", "response": "機械学習はデータを用いたアルゴリズムで..."}
]
```

### 2.2 データセットの読み込み
```python
from datasets import load_dataset

dataset = load_dataset("json", data_files={"train": "./data/train.json", "validation": "./data/valid.json"})
print(dataset)
```

---

## 3. モデルのロードと準備

事前学習済みのDeepSeekモデルをHugging Faceから取得します。

```python
from transformers import AutoModelForCausalLM, AutoTokenizer

model_name = "deepseek-ai/deepseek-llm-7b-base"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(model_name)
```

メモリ節約のために `bitsandbytes` を使用して低精度でロードすることも可能です。
```python
import torch
from transformers import BitsAndBytesConfig

quantization_config = BitsAndBytesConfig(load_in_8bit=True)
model = AutoModelForCausalLM.from_pretrained(model_name, quantization_config=quantization_config, device_map="auto")
```

---

## 4. ファインチューニングの実行

ファインチューニングには **LoRA (Low-Rank Adaptation)** を活用します。

### 4.1 LoRAのセットアップ
```python
from peft import LoraConfig, get_peft_model

lora_config = LoraConfig(
    r=8,
    lora_alpha=32,
    target_modules=["q_proj", "v_proj"],
    lora_dropout=0.05,
    bias="none"")
)

model = get_peft_model(model, lora_config)
model.print_trainable_parameters()
```

### 4.2 トレーニングの実行

Trainerを使用してトレーニングを実行します。
```python
from transformers import TrainingArguments, Trainer

training_args = TrainingArguments(
    output_dir="./deepseek_finetuned",
    per_device_train_batch_size=2,
    per_device_eval_batch_size=2,
    gradient_accumulation_steps=4,
    evaluation_strategy="steps",
    save_strategy="epoch",
    save_total_limit=2,
    learning_rate=2e-4,
    logging_dir="./logs",
    logging_steps=50,
    num_train_epochs=3,
    fp16=True,
    report_to="none"
)

trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=dataset["train"],
    eval_dataset=dataset["validation"]
)

trainer.train()
```

---

## 5. ファインチューニング後のモデルの保存と推論

### 5.1 チェックポイントの保存
```python
model.save_pretrained("./deepseek_finetuned")
tokenizer.save_pretrained("./deepseek_finetuned")
```

### 5.2 ファインチューニング済みモデルでの推論
```python
model_path = "./deepseek_finetuned"
tokenizer = AutoTokenizer.from_pretrained(model_path)
model = AutoModelForCausalLM.from_pretrained(model_path)

input_text = "ディープラーニングとは何ですか？"
input_ids = tokenizer(input_text, return_tensors="pt").input_ids
output = model.generate(input_ids, max_length=100)
print(tokenizer.decode(output[0], skip_special_tokens=True))
```

---

## 6. まとめ

本記事では、DeepSeekのオンプレミス環境でのファインチューニング手順を詳細に解説しました。

- 必要な環境とライブラリの準備
- データセットの作成とロード
- モデルの量子化によるメモリ最適化
- LoRAを利用した効率的なファインチューニング
- ファインチューニング後のモデル保存と推論

これらの手順を活用することで、DeepSeekをカスタマイズし、業務や研究に最適化されたモデルを構築できます。