12. DVCLive 实时追踪

12.DVCLive 实时追踪

DVCLive 是 DVC 生态系统中专门负责实验追踪的 Python 库。与那些需要独立服务器、复杂配置的追踪工具不同,DVCLive 的设计理念是轻量级、本地化,直接嵌入到训练代码中。它像一位默默记录的助手,在模型训练过程中实时收集参数、指标、图像等信息,最终将这些数据整理成结构化的实验记录。

使用 DVCLive 不需要改变现有的工作流程。无论是 Jupyter Notebook 里的快速原型,还是生产环境中的训练脚本,只需几行代码就能启用实验追踪。这种无侵入式的集成方式,让团队可以在不影响现有开发习惯的前提下,逐步建立起规范的实验管理流程。

DVCLive 初始化

Live 类的核心作用

DVCLive 的所有功能都围绕 Live 类展开。这个类是实验追踪的入口,负责管理日志目录、配置选项,以及协调各种记录操作。创建一个 Live 实例就像打开一本实验记录本,之后的所有操作都会写在这本记录本上。

最基本的初始化方式非常简单:

from dvclive import Live

live = Live()

这行代码会在当前目录下创建一个名为 dvclive 的文件夹,所有实验数据都会保存在这里。如果希望使用自定义目录,可以传入 dir 参数:

live = Live(dir="experiments/run_001")

上下文管理器模式

推荐使用上下文管理器的方式使用 Live,这样可以确保资源被正确释放,实验数据被完整保存:

from dvclive import Live

with Live() as live:
    # 在这里进行实验记录
    live.log_param("lr", 0.001)
    live.log_metric("accuracy", 0.95)
# 退出上下文时,Live.end() 会自动调用

这种模式的好处是无需手动调用结束方法。当代码块执行完毕,即使发生异常,DVCLive 也能保证已记录的数据被妥善保存。对于长时间运行的训练任务,这种自动清理机制可以避免数据丢失。

初始化参数详解

Live 类的构造函数提供了多个参数来控制行为:

class Live:
    def __init__(
        self,
        dir: str = "dvclive",
        resume: bool = False,
        report: Literal["md", "notebook", "html", None] = None,
        save_dvc_exp: bool = True,
        dvcyaml: Optional[str] = "dvc.yaml",
        cache_images: bool = False,
        exp_name: Optional[str] = None,
        exp_message: Optional[str] = None,
        monitor_system: bool = False,
    ):

dir 参数指定输出目录,默认值是 dvclive。所有日志文件、指标数据、图像都会存放在这个目录下。建议为每次实验使用不同的目录,或者在 DVC 实验管理框架下让系统自动处理目录隔离。

resume 参数控制是否续写之前的实验。设置为 True 时,DVCLive 会尝试从 metrics.json 文件中读取上一次的 step 值,并从这个步骤继续记录。这在训练中断后恢复时非常有用。

report 参数决定生成报告的类型。"html" 会生成可交互的 HTML 报告,"md" 生成 Markdown 格式,"notebook" 专为 Jupyter 环境优化,会在单元格输出中直接显示报告。如果设置为 None,则不自动生成报告。

save_dvc_exp 默认为 True,表示在实验结束时自动创建 DVC 实验记录。如果已经在使用 dvc exp run 运行流水线,这个选项会被自动忽略。

dvcyaml 参数控制 dvc.yaml 配置文件的生成。默认值为 "dvc.yaml",DVCLive 会自动配置指标、参数和绘图的 DVC 设置。如果设置为 None,则跳过配置生成,适合手动管理 DVC 配置的场景。

cache_images 决定是否缓存图像文件。当记录大量图像时,开启缓存可以避免 Git 仓库膨胀。缓存后的图像会被 DVC 管理,只在需要时下载。

monitor_system 参数开启系统资源监控。设置为 True 后,DVCLive 会定期记录 CPU、内存、磁盘和 GPU 的使用情况,帮助分析训练过程中的资源瓶颈。

环境变量配置

除了构造函数参数,DVCLive 还支持通过环境变量进行全局配置:

import os
from dvclive import env

os.environ[env.DVCLIVE_LOGLEVEL] = "DEBUG"
os.environ[env.DVCLIVE_OPEN] = "True"

DVCLIVE_LOGLEVEL 控制日志详细程度,可选值包括 DEBUG、INFO、WARNING、ERROR。默认是 WARNING,只在出现问题时输出提示。

DVCLIVE_OPEN 设置为 True 时,DVCLive 会在生成 HTML 报告后自动用默认浏览器打开。这在本地开发时很方便,但在服务器环境下建议保持关闭。

指标记录 log_metric

基本用法

log_metric 是实验追踪中最常用的方法。每次调用都会记录一个指标值,通常放在训练循环中:

from dvclive import Live

with Live() as live:
    for epoch in range(10):
        loss = train_one_epoch()
        accuracy = evaluate()
        
        live.log_metric("train/loss", loss)
        live.log_metric("eval/accuracy", accuracy)
        live.next_step()

