“特别是其搭载690战术核显卡的改进型号,一发就可以摧毁一个航母战斗群。”——甘肃卫视
随着深度学习的高速发展,对硬件运算速度的要求逐渐提高。使用GPU对模型进行加速运算是大部分研究人员的首要选择,运算时通常将数据打成多个batch来提高速率,而在深度学习模型训练过程中batch-size大小选择是常遇到的问题。
为什么要讨论这个问题?
【资料图】
在不少教程与示例程序中,模型训练的batch-size通常以2的整数次方递增(如1,2,4,8,16等),给出的依据通常是英伟达官方在矩阵乘法背景用户指南(Matrix Multiplication Background User's Guide)[1]中的Performance is better when equivalent matrix dimensions M, N, and K are aligned to multiples of 16 bytes,即当等效矩阵维度M、N和K对齐到16字节的倍数时性能更好;以及GPU性能背景用户指南(GPU Performance Background User's Guide)[2]中给出的不同GPU架构每个SM单元一个时钟周期的乘加操作次数表格(见表1),当乘加操作次数与矩阵维度对齐时计算效率最高。
上表对CUDA核和Tensor核的张量计算效率进行了比较。英伟达GPU从Volta架构引入了Tensor Core用于加速张量计算,但Volta和Turing架构浮点计算仅支持FP16即半精度浮点数[3](见上表)。其中Volta架构对应NVIDIA TITAN V、Tesla V100等GPU,Turing架构对应20系(包括16系)、MX450、Tesla T4等GPU,Ampere架构对应30系GPU及专业卡。本文实验所使用的GPU为Pascal架构,支持CUDA核加速,不支持任何Tensor核加速[4]。
因此请注意,本文的实验结果仅能在无Tensor Core的GPU上进行相对性能参考,不能确保在具有Tensor Core的GPU上复现。
亦有网友指出batch-size为8的整数次方时对于某些矩阵维度可能很重要[5]。扯了那么多有的没的,本文将实验探究在单机单卡训练时不同batch-size对训练和测试时间的影响,比较batch-size正好撑满显存和2的整数次方等情况下的GPU计算效率,希望对研究深度学习技术的同学有所帮助。
硬件:
二手腾讯云服务器:戴尔R730XD
CPU: Intel Xeon E5-2698 v3 @ 2.30GHz *2, 32 Cores 64 Threads
RAM: 128GB @ 2133MHz
GPU: NVIDIA Tesla P40 24GB, 3840 CUDA Cores, FP32 12 TFLOPS, CUDA算力等级6.1,矿崩后买的便宜矿卡。运行于TCC模式以节省资源;ECC OFF (ECC ON时总可用VRAM: 23040MiB;ECC OFF时总可用VRAM: 24576MiB,即6.25%显存用于ECC纠错)
软件:
OS Version: Windows Server 2022 Standard, 21H2, Build 20348.1487, Python 3.9
YOLOv7 Version: v0.1, Commit 2fdc7f14395f6532ad05fb3e6970150a6a83d290 [6]
Requirements Version: pytorch 1.13.0, pytorch-cuda 11.7, torchvision 0.14.0
数据集:
就手使用VinBigData的VinDr-CXR胸片病灶目标检测数据集,训练集共15000样本,剔除10606 No Finding样本,剩余4394样本并进行预处理[7]。数据集部分样本可视化如图所示。
YOLOv7 (Vanilla):
Run Script:
Model Summary: 415 layers, 37266678 parameters, 37266678 gradients, 105.3 GFLOPS
训练集:测试集 = 3:1 = 3296:1098,图像尺寸640*640,Epoch = 5,默认数据增强。
YOLOv7 (Vanilla), --cache-images:
Run Script:
打开--cache-images开关可以在内存中缓存训练数据,加快传播速度。
YOLOv7的大型模型计算较慢且接受尺寸为1280,对显存容量需求急剧增加,考虑到时间和电费不再嗯算。
1 batch-size为2的整数次方倍时效率不一定最高,使用显存较大时效率较高。
推论:batch-size和batch数量达到平衡时效率最高,可能与batch-size是否2整数次方无关,可以适当增加batch-size大小以减小每个epoch的传播次数来节约时间。
局限性:我没有阅读过YOLOv7的Dataloader代码,不了解是否有优化,也没有对比不同Worker数量对效率的影响。因此结论不能推广到其他神经网络。
2 不断增加batch-size直至CUDA OOM,显存占用与batch-size大小并非呈现线性关系。
3 若RAM足够大,开启YOLOv7的--cache-images选项可以显著加快训练速度(约5%-15%),但在开始训练前需要一定时间将数据读取进内存,因此在epoch较大的训练条件下效果更为显著。前文实验中开启--cache-images后python占用RAM约50GB。
混合精度:使用FP16进行乘法和存储,只使用FP32进行加法操作,避免累加误差
辅助训练头:训练p6模型时需使用train_aux.py,否则将导致IndexError: list index out of range错误。train_aux.py引用loss.py中build_targets2函数时可能出现RuntimeError: indices should be either on cpu or on the same device as the indexed tensor (cpu)错误,官方修复了build_targets函数而没有修改build_targets2函数,根据[8]中issues链接修改loss.py中build_targets2函数。
[1] https://docs.nvidia.com/deeplearning/performance/dl-performance-matrix-multiplication/index.html
[2] https://docs.nvidia.com/deeplearning/performance/dl-performance-gpu-background/index.html
[3] https://blog.csdn.net/pangxing6491/article/details/126760421
[4] https://zhuanlan.zhihu.com/p/515584277?utm_medium=social&utm_oi=930040293143674880
[5] https://sebastianraschka.com/blog/2022/batch-size-2.html
[6] https://github.com/WongKinYiu/yolov7/commit/2fdc7f14395f6532ad05fb3e6970150a6a83d290
[7] https://www.kaggle.com/datasets/awsaf49/vinbigdata-original-image-dataset?datasetId=1070245
[8] https://github.com/WongKinYiu/yolov7/issues/1224
Copyright © 2015-2022 每日青海网版权所有 备案号:京ICP备12018864号-37 联系邮箱:291 323 6@qq.com