当前位置: 首页 > news >正文

昇腾NPU的驱动程序,NPU和CPU之间的桥梁

前言

昇腾NPU插在主板上,PyTorch能直接调用它跑模型,这个过程是怎么实现的?驱动扮演了什么角色?为什么驱动版本不对,NPU就跑不起来?

第一次研究昇腾驱动的时候,也被它的分层架构搞得很懵。从PyTorch调用到NPU执行,中间经过了哪些层?每层负责什么?为什么有时候"驱动装对了,但NPU还是不可用"?

带着这个疑问,深入研究了driver仓库的源码,发现driver不是简单的"硬件驱动",而是一个分层软件栈,包括HDF(Hardware Driver Foundation)、HDK(Hardware Development Kit)、Runtime Library三层,每层各司其职,共同完成"让PyTorch能用NPU"这个目标。

本文是概念拆解——会拆开driver的分层架构、核心模块、常见问题,解释为什么driver是昇腾CANN的基础层,以及为什么它出问题会影响整个栈。

driver在CANN五层架构里的位置

先说清楚driver住在哪。昇腾CANN的架构分五层,driver住在第5层——昇腾计算基础层,是整个栈的最底层。

第1层:昇腾计算语言层 AscendCL └─ 算子开发接口 Ascend C 第2层:昇腾计算服务层 ├─ AOL 算子库 ├─ AOE 调优引擎 └─ Framework Adaptor 框架适配器 第3层:昇腾计算编译层 ├─ Graph Compiler 图编译器 └─ BiSheng / ATC 编译器 第4层:昇腾计算执行层 ├─ Runtime 运行时 ├─ Graph Executor 图执行器 ├─ HCCL 集合通信库 └─ AIPP / DVPP 第5层:昇腾计算基础层 ← driver 住在这 ├─ RMS(Resource Management Service) ├─ CMS(Configuration Management Service) ├─ DMS(Device Management Service) ├─ DRV(DRiVer,驱动核心) └─ UTILITY 硬件层:昇腾 AI 硬件(达芬奇架构)

为啥住第5层?因为driver是"硬件抽象层",是连接软件栈和物理硬件的桥梁。没有driver,软件栈就不知道硬件长什么样,更不知道怎么控制硬件。

依赖关系

driver → hardware(NPU)。driver直接控制NPU硬件,是整个栈的最底层。上层的HCCS、Runtime、AscendCL都依赖driver提供的接口。

分层架构:driver的三层结构

driver不是一层代码,而是三层代码:HDF层HDK层Runtime Library层

第1层:HDF(Hardware Driver Foundation)

HDF是驱动框架层,定义了驱动的标准框架和接口规范。所有的昇腾驱动都要遵循HDF规范,这样才能被上层软件统一管理。

核心模块

// HDF核心:设备管理classHdfDeviceManager{public:// 加载设备驱动staticintLoadDevice(constchar*device_name);// 卸载设备驱动staticintUnloadDevice(constchar*device_name);// 获取设备句柄staticvoid*GetDevice(constchar*device_name);};// HDF核心:驱动服务classHdfDriverService{public:// 初始化驱动服务virtualintInitialize()=0;// 销毁驱动服务virtualintRelease()=0;// 绑定设备virtualintBindDevice(structDevice*device)=0;// 解绑设备virtualintUnbindDevice(structDevice*device)=0;};// NPU驱动服务classNpuDriverService:publicHdfDriverService{public:intInitialize()override;intRelease()override;intBindDevice(structDevice*device)override;intUnbindDevice(structDevice*device)override;// NPU特有接口intSubmitTask(structTask*task);intQueryTask(uint64_ttask_id);intSyncDevice();};

关键点

  • HdfDeviceManager:设备管理器,负责加载/卸载设备驱动
  • HdfDriverService:驱动服务基类,定义了驱动的生命周期接口
  • NpuDriverService:NPU驱动服务,实现了NPU特有的接口

⚠️ 踩坑预警:HDF层是内核态代码,普通开发者不要直接修改,看看就好。

第2层:HDK(Hardware Development Kit)

HDK是硬件开发工具包,提供了驱动开发的常用工具和接口。开发者基于HDK,可以快速开发新的驱动或者扩展现有驱动。

