3. GPU不可见问题
好,咱们接着聊GPU调度里最让人头疼的一类问题——GPU不可见。
说白了,就是你明明插着卡,系统也认了,但应用就是找不到GPU。我这些年排查下来,90%的不可见问题都出在三个地方:驱动没加载、权限不够、容器里没配好。咱们一个一个拆开讲。
3.1 驱动未加载——最基础的坑
先问个问题:你插上GPU后,第一件事做什么?
我个人习惯,先敲nvidia-smi。如果它报错或者没输出,那驱动大概率没跑起来。
典型症状:
nvidia-smi提示 "NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver"lspci | grep -i nvidia能看到显卡,但驱动没绑定lsmod | grep nvidia返回空
为什么会这样?我遇到过好几次,最常见的原因是内核升级后驱动没重新编译。你想想看,Linux内核一升级,原来装好的驱动模块就失效了。
排查步骤:
- 先确认硬件是否被识别:
lspci | grep -i nvidia - 检查驱动模块是否加载:
lsmod | grep nvidia - 如果没加载,手动试试:
modprobe nvidia - 查看内核版本和驱动版本是否匹配:
uname -r对比cat /proc/driver/nvidia/version
小技巧: 我习惯在装驱动前先 apt-mark hold linux-image-$(uname -r) 锁定内核版本,避免一升级就炸。
3.2 权限不足——用户没资格用GPU
驱动加载成功了,但普通用户一跑程序就报错:CUDA error: no kernel image is available for execution on the device 或者干脆 Permission denied。
嗯,这里要注意。GPU设备文件默认属于root用户和video组。普通用户如果不在video组里,就没法访问。
我曾经帮一个团队排查,他们所有容器都跑在普通用户下,结果GPU全不可用。折腾了半天,最后发现是用户没加到video组。
权限检查清单:
- 查看设备文件权限:
ls -l /dev/nvidia* - 确认用户组归属:
groups $USER - 如果缺少video组:
sudo usermod -aG video $USER - 别忘了重新登录生效
还有一个容易被忽略的点——SELinux或AppArmor。我遇到过一台CentOS机器,所有权限都对了,但GPU就是不可见。最后发现是SELinux把设备访问给拦了。临时关掉测试一下:setenforce 0,如果好了,再去配策略。
3.3 容器内无法识别GPU——Docker和Kubernetes的坑
这部分我踩过的坑最多。主机上nvidia-smi跑得好好的,一进容器就找不到GPU。
核心原因就一个: 容器默认不共享宿主机的GPU设备。你得显式告诉容器:「嘿,把GPU挂进来」。
3.3.1 Docker场景
Docker 19.03之后,官方推荐用 --gpus 参数。以前还得挂设备文件、装nvidia-docker2,现在简单多了。
# 正确用法
docker run --gpus all nvidia/cuda:11.0-base nvidia-smi
# 或者指定某张卡
docker run --gpus '"device=0,1"' nvidia/cuda:11.0-base nvidia-smi
如果你还在用老版本Docker,那得装nvidia-container-runtime:
# 安装nvidia-container-runtime
sudo apt-get install nvidia-container-runtime
# 配置Docker daemon
sudo tee /etc/docker/daemon.json <<EOF
{
"runtimes": {
"nvidia": {
"path": "/usr/bin/nvidia-container-runtime",
"runtimeArgs": []
}
}
}
EOF
# 重启Docker
sudo systemctl restart docker
# 运行时指定runtime
docker run --runtime=nvidia nvidia/cuda:11.0-base nvidia-smi
我个人的排查习惯:
先在宿主机上跑 nvidia-smi 确认驱动正常。然后用 docker run --gpus all --rm nvidia/cuda:11.0-base nvidia-smi 测试。如果容器里看不到,90%是runtime没配好或者Docker版本太老。
3.3.2 Kubernetes场景
K8s里GPU不可见,通常是因为没装device plugin。我见过有人手动给Pod加了 resources: nvidia.com/gpu: 1,但集群里根本没部署NVIDIA device plugin,那当然不生效。
标准做法:
- 确保每个GPU节点都装了NVIDIA驱动和nvidia-container-runtime
- 部署NVIDIA device plugin DaemonSet
- 在Pod的resources里声明
nvidia.com/gpu
# 部署device plugin(官方推荐)
kubectl create -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v0.14.0/nvidia-device-plugin.yml
# Pod示例
apiVersion: v1
kind: Pod
metadata:
name: gpu-pod
spec:
containers:
- name: cuda-container
image: nvidia/cuda:11.0-base
command: ["nvidia-smi"]
resources:
limits:
nvidia.com/gpu: 1 # 申请1张GPU
注意: 如果你用的是containerd而不是Docker,记得在containerd配置里加上nvidia-container-runtime的配置。我去年帮一个客户排查,他们从Docker切到containerd后GPU全不可用,就是少了这步。
3.4 快速排查表
| 现象 | 可能原因 | 快速验证命令 | 解决方案 |
|---|---|---|---|
| nvidia-smi 报错 | 驱动未加载 | lsmod | grep nvidia |
重新安装或加载驱动 |
| 普通用户无法访问 | 权限不足 | ls -l /dev/nvidia* |
加入video组 |
| 容器内nvidia-smi失败 | 缺少--gpus参数 | docker run --gpus all ... |
添加--gpus或配置runtime |
| K8s Pod调度失败 | 未部署device plugin | kubectl describe pod |
部署NVIDIA device plugin |
最后说一句: 排查GPU不可见问题,我个人的顺序永远是「驱动 → 权限 → 容器配置」。别一上来就怀疑容器,先看看宿主机上能不能用。基础打牢了,上层的问题自然好解决。