
# 创建GPU应用
本文介绍如何使用GPU虚拟化能力实现算力和显存隔离，高效利用GPU设备资源。
#### 前提条件
- 已完成[GPU虚拟化资源准备](https://support.huaweicloud.com/usermanual-ucs/ucs_01_0297.html)。
- 如果您需要通过命令行创建，需要使用kubectl连接到集群，详情请参见[通过kubectl连接集群](https://support.huaweicloud.com/usermanual-ucs/ucs_01_0320.html)。
 
#### 约束与限制
- init容器不支持进行GPU虚拟化。

- 对于单张GPU卡：
  - 最多虚拟化为20个GPU虚拟设备。
  
  - 最多调度20个使用隔离能力的Pod。
  
  - 仅支持调度相同隔离模式（GPU虚拟化支持显存隔离、显存与算力隔离两种隔离模式。）的工作负载。
   
- 对于同一工作负载中的不同容器：
  - 仅支持配置单一显卡型号，不支持混合配置两种及以上GPU显卡型号。
  
  - 仅支持配置一致GPU使用模式，不支持混合配置虚拟化和非虚拟化模式。
   
- 使用GPU虚拟化后，该GPU节点不再支持调度使用[++共享GPU资源++](https://support.huaweicloud.com/usermanual-cce/cce_10_0345.html)的工作负载。
 
#### 通过控制台创建GPU应用
1. 登录[UCS控制台](https://console.huaweicloud.com/ucs/?#/aether/dashboard)。
2. 单击集群名称进入集群，在左侧选择"工作负载"，在右上角单击"镜像创建"。
3. 配置工作负载信息。在"容器配置\>基本信息"中选择异构资源为GPU，然后选择资源使用模式： 
   ![](https://support.huaweicloud.com/usermanual-ucs/zh-cn_image_0000002137360317.png "点击放大")
   - 整卡模式：整卡模式采用 Kubernetes 默认的调度方式，将 Pod 调度至满足 GPU 资源需求的节点上。
   
   - 共享模式：共享模式可将多个 Pod 调度至同一张 GPU 卡上抢占式运行，负载资源使用率波动较大时能提高空闲 GPU 资源使用率
   
   - 虚拟化模式：采用自研的 GPU 虚拟化技术，能够动态对 GPU 设备显存与算力进行划分，提高 GPU 资源利用率
   
   
   ![](https://support.huaweicloud.com/usermanual-ucs/public_sys-resources/note_3.0-zh-cn.png)
   GPU资源使用模式:
   - 整卡模式：单个Pod独享整张显卡，可填1-10，取决于节点显卡数量。
   
   - 共享模式：多个Pod共享显卡，此处配置单个Pod使用显卡的百分比。不支持跨GPU分配，如50%单显卡只会分配到一张卡上。
   
   
   GPU虚拟化模式：
   - 显存：GPU虚拟化配置项。显存值单位为Mi，需为128的整数倍，最小值为128Mi，若配置的显存超过单张GPU卡的显存，将会出现无法调度状况。
   
   - 算力：GPU虚拟化配置项。算力值单位为%，需为5的倍数，且最大不超过100。算力可以不填写，不填表示显存隔离算力共享。
    
   
   
4. 其余信息都配置完成后，单击"创建"。
 
#### 通过kubectl命令行创建GPU应用
1. 使用kubectl连接集群。
2. 创建使用GPU的应用。 
   创建gpu-app.yaml文件，内容如下：
   - 静态分配
     ```
     apiVersion: apps/v1
     kind: Deployment
     metadata:
       name: gpu-app
       namespace: default
       labels:
         app: gpu-app
     spec:
       replicas: 1
       selector:
         matchLabels:
           app: gpu-app
       template: 
         metadata:
           labels:
             app: gpu-app
         spec:
           containers:
           - name: container-1
             image: <your_image_address>     # 请替换为您的镜像地址
             resources:
               limits:
                 nvidia.com/gpu: 200m        # 申请0.2 张卡，取值为1表示独享，小于1表示共享
          schedulerName: volcano            # 开启GPU虚拟化特性但未使用，需指定volcano调度器
           imagePullSecrets:
             - name: default-secret
     ```
     ![](https://support.huaweicloud.com/usermanual-ucs/public_sys-resources/note_3.0-zh-cn.png)
     当前支持隔离显存或同时隔离显存与算力，暂不支持设置为仅隔离算力，即不支持单独设置volcano.sh/gpu-core.percentage。
     
   
   - 仅隔离显存：
     ```
     apiVersion: apps/v1
     kind: Deployment
     metadata:
       name: gpu-app
       namespace: default
       labels:
         app: gpu-app
     spec:
       replicas: 1
       selector:
         matchLabels:
           app: gpu-app
       template: 
         metadata:
           labels:
             app: gpu-app
         spec:
           containers:
           - name: container-1
             image: <your_image_address>      # 请替换为您的镜像地址
             resources:
               limits:
                 volcano.sh/gpu-mem.128Mi: 5  # 该Pod分配的显存大小，以128Mi为单位
           schedulerName: volcano            # 使用GPU虚拟化特性必须使用 volcano 调度器
           imagePullSecrets:
             - name: default-secret
     ```
     
   
   - 同时隔离显存与算力：
     ```
     apiVersion: apps/v1
     kind: Deployment
     metadata:
       name: gpu-app
       namespace: default
       labels:
         app: gpu-app
     spec:
       replicas: 1
       selector:
         matchLabels:
           app: gpu-app
       template: 
         metadata:
           labels:
             app: gpu-app
         spec:
           containers:
           - name: container-1
             image: <your_image_address>         # 请替换为您的镜像地址
             resources:
               limits:
                 volcano.sh/gpu-mem.128Mi: 5     # 该Pod分配的显存大小，以128MiB为单位
                 volcano.sh/gpu-core.percentage: 25    # 该Pod分配的算力大小
           schedulerName: volcano                 # 使用GPU虚拟化特性必须使用 volcano 调度器
           imagePullSecrets:
             - name: default-secret
     ```
     
   
   
   表1关键参数说明 
   | 参数                             | 是否必选 | 描述                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
   |:---|:---|:---|
   | nvidia.com/gpu                 | 否    | 通过 **nvidia.com/gpu** 指定申请GPU的数量，支持申请设置为小于1的数量，比如**nvidia.com/gpu: 0.5**，这样可以多个Pod共享使用GPU。GPU数量小于1时，不支持跨GPU分配，如0.5 GPU只会分配到一张卡上。 指定**nvidia.com/gpu**后，在调度时不会将负载调度到没有GPU的节点。如果缺乏GPU资源，会报类似如下的Kubernetes事件。 - 0/2 nodes are available: 2 Insufficient nvidia.com/gpu.  - 0/4 nodes are available: 1 InsufficientResourceOnSingleGPU, 3 Insufficient nvidia.com/gpu.   |
   | volcano.sh/gpu-mem.128Mi       | 否    | 显存值单位为128MiB，需为正整数，比如配置5，则表示128MiB\*5=640MiB。若配置的显存超过单张GPU卡的显存，将会出现无法调度状况。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
   | volcano.sh/gpu-core.percentage | 否    | 算力值单位为%，需为5的倍数，且最大不超过100。 暂不支持设置为仅隔离算力，即不支持单独设置volcano.sh/gpu-core.percentage。                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
      
   
   
3. 执行以下命令，创建应用。 
   ```
   kubectl apply -f gpu-app.yaml
   ```
   
   
 
#### 验证GPU虚拟化隔离能力
工作负载创建成功后，您可以尝试验证GPU虚拟化的隔离能力。
- 登录容器查看容器被分配显存总量
  ```
  kubectl exec -it gpu-app -- nvidia-smi
  ```
  预期输出：
  ```
  Wed Apr 12 07:54:59 2023
  +-----------------------------------------------------------------------------+
  | NVIDIA-SMI 470.141.03   Driver Version: 470.141.03   CUDA Version: 11.4     |
  |-------------------------------+----------------------+----------------------+
  | 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...  Off  | 00000000:21:01.0 Off |                    0 |
  | N/A   27C    P0    37W / 300W |   4792MiB /  5000MiB |      0%      Default |
  |                               |                      |                  N/A |
  +-------------------------------+----------------------+----------------------+
  +-----------------------------------------------------------------------------+
  | Processes:                                                                  |
  |  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
  |        ID   ID                                                   Usage      |
  |=============================================================================|
  +-----------------------------------------------------------------------------+
  ```
  预期输出表明，该容器被分配显存总量为**5000 MiB** ，实际使用了**4792MiB**。
  

- 查看所在节点的GPU显存隔离情况（在节点上执行）。
  ```
  export PATH=$PATH:/usr/local/nvidia/bin;nvidia-smi
  ```
  预期输出：
  ```
  Wed Apr 12 09:31:10 2023
  +-----------------------------------------------------------------------------+
  | NVIDIA-SMI 470.141.03   Driver Version: 470.141.03   CUDA Version: 11.4     |
  |-------------------------------+----------------------+----------------------+
  | 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...  Off  | 00000000:21:01.0 Off |                    0 |
  | N/A   27C    P0    37W / 300W |   4837MiB / 16160MiB |      0%      Default |
  |                               |                      |                  N/A |
  +-------------------------------+----------------------+----------------------+
  +-----------------------------------------------------------------------------+
  | Processes:                                                                  |
  |  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
  |        ID   ID                                                   Usage      |
  |=============================================================================|
  |    0   N/A  N/A    760445      C   python                           4835MiB |
  +-----------------------------------------------------------------------------+
  ```
  预期输出表明，GPU节点上的显存总量为**16160 MiB** ，其中示例Pod使用了**4837MiB**。
  
 
