G10: Enabling An Efficient Unified GPU Memory and Storage Architecture with Smart Tensor Migrations

MICRO'23

Abstract

作者提出了:a unified GPU memory and storage architecture named G10

基于这样的发现:DL中的tensor具有高度的可预测性

G10融合了GPU内存、主机内存、闪存,实现了统一内存访问、透明的数据迁移,基于这个统一的内存访问,G10借助编译技术获取DL中tensor的特征,以此实现后续的数据调度。

1. Introduction

现在人们使用GPU来进行DL模型训练,会面临GPU内存墙的问题。模型、数据的规模在增大,但是GPU内存却没有与之匹配的增大,导致DL模型的训练受到GPU内存的限制。(大模型尺寸以每两年410倍的速度疯狂增长,而GPU处理器作为AI算力基础,其内存容量增长速度只有每两年2倍。GPU内存容量严重制约了可训练的模型规模和算力提升速度,成为了阻碍AI技术发展与落地的重要瓶颈,这称之为GPU内存墙问题,见下图,该图不是来自本论文)

image-20231124092113807

因此,作者希望利用low-cost内存(主机内存、闪存)来扩展GPU内存。基于两个发现:

  1. DNN的每次迭代中只需要用到少数张量。

  2. 大部分非活跃张量的非活跃时间比较长,足够进行数据迁移。

面临三个挑战:

  1. 需要获取张量的内存需求、生命周期。

  2. 需要决策何时、何地(迁移到哪里)迁移哪个张量。

  3. 迁移应该是自动化的,不应该由人手动设置。

G10包含三个部分:

  1. tensor vitality analyzer: 抽取张量的特征。根据编译器生成的执行图来跟踪每个张量,获取每个张量的大小、生命周期等信息,在编译时就可执行,也就是说,可以在模型训练之前执行。

  2. tensor migration scheduler: 提前计划张量的迁移。尽可能多地把生命周期长的张量迁移到外部内存。

  3. unified memory system: 简化GPU内存管理,实现透明的张量迁移。扩展GPU的UVM,将GPU内存、主机内存、闪存合并为统一的内存空间。实现一个统一的页表,包含了GPU内存、主机内存、闪存上的地址,这样在进行张量迁移时,只需指定虚拟地址即可。

基于开源的GPU模拟器UVMSmart实现G10

2. Background and Motivation

Approaches to Scaling GPU Memory
  1. Expand GPU memory with host memory:

    UVM(统一虚拟内存),使得程序员可以通过虚拟地址访问host和GPU内存。GPU硬件和运行时保证了数据一致性。按需进行数据迁移,如果GPU访问到不在GPU内存中的数据,则触发缺页中断,然后将数据从host中迁移到GPU内存上,当GPU内存满了时,则通过LRU将某现存数据迁移至host,然后把这个数据放到GPU内存上。但是,仅靠host内存,无法解决DL日益增长的内存需求。

  2. Expand GPU memory with flash memory:

    利用SSD扩展GPU内存,面临通信开销,例如GPU与SSD可以通过PCIe进行通信。但是通信开销还是很大,因为flash访问是慢速的,可以考虑将DNN的处理过程与通信重叠,隐藏通信延迟,降低通信开销。但是这需要对张量的特性有充分了解,因此本文进行了张量的特性研究。

3. GPU Memory characterization

分析DNN模型的训练过程:分析数据流图、profile cuda kernels

分析得出四个发现(observation)

Observation 01 : Small memory requirement of active tensors

1700707476752

这个实验回答了yes or no的问题,确实有很大部分张量是非活跃的。

只有小部分张量是活跃的,并且只占用了小部分内存(基本低于10%)

Observation 02 : Long unused time of inactive tensors

1700707437429

大部分张量只有小部分时间是活跃的,BERT和ViT大约50%以上的张量的非活跃时间超过10^5{\mu}s,ResNet152和Inception大约60%以上的张量的非活跃时间超过10^7{\mu}s,这长于SSD的延迟(比如20{\mu}s),因此可以被交换出去。

在典型的DNN数据流图中,一个张量仅被使用两次,如果有branch、join结构,那可能会多几次,但是也是有限的次数,网络结构依然是近似线性的。

这个实验说明大部分活跃张量的非活跃时间都是充足的(足够卸载到SSD上、或是从SSD上预取到GPU上)

Observation 03 : Diversity of inactive tensors

1700707327947

由Fig 4可知,张量的非活跃时间与尺寸是一个比较稀疏的分布模式,大约60%-80%的张量是可以交换的(非活跃时间>SSD延迟)。但是不同张量的非活跃时间不同、尺寸不同,当一个张量被交换出去时,在这一段时间上,GPU内存占用是减少了的,应该设计合理的算法将性能最大化(最长的时间、最大的内存占用减少)

Observation 04 : Complexity of scheduling tensor swapping

随着张量的换入换出,GPU内存占用是在动态变化的,因此,如果采用一个静态策略来决定swap策略(什么时候换入、什么时候换出)是不够合理的,这难以做出全局最优的决策。

4. G10 Design

1700707258340

三个主要部分:

  1. Tensor Vitality Analysis : 在编译时追踪每个张量,获取其大小和生命周期,以及张量之间的依赖关系。

  2. Smart Tensor Migration Scheduler : 根据前面获取的张量的信息,动态制定张量驱逐与预取的策略,使性能最优。(张量迁移会影响后续张量迁移策略的制定,因此需要设计动态的算法来制定策略)。然后,G10将驱逐、预取指令插入到编译程序中,GPU将实时执行这些指令。

  3. Unified Memory/Storage Space : 将GPU内存、主机内存、SSD合并为统一的内存空间,使得张量迁移对开发者是透明的。

