如何优化批处理策略,最大限度地“压榨”GPU性能

新手数据科学家和机器学习工程师常常会问一个关键问题:如何判断他们的深度学习训练过程是否在正常运行?在本文中,我们将学习如何诊断和优化深度学习的性能问题,不论是在单台机器还是多台机器上进行训练。通过这些方法,我们将能够更加高效地使用各种云端 GPU 资源。

首先,我们将从了解 GPU 的利用率开始,最后探讨如何选择合适的批处理大小来最大化 GPU 的利用效率。

请注意:本文假设读者已经具备基本的 Linux 操作系统知识,并熟悉 Python 编程语言。大多数现代的 Linux 发行版(如 Ubuntu)通常已经预装了基本工具,因此我们可以直接安装 pip 和 conda,因为它们将在本文中被广泛使用。

准备工作

为了能够顺利跟进本文的内容,你需要具备一定的 Python 编程经验,并对深度学习有基础的理解。我们假设所有读者都可以使用性能足够强大的机器,便于运行本文中提供的代码。

如果你还没有合适的 GPU,或希望获取更高性能的 GPU ,比如 H100x8,我们建议可以尝试 GPU 云服务来低成本、快速获取这些资源。目前,许多云服务提供商都提供 GPU 资源。DigitalOcean 的 GPU Droplets 云服务现已开放使用,而且正在进行限时优惠,最低仅需 2.5 美元/月即可使用 H100 GPU 服务器。如需商洽,可直接联系 DigitalOcean 中国区独家战略合作伙伴卓普云。

什么是 GPU 利用率?

在机器学习和深度学习的训练过程中,GPU 利用率是需要密切关注的重要指标之一。我们可以通过一些知名的第三方工具以及内置的 GPU 工具来监控它。

GPU 利用率可以定义为单个或多个 GPU 核心在过去一秒中的运行速度,深度学习程序会并行地使用这些 GPU 资源。换句话说,GPU 利用率反映了 GPU 的工作负载情况。

如何判断是否需要更多 GPU 计算资源?

让我们来看一个实际的场景。在典型的一天里,数据科学家可能拥有两块 GPU 供他/她使用,这些资源“应该”足够应对大部分任务。在模型构建的初期阶段,GPU 的短期交互工作良好,工作流程十分顺畅。然而,一旦进入训练阶段,工作流程可能会突然需要额外的 GPU 计算资源,而这些资源并不容易获得。

这表明要完成重要任务时,需要更多的计算资源。特别是在 RAM 已经被完全分配完的情况下,以下任务将无法完成:

  • 运行更多实验
  • 利用多 GPU 进行训练,以加快训练速度,尝试更大的批处理大小,并获得更高的模型精度
  • 专注于新模型的开发,同时让其他模型独立训练

GPU 利用率的优势

通常情况下,增加 GPU 计算资源会显著提高硬件的利用率,从而使模型训练速度提升两倍。

  • GPU 利用率的提高能够帮助我们更高效地管理资源分配,减少 GPU 的空闲时间,进而提高整个集群的利用率。
  • 从深度学习专家的角度来看,消耗更多的 GPU 计算能力意味着我们可以运行更多的实验,从而提高生产力和模型的质量。
  • 此外,IT 管理员可以利用多个 GPU 进行分布式训练,例如使用 DigitalOcean Droplets 提供的 NVLink 多 GPU 机器,这将有效缩短训练时间。

最佳批处理大小与 GPU 利用率

批处理大小的选择常常让人困惑,因为对于特定的数据集和模型架构来说,没有一种单一的“最佳”批处理大小。如果选择较大的批处理大小,训练过程会更快,但会消耗更多的内存,最终可能导致模型的准确率下降。因此,首先让我们了解什么是批处理大小,以及为什么需要它。

什么是批处理大小?

在训练深度学习神经网络等模型时,指定批处理大小至关重要。简而言之,批处理大小是指一次传递给网络进行训练的样本数量。

批处理大小示例

