Zico: Efficient GPU Memory Sharing for Concurrent DNN Training
摘要
- 最近的一些工作提出了跨多个并发 DNN 培训作业共享 GPU 资源的解决方案
- 但是没有一个解决这种作业共处引入的快速增长的内存占用问题
- 这极大地限制了共享 GPU 资源的有效性
- Zico,第一个 DNN 系统,旨在减少系统范围的内存消耗并发训练
- Zico 通过监视单个训练作业在 GPU 计算上的进度来跟踪其内存使用模式,并使从作业中回收的内存可以全局共享。
- 基于这种内存管理方案,Zico 自动决定在不超过 GPU 内存容量等给定内存预算的情况下,以最小的训练延迟在并发作业之间共享内存的策略。
- 我们的评估表明,Zico 的性能优于现有的 GPU 共享方法,并提供了多种情境下的好处
引言
之前的工作集中在 GPU 的整体时间复用上或者空间共享计算单元上。
- 时间共享:将 GPU 中的计算核心和内存单独用于一个时间量子的单一训练。
- 有很好的灵活性
- 这种方法往往不能有效地利用 GPU 资源。
- 例如,对于 GNMT 和 RHN 这样的语言模型,大多数计算资源是空闲的
- 这些训练算法包括许多 RNN 模块,例如 LSTM 和 GRU 网络,它们对 GPU 表现出一定程度的数据平行,导致 GPU 资源利用不足
- 空间共享
- 可以提供比时间共享更好的吞吐量,只要一个单一训练工作不占满所有GPU 计算资源。
- 然而,应用空间共享的一个限制是并发作业的工作集大小,它随着作业同位共享而严重。如果工作集不适合 GPU 内存,系统必须关闭一个作业或者将 GPU 内存交换给主机,这就掩盖了空间共享的性能优势。
- 因此,要使空间共享得到广泛应用,就必须减少同地训练作业的内存占用。
- 时间共享:将 GPU 中的计算核心和内存单独用于一个时间量子的单一训练。
我们观察到,共享在同一地点的培训作业中生成的中间数据可以显著减少总内存占用。
- 训练是一个高度迭代的过程,首先前向传递,然后后向传递
- 在训练过程中,被称为特征映射的模型层的中间输出主导了内存占用量。
- 特征映射是在前向传递过程中在每个层中生成的,然后在后向传递过程中使用以更新该层。
- 由于常规的双向执行,单个训练作业的内存消耗通常呈现一种循环模式,即内存消耗在前向传递过程中逐渐增加,在后向传递过程中逐渐减少。
- 因此,一个简单而有效的节省内存消耗的策略是创建一个大的 GPU 内存池,并且为并发培训作业弹性地共享内存池。
- 为了增加共享机会,需要对并发培训作业进行协调,使它们运行不同的传递,如作业 A 的前向传递(增加其工作集)和作业 B 的后向传递(减少其工作集)。
- 该方法导致一个作业的内存分配与另一个作业的内存释放同时发生,有效地减少了系统范围内的内存占用。
- 训练是一个高度迭代的过程,首先前向传递,然后后向传递
尽管共享的想法是合理的,但是当今 DNN 框架在 GPU 上执行培训的方式构成了重大挑战。
- 目前的框架主要是为个人训练案例设计的。
- 遵循数据流依赖关系,他们提前分配每个 DNN 内核计算所需的内存,并向 GPU 流发出尽可能多的核函数,也就是说,GPU 计算的每个任务的工作队列,以饱和 GPU 的内部计算资源。
- 这导致 GPU 计算异步并与 CPU 处理并行。
- 因此,这些平台不知道 GPU 计算的进度,也不知道 GPU 什么时候会消耗内存。
- 如果没有对异步进行正确的处理,共享内存就不能保证正确性
- 目前的框架主要是为个人训练案例设计的。
我们提出了 Zico,一个 DNN 平台,可以实现有效的内存共享并发训练。
- Zico 改进了广泛使用的 DNN 平台 TensorFlow,以最大限度地提高并发训练的总体吞吐量。
- Zico 的目标是找到并发训练的最佳协调执行,以充分利用 GPU 的计算和内存资源。
- 为了实现这一目标
- (i) Zico 精确地监控培训工作的计算进度。在此基础上,Zico 为 DNN 内核分配和释放内存,通知更接近 GPU 视图的内存使用模式。
- (ii) Zico 合并运行时信息(例如,迭代时间,内存使用模式和 GPU 内存限制)并执行一个作业调度程序,称为 Scrooge 调度程序,以有效地引导并发作业来利用共享内存池。
- (iii) Zico 有效地将整个 GPU 空间组织为一个弹性共享内存池,以支持吝啬型调度器。
为了检测异步内核的计算进度,Zico 利用一个称为 CUDA 事件的特定内核,它通知 GPU 内核的进度。
- Zico 使用 CUDA 事件来识别 GPU 内核使用的内存的分配和释放时间。
- 在此基础上,Zico 执行我们的新型 Scrooge 调度器
- 预测迭代边界并发训练的内存消耗趋势,并在每次迭代中引入最小失速时间。
- 然而,共调度作业的内存使用趋势随着它们在 GPU 计算单元的使用中如何相互干扰而变化。
- 为了应用它们的动态行为,Scrooge 调度器根据在运行时收集的反馈精炼决策。
Zico 将内存池组织为称为区域的块的集合,并根据数据特征分离它们的使用。
- DNN 训练产生几种类型的数据作为张量,主要分类为
- 高频出现的短暂张量
- 构成最大的记忆足迹的长寿张量,例如特征映射
- 通过按类型划分区域,Zico 确保存储在特征映射中的内存不会干扰其他瞬态数据,同时使它们的需求遵循训练迭代的循环模式。
- 这种设计选择使得我们的调度决策能够在不失去分享机会的情况下应用,而且几乎没有中断。
- DNN 训练产生几种类型的数据作为张量,主要分类为
实验
- 作为流行的 DNN 框架 TensorFlow 的原型,我们使用6个模型对 Zico 进行了实验性评估,这些模型从 V100和 RTX 2080 Ti 图形处理器上的翻译到目标检测。
- 结果表明,Zico 能够在广泛的内存消耗趋势下实现有效的内存共享。
- 对于高内存占用,Zico 分别比传统的空间共享和时间共享方法快8.3倍和1.6倍,特别是在同时训练非相同模型时。
- 对于低内存占用(不需要并发训练的延迟) ,Zico 的行为类似于传统的空间共享,比时间共享快1.6倍。
- 总的来说,不管并发训练是基于相同的模型还是不同的模型,Zico 都能实现加速。
背景
深度神经网络训练
GPU共享的用例
- 超参数调优(作业间)。
- 随着 DNN 应用的日益普及,DNN 从业人员每天都在开发一些新的模型。用于开发的模型暴露了许多高级属性,例如,学习速率和动量,作为需要优化的超参数。这个任务称为超参数调优[3]。由于超参数构成了一个巨大的搜索空间,有几个流行的工具,如 Hyperdrive [35]和 HyperOpt [4] ,它们可以自动化超参数优化,并为用户构建具有最佳(或期望的)质量的新模型。这些工具通常生成大量密切相关的培训工作(多达100个[26,43]) ,为同一参考模型探索一组不同的超参数。然而,空间 GPU 共享对于这个工作负载有更大的性能潜力,如第7节所讨论的。超参数调优作业主导了运行在共享 GPU 集群上的培训工作负载[20,26,43]。为了让它们在竞争激烈的 GPU 上及时完成,以前的工作提出了几种技术,如时间和时空共享,以便将单个 GPU 分配给多个培训任务[43,44]。
- 梯度累积(内部作业)。
- 梯度积累法是一种在稳定批量以外的超参数时加速模型收敛的有效方法。它运行一组连续的迷你批处理,并在更新模型参数之前累积这些迷你批处理的梯度。其基本目标是给人一种大批量训练的错觉,通过使用小批量的 GPU 内存,可以更好地提高收敛性,而不会超量使用 GPU 内存。通常的做法是按顺序处理这些微型批处理。尽管如此,有效的空间 GPU 共享可以为小批量并发培训提供共享激励。有人可能想知道,这种培训的空间共享是否确实可行。根据我们的观察,翻译或语音识别模型(例如 GNMT [42])往往没有充分利用 GPU 的计算资源,使其有利于共享 GPU 计算。最重要的是,我们的系统支持高效的 GPU 内存共享,使每个并发训练使用的小批量大小比原来的小批量大小稍微小一点,如果不是相同的话。总之,我们的系统开辟了一个新的机会,以加快培训的梯度积累,我们将在第7部分讨论。
空分GPU共享
内存共享的挑战
内存膨胀
负载变化
GPU处理的异步
设计总览
Zico 的目标是通过协调作业调度和 GPU 内存管理来实现并发培训,从而提供高效的空间 GPU 共享。作为一个目前建立在 TensorFlow 上的系统,该框架不断跟踪每次培训中使用的内存的寿命,并生成一个并发培训执行的时间表,以避免 GPU 内存超订
- 设计目标
- 高性能
- 广泛模型支持
- 常规方法
- 系统模块
- Scrooge调度器
- 内存管理