这段代码会记录每个 epoch 的损失和准确率。next_step() 方法通知 DVCLive 进入下一个训练步骤,这一步会触发数据汇总和报告更新。

指标存储机制

DVCLive 采用双轨制存储指标。一方面,它为每个指标创建独立的 TSV 文件,保存完整的历史记录;另一方面,它维护一个 metrics.json 文件,只保存最新值。

例如,上面的代码会生成如下目录结构:

dvclive/
├── metrics.json
└── plots/
    └── metrics/
        ├── train/
        │   └── loss.tsv
        └── eval/
            └── accuracy.tsv

TSV 文件的内容包含时间戳、步骤和值:

timestamp      step  loss
1623671484747  0     0.5234
1623671484892  1     0.4123

这种设计兼顾了详细历史和快速查看的需求。绘图工具可以读取 TSV 文件生成学习曲线,而 dvc metrics 命令则直接读取 metrics.json 显示最新结果。

高级选项

log_metric 支持几个有用的选项:

live.log_metric("train/loss", 0.4, timestamp=False, plot=True)

timestamp 参数控制是否在 TSV 文件中记录时间戳。默认是 False,如果希望分析训练速度或识别性能瓶颈,可以设为 True。

plot 参数决定该指标是否出现在绘图中。某些汇总指标可能不需要可视化,设为 False 可以简化报告。

指标名称支持层级结构,使用斜杠分隔。"train/loss" 和 "eval/loss" 会被组织成树状结构,在报告中清晰展示。

步骤管理

DVCLive 使用 step 概念来组织时间序列数据。每次调用 next_step(),step 值会增加,后续的指标记录会关联到这个新步骤。

也可以手动控制步骤:

live.step = 5
live.log_metric("custom/metric", 0.8)

这种方式适合非连续的训练过程,比如交叉验证或自定义循环。手动设置步骤后,下次调用 next_step() 会从这个值继续递增。

参数记录 log_param

单个参数记录

log_param 用于记录实验的超参数和配置。与指标不同,参数在整个实验中通常是不变的:

from dvclive import Live

with Live() as live:
    live.log_param("learning_rate", 0.001)
    live.log_param("batch_size", 32)
    live.log_param("optimizer", "adam")

这些参数会被写入 dvclive/params.yaml 文件:

learning_rate: 0.001
batch_size: 32
optimizer: adam

YAML 格式的好处是人类可读,且能被 DVC 流水线直接用作参数依赖。当使用 dvc exp run --set-param 修改参数时,DVCLive 记录的参数会与命令行输入合并,形成完整的参数集。

批量参数记录

如果有多个参数需要记录,log_params 方法更加高效:

params = {
    "model": {
        "type": "resnet50",
        "pretrained": True,
        "num_classes": 10
    },
    "training": {
        "epochs": 100,
        "learning_rate": 0.01,
        "weight_decay": 1e-4
    }
}

live.log_params(params)

这会生成嵌套的 YAML 结构:

model:
  type: resnet50
  pretrained: true
  num_classes: 10
training:
  epochs: 100
  learning_rate: 0.01
  weight_decay: 0.0001

嵌套结构非常适合组织复杂的配置。模型架构、数据预处理、训练策略可以分门别类,保持配置文件的清晰。

参数类型支持

DVCLive 支持多种参数类型:整数、浮点数、字符串、布尔值,以及它们的列表和字典组合。这种灵活性允许记录任意复杂的配置结构。

需要注意的是,如果已经在使用 DVC 流水线的参数依赖功能,DVCLive 的参数记录可能会重复。在这种情况下,可以在 Live 初始化时设置 dvcyaml=False,跳过自动配置生成,手动管理参数文件。

图像日志 log_image

支持的图像类型

log_image 方法可以记录多种类型的图像数据,这在计算机视觉项目中特别有用:

from dvclive import Live
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt

with Live() as live:
    # 1. NumPy 数组
    img_array = np.random.randint(0, 255, (100, 100, 3), dtype=np.uint8)
    live.log_image("random.png", img_array)
    
    # 2. PIL 图像
    pil_img = Image.new("RGB", (200, 200), color="red")
    live.log_image("color.png", pil_img)
    
    # 3. Matplotlib 图表
    fig, ax = plt.subplots()
    ax.plot([1, 2, 3, 4], [1, 4, 2, 3])
    live.log_image("plot.png", fig)
    
    # 4. 现有图像文件
    live.log_image("existing.png", "path/to/image.jpg")

这种多样性让 log_image 可以适应不同的工作流程。无论是模型生成的图像、数据增强的可视化,还是训练过程中的图表,都能统一记录。

图像存储结构

记录的图像保存在 dvclive/plots/images/ 目录下。如果图像名称包含子路径,DVCLive 会自动创建相应目录:

live.log_image("epoch_0/confusion_matrix.png", cm_img)
live.log_image("epoch_1/confusion_matrix.png", cm_img)

这会生成:

dvclive/plots/images/
├── epoch_0/
│   └── confusion_matrix.png
└── epoch_1/
    └── confusion_matrix.png

这种组织方式便于按训练阶段或类别管理图像。在 DVC Studio 或 VS Code 扩展中,文件夹结构的图像会以滑块形式展示,方便对比不同步骤的结果。

