前言#
今天在运行 vscode 代码时,报错 RuntimeError: No CUDA GPUs are available
,令人差异,遂进入命令行检查,发现似乎掉显卡驱动了。(注:本文出乎意料的包含但不限于重装显卡驱动,重装WIFI驱动,修改Linux内核版本等问题的解决,如果此过程仍未解决你的问题,欢迎留言讨论)
问题描述#
1.命令行输入:
nvidia-smi
输出:
NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver. Make sure that the latest NVIDIA driver is installed and running.
2.此时检查 cuda,输入:
nvcc -V
意外的输出:
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2022 NVIDIA Corporation
Built on Wed_Sep_21_10:33:58_PDT_2022
Cuda compilation tools, release 11.8, V11.8.89
Build cuda_11.8.r11.8/compiler.31833905_0
说明驱动存在。
3.输入
ls /usr/src | grep nvidia
可以得到当前的驱动版本号:nvidia-535.183.01
解决办法#
1.#
根据网上的解决办法,首先尝试:
sudo apt-get install dkms
sudo dkms install -m nvidia -v 535.183.01
其中第 2 行 535.183.01
表示的是驱动版本号,应该替换为自己的驱动版本号)
可是结果却是:
Module nvidia/535.183.01 already installed on kernel 6.8.0-48-generic (x86_64).
再次输入 nvidia-smi
依然报错。
2.#
尝试另一种办法,在 ubuntu 开机启动项中选择 advanced 模式,其中选择版本号不同的上一内核启动,依然无效。
经过询问,猜测可能是内核版本自动更新过高,导致装不上驱动(本机内核版本为 6.8.0-48-generic),于是开始搜索如何安装低版本内核。
3.#
安装低版本内核,这里以 5.15.0-25-generic 举例。首先查看 grub 版本:
grub-install --version
结果是:grub-install (GRUB) 2.06-2ubuntu7.2
其中版本很重要,我的是 2.06
,大于 2.00,若是小于 2.00 的在下面的步骤中有区别。
接下来查看自己现有的内核版本(在Ubuntu启动项页面,查看advance项也能看到),输入:
grep 'menuentry' /boot/grub/grub.cfg
可以得到如下结果:(7-10行就是 linux 内核)
if [ x"${feature_menuentry_id}" = xy ]; then
menuentry_id_option="--id"
menuentry_id_option=""
export menuentry_id_option
menuentry 'Ubuntu' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-simple-81fae8c4-e902-410a-a709-dd3d57a11e8b' {
submenu 'Advanced options for Ubuntu' $menuentry_id_option 'gnulinux-advanced-81fae8c4-e902-410a-a709-dd3d57a11e8b' {
menuentry 'Ubuntu, with Linux 6.8.0-48-generic' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-6.8.0-48-generic-advanced-81fae8c4-e902-410a-a709-dd3d57a11e8b' {
menuentry 'Ubuntu, with Linux 6.8.0-48-generic (recovery mode)' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-6.8.0-48-generic-recovery-81fae8c4-e902-410a-a709-dd3d57a11e8b' {
menuentry 'Ubuntu, with Linux 6.8.0-47-generic' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-6.8.0-47-generic-advanced-81fae8c4-e902-410a-a709-dd3d57a11e8b' {
menuentry 'Ubuntu, with Linux 6.8.0-47-generic (recovery mode)' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-6.8.0-47-generic-recovery-81fae8c4-e902-410a-a709-dd3d57a11e8b' {
menuentry 'Windows Boot Manager (on /dev/nvme0n1p1)' --class windows --class os $menuentry_id_option 'osprober-efi-BE9A-11EB' {
menuentry 'UEFI Firmware Settings' $menuentry_id_option 'uefi-firmware' {
接下来安装想要的旧版本,输入:
sudo apt install linux-image-5.15.0-25-generic
之后修改 /etc/default/grub
文件,输入:
sudo gedit /etc/default/grub
将 GRUB_DEFAULT=0
的 0 替换为一段文本:这里与前面的 grub 版本有关:
- 如果是小于2的版本,先复制上面第6行的
submenu
后面的句子Advanced options for Ubuntu
,接下来输入一个>
,接下来复制上面第7行menuentry
后面的句子,并把版本改为上面新下载的版本Ubuntu, with Linux 5.15.0-25-generic
。最终结果为GRUB_DEFAULT="Advanced options for Ubuntu>Ubuntu, with Linux 5.15.0-25-generic"
- 如果是大于2的版本,先复制上面第6行的
$menuentry_id_option
后面的句子gnulinux-advanced-81fae8c4-e902-410a-a709-dd3d57a11e8b
,接下来输入一个>
,接下来复制上面第7行$menuentry_id_option
后面的句子,并把版本改为上面新下载的版本gnulinux-5.15.0-25-generic-advanced-81fae8c4-e902-410a-a709-dd3d57a11e8b
。最终结果为GRUB_DEFAULT="gnulinux-advanced-81fae8c4-e902-410a-a709-dd3d57a11e8b>gnulinux-5.15.0-25-generic-advanced-81fae8c4-e902-410a-a709-dd3d57a11e8b"
- 值得注意的是,
GRUB_DEFAULT=
后面的文本要带有双引号,中间的大于号不要忘了。 - 对于 ubuntu22.04 系统,还需要在末尾加入一段
GRUB_DISABLE_OS_PROBER=false
最后执行更新命令:
sudo update-grub
为避免出现 kernel headers are incomplete
的问题,直接将 kernel header 装一下:
sudo apt-get install linux-headers-5.15.0-25-generic
接下来重启,结果在启动Ubuntu时,载入内核时报错:Shim签名无效
无奈只能解决签名无效的问题。
4.#
经过搜索,最简单的方法是在 bios 中将安全启动关闭,尝试有效,输入:
uname -r
输出:5.15.0-25-generic
处于崩溃边缘的我看到了一丝希望,这时重新安装驱动,诶?我wifi图标去哪了?
使用 iwconfig
命令,结果是:lo no wireless extensions.
。并且发现使用原来的 6.8.0-48-generic
内核启动,可以正常连 wifi。???,去官网得知最新的版本驱动只支持内核版本 6.1 以上的,推测是内核改动导致驱动不识别,需要找一个适合内核版本的驱动。
5.#
首先查看网卡型号(可以使用能联网的内核启动查看),我的型号是 Intel AX211 Wi-Fi6
,在能联网的内核启动,执行:
sudo apt install flex bison
git clone https://github.com/intel/backport-iwlwifi.git
接下来到无驱动的内核,输入:
cd backport-iwlwifi
cd iwlwifi-stack-dev
sudo make defconfig-iwlwifi-public
sudo make
sudo make install
接下来重启,wifi图标回来了。
6.#
回到我们的正题,安装显卡驱动,首先在官网下载驱动安装包。
接下来先禁用 nouveau:
sudo gedit /etc/modprobe.d/blacklist-nouveau.conf
在文件中加入两行:
blacklist nouveau
options nouveau modeset=0
更新一下:
sudo update-initramfs -u
之后重启,重启之后验证一下是否禁用成功:
lsmod | grep nouveau
如果无输出,则禁用成功。
接下来开始驱动安装,首先找到驱动文件(通常在主目录下的 Downloads 目录),进入目录:
cd Downloads
这里以我下载的 NVIDIA-Linux-x86_64-535.154.05.run
举例。
卸载原有驱动,并给新下载的 .run
文件赋予执行权限(第3行的 -no-opengl-files
意思是只安装驱动文件,不安装 OpenGL 文件):
sudo apt-get remove nvidia-*
sudo chmod a+x NVIDIA-Linux-x86_64-535.154.05.run
sudo ./NVIDIA-Linux-x86_64-535.154.05.run -no-opengl-files
一路 Enter,最后挂载驱动:
sudo modprobe nvidia
最后的最后,我们检查一下驱动安装情况:
nvidia-smi
成功显示!但是这里我又遇到了问题,虽然成功显示了 nvidia-smi 界面,但显卡栏并未读出来显卡,反而显示无显卡设备,代码也依然跑不起来。
7.#
换一种安装方法吧,这里换成用PPA方法命令行安装。
首先先将上面的所有驱动全部删除(前3行是删除命令行安装的驱动;4-7行是卸载用 .run
文件安装的驱动):
sudo apt-get --purge remove nvidia*
sudo apt-get --purge remove "*nvidia*"
sudo apt-get remove --purge nvidia-*(/nvidia*)
cd /usr/bin
ls nvidia-*
sudo nvidia-uninstall
sudo /usr/bin/nvidia-uninstall
全部尝试过后,查看一下是否卸载干净:
ls /usr/src | grep nvidia
接下来添加PPA镜像源,开始安装:
sudo add-apt-repository ppa:graphics-drivers/ppa
sudo apt-get update
ubuntu-drivers devices
会出现许多推荐的驱动版本,没有我们想要的也没关系。(我的显示如下)
== /sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0 ==
modalias : pci:v000010DEd00002783sv00001B4Csd000018CAbc03sc00i00
vendor : NVIDIA Corporation
manual_install: True
driver : nvidia-driver-560-open - third-party non-free
driver : nvidia-driver-550-server - distro non-free
driver : nvidia-driver-550-open - third-party non-free
driver : nvidia-driver-550 - third-party non-free
driver : nvidia-driver-560 - third-party non-free recommended
driver : nvidia-driver-555 - third-party non-free
driver : nvidia-driver-550-server-open - distro non-free
driver : nvidia-driver-555-open - third-party non-free
driver : xserver-xorg-video-nouveau - distro free builtin
但是这里我们想安装 535 版本的驱动,直接尝试:
sudo apt install nvidia-driver-535
安装完成后重启,再次检测:
nvidia-smi
成功显示显卡型号!

在系统设置中的关于也可以看到显卡能检测为 NVIDIA 显卡:

最后的最后,跑代码也能顺利运行,真正成功!
8.#
为了避免以后遇到同样的问题,可以将系统更新,内核更新等全部关掉。
输入:
sudo gedit /etc/apt/apt.conf.d/10periodic
sudo gedit /etc/apt/apt.conf.d/20auto-upgrades
将这些后面参数全部设为 0。
再输入:
sudo apt-mark hold linux-image-5.15.0-25-generic
sudo apt-mark hold linux-headers-5.15.0-25-generic
sudo apt-mark hold linux-modules-5.15.0-25-generic
使得软件包保持现状,可以查看hold的软件包:
sudo apt-mark showhold
若想取消hold,可以输入:
sudo apt-mark unhold linux-image-5.15.0-25-generic
sudo apt-mark unhold linux-headers-5.15.0-25-generic
sudo apt-mark unhold linux-modules-5.15.0-25-generic
另外,在 Software & Updates(软件和更新)中,找到 update(更新)标签,将 Automatically check for updates(自动检查更新)选项设为 Never(从不),如图:

后记#
这个问题真是浅入深出啊,本来以为是个简单的掉驱动问题,没想到解决了一圈,花了一整天时间,Ubuntu 你罪该万死啊!
参考文献#
1.NVIDIA驱动失效简单解决方案:NVIDIA-SMI has failed because it couldn‘t communicate with the NVIDIA driver.
2.显卡驱动报错:NVIDIA-SMI has failed because it couldn’t communicate with the NVIDIA driver.v
5.ubuntu20.04.6安装Intel AX211网卡驱动 2024.8