news 2026/6/13 0:34:53

CANN驱动层架构拆解——从HAL硬件抽象到SVM共享虚拟内存的昇腾NPU设备使能机制全链路深度解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CANN驱动层架构拆解——从HAL硬件抽象到SVM共享虚拟内存的昇腾NPU设备使能机制全链路深度解析

前言

在做昇腾910B的推理部署,模型已经用PyTorch写好了,转换也没问题,但一上机跑就报设备不可用。他翻了半天代码,以为是AscendCL调用姿势不对,折腾了两天才发现——驱动版本跟固件对不上,HAL层初始化时设备握手失败,SVM模块根本没起来。这事儿让我意识到,很多人对CANN的认知停留在算子库和图编译器层面,对底下那层真正让昇腾NPU"活起来"的驱动模块几乎没有概念。driver仓库就是干这事的——它位于CANN五层架构的最底层,是整个软件栈与物理硬件之间的桥梁。没有它,上层的Runtime、Graph Executor、HCCL通信库全都无从谈起。这篇文章会把driver仓库的三层架构(DCMI、HAL、SDK-driver)拆开来看,重点剖析HAL层中SVM共享虚拟内存和RoCE高速通信的实现逻辑,搞清楚昇腾NPU的内存是怎么管理的、设备间数据是怎么搬的、主机和设备之间的命令通道是怎么建立的。

驱动在CANN软件栈中的位置

CANN的全称是Compute Architecture for Neural Networks,即昇腾异构计算架构。从最顶层的AscendCL应用开发接口,到中间的算子库、调优引擎、图编译器,再到底层的Runtime运行时,所有这些软件组件要真正跑起来,前提是物理设备被正确识别、初始化和调度。driver仓库承担的就是这个角色——它是CANN五层架构中"昇腾计算基础"层的核心组成,直接与昇腾NPU硬件打交道。

昇腾NPU不是插上PCIe插槽就能用的裸设备。操作系统内核看到的是一块PCIe设备,但要让这块设备执行计算任务,需要有人来完成设备发现、资源映射、内存管理、命令下发、中断处理、故障检测等一系列底层工作。driver仓库的代码就是实现这些功能的。它向上为Runtime、DVPP、HCCL等上层模块提供稳定的驱动接口,向下通过寄存器操作和固件交互控制物理硬件的行为。理解驱动的意义,可以把昇腾NPU想象成一台精密的工厂机器——算子库和图编译器是操作手册和调度系统,驱动则是机器的电气控制柜和传动装置。控制柜出了问题,不管操作手册写得多好,机器也不会动。

三层架构:DCMI、HAL与SDK-driver

driver仓库的代码不是一坨平铺的结构,而是按照职责划分成了三个清晰的层次。理解这三层的关系,是看懂整个驱动模块的关键。

DCMI层是达芬奇卡管理接口层,它的职责是设备管理。当你需要查询NPU的PCIe信息、Board信息、Flash信息,或者需要对芯片执行热复位操作时,调用的就是DCMI接口。从examples目录可以看到,DCMI的样例覆盖了配置管理、信息查询和芯片复位三大场景。在实际运维中,DCMI是最常被间接使用的层——npu-smi工具背后就是DCMI接口在支撑,当你执行npu-smi info查看设备状态时,实际上触发了一连串DCMI查询调用。

HAL层是硬件抽象层,它的定位是屏蔽不同芯片型号之间的硬件差异。昇腾910B、910_93、950这些芯片在寄存器布局、指令集细节、内存映射方式上各有不同,但上层模块不应该关心这些差异。HAL层把这些差异封装在内部,对外提供统一的接口。HAL层是driver仓库中模块最多的层,涵盖了SVM内存管理、RoCE通信、HDC主机设备通信、DVPP预处理、事件调度、设备维护组件(DMC)、设备管理系统(DMS)等十几个子模块。每个子模块都有自己的目录和独立的接口定义。