核心模块

// HDK核心:内存管理classHdkMemory{public:// 分配设备内存staticvoid*AllocDeviceMem(size_t size);// 释放设备内存staticvoidFreeDeviceMem(void*ptr);// 分配Host内存(锁页内存,用于DMA)staticvoid*AllocHostMem(size_t size);// 释放Host内存staticvoidFreeHostMem(void*ptr);// 内存拷贝(Device ↔ Host)staticvoidMemcpy(void*dst,constvoid*src,size_t size);};// HDK核心:任务调度classHdkTask{public:// 创建任务staticuint64_tCreateTask(structTaskConfig*config);// 提交任务staticintSubmitTask(uint64_ttask_id);// 等待任务完成staticintWaitTask(uint64_ttask_id,uint32_ttimeout_ms);// 取消任务staticintCancelTask(uint64_ttask_id);};// HDK核心:事件管理classHdkEvent{public:// 创建事件staticuint64_tCreateEvent();// 等待事件staticintWaitEvent(uint64_tevent_id,uint32_ttimeout_ms);// 触发事件staticintSignalEvent(uint64_tevent_id);// 销毁事件staticintDestroyEvent(uint64_tevent_id);};

关键点

  • HdkMemory:内存管理,封装了设备内存、Host内存、DMA拷贝的接口
  • HdkTask:任务调度,封装了任务创建、提交、等待、取消的接口
  • HdkEvent:事件管理,封装了事件创建、等待、触发、销毁的接口

⚠️ 踩坑预警:HDK层是内核态代码,普通开发者不要直接修改,看看就好。

第3层:Runtime Library(用户态驱动接口)

Runtime Library是用户态驱动接口,是普通开发者接触driver的唯一途径。PyTorch、AscendCL、Runtime都通过Runtime Library和driver交互。

核心模块

// Runtime Library核心:设备管理classDeviceManager{public:// 初始化设备管理staticintInit();// 销毁设备管理staticintDestroy();// 获取设备数量staticintGetDeviceCount();// 设置当前设备staticintSetDevice(intdevice_id);// 获取当前设备staticintGetDevice();// 同步设备staticintSyncDevice();};// Runtime Library核心:内存管理classMemoryManager{public:// 分配设备内存staticvoid*Alloc(size_t size);// 释放设备内存staticvoidFree(void*ptr);// 分配锁页内存(用于DMA)staticvoid*AllocPinned(size_t size);// 释放锁页内存staticvoidFreePinned(void*ptr);// 内存拷贝(同步)staticvoidMemcpy(void*dst,constvoid*src,size_t size);// 内存拷贝(异步)staticvoidMemcpyAsync(void*dst,constvoid*src,size_t size,Stream stream);};// Runtime Library核心:流管理classStreamManager{public:// 创建流staticStreamCreateStream();// 销毁流staticintDestroyStream(Stream stream);// 同步流staticintSyncStream(Stream stream);// 等待流staticintStreamWait(Stream stream,Event event);};

关键点

  • DeviceManager:设备管理,初始化driver、设置当前设备、同步设备
  • MemoryManager:内存管理,分配/释放设备内存、锁页内存、DMA拷贝
  • StreamManager:流管理,创建/销毁/同步流

⚠️ 踩坑预警:Runtime Library是用户态代码,可以直接调用,但要确保driver版本匹配。

核心能力:driver到底能干啥?

driver的核心能力分4类:设备管理内存管理任务调度中断处理

1. 设备管理

设备管理是"让软件知道NPU存在"。driver负责枚举NPU设备、加载驱动、初始化设备。

代码讲解

importacl# 初始化ACL(Ascend Computing Language)acl.init()# 获取设备数量device_count=acl.get_device_count()print(f"NPU设备数量:{device_count}")# 分配设备device_id=0acl.rt.set_device(device_id)# 释放设备acl.rt.reset_device(device_id)# 销毁ACLacl.finalize()

代码讲解

  • acl.init():初始化ACL,加载driver
  • acl.get_device_count():获取NPU设备数量
  • acl.rt.set_device():分配设备
  • acl.rt.reset_device():释放设备

⚠️ 踩坑预警:分配设备后一定要释放,不然会资源泄漏。

