Accelerate documentation
Pelacak eksperimen
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_namedan menginisialisasi API pelacak dari pustaka terintegrasi. - Jika pelacak menyimpan data secara lokal (seperti TensorBoard), parameter
logging_dirdapat ditambahkan.
- Harus menyimpan
store_init_configuration:- Harus menerima kamus
valuesdan menyimpannya sebagai konfigurasi eksperimen sekali jalan
- Harus menerima kamus
log:- Harus menerima kamus
valuesdanstep, dan harus mencatatnya ke dalam run
- Harus menerima kamus
name(str):- Nama string unik untuk pelacak, seperti
"wandb"untuk pelacak wandb. - Ini akan digunakan untuk berinteraksi dengan pelacak ini secara khusus
- Nama string unik untuk pelacak, seperti
requires_logging_directory(bool):- Apakah
logging_dirdiperlukan untuk tracker tertentu ini dan apakah tracker tersebut menggunakannya.
- Apakah
tracker:- Ini harus diimplementasikan sebagai fungsi
@property - Harus mengembalikan mekanisme pelacakan internal yang digunakan pustaka, seperti objek
rununtukwandb.
- Ini harus diimplementasikan sebagai fungsi
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)