fastai

もしあなたが fastai を使ってモデルを訓練しているなら、W&B には WandbCallback を使用した簡単なインテグレーションがあります。インタラクティブなドキュメントと例についてはこちらをご覧ください →

登録と APIキー の作成

APIキー は、あなたのマシンを W&B に認証します。APIキー は、ユーザープロフィールから生成できます。

  1. 右上のユーザープロフィールアイコンをクリックします。
  2. User Settings を選択し、API Keys セクションまでスクロールします。
  3. Reveal をクリックします。表示された APIキー をコピーします。APIキー を非表示にするには、ページを再読み込みしてください。

wandb ライブラリのインストールとログイン

wandb ライブラリをローカルにインストールしログインするには:

  1. WANDB_API_KEY 環境変数 をあなたの APIキー に設定します。

    export WANDB_API_KEY=<your_api_key>
    
  2. wandb ライブラリをインストールしログインします。

    pip install wandb
    
    wandb login
    
pip install wandb
import wandb
wandb.login()
!pip install wandb

import wandb
wandb.login()

learner または fit メソッドに WandbCallback を追加する

import wandb
from fastai.callback.wandb import *

# wandb run を開始してログをとる
wandb.init(project="my_project")

# トレーニングフェーズの一部のみログする場合
learn.fit(..., cbs=WandbCallback())

# すべてのトレーニングフェーズで継続的にログをとる場合
learn = learner(..., cbs=WandbCallback())

WandbCallback 引数

WandbCallback は以下の引数を受け入れます:

Args 説明
log モデルをログするかどうか: gradientsparameters, all 、または None (デフォルト)。損失とメトリクスは常にログされます。
log_preds 予測サンプルをログしたいかどうか (デフォルトは True)。
log_preds_every_epoch 予測をエポックごとにログするか、最後にログするか (デフォルトは False)
log_model モデルをログしたいかどうか (デフォルトは False)。これには SaveModelCallback も必要です。
model_name 保存する file の名前、SaveModelCallback をオーバーライドします。
log_dataset
  • False (デフォルト)
  • True は learn.dls.path が参照するフォルダをログします。
  • ログするフォルダを参照するパスを明示的に定義できます。

注: サブフォルダ “models” は常に無視されます。

dataset_name ログされたデータセットの名前 (デフォルトは フォルダ名)。
valid_dl 予測サンプルに使用する DataLoaders (デフォルトは learn.dls.valid からランダムなアイテム)
n_preds ログする予測の数 (デフォルトは 36)。
seed ランダムサンプルを定義するために使用します。

カスタムワークフローのために、データセットとモデルを手動でログすることができます:

  • log_dataset(path, name=None, metadata={})
  • log_model(path, name=None, metadata={})

注: サブフォルダ “models” は無視されます。

分散トレーニング

fastai はコンテキストマネージャー distrib_ctx を使用して分散トレーニングをサポートしています。W&B はこれを自動的にサポートし、マルチGPU実験をすぐにトラッキングできるようにします。

この簡単な例を確認してください:

import wandb
from fastai.vision.all import *
from fastai.distributed import *
from fastai.callback.wandb import WandbCallback

wandb.require(experiment="service")
path = rank0_first(lambda: untar_data(URLs.PETS) / "images")

def train():
    dls = ImageDataLoaders.from_name_func(
        path,
        get_image_files(path),
        valid_pct=0.2,
        label_func=lambda x: x[0].isupper(),
        item_tfms=Resize(224),
    )
    wandb.init("fastai_ddp", entity="capecape")
    cb = WandbCallback()
    learn = vision_learner(dls, resnet34, metrics=error_rate, cbs=cb).to_fp16()
    with learn.distrib_ctx(sync_bn=False):
        learn.fit(1)

if __name__ == "__main__":
    train()

そして、ターミナルで以下を実行します:

$ torchrun --nproc_per_node 2 train.py

この場合、マシンには 2 つの GPU があります。

ノートブック内で直接分散トレーニングを実行することができます。

import wandb
from fastai.vision.all import *

from accelerate import notebook_launcher
from fastai.distributed import *
from fastai.callback.wandb import WandbCallback

wandb.require(experiment="service")
path = untar_data(URLs.PETS) / "images"

def train():
    dls = ImageDataLoaders.from_name_func(
        path,
        get_image_files(path),
        valid_pct=0.2,
        label_func=lambda x: x[0].isupper(),
        item_tfms=Resize(224),
    )
    wandb.init("fastai_ddp", entity="capecape")
    cb = WandbCallback()
    learn = vision_learner(dls, resnet34, metrics=error_rate, cbs=cb).to_fp16()
    with learn.distrib_ctx(in_notebook=True, sync_bn=False):
        learn.fit(1)

notebook_launcher(train, num_processes=2)

メインプロセスのみでログを取る

上記の例では、wandb はプロセスごとに1 つの run を起動します。トレーニングの終了時には、2 つの run ができます。これが混乱を招くこともあり、メインプロセスだけでログを取りたい場合があります。そのためには、手動でどのプロセスにいるかを検出し、他のプロセスでは run (すなわち wandb.init の呼び出し) を作成しないようにする必要があります。

import wandb
from fastai.vision.all import *
from fastai.distributed import *
from fastai.callback.wandb import WandbCallback

wandb.require(experiment="service")
path = rank0_first(lambda: untar_data(URLs.PETS) / "images")

def train():
    cb = []
    dls = ImageDataLoaders.from_name_func(
        path,
        get_image_files(path),
        valid_pct=0.2,
        label_func=lambda x: x[0].isupper(),
        item_tfms=Resize(224),
    )
    if rank_distrib() == 0:
        run = wandb.init("fastai_ddp", entity="capecape")
        cb = WandbCallback()
    learn = vision_learner(dls, resnet34, metrics=error_rate, cbs=cb).to_fp16()
    with learn.distrib_ctx(sync_bn=False):
        learn.fit(1)

if __name__ == "__main__":
    train()

ターミナルで以下を実行します:

$ torchrun --nproc_per_node 2 train.py
import wandb
from fastai.vision.all import *

from accelerate import notebook_launcher
from fastai.distributed import *
from fastai.callback.wandb import WandbCallback

wandb.require(experiment="service")
path = untar_data(URLs.PETS) / "images"

def train():
    cb = []
    dls = ImageDataLoaders.from_name_func(
        path,
        get_image_files(path),
        valid_pct=0.2,
        label_func=lambda x: x[0].isupper(),
        item_tfms=Resize(224),
    )
    if rank_distrib() == 0:
        run = wandb.init("fastai_ddp", entity="capecape")
        cb = WandbCallback()
    learn = vision_learner(dls, resnet34, metrics=error_rate, cbs=cb).to_fp16()
    with learn.distrib_ctx(in_notebook=True, sync_bn=False):
        learn.fit(1)

notebook_launcher(train, num_processes=2)