# 最後のチェックポイントからのファインチューニング

次に編集する必要があるのは `Trainer` 最初に追加するために `save_strategy` および `save_steps`。以下はチェックポイントを50ステップごとにフォルダに保存します `outputs`.

```python
trainer = SFTTrainer(
    ....
    args = TrainingArguments(
        ....
        output_dir = "outputs",
        save_strategy = "steps",
        save_steps = 50,
    ),
)
```

その後、trainerでは次を行います：

```python
trainer_stats = trainer.train(resume_from_checkpoint = True)
```

これにより最新のチェックポイントから開始して学習を継続します。

### Wandb 統合

```
# ライブラリをインストール
!pip install wandb --upgrade

# Wandb の設定
!wandb login <token>

import os

os.environ["WANDB_PROJECT"] = "<name>"
os.environ["WANDB_LOG_MODEL"] = "checkpoint"
```

次に `TrainingArguments()` に設定します

```
report_to = "wandb",
logging_steps = 1, # 必要に応じて変更
save_steps = 100 # 必要に応じて変更
run_name = "<name>" # （オプション）
```

モデルをトレーニングするには、次を実行します `trainer.train()`；トレーニングを再開するには、次を実行します

```
import wandb
run = wandb.init()
artifact = run.use_artifact('<username>/<Wandb-project-name>/<run-id>', type='model')
artifact_dir = artifact.download()
trainer.train(resume_from_checkpoint=artifact_dir)
```

## :question:早期終了（Early Stopping）はどう行いますか？

評価損失が減少していないためにファインチューニング／トレーニングを停止または一時停止したい場合、トレーニングを停止する早期終了を使用できます。次を使用します `EarlyStoppingCallback`.

通常どおり trainer と評価用データセットを設定します。以下は、 `eval_loss` （評価損失）が約3ステップ後に減少しない場合にトレーニングを停止するために使用されます。

```python
from trl import SFTConfig, SFTTrainer
trainer = SFTTrainer(
    args = SFTConfig(
        fp16_full_eval = True,
        per_device_eval_batch_size = 2,
        eval_accumulation_steps = 4,
        output_dir = "training_checkpoints", # 早期終了用に保存されたチェックポイントの場所
        save_strategy = "steps",             # Nステップごとにモデルを保存
        save_steps = 10,                     # モデルを保存するまでのステップ数
        save_total_limit = 3,                # ディスク容量を節約するために保存するチェックポイントを3つだけ保持
        eval_strategy = "steps",             # Nステップごとに評価
        eval_steps = 10,                     # 評価を行うまでのステップ数
        load_best_model_at_end = True,       # 早期終了には必ず使用すること
        metric_for_best_model = "eval_loss", # 早期終了に用いる指標
        greater_is_better = False,           # 評価損失が低いほど良い
    ),
    model = model,
    tokenizer = tokenizer,
    train_dataset = new_dataset["train"],
    eval_dataset = new_dataset["test"],
)
```

次にコールバックを追加します。コールバックはカスタマイズも可能です：

```python
from transformers import EarlyStoppingCallback
early_stopping_callback = EarlyStoppingCallback(
    early_stopping_patience = 3,     # 評価損失が減少しない場合に待つステップ数
                                     # 例えば損失が増加することもあるが、3ステップ後に減少するかもしれない
    early_stopping_threshold = 0.0,  # より高く設定可能 - どれだけ損失が減少すれば
                                     # 早期終了とみなすかを設定します。例えば0.01は損失が
                                     # 0.02から0.01になった場合に実行を早期終了することを意味します。
)
trainer.add_callback(early_stopping_callback)
```

その後、通常どおり次でモデルを訓練します `trainer.train() 。`