假设你有 1000 张猫的照片,想要训练网络识别不同的猫品种。现在,假设你选择了 10 的批处理大小。这意味着在某一时刻,网络将同时处理 10 张猫的照片,也就是我们称之为的一组或一批。

明白了,批处理大小的概念很简单,但为什么它这么重要呢?理论上,你可以逐个数据元素传递给模型,而不必将数据放入批处理中。接下来,我们将在下文解释为什么需要批处理。

为什么要使用批次?

我们之前提到,较大的批次大小可以帮助模型在训练期间更快完成每个 epoch。这是因为,基于可用的计算资源,机器可能能够同时处理多个样本。

然而,即使你的机器能够处理非常大的批次,随着批次大小的增加,模型的最终输出质量可能会下降,导致模型对新数据的泛化能力减弱。

因此,我们可以得出结论:批次大小是另一个超参数,需要根据特定模型在整个训练过程中的表现进行评估和调整。同时,还需要监控机器在运行不同批次大小时对 GPU 的利用情况。

例如,如果你将批次大小设置得过高,比如 100,机器可能没有足够的处理能力同时处理所有 100 张图像。这时,减小批次大小可能是更好的选择。

现在我们已经了解了批次大小的一般概念,接下来看看如何在 PyTorch 和 Keras 中通过代码来优化合适的批次大小。

使用 PyTorch 找到合适的批处理大小

在本节中,我们将介绍如何在 Resnet18 模型上找到合适的批处理大小。我们将使用 PyTorch 的分析工具来测量 Resnet18 模型的训练性能和 GPU 利用率。

为了演示如何更好地使用 PyTorch 监控模型性能并将结果展示在 TensorBoard 上,我们将在代码中使用 PyTorch 分析器,并开启额外的选项。

跟随此演示

在你的云端 GPU 机器上,使用 wget 下载相应的 Jupyter 笔记本文件。然后,运行 Jupyter Labs 来打开笔记本。你可以通过粘贴以下内容并打开笔记本链接来完成这一操作:

wget https://raw.githubusercontent.com/gradient-ai/batch-optimization-DL/refs/heads/main/notebook.ipynb
jupyter lab

数据和模型的设置和准备

输入以下命令来安装 torch、torchvision 和 Profiler。

pip3 install torch torchvision torch-tb-profiler

以下代码将从 CIFAR10 中获取我们的数据集。接下来,我们将使用预先训练的模型 resnet18 进行迁移学习并训练模型。

#import all the necessary libraries 
import torch  
import torch.nn  
import torch.optim  
import torch.profiler  
import torch.utils.data  
import torchvision.datasets  
import torchvision.models  
import torchvision.transforms as T    
#prepare input data and transform it 
transform = T.Compose(  
    [T.Resize(224),  
     T.ToTensor(),  
     T.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])  
train_set = torchvision.datasets.CIFAR10(root='./data', train=True, download=True, transform=transform)  
# use dataloader to launch each batch 
train_loader = torch.utils.data.DataLoader(train_set, batch_size=1, shuffle=True, num_workers=4)  
# Create a Resnet model, loss function, and optimizer objects. To run on GPU, move model and loss to a GPU device 
device = torch.device("cuda:0")  
model = torchvision.models.resnet18(pretrained=True).cuda(device) 
criterion = torch.nn.CrossEntropyLoss().cuda(device)  
optimizer = torch.optim.SGD(model.parameters(), lr=0.001, momentum=0.9)  
model.train()    
# define the training step for each batch of input data 
def train(data):  
    inputs, labels = data[0].to(device=device), data[1].to(device=device)  
    outputs = model(inputs)  
    loss = criterion(outputs, labels)  
    optimizer.zero_grad()  
    loss.backward()  
    optimizer.step()

我们已经成功设置了基本模型,现在我们将启用分析器中的可选功能,以便在训练过程中记录更多信息。接下来,我们将包括以下参数:

  • schedule该参数接受一个步骤(int),并在每个阶段返回要执行的分析器操作。
  • profile_memory用于追踪 GPU 内存分配。将其设置为 true 可能会增加一些额外的时间开销。
  • with_stack记录所有跟踪操作的源代码信息。

