第一篇:基础准备阶段

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

Logo

这里是“一人公司”的成长家园。我们提供从产品曝光、技术变现到法律财税的全栈内容,并连接云服务、办公空间等稀缺资源,助你专注创造,无忧运营。

更多推荐