MLNLP

社区的愿景

是促进国内外自然语言处理,机器学习学术界、产业界和广大爱好者之间的交流和进步,特别是初学者同学们的进步。

转载自 | 极市平台

作者丨游客26024

来源丨https://www.zhihu.com/question/461811359/answer/2492822726

我穷

没钱

数据集较大

网络较深

训练较慢

想加速训练

Pytorch的AMP

autocast与Gradscaler

Pytorch的AMP

autocast与Gradscaler

自动混合精度对模型训练加速

不使用NVIDIA的apex库

使用torch.cuda.amp

AMP

什么是自动混合精度

先来梳理一下历史:先有NVIDIA的apex,之后NVIDIA的开发人员将其贡献到Pytorch 1.6+产生了torch.cuda.amp[这是笔者梳理,可能有误,请留言]

详细讲:默认情况下,大多数深度学习框架都采用32位浮点算法进行训练。2017年,NVIDIA研究了一种用于混合精度训练的方法(apex),该方法在训练网络时将单精度(FP32)与半精度(FP16)结合在一起,并使用相同的超参数实现了与FP32几乎相同的精度,且速度比之前快了不少

自动

混合精度

自动

混合精度

只能在cuda上使用

为什么我们要使用AMP自动混合精度?

1.减少显存占用(FP16优势)

2.加快训练和推断的计算(FP16优势)

3.张量核心的普及(NVIDIA Tensor Core),低精度(FP16优势)

4. 混合精度训练缓解舍入误差问题,(FP16有此劣势,但是FP32可以避免此)

5.损失放大,可能使用混合精度还会出现无法收敛的问题[其原因时激活梯度值较小],造成了溢出,则可以通过使用torch.cuda.amp.GradScaler放大损失来防止梯度的下溢

主旨

如何让网络模型加速训练

本文从1.没使用DDP与DP训练与评估代码(之后加入amp),2.分布式DP训练与评估代码(之后加入amp),3.单进程占用多卡DDP训练与评估代码(之后加入amp) 角度讲解。

运行此程序时,文件的结构:

1

『没使用DDP与DP训练与评估代码』

没使用DDP与DP的训练与评估实验,作为我们实验的参照组

(1)原本模型的训练与评估源码:

训练源码:

注意:此段代码无比简陋,仅为代码的雏形,大致能理解尚可!

train_without.py

运行结果:

Tensorboard观察:

评估源码:

代码特别粗犷,尤其是device与精度计算,仅供参考,切勿模仿!

eval_without.py

运行结果:

分析:

原本模型训练完20个epochs花费了22分22秒,得到的准确率为0.8191

(2)原本模型加入autocast的训练与评估源码:

训练源码:

训练大致代码流程:

train_autocast_without.py

运行结果:

Tensorboard观察:

评估源码:

eval_without.py 和 1.(1)一样

运行结果:

分析:

原本模型训练完20个epochs花费了22分22秒,加入autocast之后模型花费的时间为21分21秒,说明模型速度增加了,并且准确率从之前的0.8191提升到0.8403

(3)原本模型加入autocast与GradScaler的训练与评估源码:

使用torch.cuda.amp.GradScaler是放大损失值来防止梯度的下溢

训练源码:

训练大致代码流程:

train_GradScaler_without.py

运行结果:

Tensorboard观察:

评估源码:

eval_without.py 和 1.(1)一样

运行结果:

分析:

为什么,我们训练完20个epochs花费了27分27秒,比之前原模型未使用任何amp的时间(22分22秒)都多了?

这是因为我们使用了GradScaler放大了损失降低了模型训练的速度,还有个原因可能是笔者自身的显卡太小,没有起到加速的作用

2

『分布式DP训练与评估代码』

(1)DP原本模型的训练与评估源码:

训练源码:

train_DP.py

运行结果:

Tensorboard观察:

评估源码:

eval_DP.py

运行结果:

(2)DP使用autocast的训练与评估源码:

训练源码:

这样写代码

无效

正确写法

1与2皆可,之后:

模型:

须在forward函数上加入@autocast()或者在forward里面最上面加入with autocast():

alexnet.py

train_DP_autocast.py 导入自己的alexnet.py

运行结果:

Tensorboard观察:

评估源码:

eval_DP.py 相比与2. (1)导入自己的alexnet.py

运行结果:

分析:

可以看出DP使用autocast训练完20个epochs时需要花费的时间是21分21秒,相比与之前DP没有使用的时间(22分22秒)快了1分1秒

之前DP未使用amp能达到准确率0.8216,而现在准确率降低到0.8188,说明还是使用自动混合精度加速还是对模型的准确率有所影响,后期可通过增大batch_sizel让运行时间和之前一样,但是准确率上升,来降低此影响