SDK-driver层是在HAL层之上进一步封装的驱动软件开发套件。它增加了故障管理系统(FMS)、任务调度代理(TS Agent)、设备虚拟化管理(VMNG)、算力切分(vascend)、虚拟网卡(VNIC)等更高级的特性。SDK-driver层面向的是需要深度定制驱动行为的场景,比如多租户场景下的设备虚拟化、容器化部署中的算力切分。

三层之间的关系是自下而上的依赖:SDK-driver依赖HAL的接口,HAL依赖DCMI提供的设备管理能力,DCMI直接与硬件交互。这种分层设计的好处是,当你只需要做设备管理操作时,只用DCMI层就够了,不需要加载整个驱动栈;当你需要做内存管理和数据搬运时,HAL层是主要交互对象;当你要做复杂的调度和虚拟化时,才需要用到SDK-driver层。

SVM共享虚拟内存:昇腾NPU的内存管家

SVM(Shared Virtual Memory)是driver仓库中最核心的子模块之一,它负责管理昇腾NPU设备侧的所有内存操作。如果你写过CUDA程序,可以把SVM理解成昇腾版的管理GPU显存的那套机制,但它的能力范围比CUDA的内存管理更广。

SVM的初始化发生在应用进程调用aclrtSetDevice时。这个调用会触发SVM模块的初始化流程:建立SVM的管理结构体,完成Host侧与Device侧SVM模块之间的握手交互。这个过程是隐式的——开发者不需要手动初始化SVM,设置设备时它就自动完成了。

内存申请和释放是SVM最基础的功能。当你调用halMemAlloc时,SVM从预留的虚拟地址范围内分配一段虚拟地址,通过mmap将其映射出来,同时进入内核态申请物理页,建立页表项。释放时做反向操作:解除页表映射、释放物理页、归还虚拟地址。这个流程跟Linux内核的内存管理逻辑类似,但操作对象是昇腾NPU的设备内存,不是主机内存。

// 申请Host侧内存和Device侧内存,再把数据从Host搬过去void*h_ptr=NULL;void*d_ptr=NULL;halMemAlloc(&h_ptr,size,HOST_MEM);// 先在Host侧申请halMemAlloc(&d_ptr,size,DEV_MEM);// 再在Device侧申请halMemcpy(d_ptr,h_ptr,size);// 同步拷贝,阻塞等完成

halMemcpy是阻塞式的同步拷贝,调用方会一直等到全部数据搬完才返回。在数据量不大或者后续计算必须等数据就位的场景下,同步接口用起来最简单,不容易出错。如果你有大块数据要搬又不想让Host侧CPU干等着,得用异步流的方式,但这块走的是Runtime层的接口,不在SVM的职责范围内。

SVM还提供了一套VMM(Virtual Memory Management)接口,允许开发者分别申请虚拟地址和物理地址,按需动态建立映射关系。VMM的设计目标是减少内存碎片。传统的内存管理方式是申请一块连续的虚拟地址同时分配物理页,但频繁的申请和释放会产生大量碎片。VMM允许你一次性预留一大段虚拟地址空间,按需分配物理内存,动态建立映射,甚至可以解除映射后把物理内存重新映射到别的虚拟地址上复用。

// VMM模式:虚拟地址和物理地址分开管,映射按需建void*vaddr=NULL;halMemAddressReserve(&vaddr,total_size);// 只占虚拟地址,不占物理内存halMemCreate(&phys_handle,chunk_size,DEV_MEM);// 申请物理内存,拿到句柄halMemMap(vaddr,phys_handle,chunk_size);// 建映射,虚拟地址才真正可用

把虚拟地址和物理地址的申请拆开,让同一块物理内存可以被反复映射到不同的虚拟地址上。在大模型推理场景中,KV Cache的显存管理就特别需要这种能力——物理内存可以分配好备着,推理过程中根据序列长度动态映射到不同的虚拟地址空间,避免反复申请释放带来的碎片和性能抖动。

