|
作者:jikesong,腾讯CSIG腾讯云异构计算研发副总监〇、本文写作背景大约2年前,在腾讯内网,笔者和很多同事讨论了GPU虚拟化的现状和问题。从那以后,出现了一些新的研究方向,并且,有些业界变化,可能会彻底颠覆掉原来的一些论断。但这里并不是要重新介绍完整的GPU虚拟化的方案谱系。而是,我们将聚焦在英伟达GPU+CUDA计算领域,介绍下我们最新的技术突破qGPU,以及它的意义究竟是什么。关于GPU虚拟化的历史性介绍,我将直接摘抄当时的讨论。这也不是一篇介绍TKEqGPU产品特性的文章。而是,我们将潜入到前所未有的深度,去探索GPU调度和QoS的本质。本文也不是巨细靡遗的系统性探索,但你可以在这里看到别处不曾出现过的知识。本文涉及对一些厂商的推测性技术介绍,不保证准确性。一、术语介绍GPU—————GraphicsProcessingUnit,显卡CUDA————ComputeUnifiedDeviceArchitecture,英伟达2006年推出的计算APIVT/VT-x/VT-d—IntelVirtualizationTechnology。-x表示x86CPU,-d表示Device。SVM—————AMDSecureVirtualMachine。AMD的等价于IntelVT-x的技术。EPT—————ExtendedPageTable,Intel的CPU虚拟化中的页表虚拟化硬件支持。NPT—————NestedPageTable,AMD的等价于IntelEPT的技术。SR-IOV———SingleRootI/OVirtualization。PCI-SIG2007年推出的PCIe虚拟化技术。PF—————PhysicalFunction,亦即物理卡VF—————VirtualFunction,亦即SR-IOV的虚拟PCIe设备MMIO———MemoryMappedI/O。设备上的寄存器或存储,CPU以内存读写指令来访问。CSR————Control&StatusRegister,设备上的用于控制、或反映状态的寄存器。CSR通常以MMIO的方式访问。UMD————UserModeDriver。GPU的用户态驱动程序,例如CUDA的UMD是libcuda.soKMD————KernelModeDriver。GPU的PCIe驱动,例如英伟达GPU的KMD是nvidia.koGVA————GuestVirtualAddress,VM中的CPU虚拟地址GPA————GuestPhysicalAddress,VM中的物理地址HPA————HostPhysicalAddress,Host看到的物理地址IOVA————I/OVirtualAddress,设备发出去的DMA地址PCIeTLP——PCIeTransactionLayerPacketBDF————Bus/Device/Function,一个PCIe/PCI功能的IDMPT————MediatedPass-Through,受控直通,一种设备虚拟化的实现方式MDEV———MediatedDevice,Linux中的MPT实现PRM————ProgrammingReferenceManual,硬件的编程手册MIG————Multi-InstanceGPU,Ampere架构高端GPU如A100支持的一种hardwarepartition方案二、GPU虚拟化的历史和谱系2.1GPU能做什么GPU天然适合向量计算。常用场景及API:此外还有加解密、哈希等场景,例如近些年来的挖矿。渲染是GPU诞生之初的应用:GPU的G就是Graphics——图形。桌面、服务器级别的GPU,长期以来仅有三家厂商:英伟达:GPU的王者。主要研发力量在美国和印度。AMD/ATI:ATI于2006年被AMD收购。渲染稍逊英伟达,计算的差距更大。Intel:长期只有集成显卡,近年来开始推独立显卡。2006这一年,GPU工业界发生了三件大事:ATI被AMD收购;nVidia黄仁勋提出了CUDA计算;Intel宣布要研发独立显卡。日光之下并无新事。如同经常发生的,这些事有成功有失败:Intel很快就放弃了它的独立显卡,直到2018才终于明白过来自己到底放弃了什么,开始决心生产独立显卡;AMD整合ATI不太成功,整个公司差点被拖死,危急时公司股票跌到不足2美元;而当时不被看好的CUDA,则在几年后取得了不可思议的成功。从2012年开始,人工智能领域的深度学习方法开始崛起,此时CUDA受到青睐,并很快统治了这个领域。2.2系统虚拟化和OS虚拟化系统虚拟化演化之路,起初是和GPU的演化完全正交的:1998年,VMWare公司成立,采用BinaryTranslation方式,实现了系统虚拟化。2001年,剑桥大学XenSource,提出了PV虚拟化(Para-Virtualization),亦即Guest-Host的主动协作来实现虚拟化。2005年,Intel提出了VT,最初实现是安腾CPU上的VT-i(VTforItanium),很快就有了x86上的VT-x。2007年,Intel提出了VT-d(VTforDevice),亦即x86上的IOMMU。2008年,Intel提出了EPT,支持了内存虚拟化。2010年,Linux中的PVHypervisorlguest的作者,RustyRussell(他更有名的作品是iptables/netfilter),提出了VirtIO,一种Guest-Host的PV设备虚拟化方案。应该可以说,在PV时代和BinaryTranslation时代,虚拟化是危险的。只有当VT在硬件层面解决了CPU的隔离、保证了安全性之后,公有云才成为可能。VT-x于2005~2006年出现,亚马逊AWS于2006年就提出云计算,这是非常有远见的。系统的三个要素:CPU,内存,设备。CPU虚拟化由VT-x/SVM解决,内存虚拟化由EPT/NPT解决,这些都是非常确定的。但设备虚拟化呢?它的情况要复杂的多,不管是VirtIO,还是VT-d,都不能彻底解决设备虚拟化的问题,这些我们稍后还会谈到。除了这种完整的系统虚拟化,还有一种也往往被称作「虚拟化」的方式:从OS级别,把一系列的library和process捆绑在一个环境中,但所有的环境共享同一个OSKernel。严格来说,这种容器技术,和以KVM为代表的系统虚拟化,有着本质的区别。随着容器的流行,「虚拟化」这个术语,也被用来指称这种OS级别的容器技术。因此我们也从众,把它也算作虚拟化的一种——只不过为了区分,称之为「OS虚拟化」。这种OS虚拟化最初于2005年,由Sun公司在Solaris10上实现,名为「SolarisZone」。Linux在2007~2008开始跟进,接下来有了LXC容器等;到了2013年,Docker横空出世,彻底改变了软件分发的生态,成为事实上的标准。2.3GPU虚拟化的谱系2.3.1作为PCIe设备的GPU不考虑嵌入式平台的话,那么,GPU首先是一个PCIe设备。GPU的虚拟化,还是要首先从PCIe设备虚拟化角度来考虑。那么一个PCIe设备,有什么资源?有什么能力?2种资源:配置空间MMIO(有的还有PIO和OptionROM,此略)2种能力:中断能力DMA能力一个典型的GPU设备的工作流程是:应用层调用GPU支持的某个API,如OpenGL或CUDAOpenGL或CUDA库,通过UMD(UserModeDriver),提交workload到KMD(KernelModeDriver)KMD写CSRMMIO,把它提交给GPU硬件GPU硬件开始工作...完成后,DMA到内存,发出中断给CPUCPU找到中断处理程序——KMD此前向OSKernel注册过的——调用它中断处理程序找到是哪个workload被执行完毕了,...最终驱动唤醒相关的应用2.3.2PCIe直通我们首先来到GPU虚拟化的最保守的实现CIe设备直通。如前述,一个PCIe设备拥有2种资源、2种能力。你把这2种资源都(直接或间接地)交给VM、针对这2种能力都把设备和VM接通,那么,VM就能完整使用这个PCIe设备,就像在物理机上一样。这种方案,我们称之为PCIe直通(PCIePass-Through)。它只能1:1,不支持1:N。其实并不能算真正的虚拟化,也没有超卖的可能性。VM中,使用的是原生的GPU驱动。它向VM内核分配内存,把GPA填入到GPU的CSR寄存器,GPU用它作为IOVA来发起DMA访问,VT-d保证把GPA翻译为正确的HPA,从而DMA到达正确的物理内存。PCIe协议,在事务层(TransactionLayer),有多种TLP,DMA即是其中的一种:MRd/MWr。在这种TLP中,必须携带发起者的RoutingID,而在IOMMU中,就根据这样的RoutingID,可以使用不同的IOMMU页表进行翻译。很显然,PCIe直通只能支持1:1的场景,无法满足1:N的需求。2.3.3SR-IOV那么,业界对1:N的PCIe虚拟化是如何实现的呢?我们首先就会想到SR-IOV。SR-IOV是PCI-SIG在2007年推出的规范,目的就是PCIe设备的虚拟化。SR-IOV的本质是什么?考虑我们说过的2种资源和2种能力,来看看一个VF有什么:配置空间是虚拟的(特权资源)MMIO是物理的中断和DMA,因为VF有自己的PCIe协议层的标识(RoutingID,就是BDF),从而拥有独立的地址空间。那么,什么设备适合实现SR-IOV?其实无非是要满足两点:硬件资源要容易partition无状态(至少要接近无状态)常见PCIe设备中,最适合SR-IOV的就是网卡了:一或多对TX/RXqueue+一或多个中断,结合上一个RoutingID,就可以抽象为一个VF。而且它是近乎无状态的。试考虑NVMe设备,它的资源也很容易partition,但是它有存储数据,因此在实现SR-IOV方面,就会有更多的顾虑。回到GPU虚拟化:为什么2007年就出现SR-IOV规范、直到2015业界才出现第一个「表面上的」SRIOV-capableGPU【1】?这是因为,虽然GPU基本也是无状态的,但是它的硬件复杂度极高,远远超出NIC、NVMe这些,导致硬件资源的partition很难实现。注释【1】AMDS7150GPU。腾讯云GA2机型使用。表面上它支持SR-IOV,但事实上硬件只是做了VF在PCIe层的抽象。Host上还需要一个Virtualization-Aware的pGPU驱动,负责VF的模拟和调度。2.3.4API转发因此,在业界长期缺乏SRIOV-capableGPU、又有强烈的1:N需求的情形下,就有更high-level的方案出现了。我们首先回到GPU应用的场景:渲染(OpenGL、DirectX,etc.)计算(CUDA,OpenCL)媒体编解码(VAAPI...)业界就从这些API入手,在软件层面实现了「GPU虚拟化」。以AWSElasticGPU为例:VM中看不到真的或假的GPU,但可以调用OpenGLAPI进行渲染在OpenGLAPI层,软件捕捉到该调用,转发给HostHost请求GPU进行渲染Host把渲染的结果,转发给VMAPI层的GPU虚拟化是目前业界应用最广泛的GPU虚拟化方案。它的好处是:灵活。1:N的N,想定为多少,软件可自行决定;哪个VM的优先级高,哪个VM的优先级低,同理。不依赖于GPU硬件厂商。微软、VMWare、Citrix、华为……都可以实现。这些API总归是公开的。不限于系统虚拟化环境。容器也好,普通的物理机也好,都可以API转发到远端。缺点呢?复杂度极高。同一功能有多套API(渲染的DirectX和OpenGL),同一套API还有不同版本(如DirectX9和DirectX11),兼容性就复杂的要命。功能不完整。计算渲染媒体都支持的API转发方案,还没听说过。并且,编解码甚至还不存在业界公用的API!【1】注释【1】Vulkan的编解码支持,spec刚刚添加,有望被所有GPU厂商支持。见下「未来展望」部分。2.3.5MPT/MDEV/vGPU鉴于这些困难,业界就出现了SR-IOV、API转发之外的第三种方案。我们称之为MPT(MediatedPass-Through,受控的直通)。MPT本质上是一种通用的PCIe设备虚拟化方案,甚至也可以用于PCIe之外的设备。它的基本思路是:敏感资源如配置空间,是虚拟的关键资源如MMIO(CSR部分),是虚拟的,以便trap-and-emulate性能关键资源如MMIO(GPU显存、NVMeCMB等),硬件partition后直接赋给VMHost上必须存在一个Virtualization-Aware的驱动程序,以负责模拟和调度,它实际上是vGPU的device-model这样,VM中就能看到一个「看似」完整的GPUPCIe设备,它也可以attach原生的GPU驱动。以渲染为例,vGPU的基本工作流程是:VM中的GPU驱动,准备好一块内存,保存的是渲染workloadVM中的GPU驱动,把这块内存的物理地址(GPA),写入到MMIOCSR中Host/Hypervisor/驱动:捕捉到这次的MMIOCSR写操作,拿到了GPAHost/Hypervisor/驱动:把GPA转换成HPA,并pin住相应的内存页Host/Hypervisor/驱动:把HPA(而不是GPA),写入到pGPU的真实的MMIOCSR中pGPU工作,完成这个渲染workload,并发送中断给驱动驱动找到该中断对应哪个workload——当初我是为哪个vGPU提交的这个workload?——并注入一个虚拟的中断到相应的VM中VM中的GPU驱动,收到中断,知道该workload已完成、结果在内存中这就是nVidiaGRIDvGPU、IntelGVT-g(KVMGT、XenGT)的基本实现思路。一般认为graphicsstack是OS中最复杂的,加上虚拟化之后复杂度更是暴增,任何地方出现一个编程错误,调试起来都是无比痛苦。但只要稳定下来,这种MPT方案,就能兼顾1:N灵活性、高性能、渲染计算媒体的功能完整性...是不是很完美?其实也不是。**该方案最大的缺陷,是必须有一个pGPU驱动,负责vGPU的模拟和调度工作。**逻辑上它相当于一个实现在内核态的device-model。而且,由于GPU硬件通常并不公开其PRM,所以事实上就只有GPU厂商才有能力提供这样的Virtualization-AwarepGPU驱动。使用了厂商提供的MPT方案,事实上就形成了对厂商的依赖。2.3.6SR-IOV:revisited重新回到GPU的SR-IOV。AMD从S7150开始、英伟达从Turing架构开始,数据中心GPU都支持了SR-IOV。但是again,它不是NIC那样的SR-IOV,它需要Host上存在一个vGPU的device-model,来模拟从VM来的VF访问。所以事实上,到目前为止,GPU的SR-IOV仅仅是封装了PCIeTLP层的VF路由标识、从而规避了runtime时的软件DMA翻译,除此之外,和基于MDEV的MPT方案并无本质的不同。2.3.7谱系表在介绍完了上述的这些方案后,我们重新看下CUDA计算、OpenGL渲染两种场景的软件栈,看看能发现什么:CUDA计算stack:OpenGL渲染Stack:可以看出,从API库开始,直到GPU硬件,Stack中的每一个阶段,都有被截获、转发的可能性。甚至,一概称之为「API转发」是不合适的——以GRIDvGPU、GVT-g为例的DEV转发,事实上就是MPT,和任何API都没有关系。三、容器GPU虚拟化首先,我们这里谈到的,都是nVidia生产的GPU、都只考虑CUDA计算场景。其次,这里的虚拟化指的是OS虚拟化的容器技术,不适用于KATA这样的、基于系统虚拟化的安全容器。3.1CUDA的生态CUDA开发者使用的,通常是CUDARuntimeAPI,它是high-level的;而CUDADriverAPI则是low-level的,它对程序和GPU硬件有更精细的控制。RuntimeAPI是对DriverAPI的封装。CUDADriver即是UMD,它直接和KMD打交道。两者都属于NVIDIADriverpackage,它们之间的ABI,是NVIDIADriverpackage内部的,不对外公开。英伟达软件生态封闭:无论是nvidia.ko,还是libcuda.so,还是libcudart,都是被剥离了符号表的大多数函数名是加密替换了的其它的反调试、反逆向手段以nvidia.ko为例,为了兼容不同版本的Linux内核API,它提供了相当丰富的兼容层,于是也就开源了部分代码:其中这个26M大小的、被剥离了符号表的nv-kernel.o_binary,就是GPU驱动的核心代码,所有的GPU硬件细节都藏在其中。3.2vCUDA和友商cGPU为了让多个容器可以共享同一个GPU,为了限定每个容器能使用的GPU份额,业界出现了不同的方案,典型的如vCUDA和cGPU:vCUDA架构:cGPU架构:两者的实现策略不同,cGPU比vCUDA更底层,从而实现了不侵入用户环境。3.3GPU池化简介从截获的位置,看GPU池化的谱系:以CUDAAPI转发的池化方案、业界某产品为例,它到了GPU所在的后端机器上,由于一个GPU卡可能运行多个GPU任务,这些任务之间,依然需要有算力隔离。它为了实现这一点,在后端默认启用了nVidiaMPS——也就是故障隔离最差的方案。这会导致什么?一个VM里的CUDA程序越界访问了显存,一堆风马牛不相及的VM里的CUDA应用就会被杀死。所以,很显然,GPU池化也必须以同时满足故障隔离和算力隔离的方案作为基础。3.4算力隔离的本质从上述介绍中,我们可以看出:算力隔离、故障隔离都是GPU虚拟化、GPU池化的关键,缺一不可。如果没有算力隔离,不管虚拟化损耗有多低,都会导致其方案价值变低;而如果缺少实例间的故障隔离,则基本无法在生产环境使用了。事实上,英伟达GPU提供了丰富的硬件特性,支持HardwarePartition,支持TimeSharing。1.HardwarePartition,亦即:空分Ampere架构的A100GPU所支持的MIG,即是一种HardwarePartition。硬件资源隔离、故障隔离都是硬件实现的——这是无可争议的隔离性最好的方案。它的问题是不灵活:只有高端GPU支持;只支持CUDA计算;A100只支持7个MIG实例。2.nVidiaMPS除了MIG,算力隔离表现最优秀的,是MPS——它通过将多个进程的CUDAContext,合并到一个CUDAContext中,省去了ContextSwitch的开销,也在Context内部实现了算力隔离。如前所述,MPS的致命缺陷,是把许多进程的CUDAContext合并成一个,从而导致了额外的故障传播。所以尽管它的算力隔离效果极好,但长期以来工业界使用不多,多租户场景尤其如此。3.TimeSharing,亦即:时分nVidiaGPU支持基于Engine的ContextSwitch。不管是哪一代的GPU,其Engine都是支持多任务调度的。一个OS中同时运行多个CUDA任务,这些任务就是在以TimeSharing的方式共享GPU。鉴于MIG的高成本和不灵活、MPS故障隔离方面的致命缺陷,事实上就只剩下一种可能:TimeSharing。唯一的问题是,如何在原厂不支持的情况下,利用TimeSharing支持好算力隔离、以保证QoS。这也是学术界、工业界面临的最大难题。3.4.1GPUmicroarchitecture和chip真正决定GPU硬件以何种方式工作的,是chip型号。不管是GRIDDriver还是TeslaDriver,要指挥GPU硬件工作,就要首先判断GPU属于哪种chip,从而决定用什么样的软硬件接口来驱动它。3.4.2PFIFO:GPUSchedulingInternalsPFIFO架构:概念解释:PFIFOGPU的调度硬件,整体上叫PFIFO。Engine执行某种类型的GPU硬件单元。常见Engine有:PGRAPH——CUDA/GraphicsPCOPY———CopyEnginePVENC———VideoEncodingPVDEC———VideoDecoding...最重要的就是PGRAPHEngine,它是CUDA和渲染的硬件执行单元。ChannelGPU暴露给软件的,对Engine的抽象。一个app可以对应一或多个channels,执行时由GPU硬件把一个一个的channel,放在一个一个的engine上执行。channel是软件层的让GPU去执行的最小调度单位。TSGTimesliceGroup。由一或多个channel(s)组成。一个TSG共享一个context,且作为一个调度单位被GPU执行。runlistGPU调度的最大单位。调度时,GPU通常是从当前runlist的头部摘取TSG或channel来运行。因此,切换runlist也意味着切换activeTSG/channel。PBDMApushbufferDMA。GPU上的硬件,用于从Memory中获取pushbuffer。HostGPU上和SYSMEM打交道的部分(通过PCIe系统)。PBDMA是Host的一部分。注意,Host是Engine和SYSMEM之间的唯一桥梁。InstanceBlock每个Channel对应一个InstanceBlock,它包含各个Engine的状态,用于ContextSwitch时的Save/Restore;包含GMMUpagetable;包含RAMFC——其中包括UMD控制的USERD。3.4.3runlist/TSG/channel的关系Tesla驱动为每个GPU,维护一或多个runlist,runlist或位于GPU显存,或位于系统内存runlist中有很多的entry,每个entry是一个TSG或一个channel一个TSG是multi-channel或single-channel的一个channel必定隶属于某个TSG硬件执行TSG或channel,当遇到以下情景之一时,进行ContextSwitch:执行完毕timeslice到了发生了preemption3.4.4pendingchannelnotificationpendingchannelnotification是USERD提供的机制。UMD可以利用它通知GPU:某个channel有了新的任务了【1】。这样,GPU硬件在当前channel被切换后(执行完毕、或timeslice到了),就会执行相应的channel。注释【1】不同chip,实现有所不同。3.4.5从硬件调度看GRIDvGPUGRIDvGPU支持3种scheduler:1.BestEffort:所有vGPU的任务随意提交,GPU尽力执行。现象:如果启动了N个vGPU,它们的负载足够高,那么结果就是均分算力。原理:所有的vGPU使用同一个runlist。runlist内,还是按照channel为粒度进行调度。如同在native机器上运行多个CUDA任务一样。2.EqualShare:所有在用的vGPU严格拥有同样的GPU配额现象:如果启动了N个vGPU,它们严格拥有相同的算力,不管是否需要这么多。原理:为每个vGPU维护一个runlist。当它的timeslice过了,GRIDHostDriver会写GPU寄存器,触发当前runlist被抢占、下一个runlist被调度。3.FixedShare:每个vGPU有自己固定的GPU配额现象:每个vGPU严格按照创建时的规格来分配算力。原理:Ditto.3.5腾讯云qGPU简介qGPU==QoSGPU。它是目前业界唯一真正实现了故障隔离、显存隔离、算力隔离、且不入侵生态的容器GPU共享的技术。3.5.1qGPU基本架构qGPU基本架构:3.5.2qGPUQoS效果注释【1】测试数据来自T4(chip:TU104)。其它chip上,正确性、功能性和性能都待验证,虽然原理上是相通的。【2】两个PoD的算力配比为2:1。横坐标为batch值,纵坐标为运行时两个PoD的实际算力比例。可以看到,batch较小时,负载较小,无法反映算力配比;随着batch增大,qGPU和MPS都趋近理论值2,vCUDA也偏离不远,但缺乏算力隔离的业界某产品则逐渐趋近1。四、GPU虚拟化:未来展望2021以来,GPU工业界发生了一些变化,e.g.:1.英伟达GPU的QoS突破英伟达在CUDA计算领域占据压倒性的优势,但QoS表现不尽如人意。长期以来,学术界和工业界付出了大量的努力,尝试在英伟达不支持QoS的前提下,实现某种程度的算力隔离。遗憾的是,这些努力,要么集中在CUDAAPI层,能够做到一定的算力隔离,但同样会带来副作用;要么尝试在low-level层面突破——但不幸全都失败了。qGPU是十几年来在英伟达GPU上实现QoS的最大突破。基于它:腾讯云TKE的多容器共享GPU,将无悬念地领先整个工业界在线推理+离线训练的混布,成为可能GPU池化的后端实现,不管采用哪种方案,都有了坚实的基础Linux/Android场景的渲染虚拟化,也有了坚实的基础2.VulkanSpec支持了videoencode/decode很可能,编解码API不统一的乱象即将终结,这对API转发方案有很大的意义。不远的将来,或许某种API方案的vGPU会成为主流。Google在社区的一些活动标明,很可能它就有这样的计划。五、参考资料和项目简介1.nVidiaMPS官方。部分文档公开。2.nouveaudriverinLinuxKernel开源社区版的英伟达GPU驱动,基于DRM,硬件细节基本靠逆向工程。不支持CUDA、只支持OpenGL渲染。代码庞大,包含很多有用信息。3.envytools及其nVidiaHardwareDocumentationnouveau的配套项目。除了提供各种profilingGPU硬件细节的工具,还维护了一个文档仓库,记录所有已经被成功逆向了的信息。4.GDEVproject,anopensourceimplementationofCUDA基于nouveau实现了CUDAdriver和CUDAruntime,代码较旧,已不维护。大神级作品。5.libcudest,apartiallyRE-edCUDAdriver英伟达实习生实现的CUDADriver逆向工程。只逆向了一小部分UMD和KMD之间的接口。已不维护。6.vCUDA开源项目。7.nVidiaofficial:nvidia-uvmdriverforTesla官方,开源。TelsaDriver配套的UVM驱动,代码开源。和TeslaDriver有很多low-level交互,可以从中窥见很多GPU硬件细节。8.TeslaDriver官方。细节全藏在nv-kernel.o_binary文件中。9.GRIDvGPU官方。细节也是全在nv-kernel.o_binary文件中。与TeslaDriver不同的是,它为vGPU的FixedShare和EqualShare两种调度策略,实现了per-vGPUrunlist。因此有很高的参考价值。六、思考&致谢"Lasciateognesperanza,voich'intrate."--DanteAlighieri"Καιρὸνγνῶθι."--ΠιττακόςοΜυτιληναίος使用nVidiaGPU进行计算,有两种场景:1)推理业务,往往是在线业务;2)训练业务,往往是离线业务。这两种业务之间,很难混布到同一个GPU上。甚至两种在线推理业务之间,也很难进行这样的混布。因为没有QoS隔离,你不知道哪一个业务会流量突发,影响另一个业务。所以,长期以来,关键的在线业务,GPU利用率都不高,据我们了解,大多在50%以下,甚至个别BG的推理业务只能到~20%。即使GPU很昂贵,即使一个业务占不满GPU,也只能如此。我们很自然要问:是nVidia做不好QoS吗?显然不是。MPS也好,GRIDvGPU也好,其QoS表现都很优秀。但是,为什么MPS会画蛇添足地引入CUDAContextMerging呢?真的是因为这样会带来些许性能上的收益吗?我是持怀疑态度的。在我看来,更可信的解释是,英伟达公司在拥有市场支配地位的情况下,并不希望提升GPU利用率。卓越的硬件加上封闭的软件生态,当然能带来丰厚的利润。学术界、工业界在CUDA算力隔离上的努力,这里不再一一列举【1】。这其中既有GDEV这样的以一人之力做出的大神级作品,也有毫无营养的灌水式paper。有意思的是,几乎所有的努力都在上层,很少人有勇气下潜到GPU硬件的细节中。我们下潜了,也很幸运地成功了。感谢腾讯云虚拟化团队的各位同事,一起加班到深夜,分析搜罗到的各种靠谱和不靠谱的项目和paper,脑补各种可能的软硬件细节,讨论技术上的各种可能性;感谢腾讯云TKE团队的各位同事,协调客户收集需求、协同产品化开发;感谢WXG的同事,和我们一起梳理GPU利用率的痛点;感谢友商的同类产品,它的idea无疑是优秀的;注释【1】部分列表可参考阎姝含的文章:针对深度学习的GPU共享“码上有趣”视频挑战活动来了!上传视频赢HHKB键盘和罗技鼠标!了解活动可加微信:teg_helper(备注码上有趣)视频号最新视频
|
|