8. 工程可视化

日志保存与指标监控

  • 训练过程中,通常会跟踪以下指标:

    • train_loss / val_loss

    • train_acc / val_acc

    • precision/recall、F1

    • 学习率(scheduler)

  • 并按step 或 epoch控制:

    • 日志记录频率(log_step)

    • 模型保存频率(checkpoint_step)

  • optimizer.param_groups 是 PyTorch 优化器的核心接口,每个 param_group 是一个字典,存储了优化器参数和超参数,常用字段有

    字段
    含义
    可视化意义

    params

    当前组内的参数列表

    不可直接可视化,但可用于梯度统计

    lr

    学习率

    随时间变化,曲线展示优化进度

    momentum

    动量(如 SGD)

    可观察动量策略对训练影响

    betas

    Adam 的 beta 参数 (β1, β2)

    调试 Adam 收敛行为

    weight_decay

    L2 正则化系数

    用于监控正则化影响

    dampening

    SGD 特有参数

    可调试动量衰减

    nesterov

    是否使用 Nesterov

    用于策略对比

    maximize

    是否最大化 loss(少用)

    对强化学习任务有用

  • 示例代码

    import torch
    import torch.nn as nn
    import torch.optim as optim
    import os
    import numpy as np
    import matplotlib.pyplot as plt
    
    # ========== 配置 ==========
    epochs = 10
    log_step = 20          # 每多少 batch 打一次日志
    checkpoint_step = 2    # 每多少 epoch 保存一次模型
    save_dir = "./checkpoints"
    os.makedirs(save_dir, exist_ok=True)
    
    # ========== 模型 & 数据 ==========
    model = nn.Sequential(
        nn.Linear(10, 50),
        nn.ReLU(),
        nn.Linear(50, 2)
    )
    criterion = nn.CrossEntropyLoss()
    optimizer = optim.Adam(model.parameters(), lr=1e-3)
    scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=5, gamma=0.1)
    
    # 假数据
    x_train = torch.randn(200, 10)
    y_train = torch.randint(0, 2, (200,))
    train_loader = [(x_train[i:i+20], y_train[i:i+20]) for i in range(0, 200, 20)]
    
    # ========== 训练循环 ==========
    train_losses, train_accs, lrs = [], [], []
    
    for epoch in range(epochs):
        model.train()
        batch_losses, batch_accs = [], []
        for step, (x, y) in enumerate(train_loader):
            optimizer.zero_grad()
            out = model(x)
            loss = criterion(out, y)
            loss.backward()
            optimizer.step()
    
            batch_losses.append(loss.item())
            preds = out.argmax(dim=1)
            batch_accs.append((preds == y).float().mean().item())
    
            # 控制日志打印
            if (step + 1) % log_step == 0 or (step+1)==len(train_loader):
                print(f"Epoch {epoch+1}, Step {step+1}, Loss {np.mean(batch_losses):.4f}, Acc {np.mean(batch_accs):.4f}")
    
        train_losses.append(np.mean(batch_losses))
        train_accs.append(np.mean(batch_accs))
        lrs.append(optimizer.param_groups[0]['lr'])
    
        scheduler.step()
    
        # 控制 checkpoint 保存
        if (epoch + 1) % checkpoint_step == 0:
            torch.save(model.state_dict(), os.path.join(save_dir, f"model_epoch{epoch+1}.pt"))
    
    # ========== 绘图 ==========
    plt.figure(figsize=(8,4))
    plt.plot(train_losses, label="Train Loss")
    plt.plot(train_accs, label="Train Acc")
    plt.xlabel("Epoch")
    plt.ylabel("Value")
    plt.legend()
    plt.title("Training Metrics")
    plt.show()
    
    plt.figure(figsize=(8,4))
    plt.plot(lrs, label="Learning Rate")
    plt.xlabel("Epoch")
    plt.ylabel("LR")
    plt.title("Learning Rate Schedule")
    plt.show()

wandb

  • wandb 配置

    配置
    含义
    使用场景

    entity

    wandb 账号或团队名

    指定归属账户或团队

    project

    项目名

    一个 project 下可以有多个实验

    group

    分组

    用于组织相关实验,例如不同超参组合属于一个组

    tags

    标签列表

    自定义标签,用于快速搜索或对比

    name

    实验名

    唯一标识某次运行

  • 常用 API

    方法
    作用
    备注

    wandb.init()

    初始化运行,设置 entity、project、name、group、tags

    每次训练必须调用一次

    wandb.config.update(dict)

    更新超参数或配置

    超参搜索时可以方便记录

    wandb.log(dict, step=None)

    上传指标,可选 step

    step 默认为 wandb 自增

    wandb.watch(model, log="all", log_freq=10)

    监控模型参数、梯度、直方图、梯度范数

    log 可以选 gradients, parameters, all

    wandb.save("file")

    保存本地文件到 wandb 云

    可保存 checkpoint、配置文件

    wandb.finish()

    结束当前运行

    可显式调用,也可自动结束

  • 示例代码

TensorBoard

  • SummaryWriter 参数

  • 常用 API

    方法
    功能
    使用示例

    add_scalar(tag, scalar_value, global_step)

    添加单值标量

    loss/acc/lr 曲线

    add_scalars(main_tag, tag_scalar_dict, global_step)

    一次添加多条曲线

    multi-experiment loss

    add_histogram(tag, values, global_step)

    权重 / 梯度分布

    monitor layer weights

    add_image(tag, img_tensor, global_step)

    上传图片

    可视化输入 / 输出

    add_images(tag, img_tensor, global_step)

    多图片

    batch 可视化

    add_graph(model, input_to_model)

    可视化计算图

    模型结构展示

    add_embedding(mat, metadata=None, label_img=None, global_step=None)

    可视化 embedding

    特征空间分析

    flush()

    强制写入磁盘

    异步写入时有用

    close()

    关闭 writer

    必须在训练结束调用

  • 示例代码

PyTorch Profiler

  • 构造函数

  • schedule 用于控制采样周期,通常配合训练迭代:

    • wait: 忽略前几步,避免冷启动

    • warmup: 预热阶段,不统计

    • active: 开始采样的步数

    • repeat: 循环次数\

  • 常用 API

    方法
    作用
    示例

    record_function("name")

    手动打标签

    with record_function("forward")

    prof.key_averages().table(sort_by="cuda_time_total")

    按时间排序输出表格

    查看 top kernel

    prof.export_chrome_trace("trace.json")

    导出 Chrome Trace

    可用 chrome://tracing 查看 timeline

    prof.tensorboard_trace_handler("logdir")

    导出到 TensorBoard

    可直接在 TensorBoard 中查看 timeline

  • 示例代码

CUDA Profiling

  • 一般指 nsys(NVIDIA System Profiler),旧的 nvprof 已经废弃,也可以使用 Visual Profiler / Nsight Systems GUI

  • 常用命令

  • 查看指标

    • Kernel 时间:forward/backward 执行时间

    • SM Utilization:GPU 利用率

    • Memory throughput:显存带宽占用

    • Timeline:线程执行顺序和阻塞状态

  • 与 PyTorch Profiler 配合

    • PyTorch Profiler 导出 Chrome Trace (trace.json)

    • NSYS 生成 .qdrep

    • 在 GUI 中对比哪些 kernel 被 CPU 阻塞、哪些 kernel 计算时间长、数据加载是否成为瓶颈

Last updated

Was this helpful?