2. 内存管理

内存管理是"让软件能往NPU上写数据"。driver负责分配设备内存、Host内存、DMA拷贝。

代码讲解

importnumpyasnpimportacl# 分配设备内存size=1024*4# 1024个float32ptr=acl.rt.malloc(size,acl.RT_MEM_MALLOC_NORMAL_ONLY)print(f"设备内存地址:{hex(ptr)}")# 从numpy数组拷贝数据到设备host_data=np.random.randn(1024).astype(np.float32)acl.rt.memcpy(ptr,size,host_data.ctypes.data,size,acl.RT_MEMCPY_HOST_TO_DEVICE)# 从设备拷贝数据回numpy数组result=np.empty(1024,dtype=np.float32)acl.rt.memcpy(result.ctypes.data,size,ptr,size,acl.RT_MEMCPY_DEVICE_TO_HOST)print(f"结果:{result[:5]}")# 释放设备内存acl.rt.free(ptr)

代码讲解

  • acl.rt.malloc():分配设备内存
  • acl.rt.memcpy():DMA拷贝(H2D或D2H)
  • acl.rt.free():释放设备内存

⚠️ 踩坑预警:设备内存要手动释放,不然会内存泄漏。

3. 任务调度

任务调度是"让软件能往NPU上提交计算任务"。driver负责创建任务、提交任务、等待任务完成。

代码讲解

importacl# 创建流stream,ret=acl.rt.create_stream()print(f"流创建成功:{stream}")# 创建任务(以VectorAdd为例)task_config={"op_type":"VectorAdd","input_x":ptr_x,"input_y":ptr_y,"output_z":ptr_z,"count":1024}task_id=acl.rt.launch_task(stream,task_config)print(f"任务提交成功:{task_id}")# 等待任务完成acl.rt.stream_synchronize(stream)print(f"任务执行完成")# 销毁流acl.rt.destroy_stream(stream)

代码讲解

  • acl.rt.create_stream():创建流
  • acl.rt.launch_task():提交任务
  • acl.rt.stream_synchronize():等待流完成

⚠️ 踩坑预警:提交任务后一定要等待完成,不然结果还没算出来就读了。

4. 中断处理

中断处理是"让NPU能主动通知CPU"。driver负责注册中断处理函数、处理中断、唤醒等待的CPU核。

代码讲解

importacl# 注册中断回调函数definterrupt_callback(interrupt_type,task_id,user_data):print(f"中断类型:{interrupt_type}, 任务ID:{task_id}")# 处理中断...# 注册中断回调acl.rt.register_interrupt_callback(interrupt_callback,None)# 提交一个需要中断通知的任务task_id=acl.rt.launch_task_with_interrupt(stream,task_config)# CPU继续做其他事情,等中断唤醒print("CPU继续做其他事情...")# 等NPU发来中断...

代码讲解

  • acl.rt.register_interrupt_callback():注册中断回调函数
  • acl.rt.launch_task_with_interrupt():提交需要中断通知的任务

⚠️ 踩坑预警:中断回调函数要尽快返回,不然会影响其他中断。

常见问题:driver出错了怎么办?

问题1:驱动版本不匹配

现象:运行acl.init(),报错说driver version mismatch

原因:CANN版本和driver版本不匹配。

解决:去昇腾社区下载和CANN版本匹配的driver。

# 查看当前driver版本cat/usr/local/Ascend/driver/version.info# 查看CANN版本atc--version# 如果版本不匹配,重新安装匹配的driverbashascend-installer-8.0.run--full--driver

问题2:设备不可用

现象:运行acl.rt.set_device(0),报错说device not found

原因:driver没加载,或者NPU硬件故障。

解决:检查driver加载状态和NPU硬件状态。

# 检查driver是否加载lsmod|grepascend# 如果没加载,加载drivermodprobe ascend_driver# 检查NPU硬件状态npu-smi info# 如果NPU硬件故障,重启机器或者联系售后

问题3:内存分配失败

现象:运行acl.rt.malloc(),报错说out of memory

原因:设备内存不足,或者内存碎片太多。

解决:释放不必要的内存,或者重启进程。

