3. 故障检测基础

GPU集群的故障自愈,前提是“看得见、听得清、喊得出”。如果连故障都无法被及时、准确地发现,后续的隔离、调度和恢复都无从谈起。本章聚焦故障检测的三大支柱:监控指标(量化健康状态)、日志收集(记录事件轨迹)、告警机制(触发响应动作)。三者构成一个从数据采集到决策执行的闭环,是自愈系统的“感知神经”。

3.1 核心原理:三类信号的协同逻辑

监控指标回答“现在是否异常”,日志回答“发生了什么”,告警回答“是否需要行动”。三者的关系并非简单并列,而是层层递进:指标提供数值化的趋势判断,日志提供上下文细节,告警则基于前两者触发策略。一个成熟的检测体系,必须让这三类信号在时间轴上对齐,才能避免误报和漏报。

关键认知:指标是“体温计”,日志是“病历本”,告警是“护士铃”。体温升高不一定生病,病历能帮助诊断,但只有按铃呼叫医生,治疗流程才会启动。GPU集群中,NVML 提供的温度、利用率是“体温计”;驱动日志、Xid错误是“病历本”;而告警规则(如温度超过85°C持续5分钟)才是“护士铃”。

下图展示了从GPU硬件到告警动作的完整数据通路,注意每个环节的延迟和采样粒度差异:

GPU硬件层 SM温度 / 显存ECC 电源功耗 / PCIe链路 NVLink带宽 / 时钟频率 指标采集 (100ms~1s) DCGM / NVML / Prometheus node_exporter + dcgm-exporter 日志收集 (秒级~分钟级) /var/log/messages, dmesg Xid错误 / 驱动事件 / syslog 时序数据库 Prometheus / InfluxDB 指标保留15天 日志存储 Elasticsearch / Loki 全文检索 / 结构化解析 告警引擎 Alertmanager 路由/抑制/静默 通知→自愈触发 告警动作分级 P0: 立即隔离GPU P1: 5分钟内迁移任务 P2: 记录并观察 采样频率差异:指标秒级,日志事件驱动,告警规则评估周期独立 关键:三类数据必须携带统一的 GPU UUID 和主机名标签 T+0s 故障发生 T+2s 指标异常 T+5s 告警触发

3.2 监控指标:从硬件到任务的四层体系

GPU监控不能只盯着利用率。一个完整的指标体系应覆盖四层:硬件健康层(温度、功耗、ECC错误)、资源利用率层(SM占用、显存占用、带宽)、任务状态层(进程、队列、上下文切换)、业务质量层(迭代耗时、吞吐量)。前两层反映“机器是否正常”,后两层反映“任务是否健康”。

实际部署中,推荐使用 dcgm-exporter 采集硬件指标,配合 node-exporter 采集主机指标。以下是一个关键的采集配置片段:

# dcgm-exporter 常用指标(/etc/dcgm-exporter/dcgm-metrics.csv)
# 硬件健康类
DCGM_FI_DEV_GPU_TEMP,        gauge,  GPU核心温度
DCGM_FI_DEV_XID_ERRORS,      counter, XID错误累计次数
DCGM_FI_DEV_ECC_DBE_VOL_TOTAL, counter, 显存双比特错误总量
DCGM_FI_DEV_POWER_USAGE,     gauge,  实时功耗(W)
# 利用率类
DCGM_FI_DEV_SM_CLOCK,        gauge,  SM时钟频率(MHz)
DCGM_FI_DEV_MEM_COPY_UTIL,   gauge,  显存拷贝利用率(%)
DCGM_FI_DEV_GPU_UTIL,        gauge,  GPU计算利用率(%)
# 显存类
DCGM_FI_DEV_FB_USED,         gauge,  显存已用量(MiB)
DCGM_FI_DEV_FB_TOTAL,        gauge,  显存总量(MiB)
实践要点:不要只设置固定阈值。GPU温度在夏季和冬季的基线可能相差10°C以上。建议采用动态基线——以过去7天同一时段的P95值作为参考,当前值超过基线1.5倍才触发告警。这能有效减少因环境变化导致的误报。

3.3 日志收集:Xid错误与驱动事件的解析

NVIDIA驱动通过 Xid 错误码报告GPU硬件或驱动问题。Xid 错误出现在系统日志中,格式通常为:

# dmesg 或 /var/log/messages 中的典型Xid错误
# 格式: [时间] NVRM: Xid (PCI:0000:3B:00): 79, GPU has fallen off the bus.
# 含义: Xid 79 表示GPU从PCIe总线上掉线,通常是硬件或电源问题