(3)DP使用autocast与GradScaler的训练与评估源码:

训练源码:

train_DP_GradScaler.py 导入自己的alexnet.py

运行结果:

Tensorboard观察:

评估源码:

eval_DP.py 相比与2. (1)导入自己的alexnet.py

运行结果:

分析:

跟之前一样,DP使用了GradScaler放大了损失降低了模型训练的速度

现在DP使用了autocast与GradScaler的准确率为0.8409,相比与DP只使用autocast准确率0.8188还是有所上升,并且之前DP未使用amp是准确率(0.8216)也提高了不少

3

『单进程占用多卡DDP训练与评估代码』

(1)DDP原模型训练与评估源码:

训练源码:

train_DDP.py

运行结果:

Tensorboard观察:

评估源码:

eval_DDP.py

运行结果:

(2)DDP使用autocast的训练与评估源码:

训练源码:

train_DDP_autocast.py 导入自己的alexnet.py

运行结果:

Tensorboard观察:

评估源码:

eval_DDP.py 导入自己的alexnet.py

运行结果:

分析:

从DDP未使用amp花费21分21秒,DDP使用autocast花费20分20秒,说明速度提升了

DDP未使用amp的准确率0.8224,之后DDP使用了autocast准确率下降到0.8162

(3)DDP使用autocast与GradScaler的训练与评估源码

训练源码:

train_DDP_GradScaler.py 导入自己的alexnet.py

运行结果:

Tensorboard观察:

评估源码:

eval_DDP.py 与3. (2) 一样,导入自己的alexnet.py

运行结果:

分析:

运行起来了,速度也比DDP未使用amp(用时21分21秒)快了不少(用时20分20秒),之前DDP未使用amp准确率到达0.8224,现在DDP使用了autocast与GradScaler的准确率达到0.8252,提升了

参考:

1.Pytorch自动混合精度(AMP)训练:https://blog.csdn.net/ytusdc/article/details/122152244

2.PyTorch分布式训练基础--DDP使用:https://zhuanlan.zhihu.com/p/358974461

技术交流群邀请函

△长按添加小助手

扫描二维码添加小助手微信

姓名-学校/公司-研究方向

(如:小张-哈工大-对话系统)

自然语言处理/Pytorch

关于我们

MLNLP

社区

是由国内外机器学习与自然语言处理学者联合构建的民间学术社区,目前已经发展为国内外知名的机器学习与自然语言处理社区,旨在促进机器学习,自然语言处理学术界、产业界和广大爱好者之间的进步。

社区可以为相关从业者的深造、就业及研究等方面提供开放交流平台。欢迎大家关注和加入我们。


原文链接

文 | 重庆搬砖 喵@知乎 https://www.zhihu.com/question/285730093/answer/2506491786 知乎上最近有个问题很火: 有哪些值得计算机专业学生加入的国企? 这个问题确实很应今年秋招的景,于是转载了知乎答主@重庆搬砖喵 的高赞回答分享给大家。 原回答链接: https://www.zhihu.com/question/285730093/answer/2506491786 以下为回答正文: 1.首选证券公司 各省基本都有一所证券公司,沿海省份集中在税前30-40万左右,内地集中在20-30万。很少加班,多数为国企,一般要求硕士。 1.2公募&私募基金 公募和私募基金也有技术岗,比如: 易方达基金,华安基金、汇添富基金,

Python 是一种不断发展的语言。随着它的演化和扩展,可用工具和开发策略的数量也在增加。近来流行的一个过程是linting —— 检查代码的潜在问题。通过linting,我们代码中的错误会被标记出来,这样我们就可以纠正可能导致出现问题的编程方法。 Linting(提示)是在编写源代码时和编译前进行的。换句话说,Linting是一种构建前的检查,也叫 "静态代码分析"。定期检查我们的代码,以确保整个代码和代码库的一致性。这最大限度地减少了小错误在代码运行后变成复杂问题的机会。 许多开发人员不使用Linting,因为他们没有看到它的附加价值,因为Linting不会防止错误。但这种观点低估了Linting在提高代码质量方面的价值。 在这篇实践文章中,我们将探讨在Python中使用Pylint——最流行的提示工具之一——进行快速的提示检查是多么快速和简单。我们还将看到,对代码进行提示是如何帮助我们遵守PEP8代码风格指南的。 前提条件 在开始之前,确保满足以下条件: 在你的机器上安装了Python和pip 对命令行界面(CLI)有基本的了解 对Python概念的理解,如函数和类。 另外,应该注意,虽然这里显示的命令与Linux和基于macOS的系统兼容,但在Windows下工作时,你应该小心。 Linting