恒源云 (GpuShare)_ 加速 pytorch 训练的方法来喽~
被迫营业的小帅酱,分享内容相当干货了,哈哈哈哈。独乐乐不如众乐乐,今天就把小技巧搬运出来给大家瞅一瞅啦!
文章来源 | 恒源云社区
原文地址 | 如何加速pytorch训练?GPU利用率过低?
原文作者 | 小帅酱
想必有时候大家在用云服务器炼丹的时候会遇到 GPU 利用率忽高忽低,一会 0%一会 100%。这其实就是对 GPU 资源的浪费,因为 GPU 在浪费很多时间在等 CPU 和内存加载数据进来。最主要是云服务器每时每刻都在烧 money,难免不心疼。描述效果如下图:
那么如何解决???
我分享一下我个人在平时用的比较多的方法:
代码层面
其实这个没有哪个方法最好,哪个方法最有效,都是要根据自己的硬件配置和实际程序运行情况制定最佳方案,比如说像上图这种情况,大概率就是数据预处理加载时间太长,CPU 处理的速度没有跟上 GPU,导致资源浪费。我认为以下几个方法可以起到一定加速的作用:
一、DataLoader 改进
Dataloader 参数设置
根据自己的硬件情况,可以将 num_workers 调成 2,4,8,16,并不是越大越快,我一般调成 16。这个代码的意思是用多少个子进程加载数据;
pin_memory=True,锁页内存,内存够用一定要加上。科普一下:主机中的内存,有两种存在方式,一是锁页,二是不锁页,锁页内存存放的内容在任何情况下都不会与主机的虚拟内存进行交换(注:虚拟内存就是硬盘),而不锁页内存在主机内存不足时,数据会存放在虚拟内存中。而显卡中的显存全部是锁页内存,设置为 True 时可以加快内存和显卡之前的数据交换;
prefetch_factor=任意数字,默认=2。代表的含义是每个 worker 提前加载 的 sample 数量,可以适当调大,具体改调到多大合适还没做过实验,我觉得根据 batch size=prefetch_factor*num_workers 比较合理?;
persistent_workers=True,看官方文档的意思就是默认 Flase 相当于所有数据都训练完这一轮之后(跑完一次 epoch)worker 会自动关闭,下个 epoch 需要重新打开并初始化 worker,这会浪费一点时间。该参数可以控制每个 epoch 的第一个 iteration(第一批 batch)是否重新初始化 worker,所以可以通过设置=True 去除每个 epoch 第一个 iteration 多消耗的一点时间;
注:prefetch_factor 和 persistent_workers 这两个参数是 pytorch1.7 之后才有的,以前的版本没有,使用时需要注意。
二、设置 torch.backends.cudnn.benchmark = True
设置 torch.backends.cudnn.benchmark = True 将会让程序在开始时花费一点额外时间,为整个网络的每个卷积层搜索最适合它的卷积实现算法,进而实现网络的加速。
适用场景:网络结构固定(不是动态变化的),网络的输入形状(包括 batch size,图片大小,输入的通道)固定。反之,如果卷积层的设置一直变化,将会导致程序不停地做优化,反而会耗费更多的时间。
三、使用梯度裁剪
loss.backward()torch.nn.utils.clip_grad_norm_(model.parameters(), 20) # 在代码中加入这行实现梯度裁剪 optimizer.step()
四、在验证期间关闭梯度计算
在验证期间关闭梯度计算,设置:torch.no_grad() 。
五、改进 torchvision 默认的图片加载方式
可以发现默认的 pillow 是最慢的,建议使用 pillow-simd 加速或者 turbojpeg(这个好像只能加速 ubuntu 系统)。因为我用的服务器是 centos 系统,我用 pillow-simd 替换原来的 pillow,发现速度是提升了不少。
$ pip uninstall pillow
$ CC=“cc -mavx2” pip install -U --force-reinstall pillow-simd
等待替换完成即可,源代码无须改动就可以直接运行。
六、最强大的 Nvidia 加速技术 DaLi
以前都是 cpu 处理加载图片,这个技术就是把这个步骤放在 gpu 上进行,想想就知道速度有多快了。缺点是有点占显存。
不过比较麻烦的是,DaLi 只能进行一些较简单的 crop,resize 之类的操作,像 RandAugment 或 CTAugment 这些比较复杂的图像增强则需要自行修改源代码实现。
具体可看下这个项目 GitHub - tanglang96/DataLoaders_DALI: PyTorch DataLoaders implemented with DALI for accelerating image preprocessing
等下次实现了这个再发一篇 demo 分享给大家!!!
附上我知乎的链接:pytorch如何加速
评论