更新时间:2025-08-27 GMT+08:00

GPU虚拟化多卡均分调度

在AI训练、推理和科学计算中,单张GPU常因算力或显存不足无法满足需求,因此需要多张GPU卡协同工作。然而,使用多张GPU卡协同工作时,直接分配整张GPU可能导致资源浪费,尤其是当任务仅需使用部分显存或算力时。GPU虚拟化的多卡均分调度功能允许任务跨多张GPU卡分配显存和计算力,实现更高效的资源利用。

多卡均分调度是一种资源调度策略,可将任务申请的GPU资源(如显存、算力)均匀分配至多张GPU卡上,从而提升资源利用率并减少浪费。通过多卡均分调度,一个Pod可以灵活使用多张GPU,且每张GPU提供等量资源,实现GPU资源的精细化分配与高效利用。目前,多卡均分调度支持显存隔离(设置volcano.sh/gpu-mem.128Mi资源)和算显隔离(同时设置volcano.sh/gpu-mem.128Mi和volcano.sh/gpu-core.percentage资源)两种模式,具体说明如下:

  • 显存隔离模式:支持将任务所需的显存资源拆分到多张GPU卡上,实现跨卡显存共享。例如,当某应用申请M MiB显存并指定由N张GPU卡(需位于同一GPU节点)分配时,系统会将M MiB显存均匀分配至N张GPU卡。在任务执行过程中,每张GPU卡仅能使用其分配的M/N MiB显存,从而实现任务间的显存隔离,避免资源争用。
  • 算显隔离模式:支持将任务所需的算力和显存资源拆分到多张GPU卡上,实现计算能力和显存资源跨卡共享。例如,某应用申请M MiB显存和T%算力,并指定由N张GPU卡(需位于同一GPU节点)分配时,系统会将M MiB显存及T%的算力均匀分配至N张GPU卡。在任务执行过程中,每张GPU仅能使用其分配的M/N MiB显存以及T/N%算力。

在GPU虚拟化场景中,显存分配(MiB)必须为128的整数倍,因此M/N(每卡显存)需满足该条件;同时,算力分配(百分比)必须为5的整数倍,因此T/N(每卡算力)也需是5的倍数。

前提条件

  • 已有一个CCE Standard或CCE Turbo集群,且集群版本在1.27.16-r20、1.28.15-r10、1.29.10-r10、1.30.6-r10、v1.31.4-r0及以上。
  • 已安装CCE AI套件(NVIDIA GPU)插件,具体安装步骤请参见CCE AI套件(NVIDIA GPU)。同时,插件版本需符合以下要求:
    • 集群版本在1.27及以下时:插件版本要求在2.1.41及以上。
    • 集群版本在1.28及以上时:插件版本要求在2.7.57及以上。
  • 集群中已有GPU节点,且已开启集群或节点池级别的GPU虚拟化,具体操作步骤请参见准备GPU虚拟化资源
  • 已安装Volcano调度器插件,且插件版本在1.16.10及以上,具体安装步骤请参见Volcano调度器

约束与限制

  • 多卡均分调度暂不兼容Kubernetes默认GPU调度模式(支持使用nvidia.com/gpu资源的工作负载)。
  • 在多卡均分调度场景下,不支持进行集群内节点池弹性伸缩。如果开启节点池弹性伸缩功能,扩容结果不可控。

多卡均分调度使用示例

创建多卡均分调度工作负载时,支持使用控制台和kubectl命令行的方式,具体如下:

  1. 登录CCE控制台,单击集群名称进入集群。在左侧导航栏单击“工作负载”,右上角单击“创建工作负载”。
  2. “容器配置 > 基本信息 >GPU配额”中选择GPU虚拟化。在下方开启“多卡均分调度”,具体参数说明请参见表1

    “多卡均分调度”与“卡数”为容器共用配置,修改后将对负载的所有容器生效。

    图1 多卡均分调度
    表1 多卡均分调度参数说明

    参数

    示例

    说明

    卡数

    1

    必填项,表示多卡均分调度的GPU卡数量。

    总显存

    128

    必填项,表示申请的GPU显存值,单位为MiB,需为正整数,且为128的倍数。若配置的显存超过GPU卡的显存总和,将会出现无法调度状况。

    总算力

    5

    非必填项,表示申请的GPU显存算力值,单位为%,需为5的倍数,具体的取值范围与卡数有关。

    • 不填该参数时,表示该容器使用显存隔离模式。
    • 填写该参数时,表示该容器使用算显隔离模式。

  3. 其他参数请参考创建工作负载进行配置。参数配置完成后,在右下角单击“创建工作负载”。待工作负载变为运行中后,则表示创建成功。

