ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

深度学习训练中批大小(Batch Size)的控制机制与调参实战

深度学习训练中批大小(Batch Size)的控制机制与调参实战 先讲一个我常被问到的问题训练一个模型显存明明还有富余有没有必要把batch size往上加或者反过来问加了之后为什么有时候 loss 反而更抖了甚至直接不收敛这两个问题其实指向了同一个核心机制——最大批大小Max Batch Size。它不只是训练脚本里的一个数字而是连接“算力效率”和“模型质量”之间的一个关键阀门。调小了GPU 在空转调大了模型可能练废。这篇文章我打算把批大小的控制机制从原理到实操拆开讲一遍包括它如何影响训练速度、显存占用、收敛效果以及分布式场景下要怎么配合调整也希望给正在调参的同行省点时间。1. 内容整体设计与思路拆解1.1 批大小是训练过程中“每步决策”的依据要理解批大小为什么重要得先回到梯度下降最底层的逻辑。模型训练的本质是不断根据损失函数的梯度更新参数但梯度怎么算有不同的口径全量样本算出来的梯度最精确单条样本算出来的梯度最随机而批大小就决定了单次参数更新前看多少数据。批大小小的时候每一步的梯度方向噪声很大相当于“听了几句就下结论”脚步容易乱但偶尔能跳出局部坑批大小大的时候每一步的梯度信号更稳定相当于“听完全场再表态”方向更准但决策周期更长也更耗显存。所以批大小本质上是控制“每个训练步的信息量”和“决策质量”之间权衡的旋钮。从系统层面看批大小还直接决定了矩阵乘法的规模。深度学习框架底层主要依赖 GPU 的并行算力做张量乘法而 batch 维度是矩阵乘法中的一个重要轴。批大小越大单个矩阵乘法的规模越大GPU 计算单元的利用率通常越高。多数主流框架里一次 step 的耗时并不会随 batch size 线性增长所以很多时候“顺便把批翻倍”反而能省近一半的时间开销。1.2 控制机制的核心矛盾模型收敛与算力吞吐批大小控制机制最核心的矛盾在于“模型质量”和“算力吞吐”方向上的冲突。从吞吐角度看批大小越大越好。因为训练吞吐量通常用“每秒处理的样本数”来衡量而批大小直接乘在每个 step 上。大批次让 GPU 的 SMStreaming Multiprocessor尽量满载减少 kernel 启动开销和调度间隙这一步在实际中收益非常可观。但是从收敛角度看批大小并不是越大越好。大批次梯度更平滑但也更容易收敛到尖锐极小值泛化能力往往下降小批次梯度噪声大反而带有隐式的正则效果在不少任务上能收敛到更平坦的区域。更麻烦的是大批次和小批次对学习率的敏感度完全不同直接沿用原始学习率通常会让大批次训练早期失控。所以最大批大小的“控制机制”并不是一个纯粹的性能调优问题。它需要同时回答三个问题显存能不能装下算力能不能吃满模型质量是否还能保持下文我会分别从这三个维度寻找解决方案。1.3 批大小方案选型前需要明确的边界条件开始调批大小之前先把边界条件列出来免得后面反复返工单卡显存总量是多少能承载的激活值上限在哪里模型参数量多大优化器状态占用多少显存使用的分布式方案是什么是多机多卡还是单机多卡训练数据集的规模和样本特征的方差大不大任务类型是 CV、NLP 还是推荐系统不同任务对梯度噪声的耐受度完全不同。这些边界本质上决定了批大小的合理区间。比如 CV 里很多分类任务用小 batch 也能跑出不错的效果因为图像样本的信息密度高单张图就足够提供很强的监督信号。但是大规模预训练或推荐系统 CTR 预估这类任务单个样本信号稀疏必须用很大的批大小才能让梯度统计足够稳定。把边界条件想清楚再动手比盲目往上堆数字靠谱得多。2. 效率维度为什么批大小直接决定训练速度2.1 GPU 并行特性下批大小如何影响吞吐量GPU 和 CPU 的设计哲学完全不同。CPU 强调低延迟核心少但单核强适合快速处理各种串行任务GPU 则强调高吞吐核心多但单核弱适合处理大量可并行的计算。深度学习训练恰好就是典型的“数据并行计算”所以给 GPU 喂的数据越多它越“舒服”。批大小直接决定了每次喂给 GPU 的数据量。批大小为 1 时模型每个 step 只处理一张图或一条文本GPU 上几千个计算核心大部分都闲置着算力利用率可能只有个位数。批大小为 64 时矩阵乘法的维度更大计算核心几乎都在满负荷工作单位时间内处理的样本数量自然大幅提升。这里有个关键概念叫“算术强度”指计算量与访存量的比值。批大小越大同一份模型参数可以被更多样本复用权重从 HBM 加载到计算单元后能产生更多计算算术强度就越高。这就把我们常说的“内存带宽瓶颈”缓解了GPU 不再等着搬数据而是在专心算。我在实际项目中观察到批大小从 16 放大到 128训练吞吐提升了接近 4 倍但批大小从 128 继续放大到 512吞吐提升可能就不足 1.5 倍了因为计算单元已经接近饱和。2.2 吞吐量增长的边际递减效应上文提到 batch size 放大到一定程度后收益递减这背后其实是有硬件层面的原因的。当 batch size 足够大GPU 的核心已经被填满再增加数据只会延长单个 step 的计算耗时并不会显著提升每个步的效率但由于 step 总次数会更少训练时间整体仍然可能降低。不过要注意的是吞吐量的提升会呈现出接近对数曲线的增长形态尤其单卡情况下很容易遇到天花板。我比较习惯用“单位时间处理样本数”来评估吞吐量同时记录“单 step 耗时”和“GPU 利用率”两个指标。如果 GPU 利用率已经稳定在 90% 以上说明硬件侧已经没什么太多空间可压了这时候继续加大 batch size 更应该关注模型的收敛质量而不是吞吐量。2.3 小批量场景下的隐性开销很多人没注意到小批量训练里的很大一部分时间并不是花在计算上而是花在“调度”上。GPU kernel 从 CPU 侧提交到 GPU 执行队列是有启停开销的通常有几十微秒到百微秒级别。当 batch size 很小时一个 kernel 只需要执行几十微秒但启动它就需要几十微秒那么几乎所有时间都被启动开销吃掉了。另一个隐性开销是 Python 侧的数据流水线。小批量意味着每个 step 要更频繁地从 DataLoader 拉数据数据增强、预处理、拷贝到 GPU 这些操作发生的频率也更高。如果数据加载线程和训练主线程之间没有做好异步预取训练过程会被迫等待 IO显存和计算核心都在摸鱼。很多看起来“GPU 没吃满”的情况排查到最后都是数据加载跟不上。解决方案一般有两种一是加大 batch size让每个 step 的处理时间远超调度和数据加载的开销二是在代码层面用num_workers多进程加载、prefetch_factor预取、开启pin_memory减少 CPU 到 GPU 的拷贝延迟。理论上还可以用 CUDA Graph 把几个 kernel 合批执行进一步削减启动开销。2.4 梯度累积显存不够时的高效替代梯度累积是目前最常见的模拟大批次方案。核心思路是把一个大 batch 拆成几个小 batch逐个前向计算得到梯度后不立即更新参数而是把梯度累加起来累加到足够数量后再统一做一次参数更新。它的好处显而易见显存占用和一次小 batch 前向相同但等效 batch size 可以做到很大。比如显存只允许 batch size 为 16但实验需要 128 的等效批大小那就跑 8 个 step 的梯度累积累积完再更新参数。实际操作中我会把累计梯度除以累积步数保持梯度量纲的一致性否则学习率可能需要额外调整。但梯度累积也有代价。因为每一步仍然是独立前向模型参数在前向时并没有更新所以算出来的梯度其实是“旧参数下的梯度”和真正一次喂入 128 条样本得到的梯度存在偏差。对于大部分任务来说这个偏差在可接受范围内但如果追求很高的复现精度或模型训练很不稳定还是应该尽量用真正的物理大批次而不是梯度累积。3. 资源维度显存、算力与并行度的平衡之术3.1 显存占用拆解批大小到底吃掉了哪部分显存不够用几乎是每个调大 batch size 的人都会遇到的问题。但要解决它首先得搞清楚显存到底是谁吃掉的。深度学习训练过程中的显存占用可以粗略分为四块模型权重、优化器状态、激活值、临时缓冲区。模型权重和优化器状态的大小主要由参数量和优化器类型决定跟 batch size 没什么关系但激活值的大小直接受 batch size 影响而且几乎是线性增长。所谓激活值指的是前向传播过程中每一层算出来的中间结果它们在反向传播算梯度时还要被再读一遍。举个例子一个 7B 参数的模型用 Adam 优化器做 BF16 混合精度训练权重约占 14GBAdam 的一阶矩和二阶矩是 FP32 的又占 28GB这些都还只是“家底”。真正让显存失控的往往是激活值尤其在序列较长或特征图尺寸较大的任务里激活值很容易膨胀到比权重还大。批大小每次翻倍激活值的峰值得同步翻倍OOM 的风险也随之翻倍。如果你想精确估算可以在框架里开启显存统计比如 PyTorch 的torch.cuda.max_memory_allocated()或者在每次 forward 之后观测nvidia-smi的显存曲线。实际上我也习惯先把 batch size 设成一个很小的值比如 1跑通一次完整训练流程记录下这个 baseline 显存占用再根据激活值的大致线性关系估算还能加多少 batch。3.2 从算力利用率视角看批大小的最优区间显存只是硬性约束真正决定“效率高低”的是算力利用率与批大小的关系曲线。不同 GPU 架构的算力峰值不同但曲线形态很相似在批次非常小的阶段算力利用率迅速爬升到达某个拐点后增速减缓再往后就逐渐饱和增加 batch size 带来的收益越来越小。我在训练视觉模型时常用的定位方法是打开 Nvidia 官方的nsight compute或者直接用nvidia-smi dmon看 SM 利用率尝试不同 batch size 并记录每秒处理样本数。把数据点连起来后就能非常直观地找到“隐性拐点”。比如在某张显卡上 batch size 从 1 到 64 是陡增区间64 到 128 是渐增区间128 以上基本平了那这个任务的“最优区间”大概就在 64 到 128 之间。不过需要注意算力利用率和显存利用率不是一回事。有些模型的某些层计算量很大但显存占用小另一些层则相反。单纯用 batch size 去压榨算力利用率时很可能某个层已经 OOM。所以我在探索最优区间时一般会同时看两个曲线一个是吞吐量 vs batch size一个是显存峰值 vs batch size两者的交叉区域才是真正合适的操作区间。3.3 分布式训练中全局批大小的协调策略转到多卡场景后批大小的控制会变得更复杂一点因为这里有两个 batch size 的概念单卡 batch size 和全局 batch size。全局批大小等于单卡批大小乘以并行卡数。单卡 batch size 的确定原则跟单机训练基本一致需要根据每张卡的显存和算力来决定但全局 batch size 直接影响梯度统计质量这个值才是真正决定模型收敛行为的参数。比如 8 张卡每张卡 batch size 为 16全局 batch size 就是 128虽然每张卡的显存负载只相当于训练 16 条样本但学习率和调度策略应该按照 128 这个数值去思考。数据并行通信方面批大小越大计算和通信的比值越高。因为在 All-Reduce 同步梯度时通信量主要取决于模型大小而不是 batch size但每一步的计算量会随 batch size 增大而增大于是通信开销在整体时间里的占比就下降了。这也是为什么大 batch 在大规模分布式训练中特别吃香它让通信成本被更多的计算摊薄单卡那点通信耗时基本可以忽略不计。但全局 batch 也不是无限大就好。大批次会让梯度估计过于平滑容易错过一些有价值的梯度方向收敛点往往处于尖锐极小值泛化性会受损。跨节点训练里常见做法是先用较小全局 batch 做预热再逐步提升 batch size或者配合学习率 warmup 来抵消早期不稳定。3.4 显存优化三板斧混合精度、重计算与梯度检查点显存不够时的常规解法可以从三个方向入手。第一是混合精度训练。把模型权重和激活值用 FP16 或 BF16 存储优化器状态保持 FP32可以在几乎不影响模型质量的前提下把显存占用几乎减半。BF16 对大规模训练来说尤其友好因为它的指数范围和 FP32 一致在训练初期不太容易出现数值溢出问题。第二是激活重计算也叫 gradient checkpointing。思路很简单前向传播时不再保留所有层的激活值而是只保留少数关键节点的激活值反向传播时如果需要某层的中间激活值就重新计算一遍。这是典型的“用时间换空间”显存可以从 O(L) 降到 O(sqrt(L))但也意味着前向传播要额外做一次训练时间通常增加 30% 左右。第三是更精细的显存管理比如及时删除不再需要的中间变量、使用del和torch.cuda.empty_cache()释放显存碎片、把优化器状态 offload 到 CPU 内存等。对于追求单卡极致训练效率的场景可能还得配合micro-batching的思路——把一个逻辑 batch 切成几个 micro batch 连续前向只在最后一个 micro batch 后累积梯度并更新参数效果跟梯度累积本质一样。综合使用这三种手段后原本只能塞 batch size 为 8 的模型扩到 32 甚至 64 完全有可能。4. 模型性能维度批大小对收敛质量的影响4.1 梯度噪声与泛化能力的关系批大小对模型性能的影响本质上是通过梯度噪声来实现的。小批量的梯度是通过少量样本估计出来的所以它带噪方向不会特别精确。这种噪声看起来是坏事但实际研究中发现它能够帮助模型逃离尖锐的局部极小值最终收敛到更平坦的区域测试集上的表现反而更好。大批量的梯度更接近真实梯度参数更新方向更准确但它更容易收敛到局部极小值附近的“窄坑”。窄坑在小扰动下就会让泛化误差剧增这也是大批次训练经常过拟合或泛化不足的重要原因。针对这个问题一个已有的经验法则是如果学习率设置合理批次大小增加 k 倍训练步数大约也要增加 k 倍以保证相似的泛化性能。当然这只是经验总结不同任务会有差异但它清晰说明了“大步子走得快但未必走得好”。4.2 学习率缩放规则与 warmup 的必要性大批次训练最常见的问题是直接用原来的学习率结果损失剧烈震荡。原因在于梯度更稳定了同样的学习率意味着单步参数更新幅度在“有效信息”层面上比以前更大模型参数很容易一步迈过头。这方面最经典的是线性缩放规则批次大小变为原来的 k 倍学习率也近似乘以 k。这个规则在小幅度缩放时很好用比如从 32 增加到 64 或 128。不过如果批次从 32 直接增加到 1024线性缩放的学习率往往太大建议配合平方根缩放或者先做实验性小范围扫描来确定。另一个配套做法是 warmup也就是学习率从很小的值开始随着训练步数逐步升到目标值。我在实操中会把 warmup 步数设成总步数的 2% 到 5%同时把前 10 到 20 个 step 的梯度 norm 打出来。如果梯度范数在启动阶段就冲得很高说明学习率或者 batch size 的配合出了问题得及时停下来调整而不是任由训练跑完。4.3 批大小与优化器类型的相互影响不同优化器对 batch size 的敏感度差异很大。SGD 及其带动量的版本对学习率很敏感批次放大后如果不调整学习率收敛很容易恶化。Adam 这类自适应优化器因为每个参数都有独立的缩放学习率机制对批次大小的变化相对没那么敏感但也不是完全无感大批次下同样可能出现泛化损失。实际实验里我更多在 CV 任务上用 SGD 系优化器NLP 任务或大模型训练用 AdamW。前者对批大小变化敏感所以每次改 batch size 都要重新做一次小范围学习率扫描后者相对稳一些一般只做小幅调整就能适配。混合精度训练或梯度累积也会间接影响优化器看到的梯度信号因此需要一并考虑。4.4 收敛稳定性与 loss 曲线的实际观察方法比起纸上谈兵我更喜欢通过 loss 曲线的形态来判断 batch size 是否合适。批大小偏小时loss 曲线会很“毛躁”每个 step 都有明显的震荡但整体趋势是下降的批大小偏大时loss 曲线会显得过于平滑甚至早期下降速度偏慢。当 loss 平坦很长时间没有明显波动时不一定是收敛了也可能是因为 batch size 太大导致有效更新步数太少、收敛速度过于缓慢。这时我会把学习率调大一点或者减小 batch size 让梯度噪声帮忙跳出平台期。反过来如果 loss 震荡剧烈且出现持续的上涨说明学习率大概率偏大了可以先降低学习率再检查 batch size 是否设置合理。简单来说loss 曲线是一个实时反馈面板它同时反映学习率、batch size 和数据质量的问题。养成观察它的习惯比单纯依赖一两个指标更可靠。5. 完整选择策略与实战配置5.1 一个实用的批大小初始值选择流程对于一个新的训练任务我通常按照下面的流程确定批大小初始值而不是直接拍脑袋第一步根据显存大小把批大小设为能塞进显存的上限附近比如 32 或 64作为初始值第二步用小规模数据跑 100 到 200 个 step记录吞吐量和 GPU 利用率第三步如果吞吐量还在明显上升区间继续增大 batch size直到增长速度明显放缓第四步确定这个“算力友好”的 batch size 后再观察 loss 曲线和收敛质量如果发现泛化变差再逐步回退。这个流程的好处是先解决“能不能跑得快”再解决“能不能练得好”。很多人在调参时先追求模型质量把 batch size 定得很小最后训练时间翻倍其实是吃了“显存利用率低”的亏。反过来也有人直接追求最大 batch size结果模型泛化崩了还要重来两边都得不偿失。5.2 不同场景下的参考批大小建议不同任务对批大小的偏好差异很大下面是我在常见任务里的一些经验参考具体还要结合数据和模型调整图像分类ResNet/EfficientNet小图 224x224 时单卡 batch size 通常取 64 到 256分布式训练全局 512 到 4096 也很常见。目标检测YOLO/Faster R-CNNbatch size 往往偏小单卡 8 到 32 比较常见因为输入图像分辨率高、输出头复杂显存压力大。NLP 分类/序列标注单卡 16 到 64 即可大批次对梯度提升不大但容易 OOM。大模型预训练/微调预训练动辄用全局 batch size 512 到 2048微调通常 16 到 32 更稳尤其是 LoRA 这类参数高效微调。推荐系统 CTR 预估单卡样本非常稀疏通常需要较大 batch size比如 1024 到 16384 才算正常。这些数字不是绝对的但起码提供了一个起点。如果任务表现很差可以先检查是不是 batch size 偏离对应场景的常用范围太多了。5.3 案例把 batch size 加倍时如何同步调整超参数假设一个 CV 分类模型原来用 batch size 64 和 SGD 优化器学习率是 0.02跑出来验证集准确率 85%。你想把 batch size 加到 128如果只是改 batch size大概率准确率会掉 1 到 2 个点因为有效更新次数减半了学习率却没有同步调整。按照线性缩放规则目标学习率应该是 0.04。但直接从 0.02 跳到 0.04 会让早期训练波动变大所以需要同时加上 warmup前 300 步从 0 线性升到 0.04。这样一来虽然每步看到的样本数量变多了但每步的更新强度也匹配上了收敛速度更快最终准确率甚至可能比原来略高。如果发现 batch size 128 时显存快爆了可以采用梯度累积每 2 个小 batch 累积一次再更新参数等效 batch size 也是 128。梯度累积方案下学习率要不要调我的经验是先把学习率调到和等效 batch size 匹配的值并观察 loss 曲线的震荡情况如果震荡太明显就再降一点。毕竟累积梯度和真正大批次的计算路径不完全等价。5.4 批量训练中的动态批大小策略常规训练是固定 batch size但实践中也存在动态批大小策略。一个可行的方案是训练早期用较大 batch size让模型先抓住数据整体分布训练后期切换到较小 batch size用噪声帮助模型微调提升泛化能力。这种“先粗后细”的思路在一些 benchmark 上确实能改善最终精度。另一种做法是“batch size warmup”训练初期用较小批大小让模型走过最不稳定的早期阶段然后逐步增加到目标值。这本质上和学习率 warmup 类似都是为了降低早期训练的风险。虽然实现起来会多写一些调度代码但在某些大规模训练场景下非常有效。如果要实现动态批大小我通常会写一个简单的 schedule 函数根据当前 step 或 epoch 返回 batch size并用 DataLoader 的batch_sampler参数动态控制。不过要注意频繁切换 batch size 会影响数据加载效率和数据 shuffle 方式所以切换的粒度不要太细一般以 epoch 为粒度切换比较安全。6. 常见问题与排查技巧实录6.1 显存 OOM 的排查步骤与解决路径显存 OOM 是调大 batch size 时最先碰到的问题也是最容易定位的问题。我的排查步骤一般是先用小 batch size 跑通完整训练流程拿到显存基线再逐步加大 batch size比如每次翻倍记录显存占用和成功率。如果加到某个值时出现 OOM就退回上一个安全的 batch size接着检查是不是模型里某个特定层在 batch 放大时产生了异常大的激活值。如果确定是激活值导致 OOM优先开启 gradient checkpointing把显存峰值砍下来如果还不够就切换到混合精度训练把权重和激活值的精度降下来。还没解决的话就得考虑减小输入尺寸比如图像任务里减小分辨率NLP 任务里缩短序列长度。很多时候 OOM 并不是真的“一点空间都没有”而是空间碎片化导致的这时候torch.cuda.empty_cache()或者重启进程也能缓解。6.2 批大小调大后模型不收敛怎么办模型不收敛时很多人第一反应是调学习率其实也要同步检查 batch size 的配合。如果你已经把 batch size 放大但一直沿用小学习率模型会学得极其缓慢loss 下降看不出明显变化如果你直接把学习率线性放大又有可能因为步子太大导致 loss 发散。这时候建议先把学习率设回一个保守值观察 loss 是否在缓慢下降。如果是说明方向是好的耐心跑一段或者加一点学习率如果 loss 开始上升就把学习率降一半再试。另外可以把梯度裁剪打开比如 max_grad_norm 设为 1.0能有效防止梯度爆炸造成的发散特别是大 batch 大学习率的组合。还有一个容易被忽略的点batch size 变大后数据的 distribution 可能发生细微变化。比如数据加载器里如果用了多线程且有随机种子改变 batch size 会影响样本组合顺序导致训练前几十步的 loss 和原来很不一样这并不奇怪多观察一段时间再下结论。6.3 如何判断当前批大小是否“恰到好处”判断批大小是否合理不能只看单次 loss 曲线要综合三个信号吞吐量是否已经进入平台期、显存是否接近但不爆、验证集指标是否与同任务历史经验持平。如果三个信号都满足大概率批大小在合理范围内。如果不满足可以针对性调整。比如吞吐量还在涨说明有加速空间显存远未打满说明可能还可以继续加 batch验证集指标低于预期优先考虑减小 batch 或调整学习率。用这套信号组合去判断要比单纯看一两个数据更靠谱。6.4 多卡训练时批量上限与单卡不一致的情况多卡训练时常见的一个坑是单卡能支撑 batch size 648 卡全局 batch size 可以达到 512但模型综合表现反而不如全局 batch size 256 的时候好。这个现象就是前面分析的“大批次劣化”问题。遇到这种情况我会先把全局 batch size 固定到目标值然后通过增加梯度累积步数来模拟“小物理 batch 大等效 batch”的折中或者把学习率调回和较小平滑程度匹配的水平。也可以考虑使用“batch size 自动调整”的调度策略让训练前段用较小全局 batch稳定后再逐步增大。在模型并行或流水线并行场景下各设备上的 micro-batch 大小和全局 batch size 的关系会更复杂建议先从单卡维度做基准测试再逐步扩展到多卡对照每步耗时和显存曲线找出资源利用和模型质量的平衡点。7. 经验心得与实操体会7.1 我是怎么在实际项目中确定批大小方案的实际操作中我很少一上来就盯着一个精确的 batch size 数值而是先跑一组小规模的“batch size 扫描实验”分别用 16、32、64、128 的批大小训练同样的步数对比 loss 下降速度和最终验证指标。这个扫描实验只需要几百个 step花不了太多时间但能给出非常有价值的趋势参考。扫完之后我会结合吞吐量和显存数据确定“效率候选值”再结合验证集表现确定“质量候选值”如果两者不一致优先考虑用梯度累积或学习率调整来弥合差异。只有当效率和质量的候选值完全无法兼顾时才会回头重新审视模型架构或数据增强策略。7.2 调参时最容易被忽视的三个细节第一随机性控制。在对比不同 batch size 的效果时如果模型的随机种子不一致实验结果会有很大噪声。建议固定 seed、固定数据加载顺序尽量让对比结果反映的是 batch size 的影响而不是随机噪声的影响。第二评估频率。batch size 变大会让每个 epoch 的 step 数量变少因此如果还按原来的 step 间隔做评估可能看不到完整的学习曲线。建议按“多少张样本”为单位做评估比如每处理完固定数量的样本就记一次验证指标而不是固定每 N 个 step 评估一次。第三日志记录。调 batch size 时最好把学习率、warmup、梯度累积步数、数据加载耗时等所有相关参数一起记录。否则训练结束后想复盘经常发现忘了当时具体用的哪组参数白白浪费一次实验。7.3 后续扩展方向从批大小到更大尺度批大小控制机制本身是一个很好的切入点掌握之后可以继续向更系统的方向扩展。比如结合学习率调度cosine、warmupdecay设计更完整的训练策略或者把批大小纳入自动调参搜索空间用贝叶斯优化等方法自动寻找合适组合再比如研究“critical batch size”的理论测度在实践中估算出当前模型和数据规模下增长 batch 还能带来多少收益。在大模型时代训练框架也提供了越来越多自动处理 batch size 的能力比如根据显存自动估计最大 batch size、自动插入梯度累积、自动调整学习率等。但理解其背后的机制仍然重要因为自动工具只解决“能不能跑”的问题而“能不能训练出好模型”仍然依赖对 batch size 与学习率、模型结构、数据分布之间关系的深刻理解。说回开头那个问题显存有余量要不要继续加 batch size我的回答是先算账再动手。算一下吞吐量还有多少提升空间算一下梯度分布是否会变得过于平滑算一下学习率需不需要同步调整。想清楚这三笔账batch size 就不再是一个让人纠结的玄学参数而是一个可控、可调、可预期的手段。
返回列表