内存共享是SVM的另一个关键能力。它支持两种共享模式:设备间共享和主机设备间共享。设备间共享的场景是——你有两张NPU卡,dev0上算完的结果需要给dev1用,传统做法是把数据从dev0搬到Host再从Host搬到dev1,两趟拷贝开销不小。SVM的做法是让dev0通过halShmemCreateHandle创建一个共享句柄,dev1通过halShmemOpenHandleByDevId打开这个句柄,直接映射dev0的内存地址,跳过Host中转。主机设备间共享则通过halHostRegister实现,把Host侧或Device侧的内存注册到对端,使对端能直接访问。

// 设备间共享内存,dev1直接读dev0的结果,不用过HosthalMemAlloc(&dev0_ptr,size,DEV_MEM);// dev0申请设备内存halShmemCreateHandle(dev0_ptr,&shmem_handle);// 创建共享句柄// 把shmem_handle通过进程间通信传给dev1的进程halShmemOpenHandleByDevId(shmem_handle,dev1_id,&dev1_mapped_ptr);// dev1映射

多卡训练和推理中,跨设备数据搬移是性能瓶颈之一。通过共享内存让目标设备直接映射源设备的物理内存,省掉Host中转的两次拷贝。这种设计在AllReduce、AllGather等集合通信算子中被广泛使用,HCCL通信库底层的跨设备数据传输就走的是这条路。

SVM的内存查询功能提供了两种能力:内存属性查询(drvMemGetAttribute)可以获取指定虚拟地址的内存属性和物理页粒度信息;内存信息查询(halMemGetInfo)可以获取设备侧物理内存的使用情况。这两个接口在内存诊断和性能调优时很有用——当你不确定某块内存的属性或者需要确认设备剩余可用显存时,可以直接查询。

RoCE高速通信:让数据绕过CPU直接走网卡

RoCE(RDMA over Converged Ethernet)是driver仓库中另一个重要的子模块。它实现了昇腾NPU平台上的RDMA通信能力,用于减少延迟和提高数据传输效率。

RoCE基于linux-rdma社区的rdma-core开源框架实现,在此基础上做了定制化的封装。定制的核心在于"lite"接口——分为控制面lite接口和数据面lite接口两部分。

控制面lite接口做的事情是:把Device侧的内存映射到Host侧,在Host侧重建对应的RDMA上下文。传统RDMA的工作方式是,所有控制面操作(创建QP、修改QP状态、注册内存区域等)都需要通过内核驱动完成,每次操作都要经历用户态到内核态的切换。lite接口把这些控制面操作简化了,通过预先建立的映射关系,在Host侧就能完成上下文重建,减少内核交互次数。

数据面lite接口做的事情更关键:它允许在Host侧直接下发Work Request(WR),把WR写入Device侧的队列,同时可以在Host侧轮询Completion Queue(CQ)获取完成状态。传统方式下,WR下发和CQ轮询都需要跟Device侧交互,延迟较高。lite接口通过Host侧的映射关系,让这些操作可以在Host侧本地完成,大幅降低了通信延迟。这种

从代码路径看,RDMA Lite用户态驱动在src/ascend_hal/roce/host_lite/目录下,Device内存申请接口在src/ascend_hal/roce/roce_hal_api/目录下。上层集合通信库(如HCCL)通过组合下发WR来实现更高级的集合通信算子。比如AllGather操作,底层就是通过RDMA Write来实现的——每个节点把自己的数据通过RDMA Write直接写到其他节点的内存中,不用CPU参与数据搬运。

RoCE在昇腾NPU生态中的角色类似于InfiniBand在NVIDIA生态中的角色。但昇腾的RoCE实现走的是以太网路线,在标准以太网上实现RDMA语义,不需要专用的InfiniBand交换机。这对数据中心部署来说更友好——用普通以太网交换机就能组建高性能通信网络,降低了硬件成本和运维复杂度。

