神经网络使用GPU进行训练的几个条件
软硬件前提:系统中安装NVIDIA驱动(显卡驱动)
- 驱动
驱动可以用
nvidia-settings以及nvidia-smi查看是否成功安装该驱动软件。
对于CUDA Driver Version / Runtime Version,要保证CUDA Driver Version > Runtime Version
- 用于支持
Driver API的必要文件(如libcuda.so)是由GPU driver installer(显卡驱动)安装的。nvidia-smi就属于这一类API,通过该指令可以查询。 - 用于支持
Runtime API的必要文件(如libcudart.so以及nvcc)是由CUDA Toolkit installer安装的。(CUDA Toolkit Installer有时可能会集成了GPU driver Installer)。nvcc --version是与CUDA Toolkit一起安装的CUDA compiler-driver tool,它只知道它自身构建时的CUDA runtime版本。它不知道安装了什么版本的GPU driver,甚至不知道是否安装了GPU driver。
查看latest CUDA toolkit installed from NVidia’s Website
更新bashrc中的路径,可以通过nvcc查看是否成功
And updating cuda version
1
2
export PATH=/usr/local/cuda-10.0/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda-10.0/lib64:$LD_LIBRARY_PATH
Done, now just source the bashrc file again to load the changes
1
source ~/.bashrc
CUDA™是一种由NVIDIA推出的通用并行计算架构,该架构使GPU能够解决复杂的计算问题。官方安装的CUDA toolkit包含驱动与工具包,而anaconda安装的cudatoolkit只包含工具包。
Nvidia驱动问题
当Nvidia驱动失效或者与当前linux内核版本不兼容时,通过命令
1
lspci | grep -i nvidia
无法查看具体的显卡型号,需要在此网址输入对应的device代码,即可查看对应型号
虚拟环境中需要配置的
CUDA英文全称是Compute Unified Device Architecture,并安装版本兼容的以下库
cuDNN一个专门为深度学习计算设计的软件库,里面提供了很多专门的计算函数,如卷积等。
- cuda – NVIDIA计算加速器,需要安装的工具包是
cudatoolkit - cudnn for cuda –神经网络加速器,需要安装的工具包是
cudnn - tensorflow-gpu/pytorch
- python
(cuda10.0和cudnn都是安装tensorflow-gpu版本要求的,cpu版本不需要,同时cuda的版本和cudnn版本又是相关联的,其中GTX 30系列,例如GTX 3090只有cuda 11.0+才支持,不同的tensorflow-gpu版本也对应最低的cuda支持版本/兼容版本)
通过conda进行安装
1
2
conda install cudatoolkit
conda install cudnn
卸载老版本的cuda
通过sudo apt install nvidia-cuda-toolkit安装的,可以通过命令sudo apt-get remove nvidia-cuda-toolkit进行卸载。
也可以通过自带的卸载脚本进行卸载,即
1
sudo /usr/local/cuda-8.0/bin/uninstall_cuda_8.0.pl
或者直接删除对应的文件夹,文件夹地址见下一节。通过nvidia官网命令安装的,默认的文件夹地址为/usr/local/cuda-version_number
cuda和cudnn版本查询问题
使用conda安装时,没有专门创建cuda的文件夹,在对应的虚拟环境中的lib下可以找到。可以通过whereis cuda命令找到。之所以在这两个位置是由于,通过sudo apt install nvidia-cuda-toolkit
这种安装方法在/usr/include和/usr/lib/cuda/lib64中安装cuda。
1
2
3
# 显示conda安装的版本
conda list cudnn
conda list cuda
查询当前是否已经获取到GPU设备
Tensorflow
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import tensorflow as tf
print(tf.__version__) # 查看tensorflow版本
print(tf.__path__) # 查看tensorflow安装路径
a = tf.test.is_built_with_cuda() # 判断CUDA是否可以用
b = tf.test.is_gpu_available(
cuda_only=False,
min_cuda_compute_capability=None
) # 判断GPU是否可以用
print(a) # 显示True表示CUDA可用
print(b) # 显示True表示GPU可用
# 查看驱动名称
if tf.test.gpu_device_name():
print('Default GPU Device: {}'.format(tf.test.gpu_device_name()))
else:
print("Please install GPU version of TF")
# 查看当前可用设备
from tensorflow.python.client import device_lib
print(device_lib.list_local_devices())
Pytorch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 返回当前设备索引
torch.cuda.current_device()
# 返回GPU的数量
torch.cuda.device_count()
# 返回gpu名字,设备索引默认从0开始
torch.cuda.get_device_name(0)
# cuda是否可用
torch.cuda.is_available()
# 查询当前cuda支持的架构:['sm_37', 'sm_50', 'sm_60', 'sm_70', 'sm_86']
torch.cuda.get_arch_list()
# 查询当前使用的cuda版本
torch.version.cuda
使用tensorboard监督训练
tensorflow的可视化工具,pytorch从1.2.0开始支持tensorboard。之前的版本也可以使用tensorboardX代替。
在使用1.2.0版本以上的PyTorch的情况下,一般来说,直接使用pip安装即可。
1
pip install tensorboard
可视化 我们已经将关心的数据拿出来了,接下来我们只需要在命令行运行:
1
tensorboard --logdir=./path/to/the/folder --port 8123
然后打开浏览器,访问地址http://localhost:8123/ 即可。这里的8123只是随便一个例子,用其他的未被占用端口也没有任何问题,注意命令行的端口与浏览器访问的地址同步。如果发现不显示数据,注意检查一下路径是否正确,命令行这里注意是
1
--logdir=./path/to/the/folder
!注意每次环境更新时,查看老版本的库
相关内容的自己理解
- 显卡驱动/NVIDIA驱动:必须安装,可以通过
nvidia-smi的命令查询Driver Version:460.91.03, - NVIDIA-Cuda Toolkit: 包括驱动程序,CUDA开发程序,编译器,调试器,以及程序所需的库文件与头文件等。安装命令
sudo apt install nvidia-cuda-toolkit - Conda-Cuda Toolkit: 只包含程序所需的库文件与头文件等。
所以当目前版本的Tensorflow/pytorch能够与NVIDIA的cuda toolkit兼容,则不需要安装conda下的cuda toolkit也可以;反之当如果只需要运行深度学习的情况下,不需要NVIDIA的cuda toolkit,只安装conda内的cuda toolkit用于调用库文件也足够。其中,不同版本的cuda能够通过conda list cuda来进行查询。
Pytorch版本踩坑
在虚拟环境下安装指定版本的pytorch后,一直不对应正确版本,发现在系统根目录下有对应的pytorch版本,默认搜索的版本为该版本。
GPU使用情况查询
通过nvidia-smi对各个GPU使用情况进行查询,通过ps -f -p <PID>查询每个进程是谁在使用,即可查看UID。
NVIDIA显卡查看工具 gpustat
gpustat是python开发的一个包,可以直接使用pip安装,相比于NVIDIA显卡的查看工具 nvidia-smi,界面更加的美观和简洁。结合 watch 命令,可以动态实时监控 GPU 的使用情况。分为显存占用和GPU利用率,很多时候GPU利率用为0,但显存仍被占用,表明程序被错误推出,没有合理释放显存。
如何实时查看gpustat的使用情况:
1
2
3
4
5
# refresh per second
watch --color -n1 gpustat
# with process id
watch --color -n1 gpustat -cpu
显存与GPU利用率之间的关系?
通过远程服务器训练时,如何使得在终端关闭时,仍能继续训练?
方法一:使用nohup命令
Linux的nohup命令,英文全称no hang up(不挂起),用于在系统后台不挂断地运行命令,退出终端不会影响程序的运行。nohup 命令,在默认情况下(非重定向时),会输出一个名叫 nohup.out 的文件到当前目录下,如果当前目录的 nohup.out 文件不可写,输出重定向到 $HOME/nohup.out 文件中。
语法格式
1
2
3
4
nohup Command [ Arg … ] [ & ]
# Command:要执行的命令。
# Arg:一些参数,可以指定输出文件。
# &:让命令在后台执行,终端退出后命令仍旧执行。
当终端出现appending output to nohup.out时,表示运行成功。
想要停止运行,则需要通过kill -9 PID来结束进程,通过ps -aux | grep "runoob.sh" 命令可以查找对应的pid。
方法二:使用screen命令
screen是一个可以在多个进程(通常是交互式shell)之间复用一个物理终端的全屏幕窗口管理器。即linux下使用多窗口。
- 会话恢复:Screen本身没有终止,在其内部运行的会话都可以恢复。这一点对于远程登录的用户特别有用——即使网络连接中断,用户也不会失去对已经打开的命令行会话的控制。只要再次登录到主机上执行screen -r就可以恢复会话的运行。同样在暂时离开的时候,也可以执行分离命令detach,在保证里面的程序正常运行的情况下让Screen挂起(切换到后台)。
- 会话共享:Screen可以让一个或多个用户从不同终端多次登录一个会话,并共享会话的所有特性(比如可以看到完全相同的输出)。它同时提供了窗口访问权限的机制,可以对窗口进行密码保护。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 直接输入screen回车,可以进入screen会话
# 在每个screen session 下,所有命令都以 ctrl+a(C-a) 开始。
Ctrl+a + Ctrl+a: 切换当前的screen内的windows
Ctrl+a + d:临时退出当前的screen
Ctrl+a + k: kill window,强行关闭当前的 window
Ctrl+a + c: create window,新建一个 window
Ctrl+a + p: 切换到前一个窗口
Ctrl+a + n: 切换到下一个窗口
Ctrl+a + Exit: 退出并结束当前screen窗口
Ctrl+a + |: 屏幕纵向分割
Ctrl+a + S: 屏幕水平分割
Ctrl+a + X:关闭除当前焦点所在的屏幕分区
Ctrl+a + Q:关闭除当前区块之外其他的所有区块
对应基础操作及参数:
1
2
3
4
5
6
7
8
9
10
11
12
13
haoban@lambdafi:~$ screen -ls
There is a screen on:
47540.pts-0.lambdafi (10.03.2022 13.16.05) (Detached)
1 Socket in /run/screen/S-haoban.
# 其中,47540则为对应的<job_id>
-S <screen_name> 自定义创建screen的名字
-r <job_id> 恢复离线的screen作业。(**reattach**)
-R 先试图恢复离线的作业。若找不到离线的作业,即建立新的screen作业;(**reattach**)
-ls 查看是否有已存在的screen作业;
-d <job_id> 将指定的screen作业离线,即将其挂到后端;(**detach**)
-wipe 检查目前所有的screen作业,并删除已经无法使用的screen作业。
-x 恢复之前离线的screen作业。
如何关闭一个已经detached的screen
1
screen -X -S [session # you want to kill] quit
举例如下:
1
2
3
4
5
6
7
8
9
10
11
[root@localhost ~]# screen -ls
There are screens on:
9975.pts-0.localhost (Detached)
4588.pts-3.localhost (Detached)
2 Sockets in /var/run/screen/S-root.
[root@localhost ~]# screen -X -S 4588 quit
[root@localhost ~]# screen -ls
There is a screen on:
9975.pts-0.localhost (Detached)
1 Socket in /var/run/screen/S-root.