问题背景
全球主要的容器集群服务厂商的Kubernetes服务都提供了Nvidia GPU容器调度能力,但是通常都是将一个GPU卡分配给一个容器。这可以实现比较好的隔离性,确保使用GPU的应用不会被其他应用影响;对于深度学习模型训练的场景非常适合,但是如果对于模型开发和模型预测的场景就会比较浪费。 大家的诉求是能够让更多的预测服务共享同一个GPU卡上,进而提高集群中Nvidia GPU的利用率。而这就需要提供GPU资源的划分,而这里GPU资源划分的维度指的就是GPU显存和Cuda Kernel线程的划分。通常在集群级别谈支持共享GPU,通常是两件事情:
1.调度
2.隔离,我们这里主要讨论的是调度,隔离的方案未来会基于Nvidia的MPS来实现。
而对于细粒度的GPU卡调度,目前Kubernetes社区并没有很好的方案,这是由于Kubernetes对于GPU这类扩展资源的定义仅仅支持整数粒度的加加减减,无法支持复杂资源的分配。比如用户希望使用Pod A占用半张GPU卡,这在目前Kubernetes的架构设计中无法实现资源分配的记录和调用。这里挑战是多卡GPU共享是实际矢量资源问题,而Extened Resource是标量资源的描述。
针对此问题,我们设计了一个outoftree的共享GPU调度方案,该方案依赖于Kubernetes的现有工作机制:
-
Extended Resource定义
-
Scheduler Extender机制
-
Device Plugin机制
用户场景
-
作为集群管理员,我想提高集群的GPU使用率;在开发过程中,多个用户共享模型开发环境
-
作为应用开发人员,我希望能够同时在Volta GPU上运行多个推理任务
目标
-
能够让使用者通过API描述对于一个可共享资源的申请, 并能实现该种资源的调度
非目标
-
不支持该共享资源的隔离
-
不支持超卖
设计原则
-
明确问题简化设计,第一步只负责调度和部署,后续再实现运行时显存管控。
有很多的客户明确的诉求是首先可以支持多AI应用可以调度到同一个GPU上,他们可以接受从应用级别控制显存的大小,利用类似gpu_options.per_process_gpu_memory_fraction
控制应用的显存使用量。那我们要解决的问题就先简化到以显存为调度标尺,并且把显存使用的大小以参数的方式传递给容器内部。 -
不做侵入式修改
本设计中不会修改Kubernetes核心的Extended Resource的设计, Scheduler的实现,Device Plugin的机制以及Kubelet的相关设计。重用Extended Resource描述共享资源的申请API。这样的好处在于提供一个可以移植的方案,用户可以在原生Kubernetes上使用这个方案。 -
按显存和按卡调度的方式可以在集群内并存,但是同一个节