为什么 batch size 都是2的幂数?

一项实验对比了不同batchsize对AI模型训练的影响,发现2的幂或8的倍数的选择在实际性能上几乎没有显著差异。尽管理论上内存对齐和矩阵运算效率建议使用2的幂,但实验结果显示,非2的幂batchsize在某些情况下可能更优。结论是,batchsize的选择应视具体项目而定,不必过于拘泥于2的幂这一传统做法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转自:新智元

你有没有疑惑过,为啥batch size都是2的幂数?

有人觉得是「习惯」,也有人说这算是一种约定俗成的标准,因为从「计算」的角度来看,batch size为2的幂数有助于提高训练效率。

d1c646c8f5a0793081359cee0f502983.png

但计算机科学就是一门实践的学科,理论再完美也需要实验结果来验证。

最近一位AI研究者Sebastian动手试了一下所有的batch size,结果发现其对性能的影响微乎其微,甚至在某些情况下,不使用2的幂数训练速度更快!

25f86d86c20b983be949d71fa82af31c.png

实验结果一出,也得到大量网友的响应。

有网友认为,使用2的幂数单纯是出于审美上的愉悦,但我并不觉得有什么区别。有时候为了体验「游走于刀尖上」的感觉,我就用10的倍数。

也有网友认为batch size的设置存在玄学,他有时候还会用7的倍数。

a96e8aca7ca036e12d60368d4f9de1a1.png

更叛逆的网友表示,我用2的幂数,但是幂数带「小数」

adad3895121a30a76d5f08c896fa0515.png

不过也有正经点的讨论,认为作者做的基准测试可能是精度不够的,比如batch size选择512和539的区别可能根本测量不出来。

9d3ef024615e12412739c04a4c64581c.png

也有人表达反对意见,我们「不是必须」选择2的幂数,但我们「应该」这样做。

首先这个基准测试毫无意义,在一个超级小数据集上使用一个超小网络进行实验,我们无法从这样的玩具数据中获得任何现实世界的指标。

其次,在TPU上选择batch size为8的倍数太大了,数据将被填充,并且会浪费大量的计算。

我认为即使在GPU上,padding也会有影响,可能会留下潜在的性能改进空间。

21a07abe1002034813ebe19233aec389.png

理论基础

在看实践基准结果之前,我们简单回顾一下选择batch size为2的幂的主要思路。

内存对齐(Memory Alignment)

选择batch size为 2 的幂的主要论据之一是 CPU 和 GPU 内存架构是以 2 的幂进行组织的。或者更准确地说,存在内存页的概念,它本质上是一个连续的内存块。

如果你使用的是 macOS 或 Linux,就可以通过在终端中执行 getconf PAGESIZE 来检查页面大小,它应该会返回一个 2 的幂的数字。

c0f96fc6c9857997d8b8ec7b987fd4a4.png

其目的是将一个或多个batch整齐地放在一个Page上,以帮助在GPU中进行并行处理,所以batch size大小为2的幂数可以帮助获得更好的内存排列。这与在视频游戏开发和图形设计中使用OpenGL和DirectX时选择2次方纹理相类似。

矩阵乘法和Tensor Core

英伟达有一个矩阵乘法背景用户指南,解释了矩阵维度和GPU的计算效率之间的关系。

文章中建议不要选择矩阵尺寸为2的幂,而是选择矩阵尺寸为8的倍数,以便在带有Tensor Core的GPU上进行混合精度训练。当然,这两者之间是有重叠的,比如8, 16, 32等。

d2dbaabaea6a701fb0923ca28537db8e.png

为什么会是 8 的倍数?这与矩阵乘法有关。

假设我们在矩阵 A 和 B 之间有以下矩阵乘法:

0e93990eec92ae78825693190c1f6f29.png

计算两个矩阵 A 和 B 相乘的一种方法是计算矩阵 A 的行向量和矩阵 B 的列向量之间的点积(dot product)。

88a6d799f30115ce5a6647acd5f9e5d9.png

