Ascend Device Plugin 技术实践
作者:昇腾实战派
背景概述
Kubernetes原生设计聚焦于CPU、内存等通用计算资源,但无法直接管理GPU、FPGA、高性能网络等异构硬件设备。为解决这一问题,Kubernetes引入设备插件(Device Plugin)机制,允许设备厂商通过标准化接口向集群注册设备信息,实现设备发现、健康监控与资源调度。本文聚焦NPU(神经网络处理单元)设备插件的实现方案,阐述其如何通过Kubernetes设备插件规范,将NPU资源纳入集群统一管理,为AI工作负载提供高效资源调度能力。
1. 设备插件核心功能
1.1 设备发现
设备插件通过调用底层硬件管理接口(如DCMI),自动发现节点上的NPU设备数量与拓扑信息,并将设备信息上报至Kubernetes。上报内容包括:
- 芯片型号(如NPU 910)
- 设备ID(物理标识)
- 资源数量(如
huawei.com/NPU910: 8) - 设备健康状态
1.2 健康检查
插件周期性检测NPU设备状态(温度、故障率等),当设备异常时:
- 立即标记设备为
Unhealthy - 通过Kubernetes API上报状态变更
- 自动从资源池中移除故障设备,避免调度到异常节点
1.3 设备分配
当Kubernetes调度器分配NPU资源时,插件通过Allocate接口完成:
- 为容器分配指定数量的NPU资源
- 生成挂载路径与环境变量(如
NPU_DEVICE_ID) - 传递HCCL通信拓扑文件路径
- 确保容器内应用可直接访问NPU设备
2. 工作原理
2.1 核心机制
Kubernetes设备插件遵循标准gRPC接口规范,实现三个关键方法:
| 接口方法 | 功能描述 |
|---|---|
Register |
插件启动时向Kubelet注册资源类型(如huawei.com/NPU910) |
ListAndWatch |
周期性上报设备列表(默认5秒间隔),包含设备ID、状态、数量 |
Allocate |
根据调度请求分配设备,返回挂载路径与环境变量 |
2.2 通信流程
- 启动注册:插件启动后创建Unix Socket(如
/var/lib/kubelet/device-plugins/NPU910.sock),向Kubelet注册 - 设备上报:插件通过DCMI接口获取设备信息,周期性调用
ListAndWatch上报 - 资源分配:Kubelet收到调度请求后,调用
Allocate分配设备 - 容器挂载:插件返回挂载路径,容器启动时自动挂载NPU设备

