Skip to content

监控系统

不是 Agent,是一组机制

监控不是一个独立的 Agent。它是由多个组件组成的机制:

  • watchdog — 运行在 GPU 服务器上的 Python 脚本,持续监控训练进程
  • CronCreate — 定时任务,周期性检查 watchdog 的输出
  • 编排器 — 接收监控信息并做出反应
mermaid
graph LR
    T[训练进程] -->|输出| W[watchdog.py]
    W -->|写入| S[/tmp/jx-monitor/<br/>summary.txt]
    C[CronCreate] -->|定期读取| S
    C -->|异常时| O[编排器]
    O -->|决策| A[修复 / 重启 / 通知用户]

监控类别

类别监控项检查频率异常处理
进程健康GPU 利用率、显存占用、进程存活每分钟进程挂了 → 自动重启或通知
训练进度loss 趋势、学习率、当前 epoch每 5 分钟loss 爆炸 → 暂停并通知
资源状态磁盘空间、checkpoint 大小每 10 分钟空间不足 → 清理旧 checkpoint
WandB 同步WandB 进程、网络连接每 5 分钟同步中断 → 重启 WandB

两阶段训练监控

这是监控系统最重要的设计。训练的前期和后期,监控策略完全不同:

第一阶段:主动看守

训练启动 → 前 30 分钟

训练刚启动时,问题出现的概率最高:

  • CUDA OOM(显存不够)
  • 数据加载报错
  • WandB 初始化失败
  • 学习率配置错误导致 loss 爆炸

这个阶段,编排器主动等待,高频检查训练状态。不设 CronCreate,而是直接在当前 session 中监控。

yaml
# 第一阶段监控配置
phase: active-watch
check_interval: 60s    # 每分钟检查
duration: 30m           # 持续 30 分钟
watch_for:
  - process_alive
  - gpu_utilization > 0
  - loss_is_finite
  - wandb_connected

不要跳过看守期

很多训练失败发生在前几分钟。跳过看守期意味着你可能在 8 小时后才发现训练从第 2 分钟就挂了。

第二阶段:巡检模式

看守期结束(一切正常)→ 切换到 CronCreate 定时巡检

训练稳定后,没必要持续监控。切换到 CronCreate,定期检查健康状态:

yaml
# 第二阶段监控配置
phase: patrol
check_interval: 15m     # 每 15 分钟
alert_conditions:
  - loss_spike > 3x_moving_avg
  - gpu_utilization < 10%    # 可能挂了
  - disk_usage > 90%
  - process_not_alive
normal_action: log_only
alert_action: notify_orchestrator

阶段切换

mermaid
stateDiagram-v2
    [*] --> ActiveWatch: 训练启动
    ActiveWatch --> Patrol: 30 分钟内无异常
    ActiveWatch --> Alert: 发现问题
    Patrol --> Alert: 巡检发现异常
    Alert --> ActiveWatch: 修复后重新看守
    Patrol --> Complete: 训练正常结束
    Complete --> [*]

配置文件

监控配置在 .omc/research/training/monitoring.yaml

yaml
monitoring:
  # 全局设置
  server: ic2
  gpus: [0, 1, 2]
  tmux_session: train-exp03
  wandb_project: fine-grained-research
  wandb_run: exp03_contrastive

  # 第一阶段
  active_watch:
    enabled: true
    duration: 30m
    check_interval: 60s
    healthy_criteria:
      gpu_util_min: 10
      loss_finite: true
      process_alive: true

  # 第二阶段
  patrol:
    check_interval: 15m
    alert_thresholds:
      loss_spike_ratio: 3.0
      gpu_util_min: 10
      disk_usage_max: 90

  # watchdog 配置
  watchdog:
    path: tools/watchdog.py
    output: /tmp/jx-monitor/status/summary.txt
    pid_file: /tmp/jx-monitor/watchdog.pid

健康检查而非超时

核心理念

监控基于健康状态,不是超时

传统做法是设一个超时:训练超过 24 小时就报警。这很粗糙 — 训练可能本来就需要 20 小时,也可能在第 2 小时就已经 loss 爆炸了。

AutoResearch 的做法是检查健康指标

指标健康不健康
GPU 利用率> 10%持续 < 10%(训练可能挂了)
Loss有限值且在下降NaN / Inf / 3 倍移动平均
进程存活不存在
WandB在同步超过 30 分钟没有新数据点
磁盘使用率 < 90%使用率 > 90%

只要所有指标健康,训练就继续。不管它跑了 2 小时还是 20 小时。

健康检查的实现

watchdog 每次检查生成一个摘要文件:

json
{
  "timestamp": "2025-03-15T20:30:00Z",
  "status": "healthy",
  "gpu_util": [82, 79, 85],
  "gpu_mem": [18.2, 17.8, 19.1],
  "current_epoch": 45,
  "total_epochs": 100,
  "current_loss": 0.342,
  "loss_trend": "decreasing",
  "wandb_last_sync": "2025-03-15T20:29:45Z",
  "disk_usage": "67%",
  "eta": "2025-03-16T08:30:00Z"
}

CronCreate 读这个文件,解析 status 字段。只要是 healthy,就什么都不做。出现 warningcritical 时才通知编排器。

每台服务器一个 CronCreate

规则

每台远程服务器只设一个 CronCreate job。不管在上面跑了几个训练任务。

这是为了避免 CronCreate job 堆积。watchdog 脚本本身可以监控同一台机器上的多个训练任务,CronCreate 只需要读一个总摘要文件。

下一步

AutoResearch — Multi-agent Deep Learning Research System