Accelerate documentation

実験トラッカー

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v1.15.0).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

実験トラッカー

実験トラッキング用のAPIは数多く存在しますが、マルチプロセッシング環境でそれらをすべて動作させることは、しばしば複雑を極めます。 Accelerateは、スクリプト実行中に有用な項目を記録するために使用できる汎用のトラッキングAPIを提供しており、Accelerator.log()を通じて利用できます。

統合トラッカー

現在、Accelerateは8つのトラッカーを標準でサポートしています:

  • TensorBoard
  • WandB
  • Trackio
  • CometML
  • 目的
  • MLFlow
  • ClearML
  • DVCLive

それらのいずれかを使用するには、Accelerateのlog_withパラメータに選択した型を渡します:

from accelerate import Accelerator
from accelerate.utils import LoggerType

accelerator = Accelerator(log_with="all")  # For all available trackers in the environment
accelerator = Accelerator(log_with="wandb")
accelerator = Accelerator(log_with=["wandb", LoggerType.TENSORBOARD])

実験の開始時にAccelerator.init_trackers()を使用してプロジェクトを設定し、必要に応じて記録する実験ハイパーパラメータを追加します。

hps = {"num_iterations": 5, "learning_rate": 1e-2}
accelerator.init_trackers("my_project", config=hps)

データのログを記録する準備が整ったら、Accelerator.log()を使用してください。 stepを渡すことで、データをトレーニングループの特定のステップと関連付けることもできます。

accelerator.log({"train_loss": 1.12, "valid_loss": 0.8}, step=1)

トレーニングが完了したら、トラッカーに終了処理があれば実行できるように、Accelerator.end_training() を実行してください。

accelerator.end_training()

完全な例を以下に示します。

from accelerate import Accelerator

accelerator = Accelerator(log_with="all")
config = {
    "num_iterations": 5,
    "learning_rate": 1e-2,
    "loss_function": str(my_loss_function),
}

accelerator.init_trackers("example_project", config=config)

my_model, my_optimizer, my_training_dataloader = accelerator.prepare(my_model, my_optimizer, my_training_dataloader)
device = accelerator.device
my_model.to(device)

for iteration in range(config["num_iterations"]):
    for step, batch in enumerate(my_training_dataloader):
        my_optimizer.zero_grad()
        inputs, targets = batch
        inputs = inputs.to(device)
        targets = targets.to(device)
        outputs = my_model(inputs)
        loss = my_loss_function(outputs, targets)
        accelerator.backward(loss)
        my_optimizer.step()
        accelerator.log({"training_loss": loss}, step=step)
accelerator.end_training()