# 另一个常见例子
# [Tue Mar 12 14:23:45 2025] NVRM: Xid (PCI:0000:86:00): 63, pid=12345, 
#   process_name=python3, GPU fell off the bus, 无法恢复
# 含义: Xid 63 表示GPU与驱动通信超时,进程12345受影响

日志收集的关键在于结构化解析。原始日志是非结构化的文本,需要提取出GPU UUID、PCI总线地址、Xid编号、受影响进程等字段,才能与监控指标关联。推荐使用 promtail 或 filebeat 将日志转发到 Loki 或 Elasticsearch,并配置解析规则:

# promtail 配置片段(/etc/promtail/config.yml)
scrape_configs:
- job_name: gpu-xid
  static_configs:
  - targets: [localhost]
    labels:
      job: gpu-xid
      __path__: /var/log/messages
  pipeline_stages:
  - regex:
      expression: 'NVRM: Xid \((?P<pci_addr>[^)]+)\): (?P<xid_code>\d+),.*'
  - labels:
      xid_code:
      pci_addr:
  - metrics:
      xid_total:
        type: Counter
        description: 'Total Xid errors'
        source: xid_code
        config:
          action: inc
常见误区:只收集Xid错误而忽略驱动事件(如 NVML_ERROR_DRIVER_NOT_LOADED)和系统级事件(如PCIe AER错误)。实际上,很多GPU故障的前兆是PCIe链路降速或ECC警告,这些事件在Xid错误出现前数小时甚至数天就已经在日志中留下了痕迹。建议同时监控 dmesg 中的 pcieport 和 nvrm 关键字。

3.4 告警机制:分级策略与抑制规则

告警不是“越响越好”。一个每天发出200条告警的系统,最终会被运维人员忽略。有效的告警机制必须包含分级、聚合和抑制三个要素。

级别 触发条件示例 响应动作 通知渠道
P0 Xid 79/63 出现,或温度超过95°C持续1分钟 立即隔离GPU,迁移任务,创建工单 电话 + 短信 + 钉钉/企微
P1 ECC双比特错误增长,或显存利用率持续95%以上 5分钟内检查,准备热迁移 钉钉/企微 + 邮件
P2 温度超过80°C但低于95°C,或单次Xid 13(图形引擎) 记录观察,24小时内确认 邮件

Alertmanager 的配置中,抑制规则能避免“告警风暴”。例如,当某台机器已经触发P0级GPU掉线告警时,同一台机器上的其他GPU温度告警应被抑制,因为此时整个节点可能已经异常:

# Alertmanager 抑制规则示例
inhibit_rules:
- source_matchers:
  - severity = "P0"
  - alertname = "GPU_XID_ERROR"
  target_matchers:
  - severity = "P1|P2"
  equal: ["hostname"]  # 同一主机上的低级别告警被抑制

3.5 案例复盘:一次“静默故障”的教训

背景:某训练集群中,一台A100 GPU出现间歇性性能下降,任务迭代时间从2秒/步恶化到15秒/步,但GPU利用率显示为98%,温度正常,无Xid错误。

排查过程:

  1. 监控面板显示利用率高,但SM时钟频率从1.4GHz降至0.6GHz——这是功耗限制的信号。
  2. 检查 nvidia-smi -q -d POWER,发现实际功耗仅为额定功耗的60%,但温度只有70°C,排除过热降频。
  3. 查看 dmesg,发现大量 NVML_ERROR_DRIVER_NOT_LOADED 和 PCIe AER 错误,但未触发Xid。
  4. 进一步检查发现,该GPU的电源线接触不良,导致供电不稳定,驱动自动降低了时钟频率以保护硬件。

根因:监控指标只关注了利用率和温度,忽略了时钟频率和功耗这两个关键指标。日志收集没有覆盖PCIe AER错误,导致故障“静默”了3小时。

复盘改进:① 增加 DCGM_FI_DEV_SM_CLOCK 和 DCGM_FI_DEV_POWER_USAGE 的告警规则,当时钟频率低于基准值的80%或功耗低于额定值50%时触发P1告警;② 日志收集增加对 pcieport 和 nvrm 关键字的监控;③ 建立“性能基线画像”,对每台GPU记录正常运行时的时钟、功耗、温度分布,偏离基线即视为异常。

故障检测的最终目标不是“发现所有问题”,而是在用户感知之前发现问题。监控指标、日志、告警三者缺一不可,且必须通过统一的标签体系(GPU UUID、主机名、Pod名称)关联起来。当这三类数据能够在一个时间轴上对齐时,自愈系统才能做出准确的判断——是立即隔离,还是继续观察,抑或只是瞬时抖动。下一层级的故障隔离与自愈策略,将建立在这套检测体系之上。