Nvidia 简单环境工程
Ampere Pytorch
I. Introduction
近日训练神经网络花了五六十块钱,在智星云平台上。这个云平台总的来说还是很便宜的,RTX 3090大概4元/h,之前训练胶囊网络的时候还狠吹了这个平台一波。但我最近感觉,该平台貌似有点坑:
- RTX 2080Ti的训练速度比我的MX 150(比GTX 960更差一点的卡)更慢,RTX 3090没有3090的样子
- 环境非常迷惑:比如其1080 Ti的环境,CUDA10.0 + Torch 1.4.0,直接没办法跑
于是乎我在办公室一个同事的电脑上装了整个深度学习环境。很不幸(又幸运)的是,他的显卡是RTX 3060,对应架构为安培(Ampere sm_86),不兼容低版本torch,使用不了CUDA加速。考虑到我之前有装显卡驱动搞爆系统的经历,我决定记录一下本次环境工程的过程。
II. 过程
2.1 查看环境
第一步当然是需要查看硬件参数:
1 | nvidia-smi |
其中右上角会出现CUDA版本:
但这只是该驱动(426.00)可以支持的 最高版本CUDA。需要查看自己的CUDA版本则需要使用:
1 | nvcc --version |
然后我发现,该同学的驱动是475.05.xx(忘了),但是CUDA版本却是9.1。虽说英伟达驱动向下兼容,但是9.1听起来像是上个世纪的东西(雾)。直接升级CUDA即可。
2.2 乱搞驱动
我选择的是CUDA 11.4,其安装程序可以附带安装驱动,也就是说,没有驱动也没有什么问题。Ubuntu 18.04端我选择的是脚本文件安装(.run 文件),因为这个可以受控。但是安装时遇到了一些问题:
Existing package manager found... (然后建议你在继续安装前remove这个existing package manager of the driver).
Ask Ubuntu上有对应的解决方案,说是--toolkit --silent --override
等等flag上去就行了。但个人尝试无效,按照回答直接执行之后,没有报错,但是同样也没安装好CUDA。直接运行脚本,暗装脚本会列举将会被安装的内容,第一次安装时我直接取消了除了Toolkit之外的其他选项,最后貌似也没装上去。
我怒了,开始暴力了起来(安全的暴力)。我啪地一下站起来了,很快啊,输入了以下脚本:
1 | 下面这一句为了看看这个电脑上都装了哪些CUDA相关库 |
执行结束之后,reboot。
2.3 安装驱动
执行了上面这些命令之后我重启了电脑,果然,图形界面打不开了 ,因为显卡驱动已经没了。看到这里并且执行到这里的xdm可以准备重装系统了(误)。在电脑启动界面,GRUB有选择系统的画面,选择Ubuntu Recovery项,进入recovery模式进行驱动安装。recovery不需要显卡驱动也可以启动图形界面。
进入recovery模式之后,既然我们已经知道,系统里没有显卡驱动了(nvidia-smi报错了),那就可以肆无忌惮地装驱动了。直接运行驱动安装脚本,安装项可以全部勾选。安装完毕之后,安装程序将会提示我们进行环境变量设定,此时只需要修改.bashrc
文件
1 | export PATH=$PATH:... |
检查nvidia-smi
以及nvcc
两个指令是否可以正确执行。按以上步骤(先删除,再重装)的方式,应该是没有问题的。重启即可,重启之后安装一些扩展库(可选)比如cuDNN以及NCCL,这两个库的安装要领只有一个:上英伟达官网对照清楚自己的驱动、CUDA版本对应哪个版本的cuDNN或者NCCL,版本对了就没问题,反正都是.deb
包,一个sudo dpkg -i
安装就结束了。
2.4 安装Pytorch
Pytorch即使在最新的驱动以及CUDA(11.4)安装好之后,仍然不厌其烦地告诉你:sm_86
is not a supported architecture for Pytorch, among [... up to sm_70] blahblahblah。在这里我遇到了两个坑:
2.4.1 多重Pytorch
我惊奇地发现,pip管理包的时候,同一个库允许多个版本存在。对于这种行为,我不是很能理解,毕竟按我的理解,大多数用户的Python版本是固定的,没有跨版本的需求(用Docker或者Conda管一管不好么)。但我在执行pip3 list
之后,发现电脑上有:1.7.1\1.8.0\1.10.0
三个版本的torch,每次安装前的删除实际上都没有删除干净。
2.4.2 CUDA Wheel
本地安装 CUDA 11.4 并不意味着我们可以直接使用 CUDA11.4 支持。我们知道(你知道吗),Python虽然作为一种动态语言,运行时解释,它也是支持使用编译好的库的(只要编译成 .so
或者 .dll
动态库就行),pip3 不只是安装源码,它也会安装一些动态库,这些动态库的编译方式决定了 pip3 安装的库本身的一些性质。比如我们在 CUDA 踩坑实录 【1】 中已经实践过,CUDA程序作为CUDA Extension被 pytorch / python 调用,被调用的程序是由 nvcc 编译的,nvcc的一些 flag 则决定了代码受到什么样的 architecture 支持,比如我们可以显式定义 -arch=sm_86
就能使得 sm_86
架构得到支持。也就是说,我们在安装的过程中需要选择CUDA Wheels,也就是手动写一个(+xxx):
1 | pip3 install torch==1.10.0+cu113 |
上面的 +cu113
就表示,我们选择CUDA 11.3 wheels,应该就是说,本库的编译是有 CUDA 11.3 完成的。虽然本地是11.4,但并没有什么影响,对于 RTX 3060 这种 sm_86
capability 的设备,只要 CUDA 11 + 就可以了。
另一种方法,可以直接使用本地 CUDA 完成库安装:从官网上下载source(Pytorch底层就是在调用C++代码嘛),本地用 nvcc 对 source 进行手动编译,但这确实有一点麻烦。
2.5 验证
1 | import torch |
只要没有任何warning或者error,就是成功。