以显存隔离模式为例,向您介绍如何创建使用多卡均分调度功能的工作负载。在该工作负载中,Pod数量设置为1,申请显存为8GiB,并指定使用2张GPU卡,则每张GPU卡将分配4GiB的显存。创建工作负载后,系统会自动将该工作负载调度至满足条件的GPU节点。

  1. 使用kubectl连接集群。
  2. 执行以下命令,创建一个YAML文件,用于创建需要GPU虚拟化多卡均分调度的工作负载。
    vim gpu-app.yaml

    文件内容如下:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: gpu-app
      namespace: default
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: gpu-app
      template:
        metadata:
          labels:
            app: gpu-app
            volcano.sh/gpu-num: '2'    # 指定多卡均分调度的GPU卡数量,此例中Pod申请2卡,每卡占据4GB显存  
        spec:
          schedulerName: volcano
          containers:
          - image: <your_image_address>     # 请替换为您的镜像地址
            name: container-0
            resources:
              requests:
                cpu: 250m
                memory: 512Mi
                volcano.sh/gpu-mem.128Mi: '64' # 表示申请的显存量,64表示申请8GiB的显存,即64*128MiB/1024=8GiB
              limits:
                cpu: 250m
                memory: 512Mi
                volcano.sh/gpu-mem.128Mi: '64' # 表示显存的使用上限,值为8GiB
          imagePullSecrets:
          - name: default-secret

    如果需要使用算显隔离模式,请在resources.requests和resources.limits字段中配置volcano.sh/gpu-core.percentage参数,如volcano.sh/gpu-core.percentage: '5',用于为Pod分配GPU算力。

  3. 执行以下命令,创建工作负载。
    kubectl apply -f gpu-app.yaml

    回显结果如下,则说明工作负载已创建。

    deployment.apps/gpu-app created
  4. 执行以下命令,查看已创建的Pod名称。
    kubectl get pod -n default

    回显结果如下:

    NAME                      READY   STATUS    RESTARTS   AGE
    gpu-app-6bdb4d7cb-pmtc2   1/1     Running   0          21s
  5. 登录Pod,查看Pod被分配显存总量。
    kubectl exec -it gpu-app-6bdb4d7cb-pmtc2 -- nvidia-smi

    预期输出:

    Fri Mar  7 03:36:03 2025
    +---------------------------------------------------------------------------------------+
    | NVIDIA-SMI 535.216.03             Driver Version: 535.216.03   CUDA Version: 12.2     |
    |-----------------------------------------+----------------------+----------------------+
    | 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 T4                       Off | 00000000:00:0D.0 Off |                    0 |
    | N/A   33C    P8               9W /  70W |      0MiB /  4096MiB |      0%      Default |
    |                                         |                      |                  N/A |
    +-----------------------------------------+----------------------+----------------------+
    |   1  Tesla T4                       Off | 00000000:00:0E.0 Off |                    0 |
    | N/A   34C    P8               9W /  70W |      0MiB /  4096MiB |      0%      Default |
    |                                         |                      |                  N/A |
    +-----------------------------------------+----------------------+----------------------+
    +---------------------------------------------------------------------------------------+
    | Processes:                                                                            |
    |  GPU   GI   CI        PID   Type   Process name                            GPU Memory |
    |        ID   ID                                                             Usage      |
    |=======================================================================================|
    |  No running processes found                                                           |
    +---------------------------------------------------------------------------------------+

    预期输出表明,Pod可使用的GPU卡为2张,每张可使用4096MiB/1024=4GiB的显存。由此可见,Pod申请的显存资源已被平均分配至2张GPU卡,且每张GPU卡的显存资源已隔离。

其他说明

在为XGPU业务分配GPU显存或算力资源时,节点内的多张GPU卡默认采用装箱调度策略,以尽量减少资源碎片、提升集群整体资源利用率。此时,在下发多卡均分调度作业时,可能出现节点空闲资源总量满足需求,但因可用GPU卡数不足,导致作业处于Pending状态的情况,此为正常现象。

例如,某节点上有3张GPU卡存在空闲资源(编号为0、1和2),其剩余显存分别为4GiB、4GiB 和8GiB。当前存在一个工作负载,副本数为2,每个Pod需申请2张GPU卡,且每卡需提供4GiB显存。从总资源看,节点3张卡的剩余显存总和(4+4+8=16GiB)能够满足2个Pod的需求(2×2×4=16GiB)。但按装箱调度原则,系统会先将第一个Pod分配到0卡和1卡(刚好满足2卡和4GiB的需求)。此时节点仅剩一张空闲卡(2卡),虽然该卡拥有8 GiB显存,但因第二个Pod需同时占用两张GPU卡,节点已无足够GPU卡数,最终将会导致该副本调度失败,进而导致整个工作负载无法调度至该节点。