恒源云(GpuShare)_加速pytorch训练的方法来喽~

恒源云(GpuShare)_加速pytorch训练的方法来喽~
文章图片

恒源云(GpuShare)_加速pytorch训练的方法来喽~
文章图片

被迫营业的小帅酱,分享内容相当干货了,哈哈哈哈。独乐乐不如众乐乐,今天就把小技巧搬运出来给大家瞅一瞅啦!
文章来源 | 恒源云社区
原文地址 | 如何加速pytorch训练?GPU利用率过低?
原文作者 | 小帅酱
想必有时候大家在用云服务器炼丹的时候会遇到GPU利用率忽高忽低,一会0%一会100%。这其实就是对GPU资源的浪费,因为GPU在浪费很多时间在等CPU和内存加载数据进来。最主要是云服务器每时每刻都在烧money,难免不心疼。描述效果如下图:
恒源云(GpuShare)_加速pytorch训练的方法来喽~
文章图片

那么如何解决???
我分享一下我个人在平时用的比较多的方法:
代码层面
其实这个没有哪个方法最好,哪个方法最有效,都是要根据自己的硬件配置和实际程序运行情况制定最佳方案,比如说像上图这种情况,大概率就是数据预处理加载时间太长,CPU处理的速度没有跟上GPU,导致资源浪费。我认为以下几个方法可以起到一定加速的作用:
一、DataLoader改进
Dataloader参数设置
恒源云(GpuShare)_加速pytorch训练的方法来喽~
文章图片

【恒源云(GpuShare)_加速pytorch训练的方法来喽~】根据自己的硬件情况,可以将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默认的图片加载方式
恒源云(GpuShare)_加速pytorch训练的方法来喽~
文章图片

可以发现默认的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如何加速

    推荐阅读