每个点积由一个「加法」和一个「乘法」操作组成,需要得到 M×N 个这样的点积,因此共有 2×M×N×K 次浮点运算(FLOPS)。

不过现在矩阵在 GPU 上的乘法并不完全如此,GPU 上的矩阵乘法还包括tiling

b800249dfe23f775097a99d2c1c5ba95.png

如果使用带有 Tensor Cores 的 GPU,例如英伟达 V100,当矩阵维度 (M、N 和 K)与 16 字节的倍数对齐后,在 FP16 混合精度训练的情况下,8 的倍数对于计算效率来说是最佳的。

通常维度 K 和 N 由神经网络架构决定,但batch size(此处为 M)通常是由开发者控制的。

因此,假设batch size为 8 的倍数在理论上对于具有 Tensor Core 和 FP16 混合精度训练的 GPU 来说是最有效的,不过实际提升效果有多少,还需要做过实验才知道。

简单的Benchmark

为了了解不同的batch size对实际训练的影响,作者在CIFAR-10上运行了一个简单的基准训练MobileNetV3(large)的10个epoch,图像被调整为224×224以达到适当的GPU利用率。

在V100卡上运行了16位原生自动混合精度训练,这样可以更有效地利用GPU的Tensor Cores。

585754d23fdef9a73d71131ea59f41d1.png

代码链接:https://github.com/rasbt/b3-basic-batchsize-benchmark

小batch size

从batch size为128的小基准开始,Train Time对应于在 CIFAR-10 上训练 MobileNetV3 的 10 个 epoch,Inference Time为在测试集中的 10k 图像上评估模型。

e471b217a241a149b92bbbaeb76bdc4e.png

如果把batch size为128作为基准点,减少一个批处理量(127)或增加一个批处理量(129)确实会导致训练性能稍慢。然而,这里的差异几乎不明显,我认为它可以忽略不计。

将批处理量减少28(即100)会导致更明显的性能减慢。这可能是因为模型现在需要处理比以前更多的批次(50,000/100=500 vs. 50,000/100=390)。

可能由于类似的原因,当我们将批次大小增加28(156)时,我们可以观察到训练时间更短了。

最大的batch size

鉴于 MobileNetV3 架构和输入图像大小,128可能太小了,因此 GPU 利用率约为 70%。

为了研究 GPU 满负荷时的训练时间差异,作者将batch size增加到 512,以使 GPU 显示出接近 100% 的计算利用率。

11267ba92d557b1282c5d1854ea02b9c.png

由于 GPU 内存限制,batch size值无法超过 515。

同样,正如我们之前看到的,作为 2 的幂(或 8 的倍数)的批大小确实会产生很小但几乎不明显的差异。

多GPU训练

前两个基准测试评估了在单个GPU上的训练性能,转到多GPU上结果是否会有不同?

42fe4484440939073253b4a219f9ba4d.png

可以看到,这一次,2次方和8次方的批处理规模(256)并不比257快。

本处使用DistributedDataParallel(DDP)作为默认的多GPU训练策略。

注意事项

这里需要强调的是上述所有基准测试都有注意事项。例如只运行每个配置一次。理想情况下可能希望多次重复这些运行并报告平均值和标准偏差。

但最终结论可能都是一样的:即性能没有实质性差异。

此外,虽然实验是在同一台机器上运行了所有基准测试,但是以连续的顺序运行测试,运行之间没有很长的等待时间。也就是说GPU的温度在运行时可能有所不同,并且可能会对计时产生轻微影响。

资源和讨论

Ross Wightman 曾提到,他也不认为选择batch size为 2 的幂会产生明显的差异,但选择 8 的倍数对于某些矩阵维度可能很重要。

此外 Wightman 指出,在使用 TPU 时batch size至关重要,不过作者表示他无法轻松地访问到 TPU,所以也就没做基准测试。

bfc7dbb562f787e757c7b61c424beb3a.png

Rémi Coulom-Kayufu 曾经做过一个实验表明,2 次方的batch size实际上并非最佳选择。

对于卷积神经网络,可以通过以下方式计算出较好的值

