监控

在本教程中,我们介绍了 DeepSpeed 监控器并提供了其用法的示例。

概述

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

以下是 TensorBoard 的实时监控视图

TensorBoard Example Output

以下是 WandB 的实时监控视图

WandB Example Output

以下是 Comet 的实时监控视图

CometML Example Output

用法

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

自动监控

在使用 DeepSpeed 进行模型训练时,可以在 DeepSpeed 配置文件 中配置监控器。使用监控器不需要显式 API 调用。可以通过在 DeepSpeed 的配置 JSON 文件中添加以下字段来启用监控器。有关详细信息,请参阅 监控

{
  "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 将自动记录到配置中列出的所有可用且已启用的监控后端,并将生成如上所示的实时监控视图。

自定义监控

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

  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. 将导入添加到您想要的监控器
  2. 使用 DeepSpeed 配置的 monitor_config 初始化监控器
  3. [("label", value, ds_engine.global_samples), ...]* 格式创建一个或多个 3 元组列表
  4. 在步骤 3 中的列表上调用 monitor.write_events

* 注意 - 一些监控后端不支持混合样本值。请确保在每个 3 元组中使用 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)

更新: