对于每一位 AI 从业者和深度学习炼丹师来说,拥有一台满载 8 张 RTX 4090 的算力服务器绝对是梦寐以求的利器。然而,这套性能怪兽也是极其敏感的。
最近,我的服务器就遭遇了一个经典且令人抓狂的“幽灵故障”:系统跑着跑着,隔三差五就会突然掉驱动。原本好好的多张 4090,瞬间只能识别到两三张,而且完全无法调用。更诡异的是,只要把系统一重启,所有显卡又立刻满血复活。
这种现象在多卡工作站中被称为 "GPU Falling off the bus"(GPU 从总线上掉线)。经过一系列抽丝剥茧的排查,我不仅找到了硬件底层的症结,还顺手撸了一个带“飞书告警”的自动化看门狗脚本。今天,就把这份多卡服务器的排查与自救指南分享给大家。
第一步:抓取案发现场,让日志说话
遇到掉卡,千万不要急着盲目重启,重启会掩盖案发现场的线索。最准确的排查起点,是查看系统的内核日志。
在终端中执行以下命令:
dmesg -T | grep -i -E "nvrm|pcie|xid"
# 或者
sudo grep -i "fallen off the bus" /var/log/kern.log
在我的服务器崩溃日志中,满屏都是极其刺眼的底层报错:
NVRM: GPU 0000:21:00.0: RmInitAdapter failed! (0x62:0x40:2522)NVRM: GPU 0000:c1:00.0: RmInitAdapter failed! (0x62:0x65:2522)NVRM: GPU 0000:c2:00.0: RmInitAdapter failed! (0x62:0x65:2522)
破案线索一: RmInitAdapter failed 意味着英伟达驱动尝试通过主板去唤醒并初始化显卡时,PCIe 通信直接失败了,驱动连卡都“握手”不上。
破案线索二: 日志极其精准地暴露出,每次发生掉线的,都是 PCIe 总线地址为 21:00.0、c1:00.0 和 c2:00.0 的这三张卡。
第二步:深入拓扑图,揪出幕后真凶
为什么总是这三张卡“手牵手”一起掉线?为了搞清楚物理硬件的分布,在系统刚重启恢复正常后,我立即运行了拓扑查看命令:
nvidia-smi topo -m
通过拓扑图,结合报错的 Bus ID,我发现了一个极其关键的跨 CPU 掉线现象:
这是一台双路 CPU(NUMA 0 和 NUMA 1)服务器。
- 掉线的
21:00.0挂在 CPU 0 的通道下。 - 掉线的
c1:00.0和c2:00.0挂在 CPU 1 的通道下。
推理过程:
能让跨越两颗不同 CPU 的三张显卡在同一秒钟瞬间失联的,基本上排除了单一主板插槽损坏或单一 CPU 通道故障的可能性。最大的嫌疑犯只有一个:电源 (PSU)。
要知道,单张 4090 的满载功耗为 450W,但 4090 存在极其恐怖的瞬时峰值功耗 (Transient Spikes),瞬间波峰可能超过 600W。当多张卡同时爆发高负载时,如果这 3 张卡刚好都接在了同一个副电源上,瞬间的恐怖电流就会触发该副电源的 OCP(过流保护)。电源为了自保会瞬间切断或降低电压,这几张卡就会瞬间“窒息”,从而在 PCIe 总线上消失。
第三步:对症下药,软硬结合的排查清单
明确了嫌疑对象,我们就可以采取“外科手术式”的修复策略。
1. 软件级快速验证:锁定功耗墙(立刻见效)
为了证实电源供电不足的猜想,最快的方法就是锁功耗。在不影响大模型推理性能的前提下,将显卡功耗上限强制限制在 300W:
sudo nvidia-smi -pl 300
如果在锁了 300W 之后服务器再也不掉卡了,那就百分之百实锤了:原本的电源在峰值时带不动这几张卡了。
2. 软件与 BIOS 层面的维稳设置
在多卡系统中,以下几个设置是“保命”的基础:
- 关闭 ASPM: 编辑
/etc/default/grub,在启动项中加入pcie_aspm=off,防止 PCIe 链路在空闲时频繁休眠导致唤醒超时。 - 开启持久化模式: 执行
sudo nvidia-smi -pm 1,防止驱动在显卡空闲时被卸载。 - 降级 PCIe Gen 3: 如果你使用了 PCIe 延长线,强烈建议进 BIOS 将对应的 PCIe 速度从 Auto 或 Gen 4 降级为 Gen 3。Gen 4 对电磁干扰极其敏感,容易导致通信断裂,而 Gen 3 对于 AI 炼丹的带宽通常绰绰有余且稳如老狗。
3. 硬件终极修复
等停机维护时,顺着 21:00、c1:00、c2:00 这三张卡的电源线摸一下,将它们的供电线与其他运行正常的显卡电源线均匀混插,分摊副电源的压力。同时,检查这三个槽位的 PCIe 延长线是否有受热老化变形的情况,必要时予以更换。
第四步:终极兜底方案 —— 带飞书告警的自动化“看门狗”
虽然找出了病因,但如果半夜正在跑关键的训练任务时突然掉卡,难道还得定闹钟爬起来重启吗?为了实现真正的“无人值守”,我用 Shell 写了一个 Watchdog(看门狗)守护脚本,并接通了飞书机器人告警。
它的逻辑很简单:每 5 分钟巡视一次底层日志,一旦发现显卡掉线或驱动假死,立刻向飞书群发送案发报告,随后强行执行安全重启,让算力自动满血复活!
1. 创建脚本
创建文件 /usr/local/bin/gpu_watchdog.sh,写入以下代码:
#!/bin/bash
# ================= 配置区 =================
# 替换为你自己的飞书机器人的 Webhook URL
FEISHU_WEBHOOK="https://open.feishu.cn/open-apis/bot/v2/hook/xxxxxxx-xxxx-xxxx-xxxx-xxxxxxx"
CURRENT_TIME=$(date "+%Y-%m-%d %H:%M:%S")
HOST_NAME=$(hostname)
# =========================================
# 1. 检查日志与驱动状态 (仅提取最新 100 行,防止被旧日志重复触发)
ERROR_COUNT=$(dmesg -T | tail -n 100 | grep -i "RmInitAdapter failed" | wc -l)
nvidia-smi > /dev/null 2>&1
SMI_STATUS=$?
# 2. 判断是否需要重启,并记录具体原因
REBOOT_REASON=""
if [ $ERROR_COUNT -gt 0 ]; then
REBOOT_REASON="内核检测到显卡底层通信断开 (RmInitAdapter failed)"
elif [ $SMI_STATUS -ne 0 ]; then
REBOOT_REASON="显卡驱动完全无响应 (nvidia-smi 挂起)"
fi
# 3. 触发通知与重启流程
if [ -n "$REBOOT_REASON" ]; then
# 记录本地日志留底
echo "[$CURRENT_TIME] 触发自动重启,原因:$REBOOT_REASON" >> /var/log/gpu_watchdog.log
# 构造飞书消息内容
MSG_TEXT="🚨 [GPU告警] 服务器即将自动重启\n\n🖥 主机名:$HOST_NAME\n⏰ 时间:$CURRENT_TIME\n💥 原因:$REBOOT_REASON\n\n🔧 动作:正在同步数据落盘,系统将在几秒后强行重启以恢复算力..."
# 发送 HTTP POST 请求给飞书机器人
curl -s -X POST -H "Content-Type: application/json" \
-d '{"msg_type":"text","content":{"text":"'"$MSG_TEXT"'"}}' \
$FEISHU_WEBHOOK
# 强制同步内存数据到磁盘,防止文件损坏
sync
# ⚠️ 关键缓冲:等待 5 秒,确保飞书消息成功发出去后再断网
sleep 5
# 执行重启
/sbin/reboot
fi
赋予执行权限:
sudo chmod +x /usr/local/bin/gpu_watchdog.sh
2. 部署定时任务
通过 sudo crontab -e 编辑 root 用户的定时任务,在末尾加入:
*/5 * * * * /usr/local/bin/gpu_watchdog.sh
保存退出后,这套 8 卡算力怪兽就拥有了极强的自我治愈能力。
总结
多卡 4090 服务器遇到掉卡问题,绝大多数都不是显卡本身的硬件损坏,而是 PCIe 通信衰减、瞬时功耗波峰过大 或 Linux 电源管理策略冲突 导致的。
遇到问题,先看 dmesg 日志,再看 topo 拓扑图,通过锁功耗来快速排除电源问题。在彻底解决物理硬件隐患之前,部署一个 Watchdog 看门狗脚本,是保障生产力不断档的最佳兜底方案。
祝大家的炼丹炉永不宕机,Loss 天天下降!
版权属于:soarli
本文链接:https://blog.soarli.top/archives/891.html
转载时须注明出处及本声明。