第4章:GPU节点故障处理

GPU节点出故障,说实话,是推理集群里最让人头疼的事。CPU节点挂了顶多调度不过来,GPU一挂,整个推理链路直接断掉。我这些年踩过的坑,十个有八个跟GPU有关。今天咱们就把显存错误、驱动故障、MIG配置、算子定位这四个硬骨头啃下来。

4.1 显存错误检测:别等OOM才后悔

显存错误分两种:硬错误和软错误。硬错误是物理损坏,软错误是瞬时比特翻转。我个人习惯,每周至少跑一次全量显存检测。

核心命令:

# 基础显存检测
nvidia-smi -q -d MEMORY

# 更详细的ECC错误统计
nvidia-smi -q -d ECC

# 生产环境推荐:持续监控
nvidia-smi --query-gpu=index,timestamp,ecc.errors.volatile.dram,ecc.errors.aggregate.dram --format=csv -l 5

我在项目中遇到过一件事:某次大促前,一台A100节点频繁报推理超时。查了半天,发现是显存ECC错误累积到阈值,触发了GPU的自动降频。嗯,这里要注意——ECC错误不是0就是安全的。如果看到持续增长的volatile错误,哪怕数值很小,也要警惕。

避坑指南:我曾经以为nvidia-smi显示"Pass"就万事大吉。直到有一次,显存物理损坏但ECC校验还没触发,推理结果全是错的。后来我加了定期跑nvidia-smi -r重置GPU并做全量显存测试的习惯。

4.2 NVIDIA驱动故障恢复:三板斧

驱动故障,说白了就是GPU和操作系统之间的通信断了。表现很典型:nvidia-smi报错,或者GPU显示"ERR!"状态。

我的恢复流程分三步:

  1. 先重启nvidia-persistenced服务——这能解决80%的临时问题
  2. 重新加载驱动模块——解决内核态问题
  3. 重装驱动——最后手段

快速恢复脚本:

#!/bin/bash
# 第一步:重启持久化服务
systemctl restart nvidia-persistenced

# 第二步:卸载并重载驱动
nvidia-smi -pm 0
rmmod nvidia_uvm nvidia_drm nvidia_modeset nvidia
modprobe nvidia
nvidia-smi -pm 1

# 第三步:验证
nvidia-smi -q | grep "Driver Version"

你想想看,驱动挂了最怕什么?最怕你直接重启节点。我见过有人一上来就reboot,结果GPU卡在PCIe总线上,连BIOS都过不去。所以,先软后硬,先服务后内核,这个顺序不能乱。

4.3 MIG配置故障:分片不是切蛋糕

MIG(多实例GPU)配置出问题,通常是因为配置文件和实际硬件不匹配。我刚开始用MIG时,以为切分完就完事了,结果vLLM调度时死活找不到设备。

正确的MIG配置流程:

# 1. 查看当前MIG状态
nvidia-smi mig -lgi

# 2. 禁用所有MIG实例
nvidia-smi mig -dgi -i 0

# 3. 创建新的GI配置(以A100 40GB为例)
nvidia-smi mig -cgi 19,19,19,19,19,19,19 -i 0

# 4. 创建CI实例
nvidia-smi mig -cci -i 0 -gi 1

# 5. 验证
nvidia-smi mig -lgi
nvidia-smi mig -lci

这里有个坑:MIG配置重启后不持久化。我曾经在凌晨三点被叫起来,说推理集群全挂了。查了半天,原来是机房断电重启,MIG配置全丢了。后来我写了个systemd服务,开机自动加载MIG配置。

避坑指南:我曾经天真地以为MIG切分后性能是线性的。实际上,7个1g.10gb的实例,总吞吐量比单个7g.40gb低15%-20%。如果你的推理任务对延迟敏感,建议用大实例而不是多个小实例。

4.4 GPU算子故障定位:从现象到根因

算子故障,说白了就是某个CUDA内核执行出错了。表现五花八门:推理结果不对、显存泄漏、甚至直接segfault。我总结了一套定位方法:

故障现象 可能原因 定位工具
推理结果NaN 浮点精度问题或算子溢出 CUDA-MEMCHECK
显存持续增长 算子内显存泄漏 nsys profile
随机segfault 越界访问或野指针 cuda-gdb
性能突然下降 算子被回退到CPU nvidia-smi -q -d COMPUTE

我个人习惯,遇到算子问题先跑compute-sanitizer。这工具能检测到越界访问和未初始化内存,比肉眼查代码快多了。

实战案例:有一次vLLM推理结果全是0,我排查了三天。最后用compute-sanitizer --tool memcheck python run_inference.py跑了一遍,发现是attention算子里有个指针偏移量算错了。嗯,这种问题,光看日志是看不出来的。

为什么会这样?因为GPU是并行执行,错误往往不是立即崩溃,而是累积到某个临界点才爆发。所以,不要等出错了再查,要主动监控

推荐的生产监控指标:

# 每秒采集一次GPU健康状态
while true; do
    # 显存错误
    nvidia-smi --query-gpu=ecc.errors.volatile.dram --format=csv,noheader
    # 温度(超过85°C要报警)
    nvidia-smi --query-gpu=temperature.gpu --format=csv,noheader
    # 功率(异常波动可能预示硬件问题)
    nvidia-smi --query-gpu=power.draw --format=csv,noheader
    sleep 1
done

最后说一句:GPU故障处理,七分预防三分治。把监控做在前面,比事后救火轻松十倍。


公众号:蓝海资料掘金营,微信deep3321