本部分详细介绍了训练流水线。
优化输入流水线
总结:输入受限流水线的原因和干预措施高度依赖于任务。使用分析器并留意常见问题。
使用合适的分析器(例如以下分析器之一)来诊断输入受限的流水线:
- 适用于 JAX 的 Perfetto
- TensorFlow 的 TensorFlow 分析器。
最终,具体原因和干预措施高度依赖于任务。 更广泛的工程考虑因素(例如,尽量减少磁盘占用空间)可能会损害输入流水线性能。
以下是导致输入受限型流水线的常见原因:
- 数据未与训练流程并置,导致 I/O 延迟。 例如,通过网络读取训练数据可能会导致 I/O 延迟。
- 昂贵的在线数据预处理。考虑离线预处理一次并保存结果。
- 会干扰数据流水线预提取的意外同步屏障。例如,在 CommonLoopUtils 中同步设备和宿主之间的指标时。
对于输入受限的流水线,我们建议采取以下干预措施:
- 检测输入流水线以预取示例(例如,tf.data.Dataset.prefetch)。
- 尽早从流水线中移除每个数据源中未使用的特征和元数据。
- 增加为输入流水线生成示例的作业的复制次数,例如使用 tf.data 服务。
评估模型性能
总结:以比训练更大的批次大小运行评估。以固定的步数间隔(而非固定的时间间隔)运行评估。
评估设置
您可以使用以下设置来评估模型的性能:
- 在线评估:在模型于生产环境中提供预测时收集指标。在线评估通常可以最真实地评估模型质量,因为它与模型的使用方式相符。
- 离线评估:在模型针对代表生产环境的离线训练集、验证集或测试集运行时,收集指标。根据具体问题,离线评估可能相当复杂,计算成本也很高。
- 定期评估:在模型训练期间收集可能代表离线评估的指标,和/或收集离线评估中使用的数据子集的指标。定期评估是最实用且最经济的选择,但可能无法完全代表生产环境。旨在使用离线评估的权宜代理,同时不牺牲训练期间接收到的信号的可靠性。
设置定期评估
我们建议在训练期间定期进行评估,原因如下:
- 实时监控训练进度。
- 为了方便回溯性模型检查点选择。
- 在训练结束时检查训练曲线。
最简单的配置是在同一计算实例中执行训练和定期评估,定期在训练和评估之间交替进行。在这种情况下,用于执行评估的批次大小应至少与用于训练的批次大小一样大。这是因为在评估期间,您无需保持模型激活状态,从而降低了每个示例的计算要求。
以固定的步数间隔(而非时间间隔)执行定期评估。 基于时间间隔进行评估可能会使训练曲线更难解读,尤其是在训练可能受到训练作业抢占、网络延迟问题等因素的影响时。
验证和测试指标中的周期性(在使用随机混排的训练集、验证集、测试集拆分时)可能表明存在实现 bug,例如:
- 测试数据与训练数据重叠。
- 训练数据未正确随机化。
以固定的步长间隔进行评估有助于更轻松地发现这些问题。
当评估集无法被批次大小整除时,可能会出现部分批次。确保填充后的示例已正确加权(如在计算批次平均损失的示例加权平均值中),以防止损失函数受到这些示例的偏差影响。通常,您可以为这些填充后的示例指定零权重。
为每次评估保存足够的信息,以支持离线分析。 理想情况下,应保存对所选个别示例的预测,因为这些预测对于调试来说非常宝贵。生成 SavedModels 等制品可简化评估作业完成后的临时模型检查。
选择用于定期评估的样本
定期评估作业可能无法在合理的时间内计算完整离线评估集上的指标。此问题通常需要对数据进行抽样,以便定期评估。 构建抽样数据集时,请考虑样本量问题以及不平衡数据集中的特殊问题。
样本大小
检查定期作业所用抽样数据集的计算性能是否与整个离线评估集的性能相匹配;也就是说,确保抽样数据集与完整数据集之间不存在偏差。
您用于定期评估的数据集应同时满足以下条件:
- 足够小,可轻松生成整个模型的预测。
- 足够大,可执行以下两项操作:
- 准确衡量模型改进情况;也就是说,衡量结果不应受到标签噪声的严重影响。
- 在试验中按顺序容纳多次此类评估,并仍能生成准确的估计值。也就是说,要足够大,以避免随着时间的推移,以无法泛化到留出测试集的方式自适应地“拟合”到验证集。不过,这种考虑很少会成为实际问题。
不平衡的数据集
对于不平衡的数据集,稀有少数类的性能通常会受到噪声的影响。对于少数类示例数量较少的数据集,请记录正确预测的示例数量,以便更深入地了解准确率的提升情况。例如,0.05 的敏感度提升听起来很棒,但这种提升是否只是因为多了一个示例正确?
保存检查点并回顾性地选择最佳检查点
总结:运行固定步数的训练,然后回溯性地选择运行中的最佳检查点。
大多数深度学习框架都支持模型检查点。也就是说,模型当前状态会定期保存到磁盘。通过设置检查点,训练作业可以应对计算实例中断的情况。最佳检查点通常不是最后一个检查点,尤其是在验证集性能不会随时间持续增加,而是在特定值附近波动时。
设置流水线,以跟踪训练期间迄今为止看到的 N 个最佳检查点。在训练结束时,模型选择只是意味着选择最佳检查点。我们将这种方法称为回顾性最佳检查点选择。通常不需要支持前瞻性提前停止,因为您会预先指定试验预算,并保留目前为止看到的 N 个最佳检查点。
设置实验跟踪
总结:在跟踪不同的实验时,请跟踪一些基本要素,例如研究中检查点的最佳性能,以及研究的简短说明。
我们建议在电子表格中跟踪实验结果。我们的电子表格通常包含以下列:
- 研究名称
- 指向研究配置存储位置的链接。
- 研究的备注或简短说明。
- 运行的试验次数
- 研究中最佳检查点在验证集上的表现。
- 有关启动训练所需的未提交更改的具体重现命令或备注。
找到一个方便的跟踪系统,该系统至少可以捕获上述信息。未跟踪的实验可能根本不存在。
批次归一化实现细节
总结:现在,您通常可以用 LayerNorm 替换批次归一化,但在无法进行替换的情况下,更改批次大小或主机数量时会遇到一些棘手的细节问题。
批次归一化使用当前批次的平均值和方差来归一化激活。不过,在多设备设置中,除非明确同步,否则这些统计信息在每部设备上会有所不同。 根据一些传闻报告(主要针对 ImageNet),仅使用约 64 个示例计算这些归一化统计信息实际上效果更好。(请参阅训练时间更长,泛化效果更好:弥合神经网络大批量训练中的泛化差距中有关 Ghost Batch Normalization 的说明。) 将总批次大小与用于计算批次归一化统计信息的示例数量分离,对于比较批次大小特别有用。
在每设备批次大小大于虚拟批次大小的情况下,Ghost 批次归一化实现并不总是能正确处理。在这种情况下,您需要对每个设备上的批次进行子采样,以获得适当数量的批次归一化统计信息示例。
测试模式批次归一化中使用的指数移动平均值 (EMA) 只是训练统计信息的线性组合。因此,您只需在将这些 EMA 保存到检查点之前同步它们。不过,一些常见的批量归一化实现不会同步这些 EMA,而只会保存来自第一个设备的 EMA。
多主机流水线的注意事项
总结:对于日志记录、评估、RNG、检查点和数据分片,多主机训练很容易引入 bug!
对于多主机流水线,请执行以下操作:
- 确保流水线仅在一个主机上记录日志和设置检查点。
- 在评估或设置检查点之前,跨主机同步批次归一化统计信息。
- 跨主机对数据文件进行分片,因为这通常会提高性能。
关键:确保您在不同主机上拥有相同的 RNG 种子(用于模型初始化),以及在不同主机上拥有不同的种子(用于数据重排/预处理)。因此,请务必正确标记这些内容。