3. 关键特性
3.1 资源管理能力
| 能力 | 中心侧支持 | 边缘侧支持 | 说明 |
|---|---|---|---|
| 静态算力切分 | ✅ | ✅ | 按固定比例切分芯片资源 |
| 动态算力切分 | ✅ | ❌ | 运行时按需切分(如1/2/4/8核) |
| 设备故障重调度 | ✅ | ❌ | 故障设备自动从资源池移除 |
| 网络故障重调度 | ✅ | ❌ | 依赖Volcano调度器实现 |
| 推理热复位 | ✅ | ✅ | 异常设备重启恢复(NPU 310系列) |
注:动态算力切分场景下,插件将单颗NPU芯片(如NPU 310P)虚拟化为多个逻辑设备(如
npu-core0~npu-core7),用户通过npu-core数量指定资源需求。
3.2 部署与兼容性
- 部署方式:以DaemonSet形式部署,确保每个节点运行一个实例
- 权限要求:
- 需挂载
/var/lib/kubelet/device-plugins目录 - 必须以特权模式运行(
privileged: true)
- 需挂载
- 硬件兼容性:
- 中心侧:支持NPU 910、NPU 310P(含动态切分)
- 边缘侧:支持NPU 310(静态切分)、边缘设备(如Atlas 500)
3.3 故障处理机制
当NPU设备异常时:
- 插件检测到健康状态变为
Unhealthy - 立即上报Kubernetes,触发资源池更新
- 若集成Volcano调度器,自动将任务迁移至健康节点
- 故障设备恢复后,自动重新加入资源池
关键设计:热复位操作仅在设备空闲时执行,避免任务中断。复位耗时约15-24秒(NPU 310系列)。
4. 代码实现关键点
4.1 服务注册与通信
// pkg/server/server.go
func StartServer() error {
// 验证Kubelet socket权限
if err := common.VerifyPathAndPermission(); err != nil {
return err
}
// 建立gRPC连接
conn, err := grpc.Dial(kubeletSocket, grpc.WithInsecure(), grpc.WithContextDialer(...))
if err != nil { /* 错误处理 */ }
// 向Kubelet注册插件
client := deviceplugin.NewDevicePluginClient(conn)
if _, err := client.Register(context.Background(), &RegisterRequest{...}); err != nil {
return err
}
return nil
}
4.2 设备状态监控
// pkg/server/plugin.go
func (p *plugin) ListAndWatch(r *ListAndWatchRequest, stream DevicePlugin_ListAndWatchServer) error {
for {
// 获取设备状态(DCMI接口)
devices, err := p.getNpuDevices()
if err != nil { /* 重试逻辑 */ }
// 上报设备列表
if err := stream.Send(&ListAndWatchResponse{Devices: devices}); err != nil {
return err
}
time.Sleep(5 * time.Second) // 周期性上报
}
}
4.3 动态算力切分分配
// pkg/server/plugin.go
func (p *plugin) Allocate(ctx context.Context, req *AllocateRequest) (*AllocateResponse, error) {
// 1. 解析请求的npu-core数量
coreCount := req.GetContainerRequests()[0].GetResources().GetNpuCore()
// 2. 从可用设备中分配
deviceID := p.allocateDevice(coreCount)
// 3. 返回挂载路径与环境变量
return &AllocateResponse{
ContainerResponses: []*ContainerAllocateResponse{
{
Envs: map[string]string{
"NPU_DEVICE_ID": deviceID,
"HCCL_TOPO_FILE": "/etc/hccl/topo.json",
},
Mounts: []*Mount{
{HostPath: "/dev/davinci0", ContainerPath: "/dev/davinci0"},
},
},
},
}, nil
}
5. 部署约束与最佳实践
5.1 关键约束
| 约束类型 | 说明 |
|---|---|
| NPU驱动 | 升级驱动前需停止设备插件服务,避免驱动冲突 |
| 与容器运行时配合 | 需优先安装兼容的容器运行时(如Ascend Docker Runtime v5.0.RC1+) |
| DCMI动态库权限 | 父目录需属主为root,且无group/other写权限(路径深度<20) |
| 虚拟机环境 | 需在镜像中预装systemd(apt-get install -y systemd) |
5.2 部署示例(DaemonSet)
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: npu-device-plugin
spec:
selector:
matchLabels:
name: npu-device-plugin
template:
metadata:
labels:
name: npu-device-plugin
spec:
containers:
- name: npu-device-plugin
image: npu-device-plugin:latest
securityContext:
privileged: true
volumeMounts:
- name: device-plugin
mountPath: /var/lib/kubelet/device-plugins
volumes:
- name: device-plugin
hostPath:
path: /var/lib/kubelet/device-plugins
type: DirectoryOrCreate
6. 扩展能力
6.1 拓扑文件生成
插件支持动态生成HCCL通信拓扑文件,确保分布式训练任务正确建立通信链路:
- 通过DCMI接口获取NPU物理拓扑
- 生成符合HCCL要求的
ranktable与topo.json - 自动注入容器环境变量
HCCL_TOPO_FILE
6.2 与Volcano调度器集成
- 核心价值:实现故障自愈与亲和性调度
- 工作流程:
- Volcano调度器根据设备状态选择节点
- 插件在
Allocate阶段写入设备映射关系 - 故障发生时,Volcano自动迁移任务至健康节点
- 插件完成设备热复位后重新加入资源池
注:动态算力切分场景下,插件需与Volcano协同维护设备映射表,确保并发分配时资源不冲突。
技术价值总结:通过标准化设备插件机制,NPU资源管理实现与Kubernetes原生调度器的深度集成。开发者无需修改应用代码,即可通过声明式资源请求(如resources: {huawei.com/NPU910: 2})获取NPU资源,同时享受故障自愈、动态切分等高级能力,显著提升AI工作负载的资源利用率与系统可靠性。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)