PyTorch训练提升

news2025/4/5 22:19:34

1. 更换学习率schedule

学习率 schedule 的选择对模型的收敛速度和泛化能力有很大的影响。Leslie N. Smith 等人在论文《Cyclical Learning Rates for Training Neural Networks》、《Super-Convergence: Very Fast Training of Neural Networks Using Large Learning Rates 》中提出了周期性(Cyclical)学习率以及 1Cycle 学习率 schedule。之后,fast.ai 的 Jeremy Howard 和 Sylvain Gugger 对其进行了推广。下图是 1Cycle 学习率 schedule 的图示:

在这里插入图片描述

Sylvain 写到:1Cycle 包括两个等长的步幅,一个步幅是从较低的学习率到较高的学习率,另一个是回到最低水平。最大值来自学习率查找器选取的值,较小的值可以低十倍。然后,这个周期的长度应该略小于总的 epochs 数,并且,在训练的最后阶段,我们应该允许学习率比最小值小几个数量级。

与传统的学习率 schedule 相比,在最好的情况下,该 schedule 实现了巨大的加速(Smith 称之为超级收敛)。例如,使用 1Cycle 策略在 ImageNet 数据集上训练 ResNet-56,训练迭代次数减少为原来的 1/10,但模型性能仍能比肩原论文中的水平。在常见的体系架构和优化器中,这种 schedule 似乎表现得很好。

Pytorch 已经实现了这两种方法:「torch.optim.lr_scheduler.CyclicLR」和「torch.optim.lr_scheduler.OneCycleLR」
参考文档:https://pytorch.org/docs/stable/optim.html

2. 在 DataLoader 中使用多个 worker 和页锁定内存

当使用 torch.utils.data.DataLoader 时,设置 num_workers > 0,而不是默认值 0,同时设置 pin_memory=True,而不是默认值 False。
参考文档:https://pytorch.org/docs/stable/data.html
来自 NVIDIA 的高级 CUDA 深度学习算法软件工程师 Szymon Micacz 就曾使用四个 worker 和页锁定内存(pinned memory)在单个 epoch 中实现了 2 倍的加速。人们选择 worker 数量的经验法则是将其设置为可用 GPU 数量的四倍,大于或小于这个数都会降低训练速度。请注意,增加 num_workers 将增加 CPU 内存消耗。

DataLoader(dataset, batch_size=1, shuffle=False, sampler=None,
           batch_sampler=None, num_workers=0, collate_fn=None,
           pin_memory=False, drop_last=False, timeout=0,
           worker_init_fn=None, *, prefetch_factor=2,
           persistent_workers=False)
  • DataLoader是PyTorch中的一个类,它提供了一个可以遍历给定数据集的迭代器。它用于批量加载数据,以便在训练模型时限制内存使用。以下是DataLoader类的参数:

dataset:要从中加载数据的数据集。
batch_size:每个批次中的样本数量。
shuffle:如果设置为True,则数据将在每个epoch时进行洗牌。
sampler:一个可选的采样器,它提供要从数据集中选择的索引。
batch_sampler:一个可选的采样器,它会生成要从数据集中选择的索引的批次。
num_workers:要用于数据加载的子进程数。默认为0,表示数据加载在父进程中完成。
collate_fn:将样本整理成批次的函数。默认为None,表示将使用连接操作。
pin_memory:如果设置为True,则数据加载器将在返回Tensors之前将它们复制到CUDA固定内存中。
drop_last:如果设置为True,则如果最后一个批次的大小小于batch_size,则会丢弃它。
timeout:如果为正数,则数据加载在超时秒数内超时时失败。
worker_init_fn:每个工作进程上调用以初始化工作进程特定状态的可选函数。
prefetch_factor:每个工作器提前加载的项目数量。
persistent_workers:如果为True,则工作进程在数据集迭代结束后不会退出。对于具有非常小的项目的数据集来说,这有助于加速数据加载。

3. 把 batch 调到最大

把 batch 调到最大是一个颇有争议的观点。一般来说,如果在 GPU 内存允许的范围内将 batch 调到最大,你的训练速度会更快。但是,你也必须调整其他超参数,比如学习率。一个比较好用的经验是,batch 大小加倍时,学习率也要加倍。
OpenAI 的论文《An Empirical Model of Large-Batch Training》很好地论证了不同的 batch 大小需要多少步才能收敛。在《How to get 4x speedup and better generalization using the right batch size》一文中,作者 Daniel Huynh 使用不同的 batch 大小进行了一些实验(也使用上面讨论的 1Cycle 策略)。最终,他将 batch 大小由 64 增加到 512,实现了 4 倍的加速。
然而,使用大 batch 的不足是,这可能导致解决方案的泛化能力比使用小 batch 的差。

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

