Ascend Backend¶
总览¶
Ascend Backend 将 mLLM 的算子执行能力接入华为 Ascend NPU,提供端到端的调度、内存管理与算子生命周期管理,使模型在 Ascend 上高效运行。
设计目标¶
统一后端:作为 mLLM 原生后端,统一接口与调度流程。
ATB 单算子验证:打通算子从框架到 NPU 的完整链路。
生命周期管理:算子创建、准备、执行、销毁的统一抽象。
内存管理:专用 Ascend 设备内存池,减少反复申请释放。
扩展性:便于新增算子、执行模式和性能优化。
架构组件¶
架构图如下:
┌─────────────────────────────────────────────────────────────┐
│ MLLM 框架 │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ 模块 │ │ 层 │ │ 调度器 │ │
│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │
└─────────┼─────────────────┼─────────────────┼───────────────┘
│ │ │
└─────────────────┴─────────────────┘
│
┌──────────────────────────────────────────────────────────────┐
│ Ascend 后端基础设施 │
│ │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ AscendBackend(核心管理) │ │
│ │ - 设备/算子注册 - 分配器绑定 │ │
│ │ - 设备信息日志 │ │
│ └─────────┬──────────────────────────────────────────────┘ │
│ │ │
│ ┌─────────┴──────────┬──────────────┬─────────────────┐ │
│ │ │ │ │ │
│ ▼ ▼ ▼ ▼ │
│ AscendDispatcher AscendAllocator Ascend Ops AscendCommon │
│ (执行:算子/ MemoryManager (目前是add (共用代码) │
│ 模块任务) (内存池) 未来图执行) │
│ │
│ │
│ │
└────────────────────────────┬─────────────────────────────────┘
│
┌────────────────────────────▼──────────────────────────────────┐
│ Ascend runtime │
│ ┌──────────────┐ ┌──────────────┐ ┌─────────────────┐ │
│ │ ATB 上下文 │ │ ACL 流 │ │ ATB/ACL 接口 │ │
│ └──────────────┘ └──────────────┘ └─────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Ascend NPU 硬件(orangepi ai pro) │ │
│ └──────────────────────────────────────────────────────┘ │
└───────────────────────────────────────────────────────────────┘
关键模块¶
mLLM 框架层
框架层负责算子抽象、计算任务构建以及统一调度接口的提供。不依赖任何具体设备实现,仅通过 Backend 接口与底层后端交互。算子在该层被封装为可调度的任务(Task),并通过 DispatcherManager 提交给对应设备后端执行。
Ascend 后端基础设施层
该层是 Ascend Backend 的核心实现,负责承接来自框架层的算子任务,并将其映射到 Ascend 运行时执行。主要组成包括:
AscendBackend
后端入口与核心管理模块,负责后端注册、算子工厂管理、分配器与调度器绑定等。
AscendDispatcher
任务调度与执行模块,负责驱动算子按照统一的生命周期(reshape / setup / forward)执行。
AscendAllocator / AscendMemoryManager
Ascend 设备内存管理模块,负责 Tensor 与 workspace 的分配、回收及内存池管理。
Ascend Ops / AscendCommon
Ascend 专用算子实现及 ATB / ACL 公共工具封装,屏蔽底层运行时细节。
Ascend Runtime 层
运行时层由 Ascend CANN 提供,包含 ATB 算子库、ACL 执行接口以及执行上下文与流管理。
Ascend 硬件层
最底层为 Ascend NPU 硬件,负责实际的计算执行。
执行流程(单算子路径)¶
Ascend Backend 初始化 - Context 注册 Backend、Allocator、Dispatcher
输入 Tensor 准备 - Ascend Tensor 分配 - Host → Device 拷贝
构建并提交算子任务 - 创建 Ascend Op、Task - 提交至 Dispatcher
Ascend 上执行算子 - reshape、setup、forward - → ATB Operation Execute
结果回传与资源释放 - Device → Host 拷贝验证 - Tensor 资源释放
算子支持与映射¶
支持的算子¶
当前版本的 Ascend Backend 以验证端到端执行链路为目标,实现了基于 ATB 的 Add 算子 支持。
算子映射策略¶
在 Ascend Backend 中,框架算子并不直接依赖底层运行时实现,而是通过后端算子层进行统一映射。
后续扩展¶
在当前单算子执行路径稳定的基础上,Ascend Backend 将逐步扩展算子支持范围与执行模式。
添加新算子的方法¶
Step 1:确认 ATB 支持与算子约束¶
确认 ATB 是否支持目标算子类型及对应参数结构
Step 2:实现 Ascend 算子类¶
在 Ascend 后端中定义算子类
实现统一的算子生命周期:reshape → setup → forward
在 forward 阶段调用 ATB 单算子完成执行
Step 3:注册算子并接入调度链路¶
将新算子注册到 AscendBackend并完成相关适配
Step 4:测试与验证¶
构建最小示例在 Ascend 设备上运行新算子
与 CPU 参考结果对比,验证计算正确性
算子计算结果测试¶
基准结果:在 CPU/参考实现上运行同一输入,获得期望输出。
输入构造:覆盖典型维度与边界尺寸;固定随机种子,避免非确定性。
误差度量:按 dtype 选择误差标准,如浮点用相对/绝对误差(rtol/atol),整型用全相等。
数据搬运:确保 Host→Device / Device→Host 拷贝后再次比对,排查搬运或对齐问题。
内存与数据管理¶
AscendMemoryManager(单例):按设备创建独立内存池,当前通过 aclrtGetDeviceCount 为每个 device 分配池。
AscendMemoryPool:预分配一个较大的空间,aclrtMalloc(…, ACL_MEM_MALLOC_HUGE_FIRST) 获取内存,维护 base/cur 指针与剩余空间。
块分配策略:首先从 32B 对齐,优先从有空间 的 free_blocks 复用,若没有可用的则在池内线性切分(64B 对齐),并返回递增 block id。
线程安全:分配/释放/取指针均持锁。
多设备调度:通过当前 device id 选择对应内存池,确保多卡环境下内存隔离。
性能与调优¶
内存池复用:通过 AscendMemoryPool 预分配大块显存,并在线性切分/复用 block,减少频繁 aclrtMalloc/aclrtFree 带来的碎片与性能开销。
对齐与访问:按 32B/64B 对齐划分内存块,兼顾 ATB/ACL 对齐需求与访存效率。
执行路径简化:当前以单算子执行链路为主,重点验证端到端正确性与内存/数据通路的稳定性,为后续多算子/多流并行奠定基础。
日志观测:通过 AscendCommon 与统一日志系统记录内存分配、算子执行等关键行为,用于简单的性能和资源使用分析。
测试与验证¶
结果正确性测试:在 CPU 或参考实现上计算结果,在 Ascend Backend 上运行相同输入,对比数值。
时间测试:针对算子构不同步骤,记录执行时间。
端到端验证:在示例工程中跑通完整链路,同时观察输出结果与耗时,确保调度、内存池和运行时组合下行为稳定。
后续扩展¶
支持更多算子。
更完整的 profiling 与可视化。
上下文/图级缓存,减少重复创建。