现在我们已经理解了这些术语,可以回到代码继续操作了:

with torch.profiler.profile(
        schedule=torch.profiler.schedule(wait=1, warmup=1, active=3, repeat=2),
        on_trace_ready=torch.profiler.tensorboard_trace_handler('./log/resnet18_batchsize1'),  
        record_shapes=True,
        profile_memory=True,
        with_stack=True
) as prof:
    for step, batch_data in enumerate(train_loader):
        if step >= (1 + 1 + 3) * 2:
            break
        train(batch_data)
        prof.step()  # Need call this at the end of each step to notify profiler of steps' boundary.

使用 Keras 找到合适的批次大小

在这种情况下,我们将使用任意顺序模型;

model = Sequential([
    Dense(units=16, input_shape=(1,), activation='relu'),
    Dense(units=32, activation='relu', kernel_regularizer=regularizers.l2(0.01)),
    Dense(units=2, activation='sigmoid')
])

让我们集中精力于调用 model.fit() 的地方。这是人工神经网络学习并调用来训练模型的函数。

model.fit(
    x=scaled_train_samples,
    y=train_labels,
    validation_data=valid_set,
    batch_size=10,
    epochs=20,
    shuffle=True,
    verbose=2
    )

上面的 fit() 函数接受一个名为 batch_size 的参数。在这里,我们为 batch_size 变量赋值。在这个模型中,我们将该值设置为 10。因此,在模型训练过程中,我们将一次传入 10 个样本,直到整个循环完成。完成后,训练过程将重新开始下一个循环。

需要注意的重要事项

在执行多 GPU 训练时,批次大小需要特别关注,因为它可能会影响训练速度、内存使用、模型的收敛性。如果不加以注意,模型的权重甚至可能会出错。

  • 速度和内存毫无疑问,使用较大的批次可以加快训练和预测的速度。由于与从 GPU 加载和卸载数据相关的开销较大,较小的批次会导致更高的处理开销。然而,一些研究表明,使用小批次进行训练可能会提高模型的最终效果分数。另一方面,较大的批次需要更多的 GPU 内存。大批次可能会导致内存不足问题,因为每层的输入在训练期间都要保留在内存中,尤其是用于反向传播步骤时。
  • 收敛性如果你使用随机梯度下降 (SGD) 或其变体来训练模型,批次大小可能会影响网络的收敛速度和泛化能力。在许多计算机视觉问题中,通常使用的批次大小范围在 32 到 512 之间。
  • GPU 出错风险这是一个容易被忽视但可能带来灾难性后果的技术细节。在多 GPU 训练中,确保每个 GPU 都能获得数据至关重要。如果你的数据集大小不能被批次大小整除,那么在最后一个 epoch 中可能会有少量样本没有分配给某些 GPU。这种情况会导致某些 Keras 层(特别是批次规范化层)出错,导致权重中出现 NaN 值(比如在批次规范化层中的运行平均值和方差)。

更糟糕的是,在训练期间这个问题可能不会被察觉,因为学习阶段设置为 1,但在预测期间(学习阶段设置为 0)会使用运行平均值和方差,这时 NaN 值可能会导致预测结果出现问题。

因此,在多 GPU 训练时,确保批处理大小保持一致非常重要。你可以通过拒绝不符合预定义大小的批次,或者通过重复批次中的条目直到它符合预定义大小来解决这一问题。最后还要记住,在多 GPU 配置下,批次大小应该大于 GPU 总数。

结论

在本文中,我们讨论了如何通过找到合适的批次大小来最大化 GPU 的利用率。只要你设置了一个合理的批次大小(例如 16 以上),并保持迭代次数和 epochs 不变,批次大小对性能的影响就会较小。不过,训练时间会受到一定影响。对于多 GPU 训练,我们应选择尽可能小的批次大小,以确保每个 GPU 都能充分发挥其能力。每个 GPU 使用 16 个样本是一个不错的选择。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