c3eea586c0a6aa298f6c5fce896fc4fd.png

其中,n 是整数,SM 是 GPU 内核的数量(例如,V100 为 80,RTX 2080 Ti 为 68)。

结论

基于本文分享的基准结果,我不相信选择batch size规模为2的幂或8的倍数在实践中会有明显的区别。

然而,在任何特定的项目中,不管是研究基准还是机器学习的实际应用,选择2次方(即64、128、256、512、1024等)可以会更加直接和易于管理。

另外,如果你对发表学术研究论文感兴趣,将你的批次大小选择为2的幂,会使你的结果看起来不那么像「调参出来的」。

虽然坚持使用2次方的batch size可以帮助限制超参数搜索空间,但必须强调批量大小仍然是一个超参数。

b06b08f838c1c6d277f61aeea5d4da3f.png

有些人认为,较小的batch size有助于泛化性能,而另一些人则建议尽可能地增加批次大小。

就我个人而言,我发现最佳batch size高度依赖于神经网络架构和损失函数。例如,在最近一个使用相同ResNet架构的研究项目中,我发现最佳批次大小可以在16到256之间,完全取决于损失函数。

因此,我建议始终考虑将调整batch size作为你的超参数优化搜索的一部分。

如果由于内存的限制,你不能使用512的batch size,你也不必降到256,选择500也是完全可以的。

参考资料:

https://sebastianraschka.com/blog/2022/batch-size-2.html

https://www.reddit.com/r/MachineLearning/comments/vs1wox/p_no_we_dont_have_to_choose_batch_sizes_as_powers/

猜您喜欢:

26f6d1bfbc83d45fb434135308bcef58.png 戳我,查看GAN的系列专辑~!

一顿午饭外卖,成为CV视觉前沿弄潮儿!

CVPR 2022 | 25+方向、最新50篇GAN论文

 ICCV 2021 | 35个主题GAN论文汇总

超110篇!CVPR 2021最全GAN论文梳理

超100篇!CVPR 2020最全GAN论文梳理

拆解组新的GAN:解耦表征MixNMatch

StarGAN第2版:多域多样性图像生成

附下载 | 《可解释的机器学习》中文版

附下载 |《TensorFlow 2.0 深度学习算法实战》

附下载 |《计算机视觉中的数学方法》分享

《基于深度学习的表面缺陷检测方法综述》

《零样本图像分类综述: 十年进展》

《基于深度神经网络的少样本学习综述》

948e5f33f2b41ab43a9cbb5fff645a66.png

### 关于 Batch Size 是否必须是2的倍 在深度学习中,Batch Size 的选择确实存在一些特定的要求和建议。当神经网络架构中含有 Batch Normalization 层时,为了确保该层能正常工作并取得较好的效果,通常推荐 Batch Size 设置2次方形式,并且不建议将其设为1[^3]。 然而,这并不意味着 Batch Size 绝对必须严格限定为2的整倍才能进行有效的训练。实际上,Batch Size 可以根据具体应用场景灵活调整。对于不含 Batch Normalization 层或其他特殊需求的情况,任何合理的值都可以作为 Batch Size 使用,只要它适合当前硬件资源以及所处理的据集规模即可[^4]。 需要注意的是,较大的 Batch Size 虽然可以加速单步计算过程,但也可能导致收敛速度减慢甚至影响最终模型性能,尤其是在相同 Epoch 量下减少了参更新频率的情形下[^2]。因此,在实际操作过程中应当综合考虑多方面因素来选定合适的 Batch Size 值。 ```python # 示例代码展示如何定义不同的 batch size 进行实验对比 import torch def train_model(batch_size=32): dataloader = DataLoader(dataset, batch_size=batch_size, shuffle=True) for epoch in range(num_epochs): for inputs, labels in dataloader: outputs = model(inputs) loss = criterion(outputs, labels) optimizer.zero_grad() loss.backward() optimizer.step() train_model(batch_size=8) # 小批量 train_model(batch_size=16) # 中等大小批次 train_model(batch_size=32) # 较大批次 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值