拿到RTX 4090之后最磨人的往往不是显卡本身而是Ubuntu 20.04下的这套深度学习环境。很多人卡在驱动装完黑屏、CUDA版本对不上、PyTorch跑起来直接报“no kernel image available”折腾两三天才反应过来是哪个环节出了问题。这篇文章就是把我在RTX 4090机器上从零配置Ubuntu 20.04、Nvidia显卡驱动、CUDA 11.6.0、cuDNN 8.5的完整过程和踩坑记录整理出来给同样在配环境的人一份可以直接照着做的参考。这套方案特别适合刚入手RTX 4090、准备在这张卡上跑深度学习训练或推理的人。不管你是学生、研究员还是公司内部搭GPU服务器的运维只要目标是“Ubuntu 20.04 RTX 4090”这套组合文章里涉及的选型逻辑、安装步骤和问题排查基本都能覆盖到。我会把每一步为什么要这么做也讲清楚这样你遇到跟我不完全一样的报错时也能有自己的判断。1. 环境配置的整体思路与方案选型1.1 为什么锁定Ubuntu 20.04、CUDA 11.6.0、cuDNN 8.5这套组合很多人在配4090环境时会有一个惯性思维就是要用最新版本系统加最新CUDA。但实际搞过几台服务器之后你会发现深度学习环境最重要的是“各组件之间能稳定咬合”而不是单点追求新。先说系统。Ubuntu 20.04在2024年仍然处于标准支持期内而且这个版本的内核和驱动兼容性非常成熟网上能搜到的经验贴最多遇到问题最容易找到解决方案。Ubuntu 22.04虽然也好但有些深度学习相关的库在20.04上编译好的wheel包直接能用切到22.04之后可能因为glibc版本或Python版本差异出现莫名奇妙的兼容问题。所以除非你的项目代码明确依赖22.04否则20.04是更稳妥的选择。再说CUDA版本。RTX 4090是Ada Lovelace架构计算能力是sm_89。很多人以为必须用最新CUDA才能驱动其实不然。CUDA 11.6.0这个版本已经加入了Ada架构的编译支持而Nvidia官方驱动从510.39.01开始就能完整支持RTX 4090。选择CUDA 11.6.0而不是最新的CUDA 12.x核心原因是很多深度学习框架和第三方库在CUDA 11.x生态下兼容性最稳尤其是PyTorch生态里大量的预编译轮子wheel包都默认对应CUDA 11.6或11.7装起来可以省掉很多自己编译的麻烦。cuDNN 8.5则是和CUDA 11.6配套的成熟版本深度学习框架官方测试矩阵里就包含这个组合。换句话说这个方案不是最新但它是“被验证过最多次、坑最少”的组合。1.2 驱动版本、CUDA Toolkit和显卡算力三者的关系这部分我觉得还是有必要聊一下因为很多报错的根源就是没搞懂驱动和CUDA Toolkit之间的关系。Nvidia显卡驱动是运行在系统层的它负责操作系统和GPU之间的通信CUDA Toolkit是开发层里面包含了编译器nvcc、运行时库和开发工具。你安装的驱动版本决定了它最多能支持哪个版本的CUDA Toolkit而CUDA Toolkit本身不包含驱动或者说它自带的驱动往往不如单独安装的驱动新。nvidia-smi命令输出顶部会显示一行“CUDA Version”例如12.4这很容易让人误会当前环境就是CUDA 12.4。实际上这个数字表示的是当前驱动版本“能够支持的最高CUDA版本”并不代表你系统里已经装了CUDA Toolkit 12.4。真正决定代码编译和运行环境的是你PATH和LD_LIBRARY_PATH里指向的那个CUDA Toolkit版本。RTX 4090本身需要的驱动最低版本是520.61.05512.15可以点亮但稳定性不佳不建议。CUDA 11.6.0对驱动的最低要求是510.39.01。实际安装时建议选择一个比两个要求都高的驱动版本比如我这边用的是525.105.17跑CUDA 11.6配套的深度学习框架很稳。这里给一个简单的兼容对照表方便你选择组件版本选择最低驱动要求说明Nvidia驱动525.105.17或535系列无必须支持Ada架构建议≥520.61.05CUDA Toolkit11.6.0≥510.39.01首个正式支持sm_89的部分特性cuDNN8.5.0跟随CUDA与CUDA 11.6配套验证过的版本Python3.8/3.10无关建议用conda或venv管理从计算能力的角度来说RTX 4090的sm_89在PyTorch里的支持经历了一个过程PyTorch 1.13及更早版本的cu116预编译包其实没有包含sm_89的kernel直接跑会报“no kernel image available is found on the device”这个典型错误。到PyTorch 2.0才完全添加了对sm_89的支持。所以如果你是PyTorch用户安装时尽量选2.0及以上版本或者自己编译这个坑后文还会单独展开。2. 系统准备与Nvidia显卡驱动安装2.1 Ubuntu 20.04安装时的两个关键设置系统安装阶段有两个设置会直接影响后续显卡驱动装得顺不顺。第一是在引导安装时如果你用Nvidia显卡且显示器接在4090上大概率会遇到安装界面进入不了图形化的情况。解决办法是在GRUB引导界面选中“Install Ubuntu”后按e编辑启动参数在linux这一行的末尾加上nomodeset然后按F10启动。nomodeset的作用是让内核在启动时不自动加载显卡驱动模块这样安装程序就能正常用软件渲染把桌面跑起来装完系统后再手动安装Nvidia驱动。第二个关键是安装时确保勾选“Install third-party software for graphics and Wi-Fi”。很多人不勾这个选项导致装完系统后网络和显卡适配都麻烦。如果已经漏掉了问题也不大后面手动换源和装驱动时一起处理。系统装好后我习惯先做两件事更新软件源并升级基础软件包。这里注意Ubuntu官方源在国内下载速度不稳定建议把源替换成清华或阿里云的镜像源。操作很简单修改/etc/apt/sources.list把archive.ubuntu.com替换成mirrors.tuna.tsinghua.edu.cn或mirrors.aliyun.com。执行sudo apt update sudo apt upgrade -y把系统基础依赖都刷到最新再开始装驱动。2.2 禁用Nouveau开源驱动Ubuntu系统默认集成了一个开源的Nvidia驱动叫Nouveau。这个驱动的问题是它和Nvidia官方驱动的加载方式冲突如果不禁用它安装官方驱动后重启往往会导致黑屏、卡在登录界面或者循环登录。所以装官方驱动之前必须先把Nouveau拉黑。具体的操作是创建一个配置文件内容固定为以下两行sudo bash -c echo blacklist nouveau /etc/modprobe.d/blacklist-nouveau.conf sudo bash -c echo options nouveau modeset0 /etc/modprobe.d/blacklist-nouveau.conf然后更新内核模块映射并重启sudo update-initramfs -u sudo reboot重启之后验证一下Nouveau是否真正被禁用了执行lsmod | grep nouveau如果没有任何输出就说明禁成功了。这一步不能跳过我见过太多人因为省这一步驱动装完黑屏然后以为是驱动版本的问题实际上就是Nouveau在捣乱。2.3 安装Nvidia驱动runfile方式与apt方式的取舍Nvidia驱动安装有几种方式我推荐手动下载runfile安装。理由有三个方面第一runfile方式可以精确指定驱动版本不会被apt源的版本策略带偏第二即使你已经装过旧驱动runfile安装时它也会检测并替换第三安装过程会打印详细日志出了问题更好排查。到Nvidia官网驱动下载页面选择你的显卡型号和Linux 64-bit系统搜索结果里会出现一长串版本。对于RTX 4090建议选择525系列或535系列的最新版本比如525.105.17或535.104.05。下载后得到的是一个.run文件先为它加执行权限chmod x NVIDIA-Linux-x86_64-525.105.17.run由于驱动安装时需要关闭图形界面强烈推荐直接用“CtrlAltF3”切换到纯文本终端TTY登录后在终端里执行安装。如果你当前正开着桌面环境runfile会提示你需要关闭X server才能继续。安装命令如下sudo ./NVIDIA-Linux-x86_64-525.105.17.run --no-opengl-files --no-x-check这里我用了--no-opengl-files跳过OpenGL文件安装主要是避免和系统的桌面环境冲突服务器上更安全。--no-x-check则是让安装程序不检查X server是否在运行在纯文本终端里其实不加也行加上更保险。安装过程会问你是否安装32位兼容库、是否运行nvidia-xconfig等默认选项即可。装完后写一下内核模块sudo modprobe nvidia然后执行nvidia-smi如果正常输出GPU名称、驱动版本、显存信息那么驱动就已经生效了。我这边安装完成后显示的信息大概是这样--------------------------------------------------------------------------------------- | NVIDIA-SMI 525.105.17 Driver Version: 525.105.17 CUDA Version: 12.0 | ---------------------------------------------------------------------------------------注意CUDA Version显示12.0这只是说驱动能支持到CUDA 12.0不影响我们在下面安装CUDA Toolkit 11.6.0。如果你更习惯用apt方式安装也可以先加Nvidia官方PPAsudo add-apt-repository ppa:graphics-drivers/ppa sudo apt update sudo apt install nvidia-driver-525这种方式的好处是以后内核升级时模块会自动通过DKMS重建坏了也容易卸载恢复。但安装在哪个版本上不够灵活而且部分系统环境下PPA和镜像源混用可能导致依赖问题。所以我个人还是建议runfile。3. CUDA 11.6.0与cuDNN 8.5安装3.1 用runfile方式安装CUDA ToolkitCUDA Toolkit官方提供了deb网络安装包和runfile两种安装方式。我强烈建议用runfile不是因为它复杂而是因为runfile方式在换版本时最方便。deb方式会把驱动也带上而且通过apt管理容易和已经装好的驱动互相干扰。runfile方式默认只安装CUDA Toolkit本身不带驱动正好符合我们的需求。从Nvidia官网的CUDA Toolkit Archive页面找到CUDA Toolkit 11.6.0选择Linux、x86_64、Ubuntu、20.04、runfilelocal下载得到一个run文件比如cuda_11.6.0_510.39.01_linux.run。文件名里的510.39.01是自带的驱动版本但我们已经有525驱动了所以安装时需要跳过驱动部分。执行安装命令chmod x cuda_11.6.0_510.39.01_linux.run sudo ./cuda_11.6.0_510.39.01_linux.run --toolkit --silent --override这里解释一下三个参数的作用。--toolkit表示只安装CUDA Toolkit组件不装驱动--silent表示静默安装不弹出交互式界面--override是允许使用比自带驱动更新的已装驱动。如果不用--silent也可以交互式安装在出现的界面里用空格取消勾选Driver那一项然后选择Install。安装完成后默认会安装到/usr/local/cuda-11.6同时/usr/local/cuda这个软链接会自动指向它。接下来最关键的一步是配置环境变量。编辑~/.bashrc在末尾添加export PATH/usr/local/cuda-11.6/bin:$PATH export LD_LIBRARY_PATH/usr/local/cuda-11.6/lib64:$LD_LIBRARY_PATH export CUDA_HOME/usr/local/cuda-11.6然后source ~/.bashrc执行nvcc -V验证CUDA编译器是否正常。正常输出应该显示“Cuda compilation tools, release 11.6, V11.6.124”。这里有个小细节需要注意很多人会用sudo apt install nvidia-cuda-toolkit来装CUDA我强烈不建议。apt源里的CUDA版本往往很老比如可能给你装个10.1或11.0而且它装在/usr/lib目录路径完全不在常规的/usr/local/cuda下各种深度学习框架默认又都找/usr/local/cuda自然就会出问题。所以老老实实用官方runfile装。3.2 多CUDA版本共存与版本切换实际工作中你很可能不只有一个CUDA版本。比如4090刚出来时很多人要同时跑CUDA 11.6的项目和CUDA 12.1的新项目如果每次都卸载重装就太蠢了。runfile方式安装的不同版本CUDA会分别放在/usr/local/cuda-11.6、/usr/local/cuda-12.1这样的独立目录里互不干扰。唯一要改的就是/usr/local/cuda这个软链接指向哪一份。我的做法是写一个非常简单的shell切换脚本sudo rm -f /usr/local/cuda sudo ln -s /usr/local/cuda-11.6 /usr/local/cuda切换完再source一下~/.bashrcnvcc -V就会显示对应版本。只要你的PATH里写的是/usr/local/cuda/bin而不是写死/usr/local/cuda-11.6/bin切换就只影响当前用户非常干净。还有一个小技巧是各自版本的cudnn库文件是放在/usr/local/cuda-11.6/lib64下面的所以切换CUDA版本时cuDNN也跟着变不会串库。3.3 cuDNN 8.5的下载与部署cuDNN是深度学习里做卷积加速的库PyTorch和TensorFlow官方源码编译时都需要它。不过很多用PyTorch的同学会发现直接用pip安装的torch包并不要求你手动装cuDNN因为预编译的torch wheel包已经内置了cuDNN。但如果你以后要编译自定义算子、用TensorFlow源码编译或者跑某些依赖系统级cuDNN的框架那系统级cuDNN还是必须有。从Nvidia官网cuDNN Archive页面下载cuDNN for CUDA 11.x的Linux x86_64版本选择8.5.0.96这个版本。下载时需要注册登录这是Nvidia官网的正常流程。下载得到的是一个tar压缩包解压后把对应内容拷贝到CUDA目录tar -xzvf cudnn-linux-x86_64-8.5.0.96_cuda11-archive.tar.xz cd cudnn-linux-x86_64-8.5.0.96_cuda11-archive sudo cp include/cudnn*.h /usr/local/cuda-11.6/include/ sudo cp lib/libcudnn* /usr/local/cuda-11.6/lib64/ sudo chmod ar /usr/local/cuda-11.6/include/cudnn*.h /usr/local/cuda-11.6/lib64/libcudnn*拷贝完成后执行以下命令验证cuDNN是否部署成功cat /usr/local/cuda/include/cudnn_version.h | grep CUDNN_MAJOR -A 2如果输出类似#define CUDNN_MAJOR 8 #define CUDNN_MINOR 5 #define CUDNN_PATCHLEVEL 0说明cuDNN 8.5已经就位。这里再提一个我在服务器上碰到过的困惑从Nvidia官网下载的cuDNN新版本包目录结构变了早期版本是cuda/include和cuda/lib64这种二级目录现在新版本是cudnn-linux-x86_64-xxx/cuda/include这种形式里面还有lib和include两个目录拷贝时要把所有lib和include都完整拷过去别只拷一部分否则编译时可能报cudnn.h找不到或者链接库缺失的错误。4. 深度学习框架安装与跑通验证4.1 PyTorch版本选择与安装实录驱动装好、CUDA Toolkit装好、cuDNN部署好这些都只是“地基”真正跑项目还需要深度学习框架。以PyTorch为例安装时最容易踩的坑就是版本和CUDA wheel不匹配。前面说到RTX 4090是sm_89架构PyTorch旧版本的预编译包不支持这个计算能力。我实测的结果是PyTorch 1.13.1cu116在RTX 4090上运行torch.cuda.is_available()返回True但一旦真正执行张量计算就会报“no kernel image available is found on the device”。这个报错非常误导人它看起来像是驱动问题但实际上是PyTorch预编译的CUDA kernel里根本没有sm_89对应的机器码。所以要在这个配置上舒服地跑PyTorch我建议直接用PyTorch 2.0或更高版本并且选择cu116对应的轮子包。安装命令如下pip install torch2.0.0cu116 torchvision0.15.0cu116 torchaudio2.0.0cu116 --index-url https://download.pytorch.org/whl/cu116这条命令会从PyTorch官方源下载针对CUDA 11.6预编译好的轮子。如果你的网络到官方源速度不够理想可以考虑先配置国内的PyPI镜像但需要注意pip install时不能用镜像源混装CUDA的wheel因为PyTorch的CUDA wheel只有官方源有。也可以考虑先从国内镜像下载安装CPU版本的torch再把依赖的CUDA相关文件手动放到site-packages下不过这样操作复杂度高我自己实践下来还是直接走官方源最省心。安装完之后写一个简单的验证脚本import torch print(torch.__version__) print(torch.cuda.is_available()) print(torch.cuda.get_device_name(0)) print(torch.backends.cudnn.version())正常输出会类似这样2.0.0cu116 True NVIDIA GeForce RTX 4090 8500看到8500这个数字就说明cuDNN 8.5已经在PyTorch底层生效了。再做一个实际计算测试跑一个稍大点的矩阵乘法来确认没有kernel错误a torch.randn(1024, 1024).cuda() b torch.randn(1024, 1024).cuda() c a b print(c.sum().item())如果这行能正常输出一个数字那基本可以确定环境没问题可以开始跑项目了。4.2 TensorFlow 2.11以及后续版本的相关说明如果你要用TensorFlow情况稍微特殊一点。TensorFlow官方对CUDA版本的支持方式跟PyTorch不一样它发布的GPU版wheel要求系统里有特定的CUDA版本和cuDNN版本。TensorFlow 2.10是最后一个支持原生GPU的版本但TensorFlow 2.10官方要求的是CUDA 11.2和cuDNN 8.1我们用CUDA 11.6和cuDNN 8.5也可以兼容因为CUDA的小版本之间的二进制兼容规则通常允许这种组合。TensorFlow 2.11开始在Linux上可以通过pip直接安装支持GPU的版本它会自带所有CUDA运行库依赖。所以如果你坚持用TensorFlow我建议安装2.11或2.12pip install tensorflow2.12.0验证方式import tensorflow as tf print(tf.config.list_physical_devices(GPU))正常情况下会输出一个包含GPU物理设备信息的列表。4.3 深度学习环境“最高优先级”的一件事配置深度学习环境时优先级最高的事情我认为是“先确定框架的版本需求再回头反推CUDA版本”。很多人一上来就装最新CUDA然后再装PyTorch结果发现PyTorch的wheel根本不支持这个CUDA版本还需要卸载重装。最合理的顺序应该是先看项目和框架需要什么比如PyTorch 2.0的官方安装命令上写着cu117/cu118如果你FFramework版本选择比较多那CUDA 11.6、11.7、11.8其实差别不大。但像我自己的场景项目代码里编译了大量自定义CUDA算子这些算子编译时用的就是系统的CUDA 11.6不能轻易升级。所以我一边用CUDA 11.6一边用PyTorch 2.0cu116的wheel两边正好匹配起来。另外一个容易被忽略的性能参数是PyTorch里的cuDNN benchmark。对RTX 4090这种新架构卷积算法选择和比较在首次调用时会有额外开销。在训练脚本里加上torch.backends.cudnn.benchmark True可以让cuDNN在输入size固定时自动搜索最优算法对训练速度有明显提升。这一点在4090上效果尤其明显因为它支持的新特性比较多算法搜索空间跟着变大benchmark开启后能省不少时间。5. 常见问题与排查技巧实录5.1 驱动装完黑屏、登录界面循环重启这是安装Nvidia驱动时遇到最多的问题。如果你用的是runfile方式并且在安装时开了图形界面或者没有彻底禁用Nouveau驱动加载时大概率会出问题。具体现象就是开机后黑屏、卡在主板Logo、登录之后又跳回登录界面。处理办法分几步走。如果黑屏但能通过“CtrlAltF3”进入文字界面说明系统本身还是好的只是图形界面起不来。在文字界面登录后先看有没有Nouveau的残留lsmod | grep nouveau如果有输出说明黑名单没生效或者顺序不对。检查/etc/modprobe.d/blacklist-nouveau.conf文件是否写对重新执行update-initramfs -u然后reboot。如果确认没有Nouveau了再重装一次驱动。安装时有一个细节如果系统里已经有旧驱动一定要先卸载干净sudo apt purge nvidia-* libnvidia-* -y sudo apt autoremove -y或者用runfile的--uninstall参数清理。否则新旧驱动文件混杂在一起即使版本号显示装好了运行时也可能不稳定。另外还有一个坑就是某些主板开了Secure Boot的话第三方驱动模块会因为签名验证失败而被拒绝加载。这个问题表现得很隐蔽因为驱动安装过程完全正常但重启后nvidia-smi却提示没有检测到驱动。解决办法有两个方向一个是进BIOS关掉Secure Boot另一个是给驱动模块签名对不熟悉签名的同学来说还是直接关掉省心。5.2 no kernel image available是什么原因这个报错Pytorch用得非常“勤”在RTX 4090刚出来那阵几乎每天都能在论坛看到。它的完整报错一般是这样RuntimeError: CUDA error: no kernel image is available for execution on the device根本原因就是当前PyTorch或其他框架里的CUDA kernel不包含目标GPU架构对应的代码。RTX 4090是sm_89而旧版PyTorch预编译的kernel只包含到sm_86。解决方法很简单就是换成包含sm_89支持的PyTorch 2.0及以上版本。如果你不想升级PyTorch还有一个办法是编译时指定架构export TORCH_CUDA_ARCH_LIST8.9然后在源码中从PyTorch源码重新编译安装。但源码编译时间比较长非必要不建议走这条路。另外如果你是在容器里跑要注意容器的CUDA运行时版本和宿主机的driver版本匹配问题。很多人宿主机装的是CUDA 12容器里却想用CUDA 11.6按Nvidia容器工具包的设计只要宿主机的驱动版本足够新容器内可以运行多个CUDA版本nvidia-container-toolkit会把驱动转发进去。但如果宿主机驱动版本低于容器要求的最低版本就会报错。RTX 4090建议宿主机驱动至少520以上这个前面已经强调过。5.3 4090性能跑不满或torch.cuda.is_available()为False性能跑不满表现在训练时GPU利用率忽高忽低、显存占用明显但计算速度上不去。4090是PCIe 4.0 x16接口如果你把它插在PCIe 3.0的插槽上或者主板的第二条PCIe x16插槽实际上只有x4带宽数据交换带宽就会不够训练速度直接打折扣。排查方法很简单nvidia-smi -q -d PCI看看输出里的Link Speed、Current和Max值。如果Current不是16 GT/s或者Link Width是x8甚至x4那就是插槽带宽的问题需要重新插到正确的PCIe插槽上。如果torch.cuda.is_available()返回False先排除一个最基础的问题当前Python环境里装的torch是不是CPU版本。这个问题比想象中更常见很多人pip install torch时没有指定CUDA源装成了CPU版本然后在GPU服务器上怎么检查都是False。解决办法是先查python -c import torch; print(torch.version.cuda)如果输出是None那就是CPU版卸载重装GPU版即可。5.4 常见问题排查速查表现象大概率原因处理方法安装驱动后黑屏/循环登录Nouveau未禁用或旧驱动残留禁用Nouveau清理旧驱动后重装nvidia-smi提示驱动未加载Secure Boot开启或内核模块未加载关闭Secure Bootmodprobe nvidiaPyTorch报no kernel imagePyTorch版本不包含sm_89升级到PyTorch 2.0或源码编译并设置架构CUDA能编译但运行报版本不匹配PATH指向多个CUDA版本检查环境变量用软链接统一版本训练速度远低于预期PCIe插槽带宽不足或cudnn benchmark未开启nvidia-smi -q -d PCI检查插槽开启benchmarktorch.cuda.is_available()为False装了CPU版本torch或驱动/Vulkan冲突确认torch版本检查驱动状态显卡温度过高导致降频散热或风扇策略问题检查nvidia-smi温度改进风道和机箱散热排查环境问题时不要一上来就重装系统多数问题集中在驱动冲突、CUDA路径问题和框架版本三者之间。我的习惯是每改一步就记录一下nvidia-smi和nvcc -V的输出确认改动是否生效这样排查到后面不会乱。6. 一点个人体会这套配置我从2022年底开始维护到现在经手过好几台4090机器最大的体会是“稳定大于版本花哨”。很多人在配置环境时会忍不住去追最新的CUDA和驱动版本但深度学习最怕的就是环境不稳定导致复现不了结果。CUDA 11.6搭配cuDNN 8.5这套组合虽然不算新但它足够稳所有主流框架的兼容性问题在社区里都已经有了成熟答案遇到问题你能通过搜索引擎快速找到对应解决方案。如果你需要往上扩展到多机多卡环境这套单机配置的逻辑同样适用只是在驱动安装时需要在每台机器上保持一致并且还要注意NCCL的版本和网络配置。不过这些都是后话了先把单机环境装好4090就能开始愉快地跑训练了。