
# 手动实现NPU静态虚拟化
在CCE中，可通过手动配置实现对每张NPU卡的资源分配，提供更高的灵活性。然而，该方式的配置过程相对复杂，更适合对NPU资源使用有精细化需求的场景（如特定算力分配、资源隔离要求严格的业务）。
#### 前提条件
- 集群中已有支持虚拟化的NPU芯片，具体请参见[适用的NPU芯片类型](https://support.huaweicloud.com/usermanual-cce/cce_10_1009.html#cce_10_1009__section34222017365)。
- 集群中已安装CCE AI套件（Ascend NPU）插件，且版本在2.1.15及以上，具体安装步骤请参见[CCE AI套件（Ascend NPU）](https://support.huaweicloud.com/usermanual-cce/cce_10_0239.html)。
- NPU节点上已安装NPU驱动，且驱动版本在23.0.1及以上。
  ![](https://support.huaweicloud.com/usermanual-cce/public_sys-resources/caution_3.0-zh-cn.png)
  - 驱动升级时要求节点上有配套的NPU固件，**重新安装驱动将涉及节点重启** ，建议在安装驱动前排空节点，具体操作请参见[节点排水](https://support.huaweicloud.com/usermanual-cce/cce_10_0605.html)。虚拟机不支持固件升级。
  
  - 驱动升级时，如需在操作系统范围内为所有用户安装驱动，请配合使用--install-for-all参数，例如./Ascend-hdk-310p-npu-driver_*x.x.x* _linux-*{arch}*.run --full --install-for-all。
  
  - 如果驱动升级失败，请查看文档"常见问题 \> 模板插件 \> NPU驱动升级失败如何解决？"。
    
 
#### 约束与限制
- 目前，仅昇腾Snt3P3的虚拟化特性经过CCE验证，其他芯片类型是否支持算力切分请参见[虚拟化特性说明](https://www.hiascend.com/document/detail/zh/mindcluster/71RC1/clustersched/dlug/cpaug_0010.html)。
- 昇腾AI产品内已内置虚拟化模板，进行NPU静态虚拟化时，仅支持按照预定义的虚拟化模板规格进行虚拟化操作，具体模板信息请参见[虚拟化模板](https://www.hiascend.com/document/detail/zh/computepoweralloca/300/cpaug/cpaug/cpaug_00005.html)。昇腾AI产品支持虚拟化实例的灵活组合，即在同一张NPU芯片上，可以使用不同的虚拟化模板划分多个vNPU，各vNPU占用的资源总量不得超过该NPU卡的硬件上限。官方已给出推荐的组合模板，您可以根据需求进行灵活组合，具体请参见[虚拟化实例组合](https://www.hiascend.com/document/detail/zh/computepoweralloca/300/cpaug/cpaug/cpaug_00006.html)。
 
#### 步骤一：手动切分vNPU
CCE Standard/Turbo集群支持手动切分vNPU，您可以根据需求灵活配置。
1. 登录待切分节点，并[通过kubectl连接集群](https://support.huaweicloud.com/usermanual-cce/cce_10_0107.html)。
2. 执行以下命令，查看节点中的NPU设备的基本信息。该命令可查询NPU驱动版本、芯片型号及资源利用率等关键信息，为vNPU规格规划提供相关依据。 
   ```
   npu-smi info
   ```
   由回显结果可知，驱动版本为24.1.rc2.3，并且内部有2张NPU卡，每张卡中有1个NPU芯片，其中NPU卡设备ID分别为104和112。
   ```
   +--------------------------------------------------------------------------------------------------------+ 
   | npu-smi 24.1.rc2.3                               Version: 24.1.rc2.3                                   |
   +-------------------------------+-----------------+------------------------------------------------------+ 
   | NPU     Name                  | Health          | Power(W)     Temp(C)           Hugepages-Usage(page) |
   | Chip    Device                | Bus-Id          | AICore(%)    Memory-Usage(MB)                        |
   +===============================+=================+======================================================+ 
   | 104     xxx                 | OK              | NA           58                0     / 0             |
   | 0       0                     | 0000:00:0D.0    | 0            1782 / 21527                            |
   +===============================+=================+======================================================+ 
   | 112     xxx                 | OK              | NA           53                0     / 0             |
   | 0       1                     | 0000:00:0E.0    | 0            1786 / 21527                            |
   +===============================+=================+======================================================+
   +-------------------------------+-----------------+------------------------------------------------------+ 
   | NPU     Chip                  | Process id      | Process name             | Process memory(MB)        |
   +===============================+=================+======================================================+
   | No running processes found in NPU 104                                                                  |
   +===============================+=================+======================================================+ 
   | No running processes found in NPU 112                                                                  |
   +===============================+=================+======================================================+
   ```
   
   
3. 执行以下命令，查询当前节点支持的虚拟化模板，以及各模板使用的资源规格。您可以根据需求，按照一个或多个模板进行vNPU切分。
   
   ```
   npu-smi info -t template-info
   ```
   回显结果如下，其中vir01、vir02、vir02_1c等表示模板名称。不同产品可以使用的模板不同，具体请以回显结果为准。
   ```
   +------------------------------------------------------------------------------------------+ 
   |NPU instance template info is:                                                            |
   |Name                AICORE    Memory    AICPU     VPC            VENC           JPEGD     |
   |                               GB                 PNGD           VDEC           JPEGE     |
   |==========================================================================================|
   |vir01               1         3         1         1              0              2         |
   |                                                  0              1              1         |
   +------------------------------------------------------------------------------------------+ 
   |vir02               2         6         2         3              1              4         |
   |                                                  0              3              2         |
   +------------------------------------------------------------------------------------------+ 
   |vir02_1c            2         6         1         3              0              4         |
   |                                                  0              3              2         |
   +------------------------------------------------------------------------------------------+ 
   |vir04               4         12        4         6              2              8         |
   |                                                  0              6              4         |
   +------------------------------------------------------------------------------------------+ 
   |vir04_3c            4         12        3         6              1              8         |
   |                                                  0              6              4         |
   +------------------------------------------------------------------------------------------+ 
   |vir04_3c_ndvpp      4         12        3         0              0              0         |
   |                                                  0              0              0         |
   +------------------------------------------------------------------------------------------+ 
   |vir04_4c_dvpp       4         12        4         12             3              16        |
   |                                                  0              12             8         |
   +------------------------------------------------------------------------------------------+
   ```
   
   
4. 执行**npu-smiset-tcreate-vnpu-i*\<id\>* -c*\<chip_id\>* -f*\<vnpu_config\>* *\[-vnpu_id\]* *\[-gvgroup_id\]*** 命令，创建vNPU。
   
   ```
   npu-smi set -t create-vnpu -i 104 -c 0 -f vir02
   ```
   表1参数说明 
   | 参数          | 示例        | 说明                                                                                                                                                                                                          |
   |:---|:---|:---|
   | id          | **104**   | 表示设备ID，即NPU卡的ID。 获取方式：通过**npu-smi info -l**命令查出的NPU ID即为设备id。                                                                                                                  |
   | chip_id     | **0**     | 表示芯片ID，即NPU芯片的ID。 获取方式：通过**npu-smi info -m**命令查出的Chip ID即为芯片id。                                                                                                                 |
   | vnpu_config | **vir02** | 表示使用的虚拟化模板的名称，具体请参见[2]。                                                                                                                                                         |
   | vnpu_id     | **-**     | 可选参数，用于指定待创建vNPU的ID。                                                                                                                                                                                        |
   | vgroup_id   | **-**     | 可选参数，虚拟资源组（vGroup）的id，取值范围0\~3，**仅适用于Atlas推理系列产品**。 关于vGroup的详细介绍，请参见[虚拟化模式](https://www.hiascend.com/document/detail/zh/computepoweralloca/300/cpaug/cpaug/cpaug_00007.html)。 |
      
   回显结果如下，则说明vNPU创建成功。
   ```
   Status                         : OK        
   Message                        : Create vnpu success
   ```
   
   
5. 依次执行以下命令，将vNPU恢复状态配置为使能状态。配置完成后，节点重启时，系统能够保存vNPU的配置信息，确保重启后vNPU仍有效。 
   1. 执行以下命令，开启vNPU的恢复使能状态。当命令中的1改为0时，表示关闭vNPU恢复使能状态。
      ```
      npu-smi set -t vnpu-cfg-recover -d 1
      ```
      回显结果如下：
      ```
      Status : OK
      Message : The VNPU config recover mode Enable is set successfully.
      ```
      
   
   2. 执行以下命令，查看当前环境中vNPU恢复使能状态是否开启成功。
      ```
      npu-smi info -t vnpu-cfg-recover
      ```
      回显结果如下，则说明开启成功。
      ```
      VNPU config recover mode : Enable
      ```
      
   
   
   
   
6. 执行以下命令，查看已创建的vNPU，以及当前NPU芯片中的剩余资源。其中，104表示NPU ID，0表示Chip ID，请根据实际情况进行替换。 
   ```
   npu-smi info -t info-vnpu -i 104 -c 0
   ```
   由回显结果可知，现有的vNPU数量为1，ID为100，且使用的模板为vir02。当前NPU芯片中，AICore、Memory等剩余资源与vir02模板中各资源之和与该NPU芯片物理总资源相等。在进行vNPU虚拟化时，同一张NPU芯片上的所有vNPU的某类资源使用之和不能超过该NPU芯片中该类资源的物理上限。
   ```
   +-------------------------------------------------------------------------------+ 
   | NPU resource static info as follow:                                           |
   | Format:Free/Total                   NA: Currently, query is not supported.    |
   | AICORE    Memory    AICPU    VPC    VENC    VDEC    JPEGD    JPEGE    PNGD    |
   |            GB                                                                 |
   |===============================================================================|
   | 6/8       15/21     5/7      9/12   2/3     9/12    12/16    6/8      NA/NA   |
   +-------------------------------------------------------------------------------+ 
   | Total number of vnpu: 1                                                       |
   +-------------------------------------------------------------------------------+
   |  Vnpu ID  |  Vgroup ID     |  Container ID  |  Status  |  Template Name       |
   +-------------------------------------------------------------------------------+ 
   |  100      |  0             |  000000000000  |  0       |  vir02               |
   +-------------------------------------------------------------------------------+
   ```
   
   
 
#### 步骤二：重启组件并查看资源上报情况
切分vNPU后，需要重启该节点的huawei-npu-device-plugin组件，将NPU资源上报至k8s。
1. 执行以下命令，查询huawei-npu-device-plugin组件涉及的所有Pod。 
   ```
   kubectl get pods -A -o wide | grep huawei-npu-device-plugin
   ```
   回显结果如下，加粗部分表示节点的IP地址，请根据节点IP地址删除对应的Pod，以重启该节点的huawei-npu-device-plugin组件。在本示例中，被虚拟化的节点IP地址为192.168.2.27。
   ```
   kube-system   huawei-npu-device-plugin-8lq64            1/1     Running   2 (4d7h ago)   4d8h   192.168.0.9     192.168.0.9     <none>           <none>
   kube-system   huawei-npu-device-plugin-khkvr            1/1     Running   0              4d8h   192.168.0.131   192.168.0.131   <none>           <none>
   kube-system   huawei-npu-device-plugin-rltx4            1/1     Running   0              4d8h   192.168.7.56    192.168.7.56    <none>           <none>
   kube-system   huawei-npu-device-plugin-t9vxx            1/1     Running   1 (4d8h ago)   4d8h   192.168.0.72    192.168.0.72    <none>           <none>
   kube-system   huawei-npu-device-plugin-c6x7            1/1     Running   0              3d2h   192.168.2.27    192.168.2.27    <none>           <none>
   ```
   
   
2. 执行以下命令，删除对应Pod。 
   ```
   kubectl delete pod -n kube-system huawei-npu-device-plugin-c6x7
   ```
   回显结果如下，则说明删除成功。
   ```
   pod "huawei-npu-device-plugin-c6x7" deleted
   ```
   
   
3. 执行以下命令，查询vNPU资源的上报数量。一张完整的NPU芯片经过切分之后，只有创建出的vNPU是上报可用的，**剩余的资源将无法被上报k8s进行使用** 。
   
   ```
   kubectl describe node 192.168.2.27
   ```
   由回显结果可知，整卡资源的上报数量为1，vNPU资源上报数量为1，说明一个NPU芯片已被虚拟化切分，另一个NPU芯片仍为整卡状态。
   ```
   ... ... 
   Capacity: 
     cpu:                       32
     ephemeral-storage:         102683576Ki
     huawei.com/ascend-310:     1   # 整卡资源
     huawei.com/ascend-310-2c:  1   # vNPU数量
     hugepages-1Gi:             0
     hugepages-2Mi:             0
     localssd:                  0
     localvolume:               0
     memory:                    131480656Ki
     pods:                      110
   Allocatable: 
     cpu:                       31850m 
     ephemeral-storage:         94633183485 
     huawei.com/ascend-310:     1   # 整卡资源
     huawei.com/ascend-310-2c:  1   # vNPU数量
     hugepages-1Gi:             0
     hugepages-2Mi:             0
     localssd:                  0
     localvolume:               0
     memory:                    126616656Ki 
     pods:                      110
   ... ...
   ```
   
   
 
#### 步骤三：使用vNPU
在创建vNPU之后，工作负载可以通过YAML格式申请vNPU资源，从而实现资源的高效管理和灵活配置。如果需要使用Volcano调度器，则需要安装1.12.1及以上版本的Volcano调度器插件。
1. 依次执行以下命令，创建工作负载，并申请一个vir02模板的vNPU资源。 
   1. 执行以下命令，创建名为vnpu-worker的YAML文件。
      ```
      vim vnpu-worker.yaml
      ```
      文件内容如下，**容器中只支持申请NPU资源或者vNPU资源，二者不可以同时使用**。
      ![](https://support.huaweicloud.com/usermanual-cce/public_sys-resources/note_3.0-zh-cn.png)
      使用vNPU资源时，需确保该vNPU资源已存在。如果该vNPU资源未创建，则会报错，例如"0/2 nodes are available: 2 Insufficient huawei.com/ascend-310-2c"。
      ```
      kind: Deployment
      apiVersion: apps/v1
      metadata:
        name: vnpu-test
        namespace: default
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: vnpu-test
        template:
          metadata:
            labels:
              app: vnpu-test
          spec:
            schedulerName: kube-scheduler    # 该工作负载需要使用volcano调度器时，则需要安装volcano插件，且版本在1.12.1及以上
            containers:
              - name: container-0
                image: nginx:latest
                resources:
                  limits:
                    cpu: 250m
                    huawei.com/ascend-310-2c: '1'   # 表示申请的vNPU资源，固定为1
                    memory: 512Mi
                  requests:
                    cpu: 250m
                    huawei.com/ascend-310-2c: '1'   # 固定为1
                    memory: 512Mi
      ```
      - 容器只支持申请一个vNPU资源，因此requests和limits里的vNPU资源数量固定为1。
      
      - 指定的vNPU资源请在节点中提前创建，且保证资源充足。当vNPU资源不足时，会出现类似"0/2 nodes are available: 2 Insufficient huawei.com/ascend-310-2c."的报错。
      
      - huawei.com/ascend-310-2c表示申请vNPU资源名称，不同产品和模板对应的vNPU资源名称不同，具体映射关系如下：
        表2vNPU资源名称 
        | **产品类型**                                                                                       | **虚拟化模板**      | **vNPU资源名称**                        |
        |:---|:---|:---|
        | Atlas推理系列产品（8个AI Core）       | vir01          | huawei.com/ascend-310-1c            |
        | Atlas推理系列产品（8个AI Core）       | vir02          | huawei.com/ascend-310-2c            |
        | Atlas推理系列产品（8个AI Core）       | vir02_1c       | huawei.com/ascend-310-2c.1cpu       |
        | Atlas推理系列产品（8个AI Core）       | vir04          | huawei.com/ascend-310-4c            |
        | Atlas推理系列产品（8个AI Core）       | vir04_3c       | huawei.com/ascend-310-4c.3cpu       |
        | Atlas推理系列产品（8个AI Core）       | vir04_3c_ndvpp | huawei.com/ascend-310-4c.3cpu.ndvpp |
        | Atlas推理系列产品（8个AI Core）       | vir04_4c_dvpp  | huawei.com/ascend-310-4c.4cpu.dvpp  |
        | Ascend训练系列产品（30或32个AI Core）                          | vir16          | huawei.com/ascend-1980-16c          |
        | Ascend训练系列产品（30或32个AI Core）                          | vir08          | huawei.com/ascend-1980-8c           |
        | Ascend训练系列产品（30或32个AI Core）                          | vir04          | huawei.com/ascend-1980-4c           |
        | Ascend训练系列产品（30或32个AI Core）                          | vir02          | huawei.com/ascend-1980-2c           |
           
        
       
   
   2. 执行以下命令，创建上述工作负载。
      ```
      kubectl apply -f vnpu-worker.yaml
      ```
      回显结果如下：
      ```
      deployment/vnpu-test created
      ```
      
   
   3. 执行以下命令，查看Pod是否运行成功。
      ```
      kubectl get pod | grep vnpu-test
      ```
      回显结果如下，则说明工作负载中的Pod运行成功。
      ```
      vnpu-test-6658cd795b-rx76t      1/1     Running     0       59m
      ```
      
   
   
   
   
2. 执行以下命令，登录容器内部。 
   ```
   kubectl -n default exec -it vnpu-test-6658cd795b-rx76t -c container-0 -- /bin/bash
   ```
   
   
3. 在容器内依次执行以下命令，查看vNPU是否挂载成功。 
   1. 执行以下命令，配置环境变量，用于指定动态链接库的搜索路径，确保在运行与NPU相关的应用时，系统能够正确加载所需的动态库文件。
      ```
      export LD_LIBRARY_PATH=/usr/local/HiAI/driver/lib64:/usr/local/Ascend/driver/lib64/common:/usr/local/Ascend/driver/lib64/driver:/usr/local/Ascend/driver/lib64
      ```
      
   
   2. 执行以下命令，查看容器挂载的NPU信息，以确认是否成功挂载vNPU资源。
      ```
      npu-smi info
      ```
      由回显结果可知，该容器已挂载设备ID为104的NPU卡中的vNPU，且虚拟化模板为vir02**。**
      ```
      +--------------------------------------------------------------------------------------------------------+
      | npu-smi 24.1.rc2.3                               Version: 24.1.rc2.3                                   |
      +-------------------------------+-----------------+------------------------------------------------------+
      | NPU     Name                  | Health          | Power(W)     Temp(C)           Hugepages-Usage(page) |
      | Chip    Device                | Bus-Id          | AICore(%)    Memory-Usage(MB)                        |
      +===============================+=================+======================================================+
      | 104     xxx             | OK              | NA           54                0     / 0             |
      | 0       0                     | 0000:00:0D.0    | 0            445  / 5381                             |
      +===============================+=================+======================================================+
      +-------------------------------+-----------------+------------------------------------------------------+
      | NPU     Chip                  | Process id      | Process name             | Process memory(MB)        |
      +===============================+=================+======================================================+
      | No running processes found in NPU 104                                                                  |
      +===============================+=================+======================================================+
      ```
      
   
   
   
   
 
#### 步骤四：销毁vNPU
当不再使用某vNPU资源时，可以对其执行销毁操作，释放相关资源。进行销毁操作前，请确保没有任务正在使用待销毁的vNPU，否则将销毁失败。
1. 执行**npu-smi set -t destroy-vnpu -i *\<id\>* -c *\<chip_id\>* -v *\<vnpu_id\>*** 命令，销毁指定vNPU。
   
   ```
   npu-smi set -t destroy-vnpu -i 104 -c 0 -v 100
   ```
   - 回显结果如下，则说明命令执行成功。
     ```
     Status                         : OK 
     Message                        : Destroy vnpu 100 success
     ```
     
   
   - 回显结果如下，则说明存在任务正在使用待销毁的vNPU。请确保没有任务使用待销毁的vNPU后，再次执行销毁命令。
     ```
     destroy vnpu 100 failed.
     Usage: npu-smi set -t destroy-vnpu [Options...] 
     Options: 
            -i %d              Card ID     
            -c %d              Chip ID  
            -v %d              Vnpu ID
     ```
     
   
   
   
   
2. 执行销毁命令后，您需要重启对应节点的huawei-npu-device-plugin组件，将销毁信息上报k8s。具体步骤如下： 
   1. 执行以下命令，查询huawei-npu-device-plugin组件涉及的所有Pod。
      ```
      kubectl get pods -A -o wide | grep huawei-npu-device-plugin
      ```
      回显结果如下，加粗部分表示节点的IP地址，请根据节点IP地址删除对应的Pod，以重启该节点的huawei-npu-device-plugin组件。在本示例中，被虚拟化的节点IP地址为192.168.2.27。
      ```
      kube-system   huawei-npu-device-plugin-8lq64            1/1     Running   2 (4d7h ago)   4d8h   192.168.0.9     192.168.0.9     <none>           <none>
      kube-system   huawei-npu-device-plugin-khkvr            1/1     Running   0              4d8h   192.168.0.131   192.168.0.131   <none>           <none>
      kube-system   huawei-npu-device-plugin-rltx4            1/1     Running   0              4d8h   192.168.7.56    192.168.7.56    <none>           <none>
      kube-system   huawei-npu-device-plugin-t9vxx            1/1     Running   1 (4d8h ago)   4d8h   192.168.0.72    192.168.0.72    <none>           <none>
      kube-system   huawei-npu-device-plugin-tcmck            1/1     Running   0              3d2h   192.168.2.27    192.168.2.27    <none>           <none>
      ```
      
   
   2. 执行以下命令，删除对应Pod。
      ```
      kubectl delete pod -n kube-system huawei-npu-device-plugin-tcmck
      ```
      回显结果如下，则说明删除成功。
      ```
      pod "huawei-npu-device-plugin-tcmck" deleted
      ```
      
   
   
   
   
3. 执行以下命令，验证vNPU是否销毁成功。当整卡资源上报数量恢复时，则说明销毁成功。 
   ```
   kubectl describe node 192.168.2.27
   ```
   由回显结果可知，整卡资源的上报数量恢复为2，vNPU资源上报数量为0，说明vNPU资源销毁成功。
   ```
   ... ... 
   Capacity: 
     cpu:                       32
     ephemeral-storage:         102683576Ki
     huawei.com/ascend-310:     2
     huawei.com/ascend-310-2c:  0
     hugepages-1Gi:             0
     hugepages-2Mi:             0
     localssd:                  0
     localvolume:               0
     memory:                    131480656Ki
     pods:                      110
   Allocatable: 
     cpu:                       31850m 
     ephemeral-storage:         94633183485 
     huawei.com/ascend-310:     2
     huawei.com/ascend-310-2c:  0
     hugepages-1Gi:             0
     hugepages-2Mi:             0
     localssd:                  0
     localvolume:               0
     memory:                    126616656Ki 
     pods:                      110
   ... ...
   ```
   
   
 
