NPU虚拟化
NPU虚拟化是指将通过资源虚拟化的方式将物理机中配置的NPU(昇腾AI产品)切分为多个虚拟NPU(vNPU),并挂载至容器中使用,以实现对硬件资源的灵活切分与动态管理。NPU虚拟化具有以下优势:
- 资源高效利用:单台服务器的NPU可被划分为多个vNPU,供不同用户按需申请,降低算力使用成本。
- 资源强隔离:基于容器化技术,确保不同用户的vNPU资源完全隔离,避免计算干扰或数据泄露。
- 统一管理:不同规格资源的分配和回收处理过程统一,方便多租户管理。
本文将为您介绍如何进行NPU虚拟化以及如何使用虚拟化。
NPU虚拟化基本原理
昇腾NPU硬件中包含AICore、AICPU和内存等核心计算资源。通过资源虚拟化技术,系统可以根据用户需求将这些物理资源灵活划分为多个vNPU,每个vNPU包含特定数量的AICore、AICPU和内存等资源。例如,一个容器申请4个AICore资源,另一个容器申请2个AICore,则系统将创建2个vNPU实例供容器使用,具体流程请参见图1。
前提条件
- 集群中已有支持虚拟化的NPU节点,具体请参见适用的节点规格。
- 集群中已安装CCE AI套件(Ascend NPU)插件,且版本在2.1.15及以上,具体安装步骤请参见CCE AI套件(Ascend NPU)。
- NPU节点上已安装NPU驱动,且驱动版本在23.0.1及以上。
- 卸载原有NPU驱动,具体步骤请参见NPU驱动卸载。
- 进入固件与驱动,选择对应产品型号,下载23.0.1及以上版本的驱动安装包(软件包格式为run)。
- 下载安装包后,请阅读用户必读了解NPU安装相关限制和要求,并参考安装驱动(适用于.run格式)中的步骤进行安装。
约束与限制
昇腾AI产品内已内置虚拟化模板,进行NPU虚拟化时,仅支持按照预定义的虚拟化模板规格进行虚拟化操作,具体模板信息请参见虚拟化模板。昇腾AI产品支持虚拟化实例的灵活组合,即在同一张NPU芯片上,可以使用不同的虚拟化模板划分多个vNPU,各vNPU占用的资源总量不得超过该NPU卡的硬件上限。官方已给出推荐的组合模板,您可以根据需求进行灵活组合,具体请参见虚拟化实例组合。
步骤一:手动切分vNPU
CCE Standard/Turbo集群支持手动切分vNPU,您可以根据需求灵活配置。
- 登录待切分节点,并通过kubectl连接集群。
- 执行以下命令,查看节点中的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 | +===============================+=================+======================================================+
- 执行以下命令,查询当前节点支持的虚拟化模板,以及各模板使用的资源规格。您可以根据需求,按照一个或多个模板进行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 | +------------------------------------------------------------------------------------------+
- 执行npu-smiset-tcreate-vnpu-i<id>-c<chip_id>-f<vnpu_config>[-vvnpu_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的详细介绍,请参见虚拟化模式。
回显结果如下,则说明vNPU创建成功。
Status : OK Message : Create vnpu success
- 依次执行以下命令,将vNPU恢复状态配置为使能状态。配置完成后,节点重启时,系统能够保存vNPU的配置信息,确保重启后vNPU仍有效。
- 执行以下命令,开启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.
- 执行以下命令,查看当前环境中vNPU恢复使能状态是否开启成功。
npu-smi info -t vnpu-cfg-recover
回显结果如下,则说明开启成功。
VNPU config recover mode : Enable
- 执行以下命令,开启vNPU的恢复使能状态。当命令中的1改为0时,表示关闭vNPU恢复使能状态。
- 执行以下命令,查看已创建的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。
- 执行以下命令,查询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>
- 执行以下命令,删除对应Pod。
kubectl delete pod -n kube-system huawei-npu-device-plugin-c6x7
回显结果如下,则说明删除成功。
pod "huawei-npu-device-plugin-c6x7" deleted
- 执行以下命令,查询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资源,从而实现资源的高效管理和灵活配置。
- 依次执行以下命令,创建工作负载,并申请一个vir02模板的vNPU资源。
- 执行以下命令,创建名为vnpu-worker的YAML文件。
vim vnpu-worker.yaml
文件内容如下,容器中只支持申请NPU资源或者vNPU资源,二者不可以同时使用。
使用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。
- huawei.com/ascend-310-2c表示申请vNPU资源名称,不同产品和模板对应的vNPU资源名称不同,具体映射关系如下:
表2 vNPU资源名称 产品类型
虚拟化模板
vNPU资源名称
Atlas推理系列产品
vir01
huawei.com/ascend-310-1c
vir02
huawei.com/ascend-310-2c
vir02_1c
huawei.com/ascend-310-2c.1cpu
vir04
huawei.com/ascend-310-4c
vir04_3c
huawei.com/ascend-310-4c.3cpu
vir04_3c_ndvpp
huawei.com/ascend-310-4c.3cpu.ndvpp
vir04_4c_dvpp
huawei.com/ascend-310-4c.4cpu.dvpp
Ascend训练系列产品(BMS)
vir16
huawei.com/ascend-1980-16c
vir08
huawei.com/ascend-1980-8c
vir04
huawei.com/ascend-1980-4c
vir02
huawei.com/ascend-1980-2c
vir10_3c_16g
huawei.com/ascend-1980-10c.3cpu.16g
vir10_3c_16g_nm
huawei.com/ascend-1980-10c.3cpu.16g.ndvpp
vir10_4c_16g_m
huawei.com/ascend-1980-10c.4cpu.16g.dvpp
vir05_1c_8g
huawei.com/ascend-1980-5c.1cpu.8g
vir10_3c_32g
huawei.com/ascend-1980-10c.3cpu.32g
vir05_1c_16g
huawei.com/ascend-1980-5c.1cpu.16g
vir12_3c_32g
huawei.com/ascend-1980-12c.3cpu.32g
vir06_1c_16g
huawei.com/ascend-1980-6c.1cpu.16g
vir03_1c_8g
huawei.com/ascend-1980-3c.1cpu.8g
- 执行以下命令,创建上述工作负载。
kubectl apply -f vnpu-worker.yaml
回显结果如下:
deployment/vnpu-test created
- 执行以下命令,查看Pod是否运行成功。
kubectl get pod | grep vnpu-test
回显结果如下,则说明工作负载中的Pod运行成功。
vnpu-test-6658cd795b-rx76t 1/1 Running 0 59m
- 执行以下命令,创建名为vnpu-worker的YAML文件。
- 执行以下命令,登录容器内部。
kubectl -n default exec -it vnpu-test-6658cd795b-rx76t -c container-0 -- /bin/bash
- 在容器内依次执行以下命令,查看vNPU是否挂载成功。
- 执行以下命令,配置环境变量,用于指定动态链接库的搜索路径,确保在运行与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
- 执行以下命令,查看容器挂载的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 | +===============================+=================+======================================================+
- 执行以下命令,配置环境变量,用于指定动态链接库的搜索路径,确保在运行与NPU相关的应用时,系统能够正确加载所需的动态库文件。
步骤四:销毁vNPU
当不再使用某vNPU资源时,可以对其执行销毁操作,释放相关资源。进行销毁操作前,请确保没有任务正在使用待销毁的vNPU,否则将销毁失败。
- 执行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
- 回显结果如下,则说明命令执行成功。
- 执行销毁命令后,您需要重启对应节点的huawei-npu-device-plugin组件,将销毁信息上报k8s。具体步骤如下:
- 执行以下命令,查询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>
- 执行以下命令,删除对应Pod。
kubectl delete pod -n kube-system huawei-npu-device-plugin-tcmck
回显结果如下,则说明删除成功。
pod "huawei-npu-device-plugin-tcmck" deleted
- 执行以下命令,查询huawei-npu-device-plugin组件涉及的所有Pod。
- 执行以下命令,验证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 ... ...