Accelerate documentation
실험 트래커
실험 트래커
다양한 실험 추적 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"와 같이 트래커에 대한 고유한 문자열 이름 - 이것은 이 트래커와 상호 작용하는 데 구체적으로 사용됩니다
- 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)