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에 저장하고 나머지는 [~utils.ProjectConfiguration의 logging_dir 매개변수에 기록할 수 있습니다:

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 클래스를 구현하여 만들 수 있습니다. 모든 트래커는 세 가지 함수를 구현하고 세 가지 속성을 가져야 합니다:

  • __init__:

    • run_name를 저장하고 통합된 라이브러리의 트래커 API를 초기화해야 합니다.
    • 트래커가 데이터를 로컬에 저장하는 경우(예: TensorBoard), logging_dir 매개변수를 추가할 수 있습니다.
  • store_init_configuration:

    • values 딕셔너리를 입력받아 일회성 실험 구성으로 저장해야 합니다
  • log:

    • values 사전과 step을 입력으로 받아 실행에 기록해야 합니다
  • name (str):

    • wandb 트래커의 경우 "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