提高PyTorch的方法炼丹;速度?这个哥哥总结了17种方法,可以直接拿在手上改变-量子比特

时间 • 2023-04-18 09:42:29
可以
使用
方法

如何提高PyTorch的“炼丹”速度。

近日,有一位名叫Lorenz Kuhn的大哥,分享了他在冶炼过程中总结出的17种投入最低、有效的提高训练速度的方法,并且基本上可以直接在PyTorch修改,无需引入额外的库。

但是,请注意,所有这些方法都假定在GPU上训练模型。

该份额在Reddit中获得600的热量。

接下来,从加速度的高度开始依次介绍这些方法。

1、选择适当的学习率计划。

所选择的学习率调度对收敛速度和模型的泛化性能有很大影响。

所提出的周期学习速率(CLR)和1cycle策略可以快速完成复杂模型的训练。

例如,在cifar10中训练resnet-56时,使用1cycle可以将迭代次数减少10倍,获得与原始论文相同的精度。

在最好的情况下,与传统相比,该计划实现了大规模的提速。但是,它的缺点是引入了额外的超参数。

为什么有效呢。一种可能的解释是,定期增加学习率有助于更快地穿越损失函数的鞍点。

2、在DataLoader中使用多个工作程序固定内存。

使用时torch.utils.data.DataLoader、num_workers gt; 不是默认值0,而是0,pin_memory=真,而不是缺省值False。

英伟达高级工程师Szymon Micacz使用4个作业步骤和固定内存,在1个训练期间提高了2倍的速度。

另外,在选择工作人员数时,建议设定为可用GPU数的4倍。

工作器的数量多和少会减慢速度,数量越多CPU内存消耗越多

3、批次最大化。

这种方法极具争议性。但是,通常使用GPU内存允许的最大批处理量可以加快训练速度。

要更改批大小,必须调整其他超级参数,如学习率。一般情况下,批大小加倍,学习率加倍。

到目前为止,已经进行了几种不同批次尺寸的实验,通过将批次尺寸从64增加到512,实现了4倍的加速。

4、使用自动混合精度(AMP)

PyTorch1.6版本包括PyTorch自动混合精度培训的本地实现。

与其他地方使用的单精度(FP32、相比,半精度(FP16、可以更快地运行,不会损害精度。

然后让AMP自动确定应该以什么格式执行操作,这样可以加快培训速度,减少内存消耗。

一位研究人员发现,在NVIDIA V100GPU上对几种常见语言和视觉模型进行基准测试时,使用AMP可以比普通FP32训练的速度提高两倍,最高提高5.5倍。

目前,只有CUDA ops可以通过这种方式自动播放。

5、使用不同的优化器

例如,AdamW、AdamW不是L2正规化而是具有权重衰减的Adam,其被错误地实现,训练时间胜过Adam。

并且,LARS和LAMB等非局部的最优化器也值得关注。

NVIDA的APEX实现了一般优化程序(如Adam)的融合版本。与Adam的PyTorch实现相比,它避免了多次进出GPU内存,并提高了5%左右的速度。

6、打开cudNN基准测试。

如果模型体系结构保持固定且输入大小不变,则可以通过设置torch.backends.cudnn.benchmark=True来启动cudNN自动调节器。

为了获得最佳性能指标,对cudNN计算卷积的各种方法进行基准测试。

7、防止在CPU和GPU之间频繁传输数据。

请注意,经常使用tensor.cpu()将tensors从GPU传输到CPU。item()和.numpy()也一样,取而代之的是.detach()

如果正在创建张量,则可以使用关键字参数device=torch.device(“cuda:0”)直接分配给GPU。

传输数据时,只要传输后没有同步点,就可以使用.to(non_blocking=True)

8、使用坡度/激活检查点。

检查点的工作原理是计算和更换内存。检查点部分存储中间激活,而不是通过反向路径重新计算,而是存储整个计算映射中的所有中间激活并向后计算。

可应用于模型的任何部分。

具体地,在正向传输中,函数是torch.no_以grad()的方式工作。也就是说,中间激活不会被保存。相反,正向传输保存输入元组和函数参数。

在后向传输中,获取保存的输入和函数,然后再次计算前向传输函数。然后跟踪中间激活并使用这些激活值计算坡度。

可能会略微增加给定批量大小下的运行时间,但会大大减少内存使用。相反,这将进一步增加所用批次的大小,提高GPU的利用率。

9、使用坡度累积。

增加批量大小的另一种方法是在调用optimizer.step()之前在多个.backward()通道中积累梯度。

该方法主要是为了避免GPU存储器限制而开发的,但不清楚是否存在额外的.backward()循环之间的折衷。

10、使用分布式数据并行的多GPU培训。

加速分布式训练的方法可能需要单独写文章,但简单的方法是使用torch.nn.DistributedDataParallel。不是torch.nn.DataParallel。

这允许使用专用的CPU内核驱动每个GPU,从而避免数据并行GIL问题。

11、将坡度设置为无,而不是0。

.zero _.zero _grad()

这将使用内存分配器来处理坡度,并适度加速,而不是主动将其设置为0。

注意,这样做不是没有副作用的。

12,使用.as_。不是tensor()而是tensor()

torch.tensor()总是复制数据。如果存在要转换的numpy数组,则torch.as_tensor()或torch.from_numpy()避免复制数据。

13、如果不需要,请关闭调试API。

Pytorch表示autograd.profiler、autograd.grad_check和autograd.anomaly_检测,必要时使用,必要时不关闭,训练速度会变慢。

14、使用坡度片段。

可以剪裁坡度以加速收敛。最初用于避免RNNs中的梯度爆炸,orch.nn.utils.clipgrad_norm实现。

虽然还不知道哪些模型可以通过梯度修剪来加速,但似乎对于RNNs、基于Transformer和ResNets的架构以及一系列不同的优化程序非常有用。

15、在BatchNorm之前禁用偏移。

这是一种非常简单的方法,可以在批规格化层之前禁用层偏移。

对于二维体积块层叠,可以将bias关键字设置为False:,以完成torch.nn.Conv2d(…,bias=False,…)

16、验证过程中禁用坡度计算。

验证过程中torch.no_grad() 。

17、使用输入和批次规格化。

作为追加提示,使用JIT融合逐点操作。

如果每个点都有相邻的操作,则可以使用PyTorch JIT将其集成到FusionGroup中,以单个核心启动,从而节省内存读写。

许多网友在表达谢意的同时,也分享了自己训练时的Tips。

例如,这个炼丹师分享了第18种方法,下载了更多的RAM。

我有两个建议。

1、数据转换(用于数据扩展)可以是提高速度的另一源。通过使用numba包,可以加速仅使用简单Python语句的转换。

2、将数据集预处理到一个文件中对速度也有好处。

除此之外,还有什么提高训练速度的方法吗。请共享

传输门:https://efficientdl.com/faster-deep-learning-in-pytorch-a-guide/#1-consider-using-another-learning-rate-schedulehttps://www.Reddit.com/r/MachineLearning/comments/kvs1ex/d_here_are_17_ways_of_making_pytorch_training/