TensorBoard のように、データを保存するディレクトリが必要なトラッカーがある場合は、ディレクトリパスをproject_dirに渡します。project_dirパラメータは、ProjectConfigurationデータクラスで他の設定を組み合わせる場合に便利です。例えば、TensorBoardのデータをproject_dirに保存し、それ以外のすべてをlogging_dirパラメータでログに記録できます。[~utils.ProjectConfiguration:

accelerator = Accelerator(log_with="tensorboard", project_dir=".")

# use with ProjectConfiguration
config = ProjectConfiguration(project_dir=".", logging_dir="another/directory")
accelerator = Accelerator(log_with="tensorboard", project_config=config)

カスタムトラッカーの実装

Acceleratorで使用する新しいトラッカーを実装するには、GeneralTrackerクラスを実装することで作成できます。 すべてのトラッカーは、3つの関数を実装し、3つのプロパティを持つ必要があります。

  • __init__:

    • run_nameを保存し、統合ライブラリのトラッカーAPIを初期化する必要があります。
    • トラッカーがデータをローカルに保存する場合(TensorBoard など)、logging_dir パラメータを追加できます。
  • store_init_configuration:

    • values辞書を受け取り、それらをワンタイムの実験設定として保存する必要があります。
  • log:

    • values辞書とstepを受け取り、それらをランに記録する必要があります。
  • name (str):

    • の一意な文字列名。例えば、wandb trackerの場合は"wandb"などです。
    • これは、このトラッカーと特にやり取りするために使用されます
  • requires_logging_directory (bool):

    • この特定のトラッカーにlogging_dirが必要かどうか、またそれを使用しているかどうか。
  • tracker:

    • これは@property関数として実装されるべきです
    • wandbの場合はrunオブジェクトなど、ライブラリが使用する内部のトラッキング機構を返す必要があります。

各メソッドは、ロガーがメインプロセスでのみ実行されるべきである場合など、state.PartialState クラスも利用する必要があります。

Weights and Biasesとの統合を含む簡潔な例を以下に示します。関連する情報のみを含み、メインプロセスでのみログを出力します。

from accelerate.tracking import GeneralTracker, on_main_process
from typing import Optional

import wandb


class MyCustomTracker(GeneralTracker):
    name = "wandb"
    requires_logging_directory = False

    @on_main_process
    def __init__(self, run_name: str):
        self.run_name = run_name
        run = wandb.init(self.run_name)

    @property
    def tracker(self):
        return self.run.run

    @on_main_process
    def store_init_configuration(self, values: dict):
        wandb.config(values)

    @on_main_process
    def log(self, values: dict, step: Optional[int] = None):
        wandb.log(values, step=step)

Acceleratorオブジェクトの構築が準備できた時点で、トラッカーのインスタンスをAccelerator.log_withに渡すことで、APIで自動的に使用されるようになります:

tracker = MyCustomTracker("some_run_name")
accelerator = Accelerator(log_with=tracker)

これらは、"all"を含む既存のトラッカーと組み合わせることもできます:

tracker = MyCustomTracker("some_run_name")
accelerator = Accelerator(log_with=[tracker, "all"])

名前によるカスタムトラッカーの登録

インスタンスを渡す代わりに、カスタムトラッカークラスを登録することで、組み込みトラッカーと同様にnameで選択できるようになります。使用するトラッカーを設定ファイルやコマンドラインから読み込む場合に便利です。

from accelerate import Accelerator
from accelerate.tracking import GeneralTracker, register_tracker_class


class MyCustomTracker(GeneralTracker):
    name = "my_tracker"
    requires_logging_directory = False
    # ... implement the rest of the `GeneralTracker` interface


register_tracker_class(MyCustomTracker)
accelerator = Accelerator(log_with="my_tracker")

内部トラッカーへのアクセス

トラッカーとのカスタムな相互作用を直接行いたい場合、Accelerator.get_tracker() メソッドを使用して素早くアクセスできます。トラッカーの .name 属性に対応する文字列を渡すだけで、メインプロセスでそのトラッカーが返されます。

この例では、wandb を使用してこれを行う方法を示しています。

wandb_tracker = accelerator.get_tracker("wandb")

そこから、wandbのrunオブジェクトを通常どおり操作できます:

wandb_tracker.log_artifact(some_artifact_to_log)
Trackers built in Accelerate will automatically execute on the correct process, so if a tracker is only meant to be ran on the main process it will do so automatically.

Accelerateのラッピングを完全に削除したい場合は、…で同じ結果を得ることができます。

wandb_tracker = accelerator.get_tracker("wandb", unwrap=True)
if accelerator.is_main_process:
    wandb_tracker.log_artifact(some_artifact_to_log)

ラッパーが機能しない場合

Neptune.AIのように、全体を辞書として扱う厳密な.logのAPIを持たないライブラリの場合、if accelerator.is_main_processステートメントの下で手動でログを記録できます。

  from accelerate import Accelerator
+ import neptune

  accelerator = Accelerator()
+ run = neptune.init_run(...)

  my_model, my_optimizer, my_training_dataloader = accelerate.prepare(my_model, my_optimizer, my_training_dataloader)
  device = accelerator.device
  my_model.to(device)

  for iteration in config["num_iterations"]:
      for batch in my_training_dataloader:
          my_optimizer.zero_grad()
          inputs, targets = batch
          inputs = inputs.to(device)
          targets = targets.to(device)
          outputs = my_model(inputs)
          loss = my_loss_function(outputs, targets)
          total_loss += loss
          accelerator.backward(loss)
          my_optimizer.step()
+         if accelerator.is_main_process:
+             run["logs/training/batch/loss"].log(loss)
Update on GitHub