PyTorch 1.6 版本包括对 PyTorch 的自动混合精度训练的本地实现。这里想说的是,与单精度 (FP32) 相比,某些运算在半精度 (FP16) 下运行更快,而不会损失准确率。AMP 会自动决定应该以哪种精度执行哪种运算。这样既可以加快训练速度,又可以减少内存占用。
在最好的情况下,AMP 的使用情况如下:


import torch
# Creates once at the beginning of training
scaler = torch.cuda.amp.GradScaler()


for data, label in data_iter:
   optimizer.zero_grad()
   # Casts operations to mixed precision
   with torch.cuda.amp.autocast():
      loss = model(data)

   # Scales the loss, and calls backward()
   # to create scaled gradients
   scaler.scale(loss).backward()

   # Unscales gradients and calls
   # or skips optimizer.step()
   scaler.step(optimizer)

   # Updates the scale for next iteration
   scaler.update()

5. 考虑使用另一种优化器

AdamW 是由 fast.ai 推广的一种具有权重衰减(而不是 L2 正则化)的 Adam,在 PyTorch 中以 torch.optim.AdamW 实现。AdamW 似乎在误差和训练时间上都一直优于 Adam。
Adam 和 AdamW 都能与上面提到的 1Cycle 策略很好地搭配。
目前,还有一些非本地优化器也引起了很大的关注,最突出的是 LARS 和 LAMB。NVIDA 的 APEX 实现了一些常见优化器的融合版本,比如 Adam。与 PyTorch 中的 Adam 实现相比,这种实现避免了与 GPU 内存之间的多次传递,速度提高了 5%。

6. cudNN 基准

如果你的模型架构保持不变、输入大小保持不变,设置 torch.backends.cudnn.benchmark = True。

torch.backends.cudnn.benchmark = True是一个PyTorch的CUDA加速库cuDNN参数的简单指定方式。它的作用是启用cuDNN简情模式来自动搜索最适合当前配置的高效算法。

cuDNN是一个优化了的CUDA深度神经网络库,它可以在NVIDIA的GPU上提供高度优化的加速,特别是针对深度神经网络的卷积和池化操作。在后端使用cuDNN可以显著提高深度神经网络的训练和推理速度。传统的cuDNN模式需要我们手动指定一些计算参数,如卷积算法、张量的内存布局等,其中最优参数的选择通常是非常耗时的。

而在cuDNN简情模式下,cuDNN库将根据硬件和当前Tensor的属性尝试用不同的算法来加速卷积操作,从而更好地利用GPU资源,在不影响输出结果的前提下选择最快的计算方案。

因此,通过在PyTorch中设置torch.backends.cudnn.benchmark = True,便可以自动搜索最适合当前配置的高效算法,从而加速深度神经网络的训练和推理速度。但是,通过该选项深度神经网络计算的速度并不总是会提高,有时也会比非benchmark模式更慢。这是因为cuDNN简情模式在搜索最快算法的过程中会消耗额外的时间,而且由于硬件和数据的不同,搜索到的最优算法也不一定是全局最优,因此最好在具体情况下测试表现来判断是否使用该选项。

7. 小心 CPU 和 GPU 之间频繁的数据传输

通常我们会先在CPU上创建Tensor对象,并在必要时将它们移动到CUDA设备上进行GPU加速的计算。

这是因为由于硬件架构的不同,GPU和CPU之间的数据处理方式也不同,所以必须使用不同的数据结构来表示数据。在CPU上创建的Tensor对象使用CPU内存来存储数据,而在CUDA设备上创建的Tensor对象使用GPU显存来存储数据。因此,我们通常需要在CPU上创建张量,并在必要时将其移动到CUDA设备上。

当频繁地使用 tensor.cpu() 将张量从 GPU 转到 CPU(或使用 tensor.cuda() 将张量从 CPU 转到 GPU)时,代价是非常昂贵的。item() 和 .numpy() 也是一样可以使用. detach() 代替。

