摘要1、基于 https://github.com/Project-HAMi/ascend-device-plugin/tree/v1.3.0 分析软切分 NPU 的 Device Plugin 代码2、回答几个问题与华为原生的 Device Plugin 有何区别上报的资源、分配机制软切分是如何实现的简要说明其原理核心实现在 https://github.com/Project-HAMi/hami-vnpu-core后续单独讲本章只讲怎么用的软切分是如何实现的简要说明其原理核心实现在 https://github.com/Project-HAMi/hami-vnpu-core后续单独讲本章只讲怎么用的如何与 HAMi 调度器配合实现软切分Ascend Device Plugin 代码结构分析一、项目概述Ascend Device Plugin是一个 Kubernetes Device Plugin 实现用于管理华为 Ascend NPU神经网络处理器设备的分配与调度。该插件与 HAMiHierarchical AI Resource Management调度器集成支持 vNPU虚拟 NPU的动态创建和资源隔离。二、目录结构ascend-device-plugin/ ├── cmd/ # 命令行入口 │ └── main.go # 程序主入口 ├── internal/ # 内部模块 │ ├── manager/ # 设备管理器 │ │ └── manager.go # Ascend设备管理核心逻辑 │ ├── server/ # gRPC服务端 │ │ └── server.go # Device Plugin API实现 │ ├── vnpu.go # 配置结构定义 │ └── watchers.go # 文件系统/信号监视器 ├── libvnpu/ # vNPU 核心库Rust 实现都是通过子模块下载下来的git submodule update --init --recursive原代码中只有一个目录 │ ├── crates/ # Rust crates │ │ ├── hook/ # Hook模块 │ │ └── limiter/ # 资源限制器 │ └── script/ # 辅助脚本 ├── mind-cluster/ # MindSpore 集群相关组件都是通过子模块下载下来的git submodule update --init --recursive原代码中只有一个目录 │ └── component/ # 各种组件模块 │ ├── ascend-common/ # 公共组件 │ ├── ascend-device-plugin/ # 设备插件另一实现 │ ├── ascend-docker-runtime/ # Docker运行时 │ ├── ascend-faultdiag/ # 故障诊断 │ ├── ascend-for-volcano/ # Volcano调度器集成 │ └── ascend-operator/ # Kubernetes Operator ├── examples/ # 示例配置 │ ├── ascendjob-310p.yaml │ └── ascendjob-910b.yaml ├── go.mod/go.sum # Go依赖管理 └── Dockerfile/Makefile # 构建配置三、核心模块职责模块文件职责cmdmain.go程序入口参数解析初始化流程控制managermanager.go设备发现、健康检查、vNPU生命周期管理serverserver.gogRPC服务Device Plugin API实现HAMi集成internalvnpu.go配置结构定义与 YAML 加载internalwatchers.go文件系统与信号监听工具internalwatchers.go文件系统和信号监听工具四、核心组件详解4.1 主入口 (cmd/main.go)职责程序初始化和主循环控制核心流程参数解析解析命令行参数配置文件、节点名称等日志初始化配置华为日志和klog设备管理器创建初始化底层设备管理接口配置加载加载全局配置和节点特定配置服务启动启动gRPC服务并进入主循环事件监听监听文件系统事件和系统信号关键代码路径main() → checkFlags() → NewAscendManager() → LoadConfig() → NewPluginServer() → start()命令行参数参数类型默认值说明--config_filestring空配置文件路径必需--node_namestringNODE_NAME环境变量节点名称必需--node_config_filestring空节点特定配置文件路径--hw_loglevelint0华为日志级别--check_idle_vnpu_intervalint60检查空闲vNPU间隔秒4.2 设备管理器 (internal/manager/manager.go)职责管理物理NPU设备和vNPU的生命周期核心数据结构typeDevicestruct{UUIDstring// 设备唯一标识LogicIDint32// 逻辑设备IDPhyIDint32// 物理设备IDCardIDint32// 卡IDDeviceIDint32// 设备IDMemoryint64// 内存大小字节AICoreint32// AI Core数量Healthbool// 健康状态true表示健康}typeAscendManagerstruct{mu sync.RWMutex// 读写锁mgr*devmanager.DeviceManager// 底层设备管理器config internal.VNPUConfig// vNPU配置globalConfig internal.Config// 全局配置devs[]*Device// 设备列表nodeConfig*internal.NodeConfig// 节点配置}关键方法方法功能NewAscendManager()创建设备管理器实例LoadConfig(path)加载设备配置文件LoadNodeConfig(nodePath, nodeName)加载节点特定配置UpdateDevice()更新设备列表GetDevices()获取设备列表线程安全GetDeviceByUUID(UUID)根据UUID查找设备GetUnHealthIDs()获取不健康设备ID列表CleanupIdleVNPUs()清理空闲vNPUVDeviceCount()计算单个物理设备可虚拟出的vNPU数量4.3 gRPC服务端 (internal/server/server.go)职责实现Kubernetes Device Plugin API与Kubelet和HAMi调度器交互实现的Device Plugin APIAPI方法功能ListAndWatch列出设备并监听状态变化Allocate为Pod分配设备GetDevicePluginOptions获取插件选项PreStartContainer容器启动前处理核心数据结构typePluginServerstruct{commonWordstring// 设备通用标识词nodeNamestring// 节点名称grpcServer*grpc.Server// gRPC服务实例mgr*manager.AscendManager// 设备管理器socketstring// Unix socket路径stopChchaninterface{}// 停止信号通道healthChchanint32// 健康状态变更通道checkIdleVNPUIntervalint// 检查空闲vNPU的间隔}HAMi集成功能设备注册向HAMi调度器注册设备信息节点注解更新更新节点注解以支持调度决策vNPU核心模式支持HAMi vNPU Core模式的资源隔离vNPU Core模式挂载当Pod使用huawei.com/vnpu-mode: hami-core注解时会注入驱动挂载华为NPU驱动和SMI工具链只读库注入通过/etc/ld.so.preload注入HAMi运行时库共享内存挂载共享内存区域用于资源协调环境变量设置NPU_MEM_QUOTA、NPU_PRIORITY等4.4 配置模块 (internal/vnpu.go)核心配置结构typeTemplatestruct{Namestringjson:name// 模板名称Memoryint64json:memory// 内存大小字节AICoreint32json:aiCore// AI Core数量}typeVNPUConfigstruct{CommonWordstring// 通用标识词如Ascend910ChipNamestring// 芯片名称ResourceNamestring// Kubernetes资源名称MemoryAllocatableint64// 可分配内存大小MemoryCapacityint64// 总内存容量AICoreint32// AI Core总数Templates[]Template// 可用的vNPU模板列表}typeConfigstruct{VNPUsstruct{HamiVnpuCorebool// 是否启用HAMi vNPU核心模式Configs[]VNPUConfig// 各芯片型号的配置列表}}五、数据流和交互关系┌─────────────────────────────────────────────────────────────────────┐ │ Kubernetes Cluster │ ├─────────────────────────────────────────────────────────────────────┤ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ HAMi │ │ Kubelet │ │ Device │ │ │ │ Scheduler │◄───────│ │───────►│ Plugin │ │ │ │ │ │ │ │ │ │ │ └──────────────┘ └──────────────┘ └──────┬───────┘ │ │ │ │ │ │ │ 1. 注册设备信息 │ │ │ │ 2. 获取待分配设备 │ │ │ │ │ │ │ ▼ ▼ │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ Node │ │ Pod │ │ Ascend │ │ │ │ Annotations │ │ Annotations │ │ Manager │ │ │ │ │ │ │ │ │ │ │ └──────────────┘ └──────────────┘ └──────────────┘ │ │ │ │ │ │ │ │ ▼ │ │ ┌──────────────────────────────────────────────────────────────┐ │ │ │ Ascend Device Plugin │ │ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ │ │ main │───►│ server │───►│ manager │───►│ DCMI │ │ │ │ │ │入口控制 │ │ gRPC服务│ │设备管理 │ │底层接口 │ │ │ │ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │ │ └──────────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────────┘六、关键设计特点6.1 vNPU虚拟化支持支持将物理NPU划分为多个vNPU通过模板配置不同规格的vNPU内存、AI Core数量自动清理空闲vNPU释放资源6.2 健康监控机制定期检查设备健康状态发现不健康设备时自动更新设备列表通知Kubelet设备状态变化6.3 HAMi集成通过节点注解与HAMi调度器交互支持vNPU Core模式的细粒度资源隔离使用共享内存区域实现容器间资源协调6.4 容错机制gRPC服务崩溃自动重启最多5次/小时监听Kubelet socket重建事件自动重新注册优雅处理系统信号实现安全退出6.5 启动流程Start() ├─► prepareHostResources() // 准备宿主机资源 ├─► mgr.UpdateDevice() // 更新设备列表 ├─► serve() // 启动gRPC服务 ├─► registerKubelet() // 向Kubelet注册 ├─► startPeriodicCheckIdleVNPUs() // 定期检查空闲vNPU └─► watchAndRegister() // 监听并向HAMi注册七、配置示例7.1 全局配置文件vnpus:hamiVnpuCore:trueconfigs:-commonWord:Ascend910chipName:Ascend910BresourceName:huawei.com/Ascend910resourceMemoryName:huawei.com/Ascend910-memorymemoryAllocatable:32212254720# 30GBmemoryCapacity:34359738368# 32GBaiCore:64aiCPU:8templates:-name:30GBmemory:32212254720aiCore:64-name:15GBmemory:16106127360aiCore:32-commonWord:Ascend310PchipName:Ascend310PresourceName:huawei.com/Ascend310PmemoryAllocatable:8053063680# 7.5GBmemoryCapacity:8589934592# 8GBaiCore:4templates:-name:7.5GBmemory:8053063680aiCore:47.2 节点配置文件nodes:-name:node-gpu-01hami-vnpu-core:truevDeviceCount:4-name:node-gpu-02hami-vnpu-core:falsevDeviceCount:2八、运行方式# 基本运行命令./ascend-device-plugin\--config_file/path/to/config.yaml\--node_name$(NODE_NAME)\--check_idle_vnpu_interval60# 完整参数./ascend-device-plugin\--config_file/etc/ascend-device-plugin/config.yaml\--node_namenode-01\--node_config_file/etc/ascend-device-plugin/node-config.yaml\--hw_loglevel0\--check_idle_vnpu_interval60\--report_time_offset1九、环境变量环境变量说明NODE_NAME节点名称可替代--node_name参数HAMI_VNPU_ASSETS_PATHvNPU核心库资源路径十、总结Ascend Device Plugin 是一个架构清晰、功能完备的 Kubernetes Device Plugin 实现具有以下特点分层架构职责分离模块间解耦高可用设计支持故障自动恢复和优雅重启灵活配置支持全局配置和节点级配置深度集成与HAMi调度器无缝集成支持vNPU虚拟化可扩展性支持多种Ascend芯片型号该插件为在Kubernetes集群中高效管理和调度华为Ascend NPU资源提供了完整的解决方案。vnpu架构下面是软切分vNPU从物理设备到容器内虚拟设备的核心流程是否物理 NPU 设备Ascend Device Plugin收到 Allocate 请求根据 Pod 资源申请选择 vNPU 模板调用 DCMI 接口创建 vNPU 实例分配 vNPU 的内存与 AI Core 资源是否启用hami-vnpu-core 模式?注入 hami-vnpu-core 运行时库通过 ld.so.preload 拦截调用仅设置环境变量NPU_MEM_QUOTA 等挂载共享内存区域用于容器间资源协调返回设备信息给 Kubelet完成 Allocate 响应容器启动后通过挂载的驱动访问 vNPUhami-vnpu-core 的 hook 模块拦截并限制 NPU 资源使用容器内应用透明使用虚拟化后的 NPUhami-vnpu-core 的角色它是一个用 Rust 实现的运行时库通过LD_PRELOAD机制注入到容器中。其hook模块负责拦截应用对 NPU 驱动如libascendcl.so的调用根据共享内存中的配额信息动态限制内存和算力使用limiter模块则负责在超出配额时进行降速或拒绝从而实现真正的资源隔离与软切分。
HAMI-VNPU-软切分:device-plugin
摘要1、基于 https://github.com/Project-HAMi/ascend-device-plugin/tree/v1.3.0 分析软切分 NPU 的 Device Plugin 代码2、回答几个问题与华为原生的 Device Plugin 有何区别上报的资源、分配机制软切分是如何实现的简要说明其原理核心实现在 https://github.com/Project-HAMi/hami-vnpu-core后续单独讲本章只讲怎么用的软切分是如何实现的简要说明其原理核心实现在 https://github.com/Project-HAMi/hami-vnpu-core后续单独讲本章只讲怎么用的如何与 HAMi 调度器配合实现软切分Ascend Device Plugin 代码结构分析一、项目概述Ascend Device Plugin是一个 Kubernetes Device Plugin 实现用于管理华为 Ascend NPU神经网络处理器设备的分配与调度。该插件与 HAMiHierarchical AI Resource Management调度器集成支持 vNPU虚拟 NPU的动态创建和资源隔离。二、目录结构ascend-device-plugin/ ├── cmd/ # 命令行入口 │ └── main.go # 程序主入口 ├── internal/ # 内部模块 │ ├── manager/ # 设备管理器 │ │ └── manager.go # Ascend设备管理核心逻辑 │ ├── server/ # gRPC服务端 │ │ └── server.go # Device Plugin API实现 │ ├── vnpu.go # 配置结构定义 │ └── watchers.go # 文件系统/信号监视器 ├── libvnpu/ # vNPU 核心库Rust 实现都是通过子模块下载下来的git submodule update --init --recursive原代码中只有一个目录 │ ├── crates/ # Rust crates │ │ ├── hook/ # Hook模块 │ │ └── limiter/ # 资源限制器 │ └── script/ # 辅助脚本 ├── mind-cluster/ # MindSpore 集群相关组件都是通过子模块下载下来的git submodule update --init --recursive原代码中只有一个目录 │ └── component/ # 各种组件模块 │ ├── ascend-common/ # 公共组件 │ ├── ascend-device-plugin/ # 设备插件另一实现 │ ├── ascend-docker-runtime/ # Docker运行时 │ ├── ascend-faultdiag/ # 故障诊断 │ ├── ascend-for-volcano/ # Volcano调度器集成 │ └── ascend-operator/ # Kubernetes Operator ├── examples/ # 示例配置 │ ├── ascendjob-310p.yaml │ └── ascendjob-910b.yaml ├── go.mod/go.sum # Go依赖管理 └── Dockerfile/Makefile # 构建配置三、核心模块职责模块文件职责cmdmain.go程序入口参数解析初始化流程控制managermanager.go设备发现、健康检查、vNPU生命周期管理serverserver.gogRPC服务Device Plugin API实现HAMi集成internalvnpu.go配置结构定义与 YAML 加载internalwatchers.go文件系统与信号监听工具internalwatchers.go文件系统和信号监听工具四、核心组件详解4.1 主入口 (cmd/main.go)职责程序初始化和主循环控制核心流程参数解析解析命令行参数配置文件、节点名称等日志初始化配置华为日志和klog设备管理器创建初始化底层设备管理接口配置加载加载全局配置和节点特定配置服务启动启动gRPC服务并进入主循环事件监听监听文件系统事件和系统信号关键代码路径main() → checkFlags() → NewAscendManager() → LoadConfig() → NewPluginServer() → start()命令行参数参数类型默认值说明--config_filestring空配置文件路径必需--node_namestringNODE_NAME环境变量节点名称必需--node_config_filestring空节点特定配置文件路径--hw_loglevelint0华为日志级别--check_idle_vnpu_intervalint60检查空闲vNPU间隔秒4.2 设备管理器 (internal/manager/manager.go)职责管理物理NPU设备和vNPU的生命周期核心数据结构typeDevicestruct{UUIDstring// 设备唯一标识LogicIDint32// 逻辑设备IDPhyIDint32// 物理设备IDCardIDint32// 卡IDDeviceIDint32// 设备IDMemoryint64// 内存大小字节AICoreint32// AI Core数量Healthbool// 健康状态true表示健康}typeAscendManagerstruct{mu sync.RWMutex// 读写锁mgr*devmanager.DeviceManager// 底层设备管理器config internal.VNPUConfig// vNPU配置globalConfig internal.Config// 全局配置devs[]*Device// 设备列表nodeConfig*internal.NodeConfig// 节点配置}关键方法方法功能NewAscendManager()创建设备管理器实例LoadConfig(path)加载设备配置文件LoadNodeConfig(nodePath, nodeName)加载节点特定配置UpdateDevice()更新设备列表GetDevices()获取设备列表线程安全GetDeviceByUUID(UUID)根据UUID查找设备GetUnHealthIDs()获取不健康设备ID列表CleanupIdleVNPUs()清理空闲vNPUVDeviceCount()计算单个物理设备可虚拟出的vNPU数量4.3 gRPC服务端 (internal/server/server.go)职责实现Kubernetes Device Plugin API与Kubelet和HAMi调度器交互实现的Device Plugin APIAPI方法功能ListAndWatch列出设备并监听状态变化Allocate为Pod分配设备GetDevicePluginOptions获取插件选项PreStartContainer容器启动前处理核心数据结构typePluginServerstruct{commonWordstring// 设备通用标识词nodeNamestring// 节点名称grpcServer*grpc.Server// gRPC服务实例mgr*manager.AscendManager// 设备管理器socketstring// Unix socket路径stopChchaninterface{}// 停止信号通道healthChchanint32// 健康状态变更通道checkIdleVNPUIntervalint// 检查空闲vNPU的间隔}HAMi集成功能设备注册向HAMi调度器注册设备信息节点注解更新更新节点注解以支持调度决策vNPU核心模式支持HAMi vNPU Core模式的资源隔离vNPU Core模式挂载当Pod使用huawei.com/vnpu-mode: hami-core注解时会注入驱动挂载华为NPU驱动和SMI工具链只读库注入通过/etc/ld.so.preload注入HAMi运行时库共享内存挂载共享内存区域用于资源协调环境变量设置NPU_MEM_QUOTA、NPU_PRIORITY等4.4 配置模块 (internal/vnpu.go)核心配置结构typeTemplatestruct{Namestringjson:name// 模板名称Memoryint64json:memory// 内存大小字节AICoreint32json:aiCore// AI Core数量}typeVNPUConfigstruct{CommonWordstring// 通用标识词如Ascend910ChipNamestring// 芯片名称ResourceNamestring// Kubernetes资源名称MemoryAllocatableint64// 可分配内存大小MemoryCapacityint64// 总内存容量AICoreint32// AI Core总数Templates[]Template// 可用的vNPU模板列表}typeConfigstruct{VNPUsstruct{HamiVnpuCorebool// 是否启用HAMi vNPU核心模式Configs[]VNPUConfig// 各芯片型号的配置列表}}五、数据流和交互关系┌─────────────────────────────────────────────────────────────────────┐ │ Kubernetes Cluster │ ├─────────────────────────────────────────────────────────────────────┤ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ HAMi │ │ Kubelet │ │ Device │ │ │ │ Scheduler │◄───────│ │───────►│ Plugin │ │ │ │ │ │ │ │ │ │ │ └──────────────┘ └──────────────┘ └──────┬───────┘ │ │ │ │ │ │ │ 1. 注册设备信息 │ │ │ │ 2. 获取待分配设备 │ │ │ │ │ │ │ ▼ ▼ │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ Node │ │ Pod │ │ Ascend │ │ │ │ Annotations │ │ Annotations │ │ Manager │ │ │ │ │ │ │ │ │ │ │ └──────────────┘ └──────────────┘ └──────────────┘ │ │ │ │ │ │ │ │ ▼ │ │ ┌──────────────────────────────────────────────────────────────┐ │ │ │ Ascend Device Plugin │ │ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ │ │ main │───►│ server │───►│ manager │───►│ DCMI │ │ │ │ │ │入口控制 │ │ gRPC服务│ │设备管理 │ │底层接口 │ │ │ │ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │ │ └──────────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────────┘六、关键设计特点6.1 vNPU虚拟化支持支持将物理NPU划分为多个vNPU通过模板配置不同规格的vNPU内存、AI Core数量自动清理空闲vNPU释放资源6.2 健康监控机制定期检查设备健康状态发现不健康设备时自动更新设备列表通知Kubelet设备状态变化6.3 HAMi集成通过节点注解与HAMi调度器交互支持vNPU Core模式的细粒度资源隔离使用共享内存区域实现容器间资源协调6.4 容错机制gRPC服务崩溃自动重启最多5次/小时监听Kubelet socket重建事件自动重新注册优雅处理系统信号实现安全退出6.5 启动流程Start() ├─► prepareHostResources() // 准备宿主机资源 ├─► mgr.UpdateDevice() // 更新设备列表 ├─► serve() // 启动gRPC服务 ├─► registerKubelet() // 向Kubelet注册 ├─► startPeriodicCheckIdleVNPUs() // 定期检查空闲vNPU └─► watchAndRegister() // 监听并向HAMi注册七、配置示例7.1 全局配置文件vnpus:hamiVnpuCore:trueconfigs:-commonWord:Ascend910chipName:Ascend910BresourceName:huawei.com/Ascend910resourceMemoryName:huawei.com/Ascend910-memorymemoryAllocatable:32212254720# 30GBmemoryCapacity:34359738368# 32GBaiCore:64aiCPU:8templates:-name:30GBmemory:32212254720aiCore:64-name:15GBmemory:16106127360aiCore:32-commonWord:Ascend310PchipName:Ascend310PresourceName:huawei.com/Ascend310PmemoryAllocatable:8053063680# 7.5GBmemoryCapacity:8589934592# 8GBaiCore:4templates:-name:7.5GBmemory:8053063680aiCore:47.2 节点配置文件nodes:-name:node-gpu-01hami-vnpu-core:truevDeviceCount:4-name:node-gpu-02hami-vnpu-core:falsevDeviceCount:2八、运行方式# 基本运行命令./ascend-device-plugin\--config_file/path/to/config.yaml\--node_name$(NODE_NAME)\--check_idle_vnpu_interval60# 完整参数./ascend-device-plugin\--config_file/etc/ascend-device-plugin/config.yaml\--node_namenode-01\--node_config_file/etc/ascend-device-plugin/node-config.yaml\--hw_loglevel0\--check_idle_vnpu_interval60\--report_time_offset1九、环境变量环境变量说明NODE_NAME节点名称可替代--node_name参数HAMI_VNPU_ASSETS_PATHvNPU核心库资源路径十、总结Ascend Device Plugin 是一个架构清晰、功能完备的 Kubernetes Device Plugin 实现具有以下特点分层架构职责分离模块间解耦高可用设计支持故障自动恢复和优雅重启灵活配置支持全局配置和节点级配置深度集成与HAMi调度器无缝集成支持vNPU虚拟化可扩展性支持多种Ascend芯片型号该插件为在Kubernetes集群中高效管理和调度华为Ascend NPU资源提供了完整的解决方案。vnpu架构下面是软切分vNPU从物理设备到容器内虚拟设备的核心流程是否物理 NPU 设备Ascend Device Plugin收到 Allocate 请求根据 Pod 资源申请选择 vNPU 模板调用 DCMI 接口创建 vNPU 实例分配 vNPU 的内存与 AI Core 资源是否启用hami-vnpu-core 模式?注入 hami-vnpu-core 运行时库通过 ld.so.preload 拦截调用仅设置环境变量NPU_MEM_QUOTA 等挂载共享内存区域用于容器间资源协调返回设备信息给 Kubelet完成 Allocate 响应容器启动后通过挂载的驱动访问 vNPUhami-vnpu-core 的 hook 模块拦截并限制 NPU 资源使用容器内应用透明使用虚拟化后的 NPUhami-vnpu-core 的角色它是一个用 Rust 实现的运行时库通过LD_PRELOAD机制注入到容器中。其hook模块负责拦截应用对 NPU 驱动如libascendcl.so的调用根据共享内存中的配额信息动态限制内存和算力使用limiter模块则负责在超出配额时进行降速或拒绝从而实现真正的资源隔离与软切分。