Accelerate documentation
متتبعات التجارب
متتبعات التجارب
تتوفر مجموعة كبيرة من واجهات برمجة التطبيقات لتتبع التجارب، لكن قد يكون من المعقد أحياناً جعلها جميعاً تعمل في بيئة متعددة العمليات.
يوفر Accelerate واجهة برمجة تطبيقات عامة للتتبع يمكن استخدامها لتسجيل عناصر مفيدة أثناء تنفيذ سكربتك من خلال Accelerator.log()
المُتتبِّعات المُدمَجة
يدعم Accelerate حاليًا ثمانية متتبعات جاهزة للاستخدام:
- TensorBoard
- WandB
- Trackio
- CometML
- الهدف
- MLFlow
- ClearML
- DVCLive
للاستخدام أيًا منها، مرّر النوع (أو الأنواع) المحدد إلى معامل log_with في 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])في بداية تجربتك، يجب استخدام Accelerator.init_trackers() لإعداد مشروعك، وإضافة أي معاملات خارقة للتجربة (Hyperparameters) التي سيتم تسجيلها إن لزم الأمر:
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.
يجب على كل متتبع تطبيق ثلاث دوال وامتلاك ثلاث خصائص:
__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 - يجب أن يعيد آلية التتبع الداخلية التي يستخدمها المكتبة، مثل كائن
runالخاص بـwandb.
- يجب أن يتم تنفيذ هذا كدالة
يجب أن تستخدم كل طريقة أيضًا فئة 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 ليتم استخدامه تلقائيًا مع واجهة برمجة التطبيقات:
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")من هناك يمكنك التفاعل مع كائن run الخاص بـwandb بشكل عادي:
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)عندما لا يمكن للغلاف العمل
إذا كانت المكتبة تملك واجهة برمجة تطبيقات لا تتبع نمط .log صارمًا مع قاموس عام مثل Neptune.AI، فيمكن تنفيذ التسجيل يدويًا تحت عبارة 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)