如果你创建了一个新的张量,可以使用关键字参数 device=torch.device(‘cuda:0’) 将其分配给 GPU。
如果你需要传输数据,可以使用. to(non_blocking=True),只要在传输之后没有同步点。

8. 使用梯度 / 激活 checkpointing

Checkpointing 的工作原理是用计算换内存,并不存储整个计算图的所有中间激活用于 backward pass,而是重新计算这些激活。我们可以将其应用于模型的任何部分。

具体来说,在 forward pass 中,function 会以 torch.no_grad() 方式运行,不存储中间激活。相反的是, forward pass 中会保存输入元组以及 function 参数。在 backward pass 中,输入和 function 会被检索,并再次在 function 上计算 forward pass。然后跟踪中间激活,使用这些激活值计算梯度。
因此,虽然这可能会略微增加给定 batch 大小的运行时间,但会显著减少内存占用。这反过来又将允许进一步增加所使用的 batch 大小,从而提高 GPU 的利用率。

尽管 checkpointing 以 torch.utils.checkpoint 方式实现,但仍需要一些思考和努力来正确地实现。Priya Goyal 写了一个很好的教程来介绍 checkpointing 关键方面。
Priya Goyal 教程地址:
https://github.com/prigoyal/pytorch_memonger/blob/master/tutorial/Checkpointing_for_PyTorch_models.ipynb

9. 使用梯度积累

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

Hugging Face 的 Thomas Wolf 的文章《Training Neural Nets on Larger Batches: Practical Tips for 1-GPU, Multi-GPU & Distributed setups》介绍了如何使用梯度累积。梯度累积可以通过如下方式实现:

model.zero_grad()                                   # Reset gradients tensors
for i, (inputs, labels) in enumerate(training_set):
    predictions = model(inputs)                     # Forward pass
    loss = loss_function(predictions, labels)       # Compute loss function
    loss = loss / accumulation_steps                # Normalize our loss (if averaged)
    loss.backward()                                 # Backward pass
    if (i+1) % accumulation_steps == 0:             # Wait for several backward steps
        optimizer.step()                            # Now we can do an optimizer step
        model.zero_grad()                           # Reset gradients tensors
        if (i+1) % evaluation_steps == 0:           # Evaluate the model when we...
            evaluate_model()         

这个方法主要是为了规避 GPU 内存的限制而开发的。

10. 使用分布式数据并行进行多 GPU 训练

加速分布式训练可能有很多方法,但是简单的方法是使用 torch.nn.DistributedDataParallel 而不是 torch.nn.DataParallel。这样一来,每个 GPU 将由一个专用的 CPU 核心驱动,避免了 DataParallel 的 GIL 问题。
分布式训练文档地址:https://pytorch.org/tutorials/beginner/dist_overview.html

http://t.csdn.cn/ogAfU

11. 设置梯度为 None 而不是 0

梯度设置为.zero_grad(set_to_none=True) 而不是 .zero_grad()。这样做可以让内存分配器处理梯度,而不是将它们设置为0。正如文档中所说,将梯度设置为 None 会产生适度的加速,但不要期待奇迹出现。注意,这样做也有缺点,详细信息请查看文档。
文档地址:https://pytorch.org/docs/stable/optim.html

12. 使用. as_tensor() 而不是. tensor()

torch.tensor() 总是会复制数据。如果你要转换一个 numpy 数组,使用 torch.as_tensor() 或 torch.from_numpy() 来避免复制数据。

13. 必要时打开调试工具

PyTorch 提供了很多调试工具,例如 autograd.profiler、autograd.grad_check、autograd.anomaly_detection。请确保当你需要调试时再打开调试器,不需要时要及时关掉,因为调试器会降低你的训练速度。

14. 使用梯度裁剪

关于避免 RNN 中的梯度爆炸的问题,已经有一些实验和理论证实,梯度裁剪(gradient = min(gradient, threshold))可以加速收敛。HuggingFace 的 Transformer 实现就是一个非常清晰的例子,说明了如何使用梯度裁剪。本文中提到的其他一些方法,如 AMP 也可以用。
在 PyTorch 中可以使用 torch.nn.utils.clip_grad_norm_来实现。

15. 在 BatchNorm 之前关闭 bias

在开始 BatchNormalization 层之前关闭 bias 层。对于一个 2-D 卷积层,可以将 bias 关键字设置为 False:torch.nn.Conv2d(…, bias=False, …)。

16. 在验证期间关闭梯度计算