4.2 Tensor Vitality Analysis

主要是分析出来tensor inactive time period (根据GPU kernel执行时间来估算)

1700728878895

born: 张量第一次被使用

dead: 张量最后一次被使用之后,dead,可以被释放掉(deallocate)

operator的input和output都是active tensor,应该放在GPU内存上;如果一个张量当前没有被使用,并且没有dead,则是inactive tensor。

inactive time period: 一个张量是inactive但是没有dead的时间

PS :一个张量可能有多段inactive time period,可能被多次换入换出

根据inactive time period,可以知道一个张量什么时候可以换出,什么时候需要换入。

如何实现?(如何获取张量的inactive time period?)

由于DNN的执行是可预测的(可预测的dataflow),G10离线地在编译时进行profiling获取张量的信息,使用GPU kernel执行时间来估计inactive time period,根据张量的大小、带宽来估计每个张量的驱逐、预取开销。

4.3 Smart Tensor Eviction

主要需要考虑三点(three challenges):

  1. 不同张量具有不同的大小、非活跃时间,因此对于GPU内存占用的贡献是不同的。

  2. 迁移到主机内存还是SSD?主机内存带宽更高、SSD容量更大。

  3. 应该尽量充分地利用带宽,并且选择合适的数据迁移时间点。

Selecting eviction candidates

GPU memory pressure: non-evicted tensors占用的内存超出GPU内存容量的那部分(也就是下图中的阴影部分)

收益:内存占用减少

成本:驱逐、预取的I/O开销

1700730180520

❓❓❓为什么Fig 7(2)中驱逐X的时候,memory pressure == GPU Capacity的时间 与 驱逐X所花费的时间 相等❓❓❓

Choosing eviction destination

host memory or SSD ?

优先换出到SSD上,因为host memory容量比较小,如果优先换出到host memory的话,会导致快速饱和,然后还是得换出到SSD上。

在SSD带宽饱和时,就会换出到host memory上。

1700742552858

4.4 Smart Tensor Prefetching

1700743116664

latest safe prefetch time: 不会引起GPU等待张量的最晚时间

optimized prefetch time: 不会导致GPU memory pressure超过GPU内存容量的最早时间

如果按照latest safe prefetch time来预取张量,则需要对张量的非活跃时间、带宽有准确的了解,否则就可能导致GPU等待张量。因此优先按照optimized prefetch time来预取,如果没有optimized prefetch time,则按照latest safe prefetch来预取

Code Instrumentation

1700743538388

利用编译器,将换出、预取等相关指令插入到程序中

4.5 Unified GPU Memory and Storage

1700744411889

当遇到g10 api调用时,smart migration handler将去unified page table中寻找对应数据地址,然后将其放到Migration Metadata Queues上,等待后续数据到来,以batch的粒度进行卸载/预取,然后再判断一下去cpu还是ssd,结束。

一段相关翻译:

如图10所示,对于张量驱逐和预取,G10将依靠统一的页表来识别张量的物理位置(1)。对于预驱逐,G10 将查找要驱逐的 GPU 页面。之后,迁移元数据将存储在相应的迁移元数据队列中(2)。迁移仲裁器将选择几个页面迁移来形成下一个迁移batch并将它们存储在迁移集 ( 3 ) 中。在此过程中,G10 驱动程序还将与 GPU 通信,按需分配 GPU 内存。传输集中的迁移将定期批处理,相应的 SSD-GPU 数据传输将通过直接存储访问 (DSA) 过程处理,CPU-GPU 数据传输将由 DMA 过程 ( 4 ) 处理。在数据迁移之后,将更新统一的页表和相应的TLB条目(5)。

构建一个页表,存储GPU Host SSD的内存地址映射

具体而言,GPU MMU维护一个统一的页表。当GPU访问到不在GPU内存上的数据时,GPU MMU通过缺页异常机制将数据隐式传到GPU上,导致GPU等待,但是由于设计了预取,因此一般不会触发缺页异常。

❓❓❓页表存在哪?GPU? host? SSD?❓❓❓ 在GPU上??

一段相关翻译:

当将 SSD 合并到 UVM 系统中时,我们遵循先前研究中描述的方法 [3]。我们依靠主机页面故障切换机制来完成地址翻译。在访问不在 GPU 内存中的页面后,GPU 页面错误处理程序将向主机发出中断,主机负责移动数据。为了模拟 SSD 内部并捕获它们的活动,例如垃圾收集 (GC) 和闪存芯片访问,在我们的评估中,我们开发了一个基于 SSDSim [5] 的 SSD 模拟器,并将其集成到我们的模拟器框架中。因此,由于我们在实验中测量了整体系统性能,因此考虑了内部 SSD 活动。

5. Implementation Details

Tensor vitality analyzer

将DNN model 和 各个kernel的执行时间作为Tensor vitality analyzer的输入。

Simulator framework

为了更加准确地模拟DNN的执行过程,首先在A100上跑model,跟踪所有kernel的执行过程。然后再把它放到simulator上去执行,重放这些kernel的执行过程

❓❓❓对于内存占用太大,没法在GPU上执行的模型,应该怎么办❓❓❓

7. Evaluation

baseline

Ideal : 拥有无限板载内存的GPU

Base UVM : 基础的GPU-CPU-SSD UVM系统,通过缺页中断,按需进行数据迁移

DeepUM+

FlashNeuron

1700757831568

1700758109701

1700758332236

1700758519901

1700758571135

robustness

My Conclusion

优化技术(卸载、预取)已经很成熟了,主要难点在于将SSD弄到了UVM里面,然后相当于是改了体系结构。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值