为什么需要GPU虚拟化
根据平台收集的GPU使用率的历史,我们发现独占卡的模式会对GPU这种宝贵计算资源存在浪费现象,即不同用户对模型的理解深度不同,导致申请了独立的卡却没有把资源用满的情况。针对这种情况,虚拟化GPU技术可以更好的解决这种痛点,让机器的计算资源得到充分利用。
现有技术情况
目前来看,绝大多数公司使用的是英伟达(NVIDIA)的公司的计算卡,所以下面主要介绍NVIDIA的技术现状。
NVIDIA在前几年释放出来一个NVIDIA vGPU的一个硬件虚拟化的技术,该技术的介绍是
NVIDIA Virtual GPU允许多虚拟机能够同时直接访问单个物理GPU的能力,只需要在虚拟机上装上与宿主机相同的驱动设备。通过这种方式,NVIDIA vGPU给多个虚拟机非并行化图形性能,以及应用的兼容性,在不同负载间来共享一个GPU。
另外一种实现共享的方式是使用NVIDIA MPS服务,让多个应用通过MPS server管理对GPU的操作来实现共享
NVIDIA技术优缺点
NVIDIA在vGPU技术上提供了2种模式,GPUpassthrough和Bare-Metal Deployment。GPU passthrough模式相当于独占,不允许虚拟机之间共享设备,Bare-Metal相当于共享模式。GRID技术的Bare-Metal通过vfio-mdev提供了一个隔离性非常高的的硬件环境(不是模拟简单的模拟硬件),这个虚拟化技术并不会对性能有很大的伤害,对多租户需要强隔离的平台是一个很好的选择。
但是这个技术目前来看主要针对的是虚拟机平台,在技术特性方面也有明确写出某些功能不支持,其次NVIDIA GRID技术需要购买NVIDIA公司的软件授权才能使用,这个授权费相当昂贵。
NVIDIA MPS技术NVIDIA对GPU共享的最早的一种支持模式,通过MPS server和MPS client就可以让多个GPU任务共享GPU的计算能力。对于容器平台,这种共享GPU的方式是一种可行性的选择。
不过,这种指令代理技术有一个弊端,就是如果MPS Server挂掉或者其他MPS client端造成的非正常性退出,会导致处于同一个MPS server下的所有MPS client都受到影响,这种影响对于提供共享服务的平台来说是灾难性的。
NVIDIA以上2种的共享方式都不支持根据用户申请的请求对GPU计算能力的时间分片特性,举个例子,A用户申请0.8个GPU的计算能力,B用户申请0.1个GPU的计算能力,2人都跑同样的应用程序,在NVIDIA的技术方案里面,2个用户的GPU使用是0.5和0.5平均的使用方式,无法保证A用户GPU使用时间。
重新设计共享GPU方案
前面分别介绍了NVIDIA的2种共享GPU的技术的优缺点,那么有没有可能有一种新的方案,既能给容器平台提供共享,又能避免中心化代理GPU指令呢
由cgroup获得的启发
cgroup(aka control group)是linux 内核提供的一个特性,用来限制,监管和统计一组进程的资源使用。容器就是基于这种技术发展起来的,并且发展今天这个很壮大的地步。那么自然而然地,一个想法在脑中产生
既然我们提供的是容器平台,那么是不是可以像cgroup一样管理cpu和内存一样来管理gpu和显存呢?
通过各种试验,我们发现这个想法是可以实现的,并且能很好的运行起来。我们给这个技术起名为vCUDA。
vCUDA设计
cgroup是内核提供了一个特性,按照ProtectionRing,cgroup是运行在Ring 0级别,NVIDIA驱动运行在Ring 1或2级别,由于NVIDIA驱动是闭源的原因,vCUDA方案目前只能运行在Ring 3级别。
vCUDA的系统架构与NVIDIA的GRID架构类似,采用一个Manager来管理GPU,Manager负责配置容器的GPU计算能力和显存资源,做到使用者无法使用多余申请的显存,GPU的平均使用率不会大幅超出申请值。vCUDA的设计采用零入侵设计,用户的程序无需重新编译就可以运行在GaiaStack平台进行GPU共享。
vCUDA使用修改后cuda library来达到资源控制,vCUDA分别修改了计算操作,显存操作和信息获取3个方面的API。由于篇幅原因,这里只展示基本流程,更详细的原理可以阅读我们IEEE ISPA2018发布的论文《GaiaGPU: Sharing GPUs in Container Clouds》(ShengboSong, Jing Gu, Hanmei Luo, Ying Li)
vCUDA测试报告
"实践是检验真理的唯一标准",针对目前市面上的主流框架(TensorFlow, Caffe, CNTK, PyTorch),我们分别作了一下测试
其中测试选用AlexNet的benchmark程序, MNIST数据集,选用的机器配置如下
Legend:1. 单容器测试
MPS: 使用MPS服务
default: 直接在物理机
Hard: 硬限制方式
Soft: 动态调整方式
运行时间和申请的GPU卡数成反比
MNIST数据集
Hard Mode
Soft Mode
2. 多容器测试
MNIST数据集
Hard Mode
3. CPUOverhead
4.显存控制
vCUDA使用方式
tencent.com/vcuda-core 和tencent.com/vcuda-memory 是新增的针对单卡共享的一个资源标记,core对应的是使用率,单张卡有100个core,memory是显存,每个单位是256MB的显存。如果申请的资源为50%利用率,7680MB显存。tencent.com/vcuda-core 填写50,tencent.com/vcuda-memory 填写成30。那么当然我们也同样支持原来的独占卡的方式,只需要在core的地方填写100的整数倍,memory值填写大于0的任意值即可。
总结一下
GaiaStack提供的共享GPU技术可以提供一下优势:
1. 极小的CPUOverhead(小于5%)
2. 按照用户的申请值进行计算能力分配(弹性计算)
3. 保证使用的显存不会超出申请值
4. 节省资源,原来一个卡只能跑一个任务,现在可以跑多个任务,并且有隔离性
5. 无迁移成本,不需要修改镜像就可以直接在GaiaStack运行