在验证期间关闭梯度计算,设置:torch.no_grad() 。

17. 使用输入和 batch 归一化

要再三检查一下输入是否归一化?是否使用了 batch 归一化?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/451908.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

web前端 --- CSS(1)

CSS&#xff08;Cascade Style Sheet&#xff09; --- 级联样式表&#xff08;1&#xff09; <head><style>选择器{属性名&#xff1a;属性值;属性名&#xff1a;属性值;}</style> </head>属性名&#xff1a;修饰对象的属性&#xff08;样式&#xff…

docker ——安装tomcat

环境&#xff1a;centos7 安装tomcat 第一步&#xff1a;联网 第二步&#xff1a;开启docker systemctl start docker 第三步&#xff1a;拉取镜像 docker pull tomcat //下载tomcat镜像 docker pull tomcat 第四步&#xff1a;创建容器 docker run -d …

Solr之查询页面,索引,SolrJ

文章目录 1 Solr查询1.1 查询页面1.1.1 基本查询1.1.2 Solr检索运算符1.1.3 高亮1.1.4 分组1.1.4.1 分组&#xff08;Field Facet&#xff09;1.1.4.2 分组&#xff08;Date Facet&#xff09; 1.2 创建索引文件1.2.1 使用Post上传文件1.2.1.1 Linux下使用1.2.1.1.1 索引XML1.2…

BDCC- 数据湖体系

文章目录 数据湖的概念数据湖 vs 数据仓库 vs Lakehouse① 业界进展&#xff08;Databricks 2.0&#xff09;-湖上建仓② 业界进展&#xff08;Snowflake EDW 2.0&#xff09;-仓外挂湖 LakeHouse 的演进&#xff08;1&#xff09;Lakehouse 的演进路线&#xff08;2&#xff0…

基于matlab的长短期神经网络LSTM的电力负荷预测

目录 背影 摘要 LSTM的基本定义 LSTM实现的步骤 基于长短期神经网络LSTM的电力负荷预测 MATALB代码 效果图 结果分析 展望 参考论文 背影 电力负荷预测的实质是从已知的电力系统&#xff0c;经济&#xff0c;社会&#xff0c;气象等情况出发&#xff0c;根据历史负荷变化规律…

CSDN 周赛 48 期

CSDN 周赛 48 期 工作日参赛1、题目名称&#xff1a;最后一位2、题目名称&#xff1a;天然气订单3、题目名称&#xff1a;排查网络故障4、题目名称&#xff1a;运输石油小结 工作日参赛 说实话&#xff0c;今天是周末&#xff0c;但是今天也是工作日&#xff0c;老顾已经预计到…

Tossim 教程

系列文章目录 TinyOS 系列文章【一】&#xff1a;TinyOS 配置教程 TinyOS 系列文章【二】&#xff1a;Tossim 教程 文章目录 系列文章目录前言1. Tossim 简介2. TOSSIM 仿真2.1. 编译 TOSSIM2.2. 基于 Python 的仿真2.3. 调试语句2.4. 网络配置 总结 前言 本文主要用于记录在…

打破广播电视行业前端摄录设备依赖进口局面,BOSMA博冠全新国产8K摄像机重新定义广播世界

《世界广播电视》杂志曾经预测&#xff0c;2025年全球将有1000个超高清频道在播出。中国广电总局提出&#xff0c;到2025年底&#xff0c;标清频道基本关停&#xff0c;省级电视台要基本具备超高清电视制播能力。视频超高清已成为一个国际趋势。中国有14亿人口&#xff0c;是全…

蓝牙设备节点协议栈基础知识

蓝牙设备节点协议栈基础知识 一&#xff1a;TTY&#xff08;虚拟控制台&#xff0c;串口以及伪终端设备组成的终端设备&#xff09; Android/Linux 几乎所有的外设都以”设备节点”的形式存在 例如PC插入串口,会识别成COM1/COM2…在linux下面则以/dev/ttyXXX的形式存在,如/dev…

国家信息安全水平考试中NISP一级网络安全证书介绍

1、什么是NISP? 国家信息安全水平考试&#xff08;National Information Security Test Program&#xff0c;简称NISP&#xff09;&#xff0c;是由中国信息安全测评中心实施培养国家网络空间安全人才的项目。 2、考取NISP一级认证的同学就业岗位和薪资标准有那些呢&#xf…

