Accelerate documentation

Pelacak eksperimen

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

Pelacak eksperimen

Tersedia banyak API pelacakan eksperimen, namun membuat semuanya berfungsi di lingkungan multi-prosesing sering kali kompleks. Accelerate menyediakan API pelacakan umum yang dapat digunakan untuk mencatat item berguna selama skrip Anda melalui Accelerator.log()

Pelacak Terintegrasi

Saat ini Accelerate mendukung delapan pelacak secara bawaan:

  • TensorBoard
  • WandB
  • Trackio
  • CometML
  • Tujuan
  • MLFlow
  • ClearML
  • DVCLive

Untuk menggunakan salah satunya, masukkan tipe yang dipilih ke parameter log_with di Accelerate:

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])

Di awal eksperimen Anda, Accelerator.init_trackers() harus digunakan untuk mengatur proyek Anda, dan secara potensial menambahkan hiperparameter eksperimen apa pun yang akan dicatat:

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

Saat Anda siap untuk mencatat data apa pun, gunakan Accelerator.log(). Sebuah step juga dapat diteruskan untuk mengaitkan data dengan langkah tertentu dalam loop pelatihan.

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

Setelah Anda selesai melatih, pastikan untuk menjalankan Accelerator.end_training() agar semua pelacak dapat menjalankan fungsi penutupannya, jika ada.

accelerator.end_training()

Contoh lengkapnya ada di bawah ini:

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()

Jika pelacak memerlukan direktori untuk menyimpan data, seperti TensorBoard, maka berikan jalur direktori ke project_dir. Parameter project_dir berguna ketika ada konfigurasi lain yang harus digabungkan dalam kelas data ProjectConfiguration. Misalnya, Anda dapat menyimpan data TensorBoard ke project_dir dan semua hal lainnya dapat dicatat dalam parameter logging_dir dari [~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)

Implementasi Pelacak Kustom

Untuk mengimplementasikan pelacak baru yang akan digunakan di Accelerator, pelacak baru dapat dibuat dengan mengimplementasikan kelas GeneralTracker. Setiap pelacak harus mengimplementasikan tiga fungsi dan memiliki tiga properti:

  • __init__:

    • Harus menyimpan run_name dan menginisialisasi API pelacak dari pustaka terintegrasi.
    • Jika pelacak menyimpan data secara lokal (seperti TensorBoard), parameter logging_dir dapat ditambahkan.
  • store_init_configuration:

    • Harus menerima kamus values dan menyimpannya sebagai konfigurasi eksperimen sekali jalan
  • log:

    • Harus menerima kamus values dan step, dan harus mencatatnya ke dalam run
  • name (str):

    • Nama string unik untuk pelacak, seperti "wandb" untuk pelacak wandb.
    • Ini akan digunakan untuk berinteraksi dengan pelacak ini secara khusus
  • requires_logging_directory (bool):

    • Apakah logging_dir diperlukan untuk tracker tertentu ini dan apakah tracker tersebut menggunakannya.
  • tracker:

    • Ini harus diimplementasikan sebagai fungsi @property
    • Harus mengembalikan mekanisme pelacakan internal yang digunakan pustaka, seperti objek run untuk wandb.

Setiap metode juga sebaiknya memanfaatkan kelas state.PartialState jika logger hanya harus dieksekusi pada proses utama, misalnya.

Contoh singkat dapat dilihat di bawah ini dengan integrasi Weights and Biases, yang hanya berisi informasi yang relevan dan melakukan pencatatan hanya pada proses utama:

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)

Saat Anda siap membangun objek Accelerator, berikan instance dari tracker Anda ke Accelerator.log_with agar secara otomatis digunakan dengan API:

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

Ini juga dapat dicampur dengan pelacak yang sudah ada, termasuk dengan "all":

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

Mendaftarkan pelacak kustom berdasarkan nama

Alih-alih meneruskan sebuah instance, Anda dapat mendaftarkan kelas pelacak kustom sehingga dapat dipilih berdasarkan name-nya, sama seperti pelacak bawaan. Hal ini berguna ketika pelacak yang akan digunakan dibaca dari file konfigurasi atau baris perintah:

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")

Mengakses pelacak internal

Jika interaksi kustom langsung dengan pelacak mungkin diinginkan, Anda dapat dengan cepat mengaksesnya menggunakan metode Accelerator.get_tracker(). Cukup lewati string yang sesuai dengan atribut .name dari pelacak tersebut dan metode ini akan mengembalikan pelacak tersebut pada proses utama.

Contoh ini menunjukkan cara melakukannya dengan wandb:

wandb_tracker = accelerator.get_tracker("wandb")

Dari sana, Anda dapat berinteraksi dengan objek run dari wandb seperti biasa:

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.

Jika Anda ingin benar-benar menghapus pembungkus Accelerate sepenuhnya, Anda dapat mencapai hasil yang sama dengan:

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

Ketika wrapper tidak dapat berfungsi

Jika sebuah pustaka memiliki API yang tidak mengikuti .log ketat dengan kamus keseluruhan seperti Neptune.AI, pencatatan log dapat dilakukan secara manual di bawah pernyataan 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