从零开始学昇腾Ascend C算子开发-第一篇:基础准备阶段
本文介绍了昇腾AI处理器的基础知识和开发环境搭建。昇腾AI处理器是华为自主研发的AI加速芯片,包含910系列(高性能训练)和310系列(高效推理),采用DaVinci架构,具有多核设计和优化的存储层次。CANN框架为昇腾提供统一的开发接口,包含算子库、图编译器等功能。开发环境搭建推荐使用华为云ModelArts Notebook,预装CANN工具包,支持JupyterLab和VS Code远程开发
第一篇:基础准备阶段
1.1 昇腾AI处理器基础
1.1.1 昇腾AI处理器架构概述
什么是昇腾AI处理器
简单来说,昇腾AI处理器就是华为自己做的一块AI加速芯片。这东西专门用来跑深度学习、机器学习这些AI任务,算力很强,而且功耗控制得也不错。你可以把它理解成专门为AI计算定制的"超级计算器"。
主要产品系列
昇腾910系列:这玩意儿主要是用来训练大模型的,性能很强。算力方面,半精度(FP16)达到320 TFLOPS(这个数字看着就吓人),整数精度(INT8)达到640 TOPS。工艺是7nm制程,算是比较先进的。功耗310W,不算低,但考虑到这个性能,还算可以接受。主要用在数据中心训练大模型,或者云服务器上。
昇腾310系列:这个系列主打能效比,更适合做推理(就是已经训练好的模型拿来用)。算力方面,昇腾310B是20 TOPS@INT8(入门级),昇腾310P是176 TOPS@INT8(这个性能已经很不错了)。里面塞了不少东西,有CPU、AI计算核心,还有专门处理图像的模块。边缘设备、实时推理、嵌入式AI这些场景用得比较多。
DaVinci架构
昇腾处理器用的是华为自己搞的DaVinci(达芬奇)架构,这个名字还挺有意思的。这个架构主要有这么几个特点:
多核设计:AI Core专门干AI计算的,这是主力。Vector Core搞向量计算的,处理数组、矩阵这些很在行。CPU Core是通用CPU核心(比如ARM A55),处理一些控制逻辑。
计算单元:支持的数据类型挺多,FP32、FP16、INT8、INT4等等,你可以根据需要选。还能混合精度计算,就是不同地方用不同精度,这样既能保证精度又能提升速度。Cube Unit(矩阵运算单元)专门算矩阵乘法的,速度很快。Vector Unit(向量运算单元)处理向量运算的。
存储层次:Global Memory(全局内存)就是片外的内存,容量大,但访问慢一点。Local Memory(本地内存)是片上的缓存,速度快,但容量有限。TCM(紧耦合内存)这个比较特殊,可以实现零拷贝,数据传得快。寄存器最快但最小,存临时数据用的。
1.1.2 CANN框架介绍
CANN是什么
CANN(Compute Architecture for Neural Networks),名字听起来挺高大上的,其实就是华为给昇腾AI处理器做的一套开发框架。有了它,你就不用直接跟硬件打交道了,它给你提供了统一的编程接口和运行环境,写代码会方便很多。
CANN的核心组件
CANN主要包含这么几个部分:
算子库(Operator Library):里面已经有很多现成的算子可以直接用。如果现成的满足不了需求,你也可以自己写算子。这些算子都是优化过的,性能不用担心。
图编译器(Graph Compiler):把你写的模型图转换成昇腾处理器能跑的形式。还会帮你优化一下,比如把几个算子融合在一起,减少内存访问。内存使用也会优化。
运行时(Runtime):负责调度任务,让计算跑起来。管理内存分配和释放。管理设备,比如多卡的时候怎么分配任务。
驱动层(Driver):这是最底层的东西,把硬件抽象出来。负责跟硬件通信。
CANN的编程模型
CANN提供了几种写算子的方式:
TBE(Tensor Boost Engine):用Python写的,上手快。适合快速验证想法,做原型开发。
TIK(Tensor Iterator Kernel):用C++写的,更底层。控制更精细,性能也更好,但写起来复杂一些。
Ascend C:这是新出的,算是TIK的升级版。既保留了TIK的性能优势,又让写代码更简单了。对向量化和并行计算的支持很好,这也是我们主要要学的。
1.1.3 昇腾AI处理器的计算单元和存储层次
计算单元详解
1. AI Core(AI计算核心)
AI Core是昇腾处理器的核心,所有的AI计算主要靠它。里面又分了几个部分:
Cube Unit(矩阵运算单元):专门算矩阵乘法的,这是AI计算里最常见的操作。支持FP32、FP16、INT8等多种精度,你可以根据需要选。算矩阵乘法特别快,这是它的强项。
Vector Unit(向量运算单元):处理向量运算的,比如两个数组相加、相乘这些。可以一次性加载、存储、运算很多数据。支持各种向量化指令,用好了性能提升很明显。
Scalar Unit(标量运算单元):处理单个数据的运算,还有控制逻辑。比如if/else判断、for循环这些,都是它来处理的。
2. 计算流程
输入数据 → 加载到Local Memory → AI Core计算 → 结果写回 → 输出数据
存储层次详解
昇腾处理器的存储可以理解成一个金字塔,从快到慢、从近到远:
1. 寄存器(Register):最快,但容量很小,就那么几个。存临时变量和中间结果,用完就扔。一个时钟周期就能访问,非常快。
2. Local Memory(本地内存):在芯片上的缓存,速度很快,容量也比寄存器大不少。存计算需要的数据块,这是你主要要管理的地方。延迟很低,但需要你手动管理,什么时候加载、什么时候释放。这个需要你显式管理,不像CPU的缓存是自动的。
3. Global Memory(全局内存):片外的内存(比如DDR),容量很大,但访问慢。存完整的输入输出数据。需要通过DMA传输,延迟比较高。虽然带宽高,但最好批量传输,一次传多一点,这样效率才高。
4. 存储访问优化原则
写代码的时候记住这几个原则:能少访问Global Memory就少访问,它慢。尽量把数据放到Local Memory里用,它快。用向量化加载/存储,一次传多点数据。数据要对齐,这样访问效率高。
1.1.4 昇腾AI处理器的性能特点和应用场景
性能特点
昇腾处理器有这么几个特点:
高算力:算矩阵特别快,这是AI计算的核心。支持多种精度,你可以根据需求在性能和精度之间做权衡。
高能效比:专门为AI计算优化的,不像通用CPU那样浪费。功耗管理做得不错,不会动不动就发热。
低延迟:内存层次结构优化过,数据访问快。DMA传输机制效率高,数据搬移不拖后腿。
可扩展性:可以多卡一起跑,算力可以叠加。支持分布式训练和推理,适合大模型。
应用场景
1. 云计算和数据中心:大规模模型训练(如大语言模型、视觉模型)、云端推理服务、模型训练加速。
2. 边缘计算:智能监控和视频分析、自动驾驶、工业物联网(IIoT)。
3. 终端设备:智能手机AI加速、智能摄像头、嵌入式AI设备。
4. 特定领域应用:自然语言处理(NLP)、计算机视觉(CV)、推荐系统、语音识别。
1.2 开发环境搭建
1.2.1 ModelArts Notebook环境创建
为什么用ModelArts Notebook
如果你没有昇腾硬件设备,或者想快速上手,用ModelArts Notebook是个不错的选择。它已经预装了CANN工具包和开发环境,开箱即用,不用自己折腾安装配置。
创建Notebook实例
1. 进入ModelArts控制台
登录华为云,进入ModelArts控制台,找到Notebook管理页面。
2. 创建Notebook实例
点击"创建Notebook",配置以下参数:
镜像选择:选择包含CANN的镜像,比如 mindspore_2.4.0-cann_8.0.rc3-py_3.9-euler_2.10.10-aarch64-snt9b。这种镜像已经预装了CANN 8.0和MindSpore,还有Python开发环境,直接用就行。
实例规格:选择昇腾实例,比如 Ascend: 1*ascend-snt9b1|ARM: 24核 192GB。这个配置有1个昇腾NPU和24核ARM CPU,内存192GB,够用了。
存储配置:选择云硬盘EVS,至少5GB起步。如果要做大项目,可以选大一点。
SSH远程开发(可选):如果要用VS Code远程连接,可以配置SSH密钥。这样就能在本地用VS Code写代码,代码自动同步到Notebook上。
自动停止:建议设置自动停止时间,比如1小时不操作就自动停止,省钱。
3. 启动Notebook
创建完成后,点击"打开"按钮,会打开JupyterLab界面。如果Notebook是停止状态,先点"启动"等它运行起来。
验证环境
Notebook启动后,打开一个终端或者创建个Python Notebook,验证一下环境:
# 检查CANN版本(镜像里已经装好了)
ascend-toolkit --version
# 检查NPU设备信息
npu-smi info
# 检查环境变量(通常已经自动配置好了)
echo $ASCEND_TOOLKIT_HOME
如果能看到CANN版本和NPU设备信息,说明环境就绪了。
环境变量说明
ModelArts Notebook的镜像通常已经配置好了环境变量,不需要手动设置。如果遇到找不到头文件的问题,可以检查一下:
# 查看CANN路径
ls /usr/local/Ascend/ascend-toolkit/
# 如果环境变量没设置,可以手动source一下
source /usr/local/Ascend/ascend-toolkit/latest/set_env.sh
不过一般镜像都配置好了,直接用就行。
1.2.2 开发环境配置
JupyterLab开发环境
JupyterLab简介
ModelArts Notebook默认提供JupyterLab界面,这是基于Web的开发环境,用浏览器就能写代码。支持Python Notebook、代码编辑器、终端,还能预览文件,用起来挺方便的。
使用JupyterLab
打开Notebook后,会自动进入JupyterLab界面。你可以:
创建Python Notebook:写Python代码测试环境,或者做数据处理。
打开终端:在Notebook里直接打开终端,执行Linux命令,编译C++代码。
创建代码文件:可以直接在JupyterLab里创建.cpp、.h文件写Ascend C算子代码。
文件管理:上传下载文件,管理项目目录。
VS Code远程开发(推荐)
如果你习惯用VS Code,可以用VS Code远程连接Notebook,体验更好。
1. 配置SSH连接
在创建Notebook时,如果配置了SSH密钥,就可以用VS Code远程连接:
在VS Code里安装"Remote - SSH"插件。
配置SSH连接,连接到Notebook的SSH地址(ModelArts会提供)。
连接成功后,就能在本地VS Code里编辑Notebook上的文件了。
2. VS Code配置
连接上Notebook后,在项目根目录创建 .vscode/settings.json:
{
"C_Cpp.default.includePath": [
"${workspaceFolder}/**",
"/usr/local/Ascend/ascend-toolkit/latest/include"
],
"C_Cpp.default.compilerPath": "/usr/bin/g++",
"C_Cpp.default.cStandard": "c11",
"C_Cpp.default.cppStandard": "c++17"
}
这样VS Code就知道去哪找Ascend C的头文件了,会有代码提示。
3. 安装必要插件
在VS Code里安装这些插件:
- C/C++ Extension Pack:C++语法高亮和智能提示
- CMake Tools:如果用CMake构建项目的话
直接在Notebook里开发
如果不想用VS Code,直接在JupyterLab里也能开发:
用终端编译代码:在JupyterLab的终端里执行编译命令。
用代码编辑器:JupyterLab自带的代码编辑器也能写C++代码,虽然功能没VS Code那么强,但够用。
用Python Notebook:可以写Python脚本调用编译好的算子,测试功能。
1.2.3 编译工具链配置
编译器要求
编译器的版本要注意一下:GCC版本至少7.5.0,太老的版本可能不支持一些C++特性。如果用CMake的话,CMake版本至少3.10,这个一般系统自带的都够用。
编译配置
1. 基本编译命令
# 使用CANN提供的编译工具
ccec_compiler -c kernel.cpp -o kernel.o
2. CMake配置示例
创建 CMakeLists.txt:
cmake_minimum_required(VERSION 3.10)
project(AscendCOperator)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# CANN路径
set(ASCEND_TOOLKIT_HOME /usr/local/Ascend/ascend-toolkit/latest)
# 包含目录
include_directories(
${ASCEND_TOOLKIT_HOME}/include
)
# 库目录
link_directories(
${ASCEND_TOOLKIT_HOME}/lib64
)
# 源文件
add_library(operator_kernel SHARED
kernel.cpp
)
# 链接库
target_link_libraries(operator_kernel
ascend_runtime
)
3. 编译脚本示例
创建 build.sh:
#!/bin/bash
# 设置环境变量
source /usr/local/Ascend/ascend-toolkit/latest/set_env.sh
# 创建构建目录
mkdir -p build
cd build
# 运行CMake
cmake ..
# 编译
make -j$(nproc)
echo "Build completed!"
1.2.4 调试工具使用
日志调试
调试的时候最常用的就是打日志了,虽然简单但很有效:
1. 使用printf/cout输出
最简单直接的方式:
#include <iostream>
#include "ascendc.h"
void kernel_function() {
std::cout << "Debug: Entering kernel" << std::endl;
// ... 代码 ...
std::cout << "Debug: Processing data" << std::endl;
}
2. 使用日志宏
如果日志打得多,可以定义个宏,方便点:
#define DEBUG_LOG(msg) std::cout << "[DEBUG] " << msg << std::endl
这样用起来就简单了:DEBUG_LOG("something happened");
性能分析工具
性能优化的时候,这些工具能帮你找到瓶颈:
1. msprof(性能分析器)
这是CANN自带的性能分析工具,能看到哪里耗时间:
# 启动性能分析
msprof --application="your_app" --output=./prof_output
# 查看分析结果
msprof --export=on --output=./prof_output
分析结果会告诉你哪些算子耗时间,哪些内存访问是瓶颈。
2. 使用npu-smi监控
这个命令可以看设备状态,很实用:
# 实时监控设备状态
npu-smi info
# 监控设备使用率,每秒刷新一次
watch -n 1 npu-smi info
能看到设备用了多少、温度多少,如果使用率很低说明可能有问题。
内存检查工具
1. Valgrind(如果支持)
valgrind --leak-check=full ./your_program
2. 使用CANN提供的调试工具
CANN提供了内存泄漏检测、越界访问检测、性能瓶颈分析等功能。
1.3 Ascend C基础入门
1.3.1 Ascend C编程模型
Ascend C是什么
Ascend C是华为昇腾提供的算子开发语言,它基于标准C++语法,但提供了专门针对昇腾AI处理器的API。用Ascend C写算子,你不需要直接操作硬件寄存器,而是通过API来使用硬件的能力。
Ascend C的API分类
根据昇腾官方文档,Ascend C的API主要分为几类:
1. Kernel API(核函数API):包括基本数据结构(比如GlobalTensor全局张量、LocalTensor本地张量)、基础API(直接操作硬件能力的接口,比如向量计算、数据搬运)、高阶API(封装好的常用算法,比如矩阵乘法、Softmax等)。
2. Host API(主机端API):包括Tiling API(计算分块参数的接口)、算子注册API(注册算子的接口)、平台信息获取API(获取硬件信息)。
3. 算子调测API:调试用的接口,比如打印、断言等。
基本编程流程
写一个Ascend C算子,大概流程是这样的:
首先定义核函数,写一个kernel函数,这是实际在NPU上跑的计算逻辑。然后进行数据搬运,把数据从Global Memory搬到Local Memory。接着执行计算,用Ascend C的API进行计算。最后结果写回,把结果从Local Memory写回Global Memory。
1.3.2 基本数据结构
GlobalTensor(全局张量)
GlobalTensor代表在Global Memory(全局内存)中的张量数据。这是输入输出数据存放的地方,容量大但访问慢。
// GlobalTensor通常作为核函数的参数传入
// 它指向Global Memory中的数据
LocalTensor(本地张量)
LocalTensor代表在Local Memory(本地内存)中的张量数据。这是计算时实际使用的数据,速度快但容量有限,需要你手动管理。
// LocalTensor在核函数内部定义
// 用于存储从Global Memory加载的数据
向量类型(Vector)
Ascend C提供了向量类型,可以一次处理多个数据元素。这是向量化编程的基础。
// 向量类型示例(概念)
// 实际使用时需要根据数据类型选择对应的向量类型
1.3.3 基础运算API
标量计算API
标量计算API用于处理单个数值:ScalarGetCountOfValue可以计算一个数字的二进制中0或1的个数,ScalarCountLeadingZero计算前导0的个数,ScalarCast做类型转换,ToBfloat16/ToFloat做精度转换。这些API用得不多,主要在特殊场景下用。
矢量计算API(重点)
矢量计算API是Ascend C的核心,用于向量化计算。主要分为几类:
1. 单目指令(一个输入):Exp按元素计算自然指数 e^x,Ln按元素计算自然对数,Abs按元素取绝对值,Reciprocal按元素取倒数 1/x,Sqrt按元素开平方,Rsqrt按元素开平方后取倒数 1/√x,Relu按元素做ReLU激活函数 max(0, x)。
2. 双目指令(两个输入):Add按元素求和 c = a + b,Sub按元素求差 c = a - b,Mul按元素求积 c = a * b,Div按元素求商 c = a / b,Max按元素取最大值 c = max(a, b),Min按元素取最小值 c = min(a, b),FusedMulAdd融合乘加 c = a * b + c(这个很常用,性能好)。
3. 标量双目指令(向量和标量):Adds向量每个元素加标量,Muls向量每个元素乘标量,Maxs/Mins向量每个元素和标量比较。
4. 归约指令(Reduction):ReduceSum对所有数据求和,ReduceMax/ReduceMin找最大值/最小值,BlockReduceSum对每个数据块求和。
数据搬运API
DataCopy:用于在Global Memory和Local Memory之间搬运数据。这是写算子必须用的API,因为计算前要把数据从Global Memory加载到Local Memory,计算后要把结果写回去。
1.3.4 一个简单的例子
虽然现在还没深入学,但可以先看看Ascend C算子大概长什么样:
// 这是一个概念性的例子,展示基本结构
// 实际的API调用会在后续章节详细讲解
// 核函数定义
void AddKernel(GlobalTensor<input_tensor>, GlobalTensor<output_tensor>) {
// 1. 定义LocalTensor,用于存储从Global Memory加载的数据
LocalTensor local_input;
LocalTensor local_output;
// 2. 数据搬运:从Global Memory加载到Local Memory
DataCopy(local_input, input_tensor);
// 3. 执行计算:使用Add API进行向量加法
Add(local_output, local_input, local_input); // output = input + input
// 4. 结果写回:从Local Memory写回Global Memory
DataCopy(output_tensor, local_output);
}
这个例子展示了Ascend C算子的基本结构:数据从Global Memory加载到Local Memory,在Local Memory上进行计算,最后结果写回Global Memory。
1.3.5 为什么这样设计
你可能好奇为什么要分Global Memory和Local Memory,直接算不行吗?
原因很简单:性能
Global Memory容量大,但访问慢(需要DMA传输)。Local Memory容量小,但访问快(片上缓存)。所以先把数据批量加载到Local Memory,在Local Memory上快速计算,最后批量写回。
这就是昇腾处理器的计算模式,理解了这一点,写算子的时候就知道怎么优化了
学习检查点
学完这一篇,你应该能做到这些:
首先,你得知道昇腾AI处理器大概是怎么回事,有哪些型号。然后了解CANN框架是干什么的,有哪些组件。理解计算单元和存储层次,知道数据是怎么流动的。能把开发环境搭起来,能编译运行代码。了解Ascend C的基本概念,知道GlobalTensor和LocalTensor的区别。知道Ascend C有哪些基础API,比如Add、Mul这些向量计算API。最后,理解为什么需要数据搬运,知道Global Memory和Local Memory的作用。
实践练习
环境搭建实践:在ModelArts创建一个Notebook实例,选择包含CANN的镜像和昇腾实例规格。验证一下环境,确认CANN和NPU都正常。配置一下开发环境,JupyterLab或VS Code远程连接都可以。跑通一个简单的示例程序,确认环境没问题。
Ascend C基础理解:查阅昇腾官方文档,看看Ascend C的API列表。理解GlobalTensor和LocalTensor的区别,知道什么时候用哪个。看看Add、Mul这些基础API的文档,了解它们怎么用。
理解测试:画个昇腾处理器的存储层次结构图,标注Global Memory和Local Memory。解释为什么需要Local Memory,直接在Global Memory上算行不行。说明数据搬运的必要性,理解"加载-计算-写回"的流程。
下一步:基础打好了,就可以开始学Ascend C的核心概念了。下一章会讲Ascend C的编程模型、数据类型这些,到时候就能开始写真正的算子了。
2025年昇腾CANN训练营第二季,基于CANN开源开放全场景,推出0基础入门系列、码力全开特辑、开发者案例等专题课程,助力不同阶段开发者快速提升算子开发技能。获得Ascend C算子中级认证,即可领取精美证书,完成社区任务更有机会赢取华为手机,平板、开发板等大奖。
报名链接:https://www.hiascend.com/developer/activities/cann20252
社区地址:https://www.hiascend.com/developer
更多推荐


所有评论(0)