uniapp onPageScroll

子组件有onPageScroll, 首页也要引入onPageScroll, eg: 主页面 sell/detail/index 《子组件》 <script setup> 引入onPageScroll </script> 组件&#xff1a; 引入onPageScroll 别人的比较

阿里 C++面试,算法题没做出来,,,

我本人是非科班学 C 后端和嵌入式的。在我面试的过程中&#xff0c;竟然得到了阿里​ C 研发工程师的面试机会。因为&#xff0c;阿里主要是用 Java 比较多&#xff0c;C 的岗位比较少​&#xff0c;所以感觉这个机会还是挺难得的。 阿里 C 研发工程师面试考了我一道类似于快速…

五个必备的高清无水印视频素材库推荐

做抖音、短视频创作的朋友都知道&#xff0c;优质的素材往往决定了作品能否获得更多关注。如果你还不知道在哪里下载高清无水印的视频素材&#xff0c;不用担心&#xff01;今天为你推荐5个高品质的视频素材库&#xff0c;助你轻松创作出爆款视频。 蛙学网 是国内领先的视频素材…

Windows 11 24H2版本有哪些新功能_Windows 11 24H2十四大新功能介绍

距离上次发布的23H2版本已经过去了一年时间&#xff0c;现在&#xff0c;Win 11的24H2版本终于等到了&#xff0c;微软已经全面公开发布Win11 24H2版本&#xff0c;版本号为26100.1742&#xff0c;此次官宣的版本包括了消费者版、商业版、LTSC 2024版等&#xff0c;各种语言版本…

选择合适的SSL证书

随着我们在线业务的增长&#xff0c;确保网站安全变得越来越重要。对于许多人来说&#xff0c;保护网站安全的想法似乎令人望而生畏&#xff0c;尤其是在有各种SSL证书可用的情况下。您可能想知道哪一个最适合您的业务需求或如何浏览这些选项。 除了SSL证书之外&#xff0c;使…

IIC协议解析

文章目录 1 IIC理解1.1 IIC简述1.2 IIC协议优缺点1.3 传输速度 2 IIC数据格式3 数据时序3.1 写时序3.2 读时序 参考链接 1 IIC理解 1.1 IIC简述 IIC全称Inter Integrated Circuit&#xff0c;即集成电路总线。是由Philips半导体公司于八十年代初设计出的一种两线式串行总线协议…

雷达手势识别技术

1、IR-UWB 手势识别方案 该任务可以分为数据采集&#xff0c;雷达数据处理&#xff0c;识别分类三个部分。 1.1 UWB Radar 数据处理 首先采集慢时间快时间维数据&#xff1a; 然后仍然是Clutter removal filter&#xff1a; 之后正则化转化为灰度图像&#xff1a; 使用matlab f…

springboot+大数据+基于大数据的电脑硬件推荐系统【内含源码+文档+部署教程】

博主介绍&#xff1a;✌全网粉丝10W,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业毕业设计项目实战6年之久&#xff0c;选择我们就是选择放心、选择安心毕业✌ &#x1f345;由于篇幅限制&#xff0c;想要获取完整文章或者源码&#xff0c;或者代做&am…

虚幻闪烁灯光材质

创建一个材质 材质域改成光照函数 , Time让材质动起来 参数B用来控制速度 , Sine 让灯光闪烁 , Frac 增加了闪烁细节 把材质放到灯光材质上 效果还是挺不错的! 可以用于一些恐怖游戏~

Redis和Jedis的区别

目录 含义与用途 Jedis案例 总结 含义与用途 Redis&#xff1a; 概念&#xff1a;Redis是一个基于内存的键值存储数据库&#xff0c;支持丰富的数据结构。比如&#xff1a;字符串功能&#xff1a;除了基础的数据存储&#xff0c;Redis还提供了丰富的高级功能。如持久化&…

Python第七八次作业

