监控

在本教程中,我们介绍了DeepSpeed Monitor并提供了其使用示例。

概述

在训练过程中监控模型和系统指标对于确保硬件资源得到充分利用至关重要。DeepSpeed Monitor 通过一个或多个监控后端(如 PyTorch 的 TensorBoardWandBComet 和简单的 CSV 文件)实现指标的实时日志记录。

以下是TensorBoard的实时监控视图:

TensorBoard Example Output

以下是WandB的实时监控视图:

WandB Example Output

以下是Comet的实时监控视图:

CometML Example Output

用法

DeepSpeed 监视器在 deepspeed 配置文件中进行配置。DeepSpeed 会自动监视关键训练指标,包括使用 wall_clock_breakdown 配置选项跟踪的指标。此外,用户可以记录自己的自定义事件和指标。

自动监控

在使用DeepSpeed进行模型训练时,可以在DeepSpeed的配置文件中配置Monitor。使用Monitor不需要显式的API调用。可以通过在DeepSpeed的配置json文件中添加以下字段来启用Monitor。详情请参阅Monitoring

{
  "tensorboard": {
    "enabled": true,
    "output_path": "output/ds_logs/",
    "job_name": "train_bert"
  }
  "wandb": {
    "enabled": true,
    "team": "my_team",
    "group": "my_group",
    "project": "my_project"
  }
  "comet": {
    "enabled": true,
    "project": "my_project",
    "experiment_name": "my_experiment"
  }
  "csv_monitor": {
    "enabled": true,
    "output_path": "output/ds_logs/",
    "job_name": "train_bert"
  }
}

DeepSpeed 将自动记录到配置中列出的所有可用和启用的监控后端,并生成实时监控视图,例如上面列出的那些。

自定义监控

除了自动监控外,用户还可以在客户端脚本中记录自己的自定义指标。目前,有两种方法可以初始化Monitor对象:

  1. (推荐)- 创建一个MonitorMaster(ds_config.monitor_config)对象,它会自动初始化DeepSpeed配置中存在的所有监控后端
  2. 创建一个特定的TensorBoardMonitor(ds_config.monitor_config)WandbMonitor(ds_config.monitor_config)csvMonitor(ds_config.monitor_config)对象,该对象将仅初始化DeepSpeed配置中存在的特定监控后端

创建自定义监控的步骤如下:

  1. 将导入添加到您所需的Monitor
  2. 使用DeepSpeed配置的monitor_config初始化监控器
  3. 创建一个或多个3元组的列表,格式为 [("label", value, ds_engine.global_samples), ...]*
  4. 在步骤3的列表上调用monitor.write_events

* 注意 - 一些监控后端不支持混合样本值。请确保在每个三元组中使用您的DeepSpeed引擎对象的global_samples属性

例如,请参见以下修改后的DeepSpeedExamples/cifar示例:

# Step 1: Import monitor (and DeepSpeed config, if needed)
from deepspeed.monitor.monitor import MonitorMaster
from deepspeed.runtime.config import DeepSpeedConfig

# Step 2: Initialized monitor with DeepSpeed config (get DeepSpeed config object, if needed)
ds_config = DeepSpeedConfig("ds_config.json")
monitor = MonitorMaster(ds_config.monitor_config)

for epoch in range(2):

    running_loss = 0.0
    for i, data in enumerate(trainloader):
        pre = time.time()
        inputs, labels = data[0].to(model_engine.local_rank), data[1].to(
            model_engine.local_rank)
        if fp16:
            inputs = inputs.half()
        outputs = model_engine(inputs)
        loss = criterion(outputs, labels)

        model_engine.backward(loss)
        model_engine.step()
        post = time.time()
        # Step 3: Create list of 3-tuple records (single entry in this case)
        events = [("Time per step", post-pre, model_engine.global_samples)]
        # Step 4: Call monitor.write_events on the list from step 3
        monitor.write_events(events)

更新: