GPU 服务器常见故障处理
本页目录
场景
GPU 服务器(训练卡、推理卡、显卡服务器)跑着任务出问题了:卡不见了、
nvidia-smi 报错、显存占用异常、训练突然中断、推理结果不对、温度报警。
这篇按「现象 → 定位 → 处理」整理,都是实际会遇到的。11111
前置条件
- 能 SSH 上服务器,或者有 IPMI / iDRAC / iLO 的远程控制台
- 记下这台机器用的卡型(A100 / H100 / L40S / RTX 4090 / 国产卡等)和驱动版本
- 有另一台同型号的机器能对照,出问题时好比对
- 重要任务先确认有 checkpoint,别在故障状态硬跑
- 驱动和 CUDA 版本先记下来,换驱动前一定要记
配置
1. nvidia-smi 找不到卡
最常见。按顺序查:
# 先看系统能不能看到卡
nvidia-smi
# 报错信息分几种:
# "command not found" → 驱动没装或 PATH 不对
# "Failed to initialize NVML" → 驱动加载了但和内核对不上
# "No devices were found" → 驱动在,但没找到硬件
三种情况分别处理:
驱动没装 / 装了但 PATH 不对
# 看驱动模块在不在
lsmod | grep nvidia
ls /proc/driver/nvidia/version
# 模块没加载,但文件在
modprobe nvidia
nvidia-smi
Failed to initialize NVML(驱动与内核版本不匹配)
这是升级内核或升级驱动之后最常见的。内核头文件和驱动版本对不上:
uname -r # 当前内核
cat /proc/driver/nvidia/version # 驱动带的内核版本
ls /usr/src/kernels/ # 有没有对应的头文件
两种修法:
# 办法一:装当前内核的头文件,然后重装驱动
apt install linux-headers-$(uname -r)
# 重新安装对应的 .run 驱动包(会重新编译内核模块)
# 办法二:回退内核(更稳,但要重启)
# 编辑 /etc/default/grub,把 GRUB_DEFAULT 改成旧内核
# update-grub && reboot
No devices were found(驱动在,但卡不被识别)
# PCI 层面能不能看到卡
lspci | grep -i nvidia
lspci -nn | grep -i "3d controller\|nvidia"
# 内核有没有报错
dmesg -T | grep -iE "nvidia|nvrm|nouveau" | tail -30
几种典型:
"NVRM: Xid: ... GPU has fallen off the bus" → 卡掉了,PCIe 链路问题(见第 4 节)
"NVRM: Failed to initialize GPU" → 卡本身或供电有问题
"unable to map BAR" → 内存映射失败,可能是 IOMMU 或 PCIe 设置
"Nouveau ... kernel driver" → 装了开源驱动,抢占了独显
如果是 nouveau 抢占了:
# 禁用开源驱动
echo "blacklist nouveau" >> /etc/modprobe.d/blacklist-nouveau.conf
echo "options nouveau modeset=0" >> /etc/modprobe.d/blacklist-nouveau.conf
update-initramfs -u && reboot
完全看不到卡(lspci 也没有)
那就是硬件层面的问题了:卡没插好、供电没接、卡坏了、或者 PCIe 插槽有问题。 这个只能去机房看。
2. 驱动版本不对 / CUDA 版本不匹配
# 驱动版本
nvidia-smi --query-gpu=driver_version --format=csv,noheader
# CUDA 运行时版本(注意:这是驱动最高支持的版本,不是装的 toolkit 版本)
nvidia-smi | head -3
# PyTorch 实际用的版本
python -c "import torch; print(torch.__version__, torch.version.cuda, torch.cuda.is_available())"
# 实际加载的驱动
cat /proc/driver/nvidia/version
对应关系:
| CUDA 版本 | 最低驱动 |
|---|---|
| 12.4 | 550 |
| 12.1 | 530 |
| 11.8 | 520 |
| 11.4 | 470 |
注意几个容易混的点:
torch.version.cuda → 编译 PyTorch 时用的 CUDA 版本
nvidia-smi 右上角的 CUDA → 驱动最高能支持的 CUDA 版本
nvidia-smi 显示的 CUDA 版本比 torch.version.cuda 高是正常的,不用管。
反过来说,如果 torch.cuda.is_available() 返回 False,PyTorch 自己带的 CUDA 库
和驱动不兼容才是问题。
常见报错:
"CUDA driver version is insufficient for CUDA runtime version"
→ 驱动太老,升级驱动
"CUDA error: no kernel image is available for execution on the device"
→ 驱动不支持这张卡的架构(Ampere / Hopper / Ada 的 sm_xx)
→ 升级驱动到支持该卡的版本,老驱动不认新卡
"undefined symbol: cudaGetDriverEntryPoint"
→ 装了多个 CUDA toolkit,环境变量指向了旧的
多 CUDA 版本共存时,看当前用的是哪个:
echo $CUDA_HOME
ls -la /usr/local/ | grep cuda
which nvcc && nvcc --version
3. 显存占用异常 / OOM
# 当前每张卡的占用
nvidia-smi --query-gpu=index,name,memory.total,memory.used,memory.free,utilization.gpu \
--format=csv
# 找出占显存的进程
nvidia-smi --query-compute-apps=pid,process_name,used_memory --format=csv
# 僵尸进程占用(进程已死但显存没释放)
fuser -v /dev/nvidia*
典型情况:
显存被僵尸进程占住
进程被 kill -9 了,但 CUDA context 没释放:
# 找到占用的进程
nvidia-smi --query-compute-apps=pid --format=csv,noheader
# 确认是僵尸(状态 Z)
ps -o pid,stat,cmd -p <PID>
# 清理
kill -9 <PID>
如果杀不掉,说明 GPU 卡住了,只能重启:
nvidia-smi --gpu-reset -i 0
# 报 "in use" 就只能重启机器
训练中途 OOM,但之前能跑
# 看是不是有其他进程抢了显存
nvidia-smi
# PyTorch 显存碎片
python -c "import torch; torch.cuda.empty_cache()"
# 混合精度没开
# 在代码里加:
# with torch.autocast('cuda', dtype=torch.float16):
设置显存占用比例(限制 PyTorch 抢多少):
export PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True
# 老版本用:
export PYTORCH_CUDA_ALLOC_CONF=max_split_size_mb:128
4. 训练中断 / "GPU has fallen off the bus"
这个报错最吓人,但通常不是卡坏了。
# 内核日志里的 Xid
dmesg -T | grep -iE "xid|nvidia" | tail -50
# 常见 Xid 码
# Xid 13/31 → 显存错误,可能卡坏了或过热
# Xid 48 → 双位错误,通常要换卡
# Xid 63/64 → 掉卡,PCIe 链路问题
# Xid 79 → GPU 掉卡(硬件故障)
先看物理连接:
# PCIe 链路状态和速率
nvidia-smi -q | grep -A 10 "GPU Link Info"
# Link Gen 和 Link Width 都要和安装时一致
# 实际协商到的速率(应为 PCIe 4.0 x16 之类)
nvidia-smi --query-gpu=pci.bus_id,pcie.link.gen.current,pcie.link.width.current \
--format=csv
如果协商速率降了(比如装在 x8 槽位上只能跑 x8,或者速率从 4 降到 1), 说明 PCIe 链路协商有问题,检查主板插槽和转接卡。
处理顺序:
# 1. 查温度(过热也会掉卡)
nvidia-smi --query-gpu=index,temperature.gpu,power.draw,power.limit,clocks_throttle_reasons.active \
--format=csv
# 2. 查电源线(8 pin / 12VHPWR 没插紧很常见)
# 需要去机房看
# 3. 复位 GPU
nvidia-smi --gpu-reset -i 0
# 4. 换槽位测试(能换机器上的另一个槽位最好)
电源线没插紧是掉卡的头号原因。12VHPWR 接头插一半特别容易, 而且接口会发热变色,插的时候要完全到底。
5. 温度报警 / 降频
# 详细温度
nvidia-smi --query-gpu=index,name,temperature.gpu,temperature.memory,\
power.draw,power.limit,clocks.sm,clocks.max.sm --format=csv
# 降频原因(0=正常,非 0 就是被限制)
nvidia-smi --query-gpu=index,clocks_throttle_reasons.active,\
clocks_throttle_reasons.sw_thermal_slowdown,\
clocks_throttle_reasons.hw_thermal_slowdown,\
clocks_throttle_reasons.sw_power_cap,\
clocks_throttle_reasons.hw_power_brake_slowdown --format=csv
常见原因和对策:
| 现象 | 原因 | 处理 |
|---|---|---|
| 温度 85℃+ 一直降频 | 风道堵了 / 风扇转速不够 | 清灰,检查机箱进风口 |
| 温度正常但功耗被限 | 电源功率不够 | 核对电源瓦数,升级电源 |
| 瞬时温度冲到 95℃ | 散热硅脂老化 | 换硅脂 |
| 温度传感器报错 | 卡或固件问题 | 查固件版本 |
数据中心卡(A100/H100)一般是被动散热,靠机箱风扇吹。这类卡 装在普通塔式机箱里温度一定高,装之前先确认机箱风道。
6. 推理结果不对 / 精度问题
# 看是不是掉到了低精度
nvidia-smi --query-gpu=index,name,clocks.sm,clocks.max.sm,power.draw --format=csv
# 检查浮点控制状态
import torch
print(torch.cuda.get_device_capability(0))
print(torch.backends.cuda.matmul.allow_tf32)
print(torch.backends.cudnn.allow_tf32)
几个常见的「结果不对」:
TF32 导致的精度差异
A100/H100 默认开 TF32,矩阵乘法精度从 FP32 降到 TF32。 和 CPU 对数或者做精度回归测试时会对不上:
torch.backends.cuda.matmul.allow_tf32 = False
torch.backends.cudnn.allow_tf32 = False
多卡结果不一致
# 检查各卡状态
nvidia-smi --query-gpu=index,name,persistence_mode,compute_mode --format=csv
compute_mode 应该是 Default。如果是 Exclusive Process,第二个进程就起不来。
DDP 通信卡住
# 看 NCCL 状态
echo $NCCL_DEBUG
export NCCL_DEBUG=INFO
export NCCL_P2P_DISABLE=1 # 排查 P2P 问题
export NCCL_IB_DISABLE=1 # 排查 InfiniBand 问题
NCCL 卡住通常是 PCIe 拓扑问题:
nvidia-smi topo -m
看同一组卡是不是挂在同一个 CPU socket 下(NVLink 有效), 跨 socket 的 P2P 通信会慢很多甚至卡死。
显存没对齐导致跑满
# 批大小不是所有卡的倍数
if batch_size % world_size != 0:
batch_size = (batch_size // world_size) * world_size
7. 多卡训练 NCCL 挂掉
# 常见报错
# "NCCL error: unhandled system error"
# "NCCL WARN Call to ibv_open_device failed"
# "NCCL INFO Bootstrap : no socket interface found"
排查:
# 1. 网卡状态(多机训练必查)
ibstat
ip addr show | grep ib
# 2. 端口和防火墙
ss -lntp | grep -E "29[0-9]{3}"
# 3. 关掉一些高级特性先跑通
export NCCL_P2P_DISABLE=1
export NCCL_SHM_DISABLE=1
export NCCL_IB_DISABLE=1
export NCCL_SOCKET_IFNAME=eth0
export NCCL_DEBUG=INFO
NCCL_SOCKET_IFNAME 一定要显式指定,否则多网卡机器上它可能选到
IB 网卡或者管理网口,bootstrap 就连不上。
单机能跑、多机不行,基本都是 IB 网卡或防火墙的问题。
8. 容器里用不了 GPU
# 容器里跑
docker run --gpus all nvidia/cuda:12.1.0-base-ubuntu22.04 nvidia-smi
报错和对策:
"could not select device driver "" with capabilities: [[gpu]]"
→ 没装 nvidia-container-toolkit
→ 装完要 systemctl restart docker
"unknown option --gpus"(老版本 docker)
→ docker 19.03 以下不支持,装个新版本
容器里 nvidia-smi 报 "Failed to initialize NVML"
→ 通常是宿主机驱动版本和容器内 CUDA 版本不匹配
→ 容器 CUDA 版本别超过宿主机驱动支持的版本
装 toolkit:
# Ubuntu
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \
sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg
curl -s -L https://nvidia.github.io/libnvidia-container/stable/$distribution/nvidia-container-toolkit.list | \
sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
sudo apt update && sudo apt install -y nvidia-container-toolkit
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker
9. 其他常见问题
MPS 用了之后卡住
# 启动 MPS
nvidia-cuda-mps-control -d
# 停掉
echo quit | nvidia-cuda-mps-control
# 残留的 MPS 进程要手动清理
ps aux | grep mps
nvidia-smi 显示 "GPU is lost"
# 软复位
nvidia-smi --gpu-reset -i 0
# 不行就硬复位
sudo nvidia-smi --gpu-reset -i 0
ECC 报错
nvidia-smi -q | grep -A 5 "ECC Errors"
H100/A100 的 ECC 计数涨了不一定坏,看 Volatile 和 Aggregate 两项,
Aggregate 持续涨说明显存真有问题。
持久化模式没开
计算节点建议开着,容器和长时间任务启动更快:
nvidia-smi -pm 1
# 做成开机自启
cat > /etc/systemd/system/nvidia-persistenced.service <<'EOF'
[Unit]
Description=NVIDIA Persisted Daemon
After=network.target
[Service]
Type=forking
ExecStart=/usr/bin/nvidia-smi -pm 1
ExecStop=/usr/bin/nvidia-smi -pm 0
[Install]
WantedBy=multi-user.target
EOF
systemctl enable --now nvidia-persistenced
验证
# 基础检查
nvidia-smi # 能看到所有卡,温度功耗正常
nvidia-smi --query-gpu=index,name,driver_version,memory.total,temperature.gpu \
--format=csv
# 负载测试
python -c "
import torch
print('可用:', torch.cuda.is_available())
print('卡数:', torch.cuda.device_count())
for i in range(torch.cuda.device_count()):
print(i, torch.cuda.get_device_name(i))
x = torch.randn(4096, 4096, device='cuda')
print('矩阵运算 OK:', (x @ x).sum().item())
"
# 显存能正常释放(跑完再查一次)
nvidia-smi --query-gpu=index,memory.used --format=csv
多卡环境还要确认:
nvidia-smi topo -m # PCIe 拓扑正常
ibstat # IB 网卡正常(多机训练)
python -c "
import torch, torch.distributed as dist
dist.init_process_group('nccl')
print('NCCL 正常')
"
回滚
- 换驱动前先备份旧版本:
# 记下当前版本
nvidia-smi --query-gpu=driver_version --format=csv,noheader
# 旧驱动安装包留着,别删
- 驱动装坏了先别急着重装,先试软复位:
sudo nvidia-smi --gpu-reset -i 0
- 内核升级前确认 DKMS 能编译:
# 确认 dkms 装好了
dkms status
# 内核头文件在不在
ls /usr/src/kernels/$(uname -r)
内核升级后驱动模块没了,就是 DKMS 没装或头文件不对。
- 固件升级(VBIOS)不可逆,升级前用
nvidia-smi -q | grep -i vbios记下版本, 确认有备份工具(NVFlash)再动手。 - 温度问题降级处理:临时限制功耗上限,比换硬件快。
nvidia-smi -pl 200 # 限制到 200W
坑
nvidia-smi显示的 CUDA 版本是驱动上限,不是实际用的版本,别照着它装 toolkit。torch.version.cuda和nvidia-smi的 CUDA 版本不一样是正常的。- 驱动升级完不重启内核不生效,模块还在内存里,得重启。
- 12VHPWR 电源线没插紧是掉卡头号原因,而且接口会发热变色,要插到底。
- 数据中心卡是被动散热,装塔式机箱里必热。
- 装完卡要在 BIOS 里开 Above 4G Decoding 和 ReBAR,否则性能打折甚至不识别。
nvidia-smi --gpu-reset在有进程占用时会失败,先清干净再复位。- 多机训练不指定
NCCL_SOCKET_IFNAME很可能 bootstrap 失败。 - TensorRT 缓存对不上驱动版本,换驱动后清缓存:
rm -rf ~/.cache/torch。 - 别在有 checkpoint 之前就反复重试训练,卡反复掉可能损坏 checkpoint 文件。
- ECC 报错别忽略,Volatile 涨可以清,Aggregate 涨就得换卡了。
- 国产卡(华为昇腾、寒武纪等)的 CUDA 生态不一样,这套命令大多不通用, 得看厂商自己的工具链。