Docker创建镜像,建立网桥,容器制作虚拟机

新建基础镜像&#xff0c;希望能够SSH&#xff0c;安装java&#xff0c;用户&#xff0c;声明22端口等等&#xff1b;拷贝基础hadoop安装文件 新建Dockerfile FROM centos:7.9.2009RUN rm -f /etc/localtime && ln -sv /usr/share/zoneinfo/Asia/Shanghai /etc/local…

【C++】Windows使用Visual Studio C++链接云数据库PostgreSQL(沉浸式老爷教学)

Windows使用C Visual Studio链接云数据库PostgreSQL 一、前置条件二、安装PostgreSQL工具三、编译libpqxx库四、Visual Studio配置测试**如果对您有帮助&#xff0c;关注收藏&#xff01;** 关注 “测试开发自动化” 公众号&#xff0c;获取更多学习内容 一、前置条件 下载lib…

MQTT 开放基准测试规范:全面评估你的 MQTT Broker 性能

引言 我们很高兴地宣布&#xff1a;由 EMQ 提供的 MQTT 开放基准测试规范现已正式发布&#xff01; 该测试规范包含了实用的典型使用场景、一套衡量 Broker 性能的主要指标&#xff0c;以及一个模拟负载和收集测试结果的工具&#xff0c;可以帮助开发者评估 MQTT Broker 的可…

让同为2.4G的ZigBee与Wi-Fi相容的解决方案解析

2.4G (WIFI,BT,ZIGBEE,普通2.4G 无线) 4种2.4G 无线通信协议。 普通2.4G 无线 最便宜。 众所周知&#xff0c;小米的智能套装包含的4件套&#xff0c;人体传感器、门窗传感器、无线开关与多功能网关采用的是基于NXP的一颗工业级ZigBee射频芯片–JN5168进行组网通讯。而多功能网…

office实操技能01:修改微软Office页面的(非背景的)浅绿底色、设置默认字体和主题颜色、取消页眉横线、PPT默认的等线字体

目录 1 处理word中默认中文字体是等线的问题 2 处理word中没有设置背景色&#xff0c;但页面底色是浅绿色的问题 3 修改office的主题颜色 4 删除页眉横线 5 处理PPT中的等线字体 这篇博文主要介绍两个使用技能&#xff1a; 技能1&#xff1a;修改word的默认等线字体技能2&…

( “树” 之 BST) 653. 两数之和 IV - 输入二叉搜索树 ——【Leetcode每日一题】

二叉查找树&#xff08;BST&#xff09;&#xff1a;根节点大于等于左子树所有节点&#xff0c;小于等于右子树所有节点。 二叉查找树中序遍历有序。 653. 两数之和 IV - 输入二叉搜索树 难度&#xff1a;简单 给定一个二叉搜索树 root 和一个目标结果 k&#xff0c;如果二叉…

关于Java注解的一些理解 小结

目录 1. 常用注解和理解 2. 自定义注解 2.1 案例背景 2.2 设计思路 3 总结 1. 常用注解和理解 注解在我的理解下&#xff0c;就是代码中的特殊标记&#xff0c;这些标记可以在编译、类加载、运行时被读取&#xff0c;并执行相对应的处理。 可能有些抽象&#xff0c;简单…

Web3中文|好莱坞新星如何成就电影业?

Web3 技术已经被用于电影行业&#xff0c;以建立社区并将利基内容代币化。NFT 将是好莱坞的下一个新星。 【利基&#xff08;niche&#xff09;是指针对企业的优势细分出来的市场&#xff0c;这个市场不大&#xff0c;而且没有得到令人满意的服务。产品推进这个市场&#xff0c…

DATAFAKER 使用方法记录

DATAFAKER 使用方法记录 win10 64位 Python 3.10.11 参考网址 datafaker的使用–详细教程 https://blog.csdn.net/A15517340610/article/details/105623103 https://github.com/gangly/datafaker python 版本 It is compatible with python2.7 and python3.4 也就是说 他…

开箱即用的ChatGPT替代模型,还可训练自己数据

一、普遍关注是什么&#xff1f; OpenAI 是第一个在该领域取得重大进展的公司&#xff0c;并且使围绕其服务构建抽象变得更加容易。然而&#xff0c;便利性带来了集中化、通过中介的成本、数据隐私和版权问题。 而数据主权和治理是这些新的LLM服务提供商如何处理商业秘密或敏…