步骤化图像记录

对于需要记录每个训练步骤图像的场景,可以在文件名中包含步骤号:

with Live() as live:
    for step in range(10):
        # 生成当前步骤的图像
        generated_img = generate_sample(step)
        live.log_image(f"samples/{step}.png", generated_img)
        live.next_step()

DVCLive 会识别这种命名模式,在报告中提供图像序列的交互式查看器。可以像播放视频一样浏览训练过程中图像的演变,这对 GAN 训练或语义分割等任务非常有帮助。

图像缓存管理

当记录大量图像时,Git 仓库可能迅速膨胀。开启 cache_images 选项可以让 DVC 管理图像文件:

with Live(cache_images=True) as live:
    for i in range(100):
        live.log_image(f"batch_{i}.png", images[i])

开启后,DVCLive 会在实验结束时将图像目录加入 DVC 缓存,生成 images.dvc 文件。原始图像会被加入 .gitignore,避免直接提交到 Git。这样既保持了仓库的轻量,又能通过 DVC 追踪图像版本。

系统监控 monitor_system

监控功能概述

monitor_system 是 DVCLive 3.0 引入的功能,用于自动记录系统资源使用情况。在深度学习训练中,硬件瓶颈常常影响效率,系统监控能帮助识别这些问题。

启用监控非常简单:

from dvclive import Live

# 方式一:初始化时开启
live = Live(monitor_system=True)

# 方式二:手动调用配置
live = Live()
live.monitor_system(
    interval=0.05,
    num_samples=20,
    directories_to_monitor={"data": "/data", "temp": "/tmp"}
)

监控指标详解

系统监控会记录多类指标,覆盖训练过程的各个方面。

GPU 指标(需要 NVIDIA GPU 和驱动):

  • system/gpu/count:GPU 数量
  • system/gpu/usage (%)/<index>:每个 GPU 的使用率百分比
  • system/vram/usage (%)/<index>:显存使用百分比
  • system/vram/usage (GB)/<index>:显存使用量(GB)
  • system/vram/total (GB)/<index>:显存总量(GB)

CPU 指标:

  • system/cpu/count:CPU 核心数
  • system/cpu/usage (%):平均 CPU 使用率
  • system/cpu/parallelization (%):CPU 并行化程度,反映多核利用效率

内存指标:

  • system/ram/usage (%):内存使用百分比
  • system/ram/usage (GB):内存使用量
  • system/ram/total (GB):内存总量

磁盘指标:

  • system/disk/usage (%)/<name>:指定目录所在分区的使用百分比
  • system/disk/usage (GB)/<name>:磁盘使用量
  • system/disk/total (GB)/<name>:磁盘总容量

配置参数说明

monitor_system 方法接受三个参数来调整监控行为:

interval 控制采样间隔,单位是秒。默认值 0.05 秒(50 毫秒)适合大多数场景。值越小,采样越频繁,但会略微增加 CPU 开销。最大允许值为 0.1 秒。

num_samples 定义每次聚合的样本数。DVCLive 会采集多个样本后计算平均值,避免瞬时波动干扰。默认值 20 意味着每次记录的是过去 1 秒(20 × 0.05)的平均值。取值范围 1 到 30。

directories_to_monitor 允许监控特定目录的磁盘使用情况。默认只监控根分区 {"main": "/"}。在数据存储在单独磁盘的场景下,可以添加数据目录的监控:

live.monitor_system(
    directories_to_monitor={
        "main": "/",
        "data": "/mnt/data",
        "models": "/mnt/models"
    }
)

监控数据的应用

系统监控数据会和其他指标一起存储在 dvclive/plots/metrics/system/ 目录下,可以在 DVC Studio 或 VS Code 扩展中实时查看。当发现 GPU 使用率持续低于预期时,可能意味着数据加载成为瓶颈;当内存使用接近极限时,可能需要减小批次大小。

这些指标为性能调优提供了客观依据。比如,通过对比不同数据加载方式的 CPU 和磁盘使用率,可以选择最优的预处理策略;通过监控 GPU 显存使用,可以确定模型的最大可行批次大小。

总结

DVCLive 的实时追踪功能为机器学习实验提供了轻量级但完整的记录方案。从初始化到各类数据的记录,每个环节都设计得简洁实用。Live 类的上下文管理器模式让资源管理变得自动;log_metric 的双轨存储兼顾了详细历史和快速查看;log_param 的嵌套结构适合复杂配置;log_image 的多样性支持各种可视化需求;monitor_system 则为性能分析提供了硬件层面的洞察。

这些功能组合起来,构成了一个无需外部服务、完全本地化的实验追踪系统。数据科学家可以在自己的机器上完成从开发到分析的全流程,同时保持与 DVC 版本控制的无缝集成。

在下一章中,我们将探讨 DVCLive 与主流机器学习框架的深度集成,看看如何在 PyTorch Lightning、Hugging Face Transformers 等框架中零成本地启用实验追踪,以及如何利用框架特有的功能进一步简化记录流程。