第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!"状态。
我的恢复流程分三步:
- 先重启nvidia-persistenced服务——这能解决80%的临时问题
- 重新加载驱动模块——解决内核态问题
- 重装驱动——最后手段
快速恢复脚本:
#!/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