本次分享将首先引见百度智能云 GPU 容器虚构化 2.0 的更新变动,而后引见新版本中的技术成功方法并演示详细性能,最后引见在各类业务场景的通常和探求。
1. 双引擎 GPU 容器虚构化 2.0
咱们去年颁布了业内首个双引擎 GPU 容器虚构化架构,驳回了「用户态」和「内核态」两种引擎,以满足用户对隔离性、性能、效率等多方面不同并重的需求。
在隔离引擎之上是资源池化层,该档次关键基于远程调用成功资源的解耦和池化。
在资源池化层之上是 K8s 一致资源调度层。在调度机制之上,咱们会依据不同业务场景,形象进去多种混布模式,包括共享混布、抢占混布、分时混布、潮汐混布等。
经过以上技术才干允许了各类AI 业务的落地,包括模型开发、模型训练、在线推理等,大幅优化了 GPU 资源的经常使用率,缩小了 GPU 的经常使用数量。
关于这些内容更详细片面的解说,在咱们去年的分享中引见过,文字稿件的链接在文末。
1.0 版本很好地满足了 AI 场景的业务需求,不论是厂内还是厂外的业务中,获取了比拟宽泛的运行。
咱们的技术指标就是宿愿:吃干榨尽一切资源,笼罩一切业务场景,优化业务总体体现。
所以 1.0 版本还不够完美,并没有监禁 GPU 的所有才干:GPU 上的一切资源在容器虚构化环境中并没有齐全使能,更多的场景是不可经常使用 GPU 容器虚构化才干的,所以往年咱们继续推出了 2.0 版本。
这是咱们双引擎GPU 容器虚构化 2.0 架构图。
在 2.0 版本中, 除了对 GPU 的显存和 AI 算力启动隔离之外,还成功了对 GPU 的渲染算力和编解码器的隔离。
基于这些新的才干,在资源调度层面可以提供渲染混布和编解码混布,成功了 AI 算力、渲染算力、编解码器等 GPU 所有资源的一致调度。
同时,2.0 版本可以经过多调度器的模式,允许客户的现有业务平滑融合到咱们的架构中,这对客户业务能够极速经常使用最新的 GPU 容器虚构化才干,是十分关键的。
在这些新才干的允许下,更多的业务场景,比如智能驾驶仿真、ARM 平台的云游戏等都可以经过这套平台优化资源应用率,将所需 GPU 的经常使用量显著降落。
除此之外,两个容器虚构化引擎咱们都会随着底层库的更新启动始终迭代,确保用户能够经常使用业界最新的技术。其中用户态允许最新版本 nvidia driver 和cuda 12.1,内核态允许 nvidia driver 525/530/535 等最新版本。
2. 新才干技术解析
接上去我会详细引见渲染算力和编解码器隔离的技术方案。
首先咱们先剖析一下 AI 算力和渲染算力的区别。
在 NVIDIA GPU 上不只能启动 AI 计算,还可以做图形的渲染计算。AI 负载经过 Cuda 访问 GPU,渲染负载经过 OpenGL/Vulkan 访问 GPU。这两类计算均经常使用相反的算力资源。
那么在 AI 计算隔离曾经成功的基础上,渲染负载能否在 AI 计算的隔离环境中成功运转?
假设渲染负载能够隔离成功,经常使用哪种类型的 GPU 容器虚构化引擎是适合的方案?
接上去咱们详细剖析一下 AI 算力架构。
从上往下看,最下层的是 AI APP,它们依赖于底层的 Cuda 系列库,包括 cuda-x,cuda runtime 等,它们给下层 AI APP 提供易于经常使用的初级 API。再往下就是运行层 driver 库,包括 cuda driver,NVML 等,它们会经过设施文件和内核态的 driver 启动通讯,最终到达经常使用 GPU 的目的。
架构图中灰色的箭头是 AI 程序经常使用 GPU 的控制流,白色的箭头是 AI 程序经常使用 GPU 的的数据流。
那么 AI 算力架构和渲染架构有什么不一样呢?咱们继续往下看。
渲染算力架构,从上往下看,最下层的是 UI/3D APP,比如游戏引擎,它的底层库相比 AI 算力架构要复杂一些,调用底层库关键包括两种模式:经过转发层 GLX 调用 X11 server,或许间接调用 EGL。
最终他们都会调用底层的图形库 OpenGL 或许 Vulkan,这些图形库就相当于 AI 计算中的 Cuda 库。
再往下就是运行层 driver 库,包括 libnvidia-glcore/libnvidia-eglcore/libdrm 等,它们也是经过设施文件和内核态的 driver 启动通讯,最终到达经常使用 GPU 的目的。
架构图中灰色的箭头是渲染程序经常使用 GPU 的控制流,白色的箭头是渲染程序经常使用 GPU 的数据流。
经过以上剖析和对比,咱们可以发现 AI 算力架构和渲染算力架构,只管下层软件不同,然而他们的控制流都是分歧的,经常使用相反的设施文件和内核模块启动通讯。
回到咱们之前的疑问,渲染负载能否在 AI 计算的隔离环境中成功运转?依据这个剖析结果预测,渲染运行是可以在 AI 算力的隔离环境中运转。
然而在实践验证中,论断能否认的。
经过逆向剖析发现两个方案的控制命令字存在一些差异,须要将这局部差异在隔离成功中区分开来。经过少量的试验后,最终在内核层面成功了渲染算力的隔离。
为什么咱们没有选用在用户态成功这个方案呢?
由于用户态成功须要阻拦的下层库函数多,成功难度高。同时,对用户的软件不透明。所以经过用户态成功渲染算力隔离并不是一个好的工程方案。
接上去我向大家演示 AI 算力和渲染算力的隔离成果。演示的配件环境为一张 NVIDIA V100 16G。
在这个 GPU 上运转单个 AI 负载,pytorch resnet50 训练,batch-size 为 32 时,调配 100% 算力,吞吐在 340 左右。运转单个渲染负载,经常使用的 GPUtest 的 Furmask 测试,调配 100% 算力,FPS 在 550。在混合负载测试中,一个 AI 负载,一个渲染负载,各调配 50% 算力,AI 负载的吞吐为 170,渲染的 FPS 为 260~270。
可以看到在单个 GPU 上,AI 负载和渲染负载都成功了隔离,取得了约一半的算力,获取了预期的性能体现。
在 2.0 版本中,另外一个新增的性能就是编解码器的隔离。
咱们区分在用户态和内核态都成功了编解码实例。
用户态的编解码器实例中,编解码器是裸混经常使用,不允许对编解码器的算力做隔离,每个实例都可以所有编解码算力。
内核态的编解码器实例中,咱们成功了对编解码器的隔离,在实例中编码器的权重和 AI 算力、渲染算力的权重共享,做到一致算力调配。
那么内核态和用户态的成功有什么不同呢?用户态在实例中经常使用的是编解码器的所有算力,而内核态成功了编解码器的算力调配。比如在内核态调配 20% 的算力,那么你就可以在内核态的编解码实例中经常使用 20% 的编解码才干。
这样咱们就成功了 GPU 资源的一致算力调配和使能,做到了资源的吃干榨净。
3.全场景通常
接上去咱们将会结合前面的技术,做各个场景的通常分享。
咱们先看看用户态和内核态两个引擎在技术和场景上的差异。
在技术个性对比上,业务层普通会在隔离性能的强弱、延时高下、资源调配颗粒度、多用户允许才干等维度做技术考量,为运行婚配适合的 GPU 容器虚构化引擎。
依据这些个性的剖析,咱们列出了不同运行场景实用的技术方案。
比如在线推理,对延时的要求很高,普通就会介绍用户态的方案。离线推理,则两种方案都可以选用。在渲染仿真场景,由于用户态不允许渲染隔离,故只能经常使用内核态的方案。
这是一个经典的互联网的介绍业务,蕴含了数据处置、模型开发和在线服务等业务。其中数据处置和模型开发是离线业务,用来允许在线服务,一切业务都经常使用了少量的 GPU。
在没有经常使用 GPU 容器虚构化方案之前,每个业务虚例经常使用一个 GPU,经过少量的监控数据发现,在线推理服务的全体 GPU 经常使用率并不高,全体在 20%,这是一个业界普遍存在的疑问。
由于在线服务对时延要求比拟高,咱们在这种场景选用部署用户态的方案。在保障业务 SLA 相反的状况下,大幅优化全体 GPU 资源经常使用率,将全体资源应用率到 35%。
在结合用户态自身允许的抢占混布和分时混布,使得数据处置和模型开发等离线义务,可以和在线推理业务启动在离线混布,当在线业务处于波谷时,离线业务抢占较多 GPU 闲暇资源启动业务处置,节俭了全体的 GPU 经常使用数量。
这种场景在厂内和厂外都获取了少量的运行,节俭了很多的老本。在 GPU 资源比拟弛缓的时代是一个很好的技术选用。
很多客户的平台中曾经存在自己定制的义务调度器,包括自定义的排队算法等性能。客户假设要引入第三方供应商的 GPU 容器虚构化平台,则须要经常使用相应的义务调度器。
如何使得定制的义务调度器和百度智能云的义务调度器在客户业务中共存,一种模式是经常使用多套 K8s 集群,这会造成治理复杂。另外一种模式就是经常使用百度智能云开发的多调度器允许方案,在同一 K8s 调度集群内经常使用多个调度器。
在这个方案外面咱们将 GPU 资源分为两个池子,经过标签识别两个 GPU 池的资源。义务形容经常使用不同的标签,K8s 会把义务调配对应的义务调度器,从而使不同义务调度器的共存。
假设客户经常使用的是开源版的义务调度器,未做深度改变,则可以经过这套方案成功业务的平滑过渡,最后将一切业务都迁徙到百度智能云的义务调度器上。
开发人员会用小规模的模型启动调试、验证、算子开发等上班,这些模型参数规模普通在 1.5B 以内。普通经常使用一块 A100 或许 A800 GPU启动,允许 2~4 个用户。
然而在开发环节中,GPU 有较多期间处于闲暇形态,造成全体 GPU 经常使用率较低。
同时,每个开发人员须要少量的存储资源,保留自己的训练数据和模型数据,须要经过大容量的远程文件系统来存储。
远程文件系统要挂载到客户容器内,须要驳回不同参数启动挂载,以挂载不同的卷。这是经过不同用户的 user id 来识别用户的身份来成功的。
然而用户态虚构化不允许不同 user id 的用户经常使用,即不允许多用户隔离,不可在此场景经常使用。内核态虚构化可以成功多用户隔离,可以保障不同用户同时挂载不同的资源来经常使用。
内核态虚构化允许 burst 调度战略,可以只针对生动的容器负载,依照权重启动算力调配。比如一个 GPU,虚构化给两个用户经常使用,平分 50% 的算力,当只要一个用户实践经常使用 GPU 时,调度战略会把一切算力调配给此用户。当两个用户都在经常使用时,各经常使用 50% 的算力。
这样既提供了共享算力的才干,又总体提高了 GPU 的经常使用率和业务体现。
智能驾驶仿真场景触及到了 3 个模块,其中渲染仿真编码模块和感知推理模块经常使用了 GPU,笼罩了 AI 计算、图形渲染和编解码器等所有资源类型。
在没有经常使用 GPU 容器虚构化方案之前,渲染仿真编码仿真经常使用一块 GPU 运转相似游戏引擎的环境,实时渲染出车辆和路面状况,每隔 1 到 2 秒,截取一张图片编码后输入给感知推理模块。感知推理模块经常使用另外一块 GPU,运转相似图像识别和分类推理的 AI 模型,识别出车道线、行人、阻碍物等,把数据给规控模块。规控模块会依据感知数据,布局和控制车辆的下一步形态,发送控制命令给仿真模块,启动下一步操作。
这时刻业务对 GPU 的经常使用率都较低,不超越 50%。
咱们驳回内核态虚构化技术,在同一个 GPU 上同时运转仿真和推理义务,每个义务调配 50% 的算力,到达同时在一个 GPU 运转两种不同的负载。同时数据在一个 GPU 中的显存传递,提高了数据传输效率,优化了业务性能。
相比过去,这样在仿真环境提高了 100% 的 GPU 经常使用率。
云游戏通常是同一个 GPU 上运转多个容器,每个容器运转着一个完整的 android 实例。在这个实例里蕴含了 android 的运转时环境,在最下面会运转一个 android 游戏,例如王者荣耀、敌对精英、原神等。
由于云游戏是没有实在屏幕的,只要模拟进去的虚构屏幕,每个实例会经常使用 GPU 渲染资源,把游戏的图像界面渲染到虚构屏幕的上。这些图像画面会经过对虚构屏幕的截屏和编码,输入成相似 H.264 视频流,经过流媒体协定播放到用户的手机客户端上。
在没有经常使用 GPU 容器虚构化方案之前,多个云游戏实例是经过裸混争抢的模式,共享 GPU 的渲染资源,可以说是没有任何服务保障和资源隔离才干的,造成游戏体验不可启动 SLA 治理。
由于手机云游戏运转在 ARM 平台中,咱们做了少量新的技术开发,使得整个云原生 AI 平台能够运转在 ARM 上。
咱们经常使用内核态方案来对每个 android 实例启动治理,启动渲染显存的隔离,保障显存调配的 QoS。
那么在这个场景中,咱们为什么没有用内核态虚构化对渲染算力和编解码器做隔离?由于云游戏对实时性要求比拟高,内核态虚构化不可满足时延的要求,渲染隔离更多满足对实时性不高的场景。所以在这个场景,只经常使用了内核态虚构化的显存隔离才干,保障显存调配的 QoS。
以上就是我当天和大家分享的所有内容了。