HDC与TRS:命令下发与任务调度的管道

HDC(Host-Device Communication)是主机侧和设备侧之间的通信通道。当你从Host侧下发一个计算任务到NPU时,命令就是通过HDC传递的。HDC不是一个简单的消息队列,它需要处理Host侧和Device侧之间的地址转换、内存映射、中断通知等复杂逻辑。

TRS(Task Resource Schedule)负责任务资源的调度管理。在多任务并发执行的场景下,多个进程可能同时向同一个NPU提交计算任务,TRS负责协调这些任务的执行顺序和资源分配。TRS的实现涉及软件sqcq通信和mailbox消息机制——sqcq是提交队列和完成队列的简称,Host侧把任务描述符写入提交队列,Device侧执行完后把结果写入完成队列,mailbox用于传递控制消息。

这两个模块在日常开发中不会被直接调用,但它们是驱动正常运转的基础设施。当你通过AscendCL下发一个算子执行请求时,请求经过Runtime层后,最终会通过HDC通道到达Device侧固件,TRS在Device侧负责任务的排队和调度。如果这两个模块出问题,表现通常是计算任务挂起或者超时。

设备维护与故障管理

DMC(Device Maintenance Components)和DMS(Device Manage System)是驱动中的设备维护和管理子系统。DMC包含DSMI设备系统管理接口、设备监控、日志采集、性能Profiling和镜像校验等子模块。DMS负责设备生命周期管理,包括设备上线、下线、状态监控等。

在SDK-driver层还有一个FMS(Fault Manage System)故障管理系统。FMS的设计思路是:当设备发生硬件故障时,系统需要在最短时间内完成故障隔离和业务恢复。FMS会检测故障类型(内存ECC错误、PCIe链路异常、芯片温度过高等),根据故障严重程度决定处理策略——轻微故障可能只是记录日志,严重故障则触发任务迁移和设备隔离。

bbox(Black Box)模块是系统临终遗言——当设备发生致命错误即将失联时,bbox会尽可能多地把关键寄存器状态和内部日志dump到预留的存储区域,供事后分析。这个模块在问题定位时非常有价值,因为很多硬件故障是瞬间发生的,如果没有bbox记录,事后可能完全无法复现和排查。

DMC中的Profiling模块负责性能数据采集。昇腾NPU上运行的计算任务,其执行时间、带宽利用率、计算单元占用率等指标都可以通过Profiling接口采集。昇腾MindStudio中的性能分析工具,底层数据来源之一就是驱动的Profiling模块。

使用前vs使用后:驱动层优化的效率对比

在实际工程中,是否正确使用driver仓库提供的优化接口,对性能影响非常大。下面这张表从几个关键维度对比了通用实现和优化实现的差异。

维度使用通用实现使用优化实现差异来源
跨设备数据传输Host中转两次拷贝(dev0→Host→dev1)SVM共享内存直接映射省掉Host中转的两次内存拷贝开销
内存申请灵活性每次申请同时分配虚拟地址和物理页VMM模式分别管理虚拟地址和物理内存减少内存碎片,物理内存可复用
RDMA通信延迟标准verbs接口,每次WR下发需内核交互lite接口Host侧直接下发WR减少用户态内核态切换次数
设备间通信带宽依赖TCP/IP协议栈走以太网RoCE硬件级RDMA绕过CPU和协议栈,直接内存到内存
故障恢复速度人工排查+手动隔离FMS自动检测+隔离+迁移自动化故障处理减少业务中断时间
内存诊断效率无法查询内存属性和设备物理内存状态drvMemGetAttribute+halMemGetInfo实时查询驱动层直接提供内存诊断接口

这张表里的每一行差异,背后都是driver仓库中某个具体模块在发挥作用。跨设备传输优化靠SVM的共享内存能力,RDMA优化靠RoCE的lite接口,故障管理靠FMS的自动化处理。这些优化不是独立的,在实际的大规模训练或推理场景中往往是组合使用的——一个典型的多卡训练任务,数据传输走RoCE lite接口降低延迟,KV Cache管理走VMM减少显存碎片,故障场景靠FMS保障训练不中断。