# 检查设备内存使用情况mem_info=acl.rt.get_mem_info(acl.RT_MEM_INFO_TOTAL)print(f"设备总内存:{mem_info['total']/1024**3:.2f}GB")mem_info=acl.rt.get_mem_info(acl.RT_MEM_INFO_USED)print(f"设备已用内存:{mem_info['used']/1024**3:.2f}GB")# 释放不必要的内存dellarge_tensor# Python层面释放acl.rt.reset_device(0)# 重置设备,释放所有设备内存

结尾

driver是昇腾CANN的基础层,住在第5层昇腾计算基础层,用HDF+HDK+Runtime Library三层架构,实现了"让PyTorch能用NPU"这个目标。

如果遇到driver问题(版本不匹配、设备不可用、内存分配失败等),先检查driver加载状态和版本信息,确认没问题再往上层排查。driver是整个栈的最底层,driver出问题,上层全都受影响。

昇腾CANN的驱动潜力还很大,driver仓库还有很多细节值得研究。如果想深入了解driver的实现细节,欢迎去AtomGit上的昇腾CANN开源社区逛逛,里面有一手资料和活跃社区。

https://atomgit.com/cann/driver

http://www.jsqmd.com/news/878142/

相关文章:

  • 5分钟解决Zotero文献重复问题:智能合并插件完整使用指南
  • 泉州汽车音响改装综合实力 NO.1|众毅汽车音响:十二项权威认证加持,定义闽南音响改装新标杆 - 汽车音响改装
  • 淘金币自动化脚本:每天节省25分钟,让淘宝任务自己完成
  • 腾讯电子签、法大大、契约锁代理怎么选?企业电子合同选型实操指南 - 资讯纵览
  • 如何快速移除Unity游戏马赛克:UniversalUnityDemosaics完整使用指南
  • NVIDIA Profile Inspector深度解析:解锁显卡驱动的隐藏配置层
  • 2026年国产在线溶解氧仪品牌综合实力排行榜与技术选型指南 - 仪表品牌排行榜
  • 对比直接使用官方接口体验Taotoken在模型调用失败时的自动容灾效果
  • 如何用嘎嘎降AI处理法学论文:法学毕业论文降AI免费完整操作教程
  • 深圳华为云代理大宇云 优质华为云合作伙伴助力企业解锁上云优惠 - 资讯纵览
  • 2026年便携式溶解氧仪国产品牌综合实力排行榜与技术选型指南 - 仪表品牌排行榜
  • Windows Cleaner架构解析:智能磁盘空间管理与系统性能优化方案
  • 2026年毕业季必藏:免费降AIGC率工具+避坑指南,系统审核绝不翻车! - 降AI实验室
  • 火爆分享如何用Taotoken一分钟接入OpenAI兼容API并开始调用
  • 城市创意产业区的空间集聚度及组织驱动系统【附程序】
  • Windows Defender移除工具:从核心引擎到用户界面的完整解决方案
  • STM32 串口计算器实现
  • 使用 Taotoken 后 OpenClaw 任务执行的延迟与稳定性体验
  • 医疗AI数据预处理与可解释性博弈:平衡模型性能与临床可解释性
  • AI辅助系统综述实战:基于检索与微调的信息提取与摘要生成
  • 2026木门十大品牌加盟指南:值得关注的木门十大品牌深度解析 - 匠言榜单
  • 佛山地下管道漏水检测——东诚管线自研技术定位误差≤5cm - 品牌优选官
  • Diablo Edit2:如何快速打造你的完美暗黑破坏神II角色
  • 终极解决方案:如何一键修复Windows系统DLL缺失和软件兼容性问题
  • Hotkey Detective:3分钟解决Windows热键冲突的终极免费工具
  • 工商管理论文降AI工具免费推荐:2026年工商管理研究生毕业论文降AI99.26%达标知网4.8元指南
  • Windows右键菜单终极清理指南:3分钟打造高效工作流
  • WechatDecrypt终极指南:3步快速解密微信聊天记录
  • 终极指南:如何使用BooruDatasetTagManager将AI训练数据标注效率提升10倍
  • 上门回收行业获客越来越难?放弃盲目扫楼,GEO优化靠AI搜索大模型流量营销推广精准接单 - 一点学习库