本文来自微信公众号“twt企业IT社区”,作者/汪照辉,中国银河证券架构师,专注于容器云、微服务、DevOps、数据治理、数字化转型等领域,对相关技术有独特的理解和见解。擅长于软件规划和设计,提出的“平台融合”的观点越来越得到认同和事实证明。发表了众多技术文章探讨容器平台建设、微服务技术、DevOps、数字化转型、数据治理、中台建设等内容,受到了广泛关注和肯定。
智能化应用如人脸识别、语音识别、文本识别、智能推荐、智能客服、智能风控等已广泛应用于各行各业,这些应用被称为判定式AI的范畴,通常和特定的业务场景相绑定,因此在使用GPU(Graphics Processing Unit)卡的时候也通常各自独立,未考虑业务间GPU共享能力,至多实现vGPU虚拟化切分,从而一张物理GPU卡虚拟出多张vGPU,可以运行多个判定式AI应用。随着大模型的兴起,对GPU算力的需求越来越多,而当前现实情况使企业往往受限于有限的GPU卡资源,难以支撑众多的业务需求,同时由于业务特性等,即便进行了虚拟化,往往难以充分使用GPU卡资源或持续使用资源,从而也造成有限的卡资源也无法有效利用。
从GPU虚拟化需求到池化需求
智能化应用数量的增长对GPU算力资源的需求越来越多。NVIDIA虽然提供了GPU虚拟化和多GPU实例切分方案等,依然无法满足自由定义虚拟GPU和整个企业GPU资源的共享复用需求。TensorFlow、Pytorch等智能化应用框架开发的应用往往会独占一张GPU整卡(AntMan框架是为共享的形式设计的),从而使GPU卡短缺,另一方面,大部分应用却只使用卡的一小部分资源,例如身份证识别、票据识别、语音识别、投研分析等推理场景,这些场景GPU卡的利用率都比较低,没有业务请求时利用率甚至是0%,有算力却受限于卡的有限数量。单个推理场景占用一张卡造成很大浪费,和卡数量不足形成矛盾,因此,算力切分是目前很多场景的基本需求。再者,往往受限于组织架构等因素,GPU由各团队自行采购和使用,算力资源形成孤岛,分布不均衡,有的团队GPU资源空闲,有团队无卡可用。
为解决GPU算力资源不均衡等问题,同时支持GPU算力的国产化替代,协调在线和离线资源需求、业务高峰和低峰资源需求、训练和推理、以及开发、测试、生产环境对资源需求不同,实现算力的统一管理和调度复用,实现GPU资源的切分、聚合、超分、远程调用、应用热迁移等能力,提升GPU资源的利用率,GPU算力池化需求迫在眉睫。
GPU设备虚拟化路线
GPU设备虚拟化有几种可行方案。
首先是PCIe直通模式(PCIe Pass-through技术,pGPU),也就是将物理主机上的整块GPU卡直通挂载到虚拟机上使用。但这种方式是独占模式,GPU卡没有虚拟化切分,并不能解决多个应用运行在一张卡上的问题,因此意义不是很大。
第二是采用SR-IOV技术,允许一个PCIe设备在多个虚拟机之间共享,同时保持较高性能。通过SR-IOV在物理GPU设备上创建多个虚拟vGPU来实现的,每个虚拟vGPU可以被分配给一个虚拟机,让虚拟机直接访问和控制这些虚拟功能,从而实现高效的I/O虚拟化。NVIDIA早期的vGPU就是这样的实现,不过NVIDIA vGPU需要额外的license,额外增加了成本。SR-IOV虽然实现了1:N的能力,但其灵活性比较差,难以更细粒度的分割和调度。
第三是MPT(Mediated Pass-Through,受控的直通)模式。MPT本质上是一种通用的PCIe设备虚拟化方案。兼顾了1:N灵活性、高性能、功能完整性,但逻辑上相当于实现在内核态的device-model,厂商通常不会公开硬件编程接口,因此采用MPT可能会形成厂商依赖。
用的最多的模式是API转发模式。根据AI应用的调用层次(如下图),API转发有多个层次,包括CUDA API转发(图中①)、GPU Driver API转发(图中②)和设备硬件层API转发(图中③)。设备硬件层API通常是难以获得的,因此目前市面上通常采用CUDA API转发模式(截获CUDA请求转发,也被称为用户态)和GPU卡驱动Driver API转发模式(截取驱动层请求转发,也被称为内核态)。
另外AI开发框架往往和GPU卡绑定(比如华为支持CANN框架,海光支持DTK框架,英伟达则支持TensorFlow、Pytorch等框架),AI应用在使用AI框架时,也可以在AI框架层进行转发,在AI应用迁移时比较有用。
AI应用调用层次
GPU虚拟化和共享方案
了解了GPU设备虚拟化的方式,基于设备虚拟化技术,看下GPU虚拟化和共享的实现方式。GPU虚拟化和共享有多种方案,英伟达从官方也提供了vGPU、MIG、MPS等方案,以及非官方的vCUDA、rCUDA、内核劫持等多种方案。
NVIDIA VGPU方案
NVIDIA vGPU是NVIDIA提供的一种虚拟化方案,可靠性和安全性高,但不支持容器,只能虚拟化若干个vGPU,使用不灵活;无法动态调整资源比例;有一定的共享损耗;不支持定制开发,需支付额外license费用。
MIG方案
MIG是多实例GPU方案。只支持Linux操作系统,需要CUDA11/R450或更高版本;支持MIG的卡有A100,H100等比较高端的卡;支持裸机和容器,支持vGPU模式,一旦GPU卡设置了MIG后,就可以动态管理instance了,MIG设置时persistent的,即使reboot也不会受影响,直到用户显式地切换。借助MIG,用户可以在单个GPU卡上获得最多7倍的GPU资源,为研发人员提供了更多的资源和更高的灵活性。优化了GPU的利用率,并支持在单个GPU上同时运行推理、训练和高性能计算(HPC)任务。每个MIG实例对于应用程序都像独立GPU一样运行,使其编程模型没有变化,对开发者友好。
MPS(Multi-Process Scheduling)
MPS多进程调度是CUDA应用程序编程接口的替代二进制兼容实现。从Kepler的GP10架构开始,NVIDIA引入了MPS,允许多个流(Stream)或者CPU的进程同时向GPU发射K ernel函数,结合为一个单一应用程序的上下文在GPU上运行,从而实现更好的GPU利用率。当使用MPS时,MPS Server会通过一个CUDA Context管理GPU硬件资源,多个MPS Clients会将他们的任务通过MPS Server传入GPU,从而越过了硬件时间分片调度的限制,使得他们的CUDA Kernels实现真正意义上的并行。但MPS由于共享CUDA Context也带来一个致命缺陷,其故障隔离差,如果一个在执行kernel的任务退出,和该任务共享share IPC和UVM的任务一会一同出错退出。
rCUDA
rCUDA指remote CUDA,是远程GPU调用方案,支持以透明的方式并发远程使用CUDA设备。rCUDA提供了非GPU节点访问使用GPU的方式,从而可以在非GPU节点运行AI应用程序。rCUDA是一种C/S架构,Client使用CUDA运行库远程调用Server上的GPU接口,Server监控请求并使用GPU执行请求,返回执行结果。在实际场景中,无需为本地节点配置GPU资源,可以通过远程调用GPU资源从而无需关注GPU所在位置,是非常重要的能力,隔离了应用和GPU资源层。
vCUDA
vCUDA采用在用户层拦截和重定向CUDA API的方式,在VM中建立pGPU的逻辑映像,即vGPU,来实现GPU资源的细粒度划分、重组和再利用,支持多机并发、挂起恢复等VM的高级特性。vCUDA库是一个对nvidia-ml和libcuda库的封装库,通过劫持容器内用户程序的CUDA调用限制当前容器内进程对GPU算力和显存的使用。vCUDA优点是API开源,容易实现;缺点是CUDA库升级快,CUDA库升级则需要不断适配,成本高;另外隔离不准确无法提供算力精准限制的能力、安全性低用户可以绕过限制等。目前市面上厂商基本上都是采用vCUDA API转发的方式实现GPU算力池化。
GPU算力池化云原生实现
GPU池化(GPU-Pooling)是通过对物理GPU进行软件定义,融合了GPU虚拟化、多卡聚合、远程调用、动态释放等多种能力,解决GPU使用效率低和弹性扩展差的问题。GPU资源池化最理想的方案是屏蔽底层GPU异构资源细节(支持英伟达和国产各厂商GPU),分离上层AI框架应用和底层GPU类型的耦合性。不过目前AI框架和GPU类型是紧耦合的,尚没有实现的方案抽象出一层能屏蔽异构GPU。基于不同框架开发的应用在迁移到其他类型GPU时,不得不重新构建应用,至少得迁移应用到另外的GPU,往往需要重新的适配和调试。
算力隔离、故障隔离是GPU虚拟化和池化的关键。算力隔离有硬件隔离也就是空分的方式,MPS共享CUDA Context方式和Time Sharing时分的方式。越靠底层,隔离效果越好,如MIG硬件算力隔离方案,是一种硬件资源隔离、故障隔离方式,效果最好。但硬件设备编程接口和驱动接口往往是不公开的,所以对厂商依赖大,实施的难度非常大,灵活性差,如支持Ampere架构的A100等,最多只能切分为7个MIG实例等。NVIDIA MPS是除MIG外,算力隔离最好的。它将多个CUDA Context合并到一个CUDA Context中,省去Context Switch的开销并在Context内部实现了算力隔离,但也致额外的故障传播。MIG和MPS优缺点都非常明显,实际工程中用的并不普遍。采用API转发的多任务GPU时间分片的实现模式相对容易实现和应用最广。
根据AI应用使用GPU的调用层次,可以实现不同层次的资源池化能力。比如CUDA层、Diver层、硬件设备层等。在不同的抽象层次,将需要加速的应用转发(Forwarding)到GPU资源池中。总的来说,越靠底层的转发性能损失越小,可操作的范围越大;但同时,编程量也越大,也越难。
由于云原生应用的大量部署,GPU算力资源池化需要支持云原生部署能力,比如说支持Kubernetes、Docker服务,通过K8s Pod绑定由GPU资源池按需虚拟出来的vGPU,执行Pod中的应用。不管是英伟达的GPU卡或者是国产GPU,所有的卡都在算力资源池中,当前可以将不同的卡进行分类,不同框架的应用按需调度到合适的分类GPU算力池上。从而提升资源管理效率。算力资源池同样需要实现相应的资源、资产管理和运行监控和可观测性,优化调度能力,减少GPU资源碎片。随着AI应用需求的迅速增长,算力资源池化在未来一段时间内将是企业关注的重要的一个方面。