阿里云GPU调度插件
GPU资源划分调度方案
一、工具
阿里云k8s共享GPU调度插件专业版
二、使用前提
1、 阿里云k8s集群,且集群为ACK Pro版本集群
2、集群内预期被调度的服务器实例为异构计算GPU服务器
3、使用kubectl工具连接到集群
4、集群地域应为北京/上海/杭州/深圳/张家口/成都/香港/东京/雅加达/新加坡/弗吉尼亚/硅谷
5、版本要求
Kubernetes | 1.18.8及其以上 |
---|---|
Nvidia驱动版本 | 418.87.01及以上版本 |
Docker版本 | 19.03.5 |
操作系统 | CentOS 7.6、CentOS 7.7、Ubuntu 16.04和Ubuntu 18.04,Alibaba Cloud Linux 2.x |
支持显卡 | Tesla P4、Tesla P100、 Tesla T4和Tesla v100 |
三、使用方法
步骤一:安装共享GPU组件
- 登录容器服务管理控制台。
- 在控制台左侧导航栏中,单击集群。
- 在集群列表页面中,单击目标集群名称或者目标集群右侧操作列下的详情。
- 在集群管理页左侧导航栏中,选择*应用* > *云原生AI套件(公测)*。
- 在云原生AI套件页面,单击一键部署。
- 在一键部署云原生AI套件页面,选中调度组件(批量任务调度、GPU共享、GPU拓扑感知、NPU调度),单击页面下方的部署云原生AI套件。
步骤二:开启GPU共享调度能力和显存隔离能力
- 登录容器服务管理控制台。
- 在控制台左侧导航栏中,单击集群。
- 在集群列表页面单击已安装ack-ai-installer组件集群操作列的节点池。
- 在节点池页面单击创建节点池。
-
在创建节点池页面,设置创建节点池的配置项,给节点配置键:
- 如果开启GPU共享调度能力+GPU显存隔离能力。设置键为ack.node.gpu.schedule,值为cgpu。
- 如果只需要节点池支持共享调度,不支持显存隔离,设置键为ack.node.gpu.schedule,值为share。 只共享不隔离策略,适配于已有深度学习应用内已自建应用层隔离能力的场景。
-
在节点上为Pod配置选择GPU卡的策略。
- 如果使用Binpack算法,则设置键为ack.node.gpu.placement,设置值为binpack。 多个Pod会优先集中共享使用同一GPU卡,适用于需要提升GPU卡利用率的场景。
- 如果使用spread算法,则设置键为ack.node.gpu.placement,设置值为spread。 多个Pod会尽量分散使用不同GPU卡,适用于GPU高可用场景。尽量避免将同一个应用的副本放置到同一个GPU设备。
步骤三:添加GPU节点
完成创建节点池后,还可以在节点池中添加GPU节点。添加GPU节点时,同样实例规格类型应为异构计算GPU,如果添加节点池时已经创建GPU节点,可以跳过此步骤。
步骤四:安装和使用GPU资源查询工具
- 配置kubeconfig文件。
-
下载kubectl-inspect-cgpu。
-
Linux系统通过以下命令下载kubectl-inspect-cgpu。
wget http://aliacs-k8s-cn-beijing.oss-cn-beijing.aliyuncs.com/gpushare/kubectl-inspect-cgpu-linux -O /usr/local/bin/kubectl-inspect-cgpu
-
macOS系统通过以下命令下载kubectl-inspect-cgpu。
wget http://aliacs-k8s-cn-beijing.oss-cn-beijing.aliyuncs.com/gpushare/kubectl-inspect-cgpu-darwin -O /usr/local/bin/kubectl-inspect-cgpu
-
-
为kubectl-inspect-cgpu添加执行权限。
chmod +x /usr/local/bin/kubectl-inspect-cgpu
-
查看集群GPU使用情况。
kubectl inspect cgpu
预期输出:
NAME IPADDRESS GPU0(Allocated/Total) GPU Memory(GiB) cn-shanghai.192.168.6.104 192.168.6.104 0/15 0/15 ---------------------------------------------------------------------- Allocated/Total GPU Memory In Cluster: 0/15 (0%)
四、实现功能
1、单卡显存隔离
不安装插件的情况下,一个pod会占用一个gpu,现通过部署创建GPU共享容器的YAML文件使用cGPU显存隔离能力。,使得一个节点的gpu上可以运行多个pod,并且为每个pod指定最大可用显存大小。
操作步骤
执行以下命令查询集群的GPU共享能力。
kubectl inspect cgpu
NAME IPADDRESS GPU0(Allocated/Total) GPU1(Allocated/Total) GPU Memory(GiB)
cn-shanghai.192.168.0.4 192.168.0.4 0/7 0/7 0/14
---------------------------------------------------------------------
Allocated/Total GPU Memory In Cluster:
0/14 (0%)
部署共享GPU示例应用,该应用申请3 GiB显存。其中参数 aliyun.com/gpu-mem设置该pod的GPU显存大小。
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: binpack
labels:
app: binpack
spec:
replicas: 1
serviceName: "binpack-1"
podManagementPolicy: "Parallel"
selector: # define how the deployment finds the pods it manages
matchLabels:
app: binpack-1
template: # define the pods specifications
metadata:
labels:
app: binpack-1
spec:
containers:
- name: binpack-1
image: registry.cn-beijing.aliyuncs.com/ai-samples/gpushare-sample:tensorflow-1.5
command:
- python
- cgpu/main.py
resources:
limits:
# GiB
aliyun.com/gpu-mem: 3
执行以下命令,查看集群GPU显存使用情况。
kubectl inspect cgpu
预期输出:
NAME IPADDRESS GPU0(Allocated/Total) GPU Memory(GiB)
cn-beijing.192.168.1.105 192.168.1.105 3/14 3/14
---------------------------------------------------------------------
Allocated/Total GPU Memory In Cluster:
3/14 (21%)
执行以下命令登录容器查看容器被分配显存总量。
kubectl exec -it binpack-0 nvidia-smi
预期输出: ( 可以看到该容器被分配显存总量为3231 MiB )
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 418.87.01 Driver Version: 418.87.01 CUDA Version: 10.1 |
|-------------------------------+----------------------+----------------------+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
|===============================+======================+======================|
| 0 Tesla T4 On | 00000000:00:07.0 Off | 0 |
| N/A 41C P0 26W / 70W | 3043MiB / 3231MiB | 0% Default |
+-------------------------------+----------------------+----------------------+
+-----------------------------------------------------------------------------+
| Processes: GPU Memory |
| GPU PID Type Process name Usage |
|=============================================================================|
+-----------------------------------------------------------------------------+
2、多卡共享
多卡共享策略指的是某个应用申请了N个GiB的显存,并指定了这N个GiB的显存由M块GPU卡分配,每块GPU卡分配的显存为N/M(目前N/M必须为整数,并且这M张GPU卡必须在同一个Kubernetes节点上)。例如,某个应用申请了8 GiB显存,并指定了GPU卡个数为4,那么某个节点需分配4块GPU卡给该应用,每块GPU卡分配2 GiB显存。
操作步骤
创建binpack-1.yaml。
使用YAML文件创建一个资源类型为StatefulSet的binpack-1应用,并在YAML文件中设置以下配置。
- 设置Replicas为1。
-
申明每个Pod使用4张GPU卡,每张GPU卡使用2 GiB显存。
- 给Pod添加标签
aliyun.com/gpu-count=4
。 - 指定Pod的扩展资源
aliyun.com/gpu-mem
数量为8。
- 给Pod添加标签
-
apiVersion: apps/v1 kind: StatefulSet metadata: name: binpack-1 labels: app: binpack-1 spec: # 副本数设置1,便于观察。 replicas: 1 serviceName: "binpack-1" podManagementPolicy: "Parallel" selector: # define how the deployment finds the pods it manages matchLabels: app: binpack-1 template: # define the pods specifications metadata: labels: app: binpack-1 # 申明8 GiB显存由4块GPU卡提供,每块提供2 GiB显存。 aliyun.com/gpu-count: "4" spec: containers: - name: binpack-1 image: registry.cn-shanghai.aliyuncs.com/tensorflow-samples/tensorflow-gpu-mem:10.0-runtime-centos7 resources: limits: # 单位为GiB,该Pod总共申请了8 GiB显存。 aliyun.com/gpu-mem: 8
部署binpack-1应用
kubectl apply -f binpack-1.yaml
查看GPU数量和GPU的显存。
kubectl exec binpack-1-0 -- nvidia-smi
预期输出
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 418.87.01 Driver Version: 418.87.01 CUDA Version: 10.1 |
|-------------------------------+----------------------+----------------------+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
|===============================+======================+======================|
| 0 Tesla V100-SXM2... On | 00000000:00:07.0 Off | 0 |
| N/A 31C P0 54W / 300W | 2084MiB / 2150MiB | 1% Default |
+-------------------------------+----------------------+----------------------+
| 1 Tesla V100-SXM2... On | 00000000:00:08.0 Off | 0 |
| N/A 32C P0 55W / 300W | 2084MiB / 2150MiB | 0% Default |
+-------------------------------+----------------------+----------------------+
| 2 Tesla V100-SXM2... On | 00000000:00:09.0 Off | 0 |
| N/A 32C P0 54W / 300W | 2084MiB / 2150MiB | 0% Default |
+-------------------------------+----------------------+----------------------+
| 3 Tesla V100-SXM2... On | 00000000:00:0A.0 Off | 0 |
| N/A 34C P0 54W / 300W | 2084MiB / 2150MiB | 0% Default |
+-------------------------------+----------------------+----------------------+
+-----------------------------------------------------------------------------+
| Processes: GPU Memory |
| GPU PID Type Process name Usage |
|=============================================================================|
+-----------------------------------------------------------------------------+
3、显存隔离+算力分配
共享GPU调度目前支持仅申请显存和同时申请显存和算力两种任务,这两种任务不能同时存在于一个节点上,即一个节点只运行仅申请显存的任务,或者只运行同时申请显存和算力的任务。
-
为任务申请算力时,有如下限制:
- 每一张GPU提供的算力按100计量,代表这张卡的100%算力,例如申请20代表使用GPU卡的20%算力。
- 申请的算力值应为5的倍数,最小为5。如果不为5的倍数,任务将提交失败。
使用步骤
步骤一:创建支持算力分配的节点池
- 操作系统仅支持CentOS 7.x和Alibaba Cloud Linux 2.x。
- 为节点添加标签,键为ack.node.gpu.schedule,值为core_mem,开启节点GPU显存和算力隔离能力。
- 输入第二个节点标签,键为ack.node.gpu.placement,值为binpack,在节点上使用Binpack算法为Pod选择GPU卡。
- 如果需要将集群中已存在的GPU节点切换为算力隔离模式,要先将该节点从集群中移除,然后重新加入支持算力隔离的节点池。不支持直接使用
kubectl label nodes ack.node.gpu.schedule=core_mem
命令将该GPU节点切换为算力隔离模式。
步骤二:查看节点池是否开启算力分配功能
执行以下命令,查看节点池的节点是否开启算力分配功能。
kubectl get nodes <NODE_NAME> -o yaml
预期输出:
#省略其他字段。
status:
#省略其他字段。
allocatable:
#节点共有400%的算力,4张GPU卡,每张卡提供100%算力。
aliyun.com/gpu-core.percentage: "400"
aliyun.com/gpu-count: "4"
#节点共有60 GiB显存,4张GPU卡,每张卡提供15 GiB显存。
aliyun.com/gpu-mem: "60"
capacity:
aliyun.com/gpu-core.percentage: "400"
aliyun.com/gpu-count: "4"
aliyun.com/gpu-mem: "60"
由预期输出得到,存在aliyun.com/gpu-core.percentage
字段表示算力分配功能已开启。
步骤三:使用算力分配功能
以同时申请显存和算力任务为例,申请2 GiB显存、一张GPU卡的30%算力,使用GPU显存算力分配功能。
使用以下YAML内容,创建申请GPU显存和算力的任务。
apiVersion: batch/v1
kind: Job
metadata:
name: cuda-sample
spec:
parallelism: 1
template:
metadata:
labels:
app: cuda-sample
spec:
containers:
- name: cuda-sample
image: registry.cn-beijing.aliyuncs.com/ai-samples/gpushare-sample:cuda-sample-11.0.3
command:
- bandwidthTest
resources:
limits:
#申请2 GiB显存。
aliyun.com/gpu-mem: 2
#申请一张GPU卡的30%算力。
aliyun.com/gpu-core.percentage: 30
workingDir: /root
restartPolicy: Never
执行以下命令,提交cuda-sample任务。
kubectl apply -f /tmp/cuda-sample.yaml
执行以下命令,查看显存和算力的使用情况。
kubectl exec -ti cuda-sample-m**** -- nvidia-smi
预期输出:
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 450.102.04 Driver Version: 450.102.04 CUDA Version: 11.0 |
|-------------------------------+----------------------+----------------------+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|===============================+======================+======================|
| 0 Tesla V100-SXM2... On | 00000000:00:08.0 Off | 0 |
| N/A 33C P0 56W / 300W | 337MiB / 2154MiB | 30% Default |
| | | N/A |
+-------------------------------+----------------------+----------------------+
+-----------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=============================================================================|
+-----------------------------------------------------------------------------+
由预期输出得到:未开启算力分配功能前,Pod能够使用的总显存为该GPU卡的总显存,本文为15 GiB(在节点上执行nvidia-smi
命令即可查询GPU卡的总显存)。开启算力分配功能后,Pod当前已使用337 MiB,能够使用的总显存为2154 MiB(约为2 GiB),说明显存隔离生效。
使用以下命令,查看Pod日志。
kubectl logs cuda-sample-m**** -f
预取输出Pod日志刷新较慢,刷新速度约为不作算力限制的30%,此时算力被限制在该GPU卡的30%左右。