1.输入一个大于0的正整数n&#xff0c;如果n 1 ,则返回1&#xff0c; 如果n是偶数&#xff0c;则返回 n // 2 &#xff0c;如果n是奇数&#xff0c;则返回 3n 1&#xff0c;将所有的返回值存放到一个列表中&#xff0c;注意&#xff1a;n是第一个元素&#xff0c;其他的元素根…

entity,pojo,vo,dto 详解

在Java项目中&#xff0c;包名通常用于组织代码&#xff0c;使其更加清晰和易于维护。entity、pojo、vo和dto是常见的包名&#xff0c;它们各自有不同的含义和用途。下面将详细解释这些包名的含义&#xff0c;并提供一个示例&#xff0c;帮助你更好地理解它们在项目中的应用。 …

DAPLINK 之 RTT 输出日志

文章目录 前言1 安装 SEGGER RTT2 OpenOCD 下的 rtt2.1 调试环境2.2 输出日志 3 关于日志中的文件名参考 前言 1&#xff09;RTT&#xff08;Real Time Transfer&#xff0c;实时传输&#xff09;&#xff1a;SEGGER 的 Real Time Transfer (RTT) 是一种经过验证的技术&#x…

mysql查看和修改默认配置

1.查看最大连接数 SELECT max_connections; 或者 SHOW VARIABLES LIKE max_connections;2.查看当前连接的客户端 SHOW PROCESSLIST;2.临时设置最大连接数 SET GLOBAL max_connections 500;3.临时设置连接客户端交互超时时间 SET GLOBAL interactive_timeout 1800;4.永久生…

3.3 Thymeleaf语法

文章目录 引言Thymeleaf标签显示标签链接地址标签条件判断标签元素遍历标签 Thymeleaf表达式变量表达式选择变量表达式消息表达式链接表达式 Thymeleaf内置对象上下文对象上下文变量上下文区域请求对象响应对象会话对象日期对象 实战演练创建控制器创建模板页面 结语 引言 Thy…

【Python爬虫】看电影还在用VIP?一个python代码让你实现电影自由!附源码

今日主题 如何用Python解析vip电影。 什么是vip电影&#xff1f; 这些vip电影啊&#xff0c;想要观看的话&#xff0c;必须充值会员&#xff0c;否则没法看。 比如这个&#xff1a; 这些vip电影解析后呢&#xff1f; 不需要会员&#xff0c;不需要登录&#xff0c;可以直接…

4、.Net 快速开发框架:DncZeus - 开源项目研究文章

DncZeus 是一个基于 ASP.NET Core 和 Vue.js 的前后端分离的通用后台管理系统框架&#xff0c;其愿景是成为一个易于使用且功能丰富的 .NET Core 通用后台权限管理模板系统基础框架。项目名称 "DncZeus" 由 "Dnc"(.NET Core 的缩写)和 "Zeus"(古…

STMicroelectronics 意法半导体芯片选型表

意法半导体作为全球知名的半导体厂商&#xff0c;其产品广泛应用于各个领域&#xff0c;从消费电子到工业控制&#xff0c;从汽车电子到通信设备&#xff0c;都能看到意法半导体芯片的身影。在电子硬件设计领域&#xff0c;芯片的选型至关重要。亿配芯城&#xff08;ICgoodFind…

SpringBoot+MyBatis+MySQL项目基础搭建

一、新建项目 1.1 新建springboot项目 新建项目 选择SpringBoot&#xff0c;填写基本信息&#xff0c;主要是JDK版本和项目构建方式&#xff0c;此处以JDK17和Maven举例。 1.2 引入依赖 选择SpringBoot版本&#xff0c;勾选Lombok&#xff0c;Spring Web&#xff0c;MyBa…

线性代数知识学习

1.标量 简单操作 长度 2.向量 parallel for all do 点乘、正交 3.矩阵 乘法&#xff08;矩阵乘以向量&#xff09; 4.范数 &#xfeff;&#xfeff;取決于如何衡量b和c的长度 &#xfeff;&#xfeff;常见范数 &#xfeff;&#xfeff;矩阵范数&#xff1a;最小的满足的…