3. 故障检测基础
GPU集群的故障自愈,前提是“看得见、听得清、喊得出”。如果连故障都无法被及时、准确地发现,后续的隔离、调度和恢复都无从谈起。本章聚焦故障检测的三大支柱:监控指标(量化健康状态)、日志收集(记录事件轨迹)、告警机制(触发响应动作)。三者构成一个从数据采集到决策执行的闭环,是自愈系统的“感知神经”。
3.1 核心原理:三类信号的协同逻辑
监控指标回答“现在是否异常”,日志回答“发生了什么”,告警回答“是否需要行动”。三者的关系并非简单并列,而是层层递进:指标提供数值化的趋势判断,日志提供上下文细节,告警则基于前两者触发策略。一个成熟的检测体系,必须让这三类信号在时间轴上对齐,才能避免误报和漏报。
NVML 提供的温度、利用率是“体温计”;驱动日志、Xid错误是“病历本”;而告警规则(如温度超过85°C持续5分钟)才是“护士铃”。
下图展示了从GPU硬件到告警动作的完整数据通路,注意每个环节的延迟和采样粒度差异:
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)
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
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错误。
排查过程:
- 监控面板显示利用率高,但SM时钟频率从1.4GHz降至0.6GHz——这是功耗限制的信号。
- 检查
nvidia-smi -q -d POWER,发现实际功耗仅为额定功耗的60%,但温度只有70°C,排除过热降频。 - 查看
dmesg,发现大量NVML_ERROR_DRIVER_NOT_LOADED和 PCIe AER 错误,但未触发Xid。 - 进一步检查发现,该GPU的电源线接触不良,导致供电不稳定,驱动自动降低了时钟频率以保护硬件。
根因:监控指标只关注了利用率和温度,忽略了时钟频率和功耗这两个关键指标。日志收集没有覆盖PCIe AER错误,导致故障“静默”了3小时。
DCGM_FI_DEV_SM_CLOCK 和 DCGM_FI_DEV_POWER_USAGE 的告警规则,当时钟频率低于基准值的80%或功耗低于额定值50%时触发P1告警;② 日志收集增加对 pcieport 和 nvrm 关键字的监控;③ 建立“性能基线画像”,对每台GPU记录正常运行时的时钟、功耗、温度分布,偏离基线即视为异常。
故障检测的最终目标不是“发现所有问题”,而是在用户感知之前发现问题。监控指标、日志、告警三者缺一不可,且必须通过统一的标签体系(GPU UUID、主机名、Pod名称)关联起来。当这三类数据能够在一个时间轴上对齐时,自愈系统才能做出准确的判断——是立即隔离,还是继续观察,抑或只是瞬时抖动。下一层级的故障隔离与自愈策略,将建立在这套检测体系之上。