阿里云GPU调度插件

阿里云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组件

  1. 登录容器服务管理控制台
  2. 在控制台左侧导航栏中,单击集群
  3. 集群列表页面中,单击目标集群名称或者目标集群右侧操作列下的详情
  4. 在集群管理页左侧导航栏中,选择*应用* > *云原生AI套件(公测)*
  5. 云原生AI套件页面,单击一键部署
  6. 在一键部署云原生AI套件页面,选中调度组件(批量任务调度、GPU共享、GPU拓扑感知、NPU调度),单击页面下方的部署云原生AI套件

步骤二:开启GPU共享调度能力和显存隔离能力

  1. 登录容器服务管理控制台
  2. 在控制台左侧导航栏中,单击集群
  3. 集群列表页面单击已安装ack-ai-installer组件集群操作列的节点池
  4. 节点池页面单击创建节点池
  5. 创建节点池页面,设置创建节点池的配置项,给节点配置

    • 如果开启GPU共享调度能力+GPU显存隔离能力。设置为ack.node.gpu.schedule,为cgpu。
    • 如果只需要节点池支持共享调度,不支持显存隔离,设置为ack.node.gpu.schedule,为share。 只共享不隔离策略,适配于已有深度学习应用内已自建应用层隔离能力的场景。
  6. 在节点上为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资源查询工具

  1. 配置kubeconfig文件。
  2. 下载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
  3. 为kubectl-inspect-cgpu添加执行权限。

    chmod +x /usr/local/bin/kubectl-inspect-cgpu
  4. 查看集群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。
  • 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%左右。

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注