从DCMI接口开发看驱动扩展方式

driver仓库开源的价值不只是让你读懂代码,更重要的是让你能改代码。QUICKSTART文档中给出了一个新增DCMI接口的完整示例,展示了从修改驱动源码到编译部署的全流程。

以新增dsmi_get_host_device_connect_type接口为例:你需要在dsmi_common_interface.c中实现函数逻辑,在dsmi_common_interface.h中声明接口。函数内部通过drvGetDevInfo获取NPU设备信息结构体,从中提取host_device_connect_type字段返回给调用者。这个流程反映了驱动开发的典型模式——底层有一个获取完整设备信息的能力,上层按需封装出查询特定属性的接口。

编译源码的入口是build.sh脚本,通过–pkg和–soc参数指定芯片类型来编译。当前支持的芯片类型包括ascend910b、ascend910_93和ascend950。编译过程会自动下载第三方依赖和开源二进制库,需要网络畅通。编译产物是一个.run格式的安装包,部署时执行–full安装即可替换已安装CANN开发套件中的Driver组件。

开发过程中的调试主要依赖两类日志:应用类日志和系统类日志。应用类日志是Host侧用户态产生的,记录了驱动接口调用的过程和结果。系统类日志分Host侧内核态日志和Device侧日志,前者通过dmesg查看,后者通过msnpureport工具导出。当ERROR级别日志不够用时,可以设置更详细的DEBUG级别来深入分析。这种分级日志体系在问题定位时非常实用——日常运维看ERROR就够了,排查疑难问题时开DEBUG上详细信息。


仓库地址:https://atomgit.com/cann/driver

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/13 0:33:01

2026大湾区领导力EMBA客观测评与理性选型指南

一、引言:大湾区领导力EMBA择校核心痛点 大湾区作为跨境商贸、科创融合核心区域,近两年领导力导向EMBA报考人数同比上涨27%,报考人群以制造业、跨境金融、科创企业高管为主。结合《经理人2026粤港澳EMBA行业报告》及教育部留学服务中心公开数…

作者头像 李华
网站建设 2026/6/13 0:33:01

如何通过Ryzen SDT调试工具深度掌控AMD处理器底层性能

如何通过Ryzen SDT调试工具深度掌控AMD处理器底层性能 【免费下载链接】SMUDebugTool A dedicated tool to help write/read various parameters of Ryzen-based systems, such as manual overclock, SMU, PCI, CPUID, MSR and Power Table. 项目地址: https://gitcode.com/g…

作者头像 李华
网站建设 2026/6/13 0:32:13

计算机毕业设计之药品管理系统的设计与实现

随着信息技术的迅猛发展,传统药品管理方式已无法满足现代医疗行业的高效、精准需求。药品信息管理系统的研发与应用,旨在通过数字化手段提升药品管理的效率与准确性,保障药品供应链的顺畅运行。本研究基于当前医疗行业对药品信息管理的迫切需…

作者头像 李华
网站建设 2026/6/13 0:24:51

Java 中 List 局部反转方法

目录 一、需求说明 1. 原生手动交换(最通用,推荐) 2. 借助 Collections 工具类(简洁) 关键注意点 3. Java 8 Stream 写法(不修改原列表,返回新集合) 总结选型 这里介绍 Java 中…

作者头像 李华
网站建设 2026/6/13 0:24:50

舞台灯光师必看:除了控台,用Python也能玩转DMX512协议

舞台灯光师必看:用Python解锁DMX512协议的创意控制当聚光灯亮起的那一刻,舞台便有了生命。传统灯光控制依赖昂贵的硬件控台,但今天,我们将用Python和一台普通电脑打开全新的灯光编程世界。这不是未来科技,而是每个灯光…

作者头像 李华