运行程序的时候提醒显存不够,查看了一下nvidia-smi
,确实显存占满了,但是GPU-Util,gpu利用率有三个都是0,只有一个是56%
搜索后发现这个现象的原因还比较普遍,但是似乎没有几个可以很好解决这个问题,
参考:
下面的2.1和2.2部分来自于
深度学习PyTorch,TensorFlow中GPU利用率较低,CPU利用率很低,且模型训练速度很慢的问题总结与分析
可以移步去原文!
volatile memory 易失性存储器
Dataloader
类中包含了一些优化,包括num_workers
(线程数)以及pin_memory
,可以提升速度。解决数据传输的带宽瓶颈和GPU的运算效率低的问题。详细来说
- 首先要将num_workers(线程数)设置合理,4,8,16是几个常选的几个参数。
测试发现将num_workers设置的非常大,例如,24,32,等,其效率也不一定会变高,因为模型需要将数据平均分配到几个子线程去进行预处理,分发等数据操作,设高了反而影响效率。
当然,线程数设置为1,是单个CPU来进行数据的预处理和传输给GPU,效率也会低。- 其次,当服务器或者电脑的内存较大,性能较好的时候,可以打开pin_memory,就省掉了将数据从CPU传入到缓存RAM里,再给传输到GPU上;为True,会直接映射到GPU的相关内存块上,省掉了一点数据传输时间。
官方文档:torch.utils.data.dataloader
确实有两个重要的参数:
num_workers (int, optional): how many subprocesses to use for data
loading. ``0`` means that the data will be loaded in the main process.
(default: ``0``)
collate_fn (callable, optional): merges a list of samples to form a
mini-batch of Tensor(s). Used when using batched loading from a
map-style dataset.
pin_memory (bool, optional): If ``True``, the data loader will copy Tensors
into CUDA pinned memory before returning them. If your data elements
are a custom type, or your :attr:`collate_fn` returns a batch that is a custom type,
see the example below.
使用这个参数,可以将tensor拷贝到cuda的pinned memory,
关于pinned memory,可以参考文章:博客园6.1 CUDA: pinned memory固定存储,是一种加速数据从cpu到gpu传输速度的方式。
https://www.zhihu.com/question/298616211
在调试过程,
top
实时查看CPU的进程利用率,这个参数对应你的num_workers的设置;watch -n 0.5 nvidia-smi
每0.5秒刷新并显示显卡设置。实时查看你的GPU的使用情况,这是GPU的设置相关。使用了watch -n 0.5 nvidia-smi
这个命令之后,才确实可以看到,其实GPU是在运行的,只是变化很快。一直在变动。
有一个公用服务器,多人使用,同时多块GPU,可以看到,其实前面0,2这两块GPU基本是满载的,1和3这两块也有人在使用,但是我所使用的4号GPU,加载速度非常慢,差不多3-5分钟才加载了600MB的内容。。。
所以考虑是CPU到GPU的数据传输问题导致的瓶颈,故去查看CPU信息:
lscpu
结合top命令发现,CPU数量48个,但是top命令中cpu最多就是9.4,根本占不满。。所以应该不是硬件的问题,不是cpu和gpu之间数据传输导致的
参考:GPU导入模型非常缓慢的解决办法,大概可以感觉到,应该是cudann版本太老了的问题,
2.0.1-gpu-cuda11.0-cudnn8
2.1.2-gpu-cuda10.2-cudnn7
一个老的cudnn8的镜像,确实也是这次很慢。。。换!