社区目前解决方案,抽象了一个PodGroup的概念。无论是批调度器 Volcano 或是 原生调度器coscheduling插件都是基于该概念来实现gang调度。
任务调度对于多任务来说,引入任务队列的概念,实现多队列任务调度。可以给不同的队列设置资源容量quota,解决多租户场景下的配额和成本管理的问题。
此外优先级调度。任务的优先级一般是由priorityClassName来确定。一些特殊case,也会由任务申请的资源套餐规格来确定,比如大资源套餐规格优先、DRF(占用资源较少的任务具有更高的优先级)。

高级抢占策略,比如组抢占。
为了解决GPU卡碎片的问题,需要有binback策略以及二次调度器碎片整理功能。
社区目前解决方案:主要是 批调度器 Volcano。 此外,社区提供了基于 K8s原生的作业队列和弹性配额管理器Kueue。
拓扑感知调度需要感知到节点之间网络链路以及单个节点内资源的连接方式,从而提升任务的性能、加速训练速度、解决实例性能不一致的问题。
GPU拓扑
将同一个任务的不同实例调度到GPU卡之间有高速连接方式(nvlink等)的卡组合上更加好。调度器需要有感知单个节点内资源连接拓扑的能力。
以V100架构举例:
每块V100 GPU有6个NVLink通道,8块GPU间无法做到全连接,2块GPU间最多只能有2条NVLink连接。其中GPU0和GPU3,GPU0和GPU4之间有2条NVLink连接,GPU0和GPU1之间有一条NVLink连接,GPU0和6之间没有NVLink连接,故GPU0与GPU6之间仍然需要通过PCIe进行通信。
而A100,通过下图可以看出,8块GPU通过6个nvswitch实现了连接。不像V100存在GPU卡之间nvlink的差异。
网络拓扑
同一个机架或是tor内节点之间通信更快、延迟更低。主要是大规模分布式训练混合并行场景下,调度器会依据交换机收敛比,尽可能将同一单元内的 m 个 Pod 调度到同一个 Tor 下的 Node 上。
这里社区的 Koordinator 项目有部分实践。
感知作业并行策略
对于大模型训练,模型张量并行,涉及大量传输,所以需要同一路并行worker调度到一台主机上,走机内通信的方式。流水线并行,通信负担小,一路流水线并行的worker是可以调度到不同的机器上。
比如一个作业并行策略为3D 并行,2路数据并行+4路模型张量并行+4路流水线并行。需要在8台4张A100的机器(对应GPU0到GPU31)上运行32个POD(对应worker0到worker31)。具体调度结果如下图:
GPU共享调度
GPU的共享实际上就是多个实例运行在同一张卡上,进而提升GPU的利用率。实际上,共享调度主要的场景是:
小模型推理服务场景。训推一体,GPU的在离线混部。原生的kubernetes 中对于GPU的支持:
算力的最小调度单位是整卡。没有考虑显存。需要做一些扩展(调度器 + device plugin)开发,来支持共享调度。但是核心还是GPU的算力和显存的隔离。关于GPU算力和显存隔离解决方案在后续的文章中分析。
这里我们主要介绍一下英伟达MIG解决方案以及在kubernetes中如何使用。
NVIDIA 多实例 GPU(Multi-Instance GPU,简称 MIG)是 NVIDIA 在 H100,A100,A30 系列 GPU 卡上推出的一项新特性, 旨在将一块物理 GPU 分割为多个 GPU 实例,以提供更细粒度的资源共享和隔离。MIG 最多可将一块 GPU 划分成七个 GPU 实例, 使得一个 物理 GPU 卡可为多个用户提供单独的 GPU 资源,以实现最佳 GPU 利用率。
而且英伟达官方提供了 GPU Operator 来自动化部署和管理依赖的组件,简化管理工作。其中和MIG相关的组件主要是:
k8s-device-plugingpu-feature-discoverymig-manager比如我们对一台H100主机执行如下操作:
% kubectl label nodes xx nvidia.com/mig.config=all-1g.10gb --overwrite
上述的三个组件就会按照指令执行MIG相关操作。
然后查看结果:
kubectl exec nvidia-driver-daemonset-xx -t -n kube-system -- nvidia-smi -LGPU 0: NVIDIA H100 PCIe (UUID: GPU-717ef73c-2d43-4fdc-76d2-1cddef4863bb)MIG 1g.10gb Device 0: (UUID: MIG-222504cc-4a15-589b-8ec8-dbc02e6fb378)MIG 1g.10gb Device 1: (UUID: MIG-fdfd2afa-5cbd-5d1d-b1ae-6f0e13cc0ff8)MIG 1g.10gb Device 2: (UUID: MIG-b2925bc6-41ca-5ccd-bf5e-24259386f88e)MIG 1g.10gb Device 3: (UUID: MIG-083c76fc-5d21-5322-9d50-c8e21a01852f)MIG 1g.10gb Device 4: (UUID: MIG-13d8a181-5bc1-5527-9a0f-9c3f9cc1d89e)MIG 1g.10gb Device 5: (UUID: MIG-db99bb81-dde3-5c95-9778-daa291fce210)MIG 1g.10gb Device 6: (UUID: MIG-2d636152-57c2-5e73-9654-b1d21d6d21fb)
已经虚拟了7个1g.10gb MIG资源。
此时,我们就可以部署如下的pod使用这些MIG资源了。
apiVersion: apps/v1kind: Deploymentmetadata: name: deployment-1 namespace: demospec: replicas: 5 selector: matchLabels: app: dummy template: metadata: labels: app: dummy spec: containers: - name: sleepy image: busybox:latest command: ["sleep", "120"] resources: limits: nvidia.com/mig-1g.10gb: 1
存算协同调度
Kubernetes强调实例的可迁移性,一些有状态服务往往是存算分离的架构。而数据处理和模型训练都属于重数据场景。这种情况下,需要调度器有以下两个功能来加速作业获取数据的速度,进而降低昂贵GPU等待时间,加速训练:
感知任务目的数据集的缓存信息,将数据亲和性作为一个调度策略,优先将实例调度到包含目的数据集的节点。对于批调度器,有我们整个作业的信息(包含排队中的作业),因此提前触发数据预热的工作。社区主要的解决方案是 Fluid,提供了 2个调度插件,来实现存算协同调度。具体的细节将在后续的数据加速篇来分析。
总结本文主要介绍了基于kubernetes的AI算力平台需要在调度领域的那些工作来加速训练、提升资源的效能。