超节点拓扑亲和调度
在AI大规模训练和推理场景中,随着计算资源的分布式扩展,Pod间网络通信常面临带宽瓶颈和高延迟问题,尤其是关联度高的Pod之间频繁的跨节点通信,会显著降低系统性能和响应速度。为此,Volcano调度器支持使用超节点拓扑亲和调度能力。超节点由48个节点组成,其内部NPU采用特定网络连接方式形成一种超平面网络,可以提供更快的网络传输速率。超节点拓扑亲和调度可以将关联度高的Pod调度至同一超节点内,从而有效减少跨节点通信,降低网络延迟,并提高数据传输速度。
超节点拓扑亲和调度简介
针对该场景,Volcano调度器支持使用新的工作负载API HyperJob。您可以通过HyperJob,对相关任务进行统一调度和管理,具体示例请参见超节点拓扑亲和调度使用示例。超节点拓扑亲和调度遵循的具体调度原则如下:
- 亲和调度:Volcano调度器根据HyperJob模板创建Volcano Job,且每个Volcano Job为一个亲和组。进行调度时,系统将任务Pod调度至具有“volcano.sh/hypernode”标签的节点中(具有该标签说明其为超节点内的节点)。同时,同一个亲和组内的Pod将被调度至“volcano.sh/hypernode”标签值相同的节点中(标签值相同说明节点位于同一超节点)。
图1 亲和调度流程图
- 组调度(Gang):HyperJob支持组调度,即当Volcano Job运行数量满足minAvailable(不指定时为replicatedJobs.replicas之和)时,系统才会调度HyperJob。同时,HyperJob中的每个Volcano Job也支持组调度。
- 装箱调度(Binpack):HyperJob支持装箱调度,即在超节点网络等价时,调度器优先将HyperJob的任务分配至资源碎片最少的超节点中,以提高资源利用率。如图2 装箱调度对比所示,假设集群内有2个超节点,其中超节点1已经分配8个节点给其他任务。此时用户下发一个HyperJob,其中包含2个Volcano Job,每个Volcano Job包含20个Pod,每Pod请求独占一个节点。
- 不使用装箱调度时,调度结果可能是VcJob-0调度至超节点1,VcJob-1调度至超节点2。此时,超节点1的使用率为28/48=58%,超节点2的使用率为20/48=41%。
- 使用装箱调度时,VcJob-0和VcJob-1都会优先调度到超节点1,超节点1使用率为100%,超节点2使用率为0%。此时,超节点2可作为一个完整的空闲超节点供其他任务使用。
前提条件
- 已创建v1.23及以上版本的CCE Standard/Turbo集群,具体步骤请参见购买Standard/Turbo集群。
- 集群中已有超节点。CCE Standard/Turbo集群暂不支持购买超节点,您可以在ModelArts中提前购买超节点(Ascend规格实例),购买后CCE集群将自动纳管,具体步骤请参见创建Standard专属资源池。
在CCE Standard/Turbo集群中,您可以通过“volcano.sh/hypernode”标签确定该节点是否属于超节点,以及属于哪个超节点。
- 集群中已安装Volcano插件,且插件版本在1.15.8及以上,具体步骤请参见Volcano调度器。
- 集群中已安装CCE AI套件(Ascend NPU)插件,且版本在2.1.23及以上,具体步骤请参见CCE AI套件(Ascend NPU)。
约束与限制
在单个Pod内,仅支持1个容器申请NPU资源,且不允许init容器申请NPU资源,否则Pod将无法被调度。
开启超节点拓扑亲和调度功能
开启“超节点拓扑亲和调度”功能后,您可以根据训练任务间的数据传输需求手动划分亲和组,系统会将同一亲和组的任务调度至同一超节点,从而有效提升网络传输效率。
- 登录CCE控制台,单击集群名称,进入集群概览页。在左侧导航栏中选择“配置中心”,在右侧切换至“调度配置”页签。
- 在Volcano调度器配置中,“超节点拓扑亲和调度”默认关闭,需进一步修改调度器配置参数以开启该功能。
- 在设置“设置集群默认调度器”中选择Volcano调度器,在“专家模式”中单击“开始使用”。
图3 “专家模式 > 开始使用”
- 在YAML配置文件中,添加如下参数,开启“超节点拓扑亲和调度”,以实现同一亲和组不同任务间数据的高效传输。
... tiers: - plugins: - name: priority - enableJobStarving: false enablePreemptable: false name: gang - name: conformance - plugins: - enablePreemptable: false name: drf - name: predicates - name: nodeorder - plugins: - name: cce-gpu-topology-predicate - name: cce-gpu-topology-priority - name: xgpu - plugins: - name: nodelocalvolume - name: nodeemptydirvolume - name: nodeCSIscheduling - name: networkresource - plugins: # 开启超节点拓扑亲和调度 - name: hypernode-topology-aware ...
- 参数填写完成后,在右下角单击“保存”。
- 在设置“设置集群默认调度器”中选择Volcano调度器,在“专家模式”中单击“开始使用”。
- 在右下角单击“确认配置”。在“确认配置”弹窗中,确认修改信息,无误后单击“保存”。
超节点拓扑亲和调度使用示例
- 依次执行以下命令,创建一个HyperJob,并在该HyperJob内定义2个亲和组(Volcano Job)用于执行任务。
- 执行以下命令,创建HyperJob的YAML文件。
vim hyper-job.yaml
文件内容如下,在单个Pod内,仅支持1个容器申请NPU资源,且不允许init容器申请NPU资源,否则Pod将无法被调度。apiVersion: batch.volcano.sh/v1alpha1 kind: HyperJob metadata: name: hyperjob-test spec: replicatedJobs: - replicas: 2 # Volcano job的副本数 name: vcjob-test # Volcano job的名称 template: tasks: - replicas: 2 # Pod的副本数 name: worker # Pod的名称 template: spec: containers: # 定义容器 - name: test image: busybox command: ['sh', '-c', 'echo "Hello, Kubernetes!" && sleep 3600'] imagePullPolicy: IfNotPresent resources: requests: cpu: 1 "huawei.com/ascend-1980": 8 # 申请的NPU数量,需与limits值需要保持一致,系统将根据申请NPU的数量决定Pod是否独占节点 limits: cpu: 1 "huawei.com/ascend-1980": 8
- requests."huawei.com/ascend-1980"表示业务Pod申请的NPU芯片数量,需与limits值需要保持一致,系统将根据该参数值以及节点中NPU芯片的数量决定Pod是否独占节点。
- 执行以下命令,创建上述HyperJob。
kubectl apply -f hyper-job.yaml
回显结果如下:
hyperjob.batch.volcano.sh/hyperjob-test created
- 执行以下命令,查看HyperJob是否已创建。
kubectl get hyperjob
回显如下,则说明HyperJob资源已创建。NAME MINAVAILABLE AGE hyperjob-test 2 68s
- 执行以下命令,查看Volcano Job是否运行成功。
kubectl get vcjob
回显结果如下,则说明2个Volcano Job已成功运行,且Pod全部调度成功。
NAME STATUS MINAVAILABLE RUNNINGS AGE hyperjob-test-vcjob-test-0 Running 2 2 2m30s hyperjob-test-vcjob-test-1 Running 2 2 2m30s
- 执行以下命令,创建HyperJob的YAML文件。
- 执行以下命令,查看每个Pod所在的节点IP。
kubectl get pod -o wide
回显内容如下,其中NODE列表示当前Pod所在节点的IP地址。
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES hyperjob-test-vcjob-test-0-worker-0 1/1 Running 0 2m56s 192.168.9.35 192.168.9.104 <none> <none> hyperjob-test-vcjob-test-0-worker-1 1/1 Running 0 2m55s 192.168.9.105 192.168.9.37 <none> <none> hyperjob-test-vcjob-test-1-worker-0 1/1 Running 0 2m56s 192.168.9.32 192.168.9.100 <none> <none> hyperjob-test-vcjob-test-1-worker-1 1/1 Running 0 2m55s 192.168.9.202 192.168.9.75 <none> <none>
- 执行以下命令,查看每个Pod所在节点的“volcano.sh/hypernode”标签值,以确认同一亲和组(Volcano Job)中的Pod是否调度至同一超节点。仅超节点中的节点存在“volcano.sh/hypernode”标签值,且标签值相同则说明这些节点属于同一超节点。
kubectl describe node 192.168.9.104 | grep volcano.sh/hypernode kubectl describe node 192.168.9.37 | grep volcano.sh/hypernode kubectl describe node 192.168.9.100 | grep volcano.sh/hypernode kubectl describe node 192.168.9.75 | grep volcano.sh/hypernode
回显结果依次如下:
volcano.sh/hypernode=hypernode-1 volcano.sh/hypernode=hypernode-1 volcano.sh/hypernode=hypernode-2 volcano.sh/hypernode=hypernode-2
由此可知,hyperjob-test-vcjob-test-0的Pod皆已调度至hypernode-1超节点, hyperjob-test-vcjob-test-1的Pod皆已调度至hypernode-2超节点,调度结果符合超节点拓扑亲和。