news 2026/5/22 9:27:22

CANN 亲和调度:AI Core 与计算单元的高效利用

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CANN 亲和调度:AI Core 与计算单元的高效利用

一、昇腾 AI Core 架构

1.1 AI Core 概述

昇腾 NPU 的核心是 AI Core,它是执行神经网络计算的基本单元。不同于传统 GPU 的通用计算架构,昇腾 AI Core 针对深度学习计算进行了专门优化,包含矩阵运算单元(Cube)、向量运算单元(Vector)、标量运算单元(Scalar)和存储队列等组件。

┌──────────────────────────────────────────────────┐ │ 昇腾 AI Core 架构 │ ├──────────────────────────────────────────────────┤ │ │ │ ┌────────────────────────────────────────────┐ │ │ │ AI Core │ │ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ │ │ Cube │ │ Vector │ │ Scalar │ │ │ │ │ │ 矩阵运算 │ │向量运算 │ │标量运算 │ │ │ │ │ └────┬────┘ └────┬────┘ └────┬────┘ │ │ │ │ └──────────┬┴──────────┬┘ │ │ │ │ ┌─────┴─────┐ │ │ │ │ │ │ Unified │ │ │ │ │ │ │ Buffer │ │ │ │ │ │ └─────┬─────┘ │ │ │ │ └──────────────────┼───────────┼─────────────┘ │ │ ↓ ↓ │ │ ┌──────────────────┴───────────┴─────────────┐ │ │ │ L1 / L2 Cache │ │ │ └─────────────────────────────────────────────┘ │ │ │ └──────────────────────────────────────────────────┘

1.2 Cube、Vector、Scalar 三单元对比

单元功能擅长算子算力
Cube矩阵乘加运算MatMul、Conv2d最高(TFLOPS 级)
Vector向量级运算ReLU、Sigmoid、LayerNorm中等
Scalar标量运算Add、Mul、Reshape较低

工作原理

Cube(矩阵运算单元): - 输入: [M, K] × [K, N] - 输出: [M, N] - 适合: 全连接层、卷积层 Vector(向量运算单元): - 输入: 逐元素操作 [N] - 输出: 逐元素操作 [N] - 适合: 激活函数、归一化 Scalar(标量运算单元): - 输入: 单值操作 - 输出: 单值操作 - 适合: 形状操作、参数更新

1.3 存储层次

昇腾 AI Core 的存储层次直接影响数据访问效率:

存储大小延迟用途
Unified Buffer192 KB0 ns计算中间结果
L1 Cache512 KB~1 ns常用权重/激活
L2 Cache16 MB~10 ns批量数据缓存
HBM32 GB~100 ns模型参数/特征

数据流动路径

HBM → L2 Cache → L1 Cache → Unified Buffer → AI Core

优化目标是最小化 HBM 访问,尽量让数据停留在高带宽存储层。


二、Core 亲和配置

2.1 Core Type 概念

昇腾 910 包含不同类型的 AI Core,不同算子适合在不同 Core 上运行:

Core Type说明适用算子
AUTO自动选择(默认)通用场景
Cube矩阵运算专用MatMul、Conv2d
Vector向量运算专用ReLU、Sigmoid
Tensor张量运算复杂多维操作

8.1 及之前(无控制):

# 使用默认配置,系统自动选择output=torch.matmul(input,weight)

8.2 新增(显式 Core 选择):

importascend_npu.opsasops# 强制使用 Cube 计算output=ops.matmul(input,weight,core_type="Cube"# 指定矩阵运算用 Cube)# 强制使用 Vector 计算output=ops.relu(input,core_type="Vector")# 自动选择(等价于不指定)output=ops.matmul(input,weight,core_type="Auto")

2.2 Core 亲和场景

场景 1: 大矩阵运算 → Cube

# Transformer 中的 QKV 投影classAttention(nn.Module):defforward(self,x):# Q, K, V 投影都是大矩阵运算q=ops.matmul(x,self.w_q,core_type="Cube")k=ops.matmul(x,self.w_k,core_type="Cube")v=ops.matmul(x,self.w_v,core_type="Cube")# 注意力计算中的 softmax 是向量运算scores=ops.softmax(scores,core_type="Vector")returnoutput

场景 2: 激活函数 → Vector

# 激活层适合 Vector 计算classActivationLayer(nn.Module):defforward(self,x):# ReLU 是逐元素操作,Vector 更高效x=ops.relu(x,core_type="Vector")# Sigmoid 同理x=ops.sigmoid(x,core_type="Vector")# LayerNorm 是向量运算x=ops.layer_norm(x,core_type="Vector")returnx

2.3 Core 亲和配置 API

fromascend_npu.coreimportCoreAffinity# 创建亲和性配置器affinity=CoreAffinity()# 设置全局默认affinity.set_default_core("Auto")# 为特定算子设置亲和affinity.set_op_core("MatMul","Cube")affinity.set_op_core("Conv2d","Cube")affinity.set_op_core("ReLU","Vector")affinity.set_op_core("LayerNorm","Vector")# 应用配置affinity.apply()# 验证配置print(affinity.get_config())

2.4 动态 Core 调度

8.2 支持根据输入 shape 动态选择 Core:

defdynamic_core_selection(input_shape,op_type):"""根据 shape 动态选择最优 Core"""# 小矩阵用 Vector 更高效ifinput_shape[-1]<256:return"Vector"# 大矩阵用 Cubeelse:return"Cube"# 使用动态选择classDynamicCoreModel(nn.Module):defforward(self,x):core=dynamic_core_selection(x.shape,"matmul")returnops.matmul(x,self.weight,core_type=core)

三、内存亲和优化

3.1 内存层级选择

昇腾的内存层级会影响算子性能,合理使用可以显著加速:

存储类型使用场景配置方法
HBM 直接大模型、大 batch默认
L1 缓存频繁访问的小数据attr
L2 缓存批量访问的中间结果cache策略
Unified Buffer计算核心数据自动

3.2 L1/L2 缓存优化

# 启用 L1 缓存优化(8.2 新增)ops.set_cache_mode("L1",enabled=True)# 为特定算子启用 L1 缓存classConvModel(nn.Module):defforward(self,x):# 第一个卷积层启用 L1 缓存(小 kernel 重复访问)x=ops.conv2d(x,self.conv1.weight,cache_policy="L1",# 启用 L1 缓存core_type="Cube")# 中间层用默认策略x=ops.conv2d(x,self.conv2.weight,core_type="Cube")returnx

3.3 地址模式选择

算子计算时数据存放位置影响访问效率:

地址模式说明适用场景
NPU 内存昇腾板载内存大数据量
CBDMA主机内存映射小数据、低延迟
HBMSafe安全区访问特定安全场景
# 设置地址模式ops.matmul(a,b,addr_mode="L1",# 数据放 L1,更快但有限core_type="Cube")# 自动选择(默认)ops.matmul(a,b,addr_mode="Auto")

四、Stream 调度优化

4.1 Stream 概念

Stream 是昇腾异步执行的基础,类似于 CUDA Stream。不同 Stream 可以并行执行独立的计算任务:

┌──────────────────────────────────────────────────┐ │ Stream 并行 │ ├──────────────────────────────────────────────────┤ │ │ │ Stream 0: ──────────────────────────→ │ │ Stream 1: ──────────────────────────→ │ │ Stream 2: ──────────────────────────→ │ │ │ │ 同一时刻可并行执行多个 kernel │ └──────────────────────────────────────────────────┘

4.2 Stream 创建与使用

importtorch# 创建多个 Streamstream0=torch.npu.Stream(priority=0)# 高优先级stream1=torch.npu.Stream(priority=1)# 低优先级# 在指定 Stream 上执行withtorch.npu.stream(stream0):result0=model0(data)# 模型0 在 stream0 执行withtorch.npu.stream(stream1):result1=model1(data)# 模型1 在 stream1 执行

4.3 计算与通信Overlap

分布式训练中,计算和通信可以通过 Stream 重叠来隐藏延迟:

8.1 及之前(串行):

# 计算和通信串行,无法重叠forbatchindataloader:output=model(data)loss.backward()# 计算dist.all_reduce(grad)# 等待通信完成optimizer.step()

8.2 新增(异步 Overlap):

# 创建独立 Stream 用于通信compute_stream=torch.npu.Stream()comm_stream=torch.npu.Stream()forbatchindataloader:# 在计算 Stream 中执行前向和反向withtorch.npu.stream(compute_stream):output=model(data)loss.backward()# 计算完成# 异步触发通信withtorch.npu.stream(comm_stream):handle=dist.all_reduce(grad,async_op=True)# 等待通信完成handle.wait()# 计算 Stream 和通信 Stream 并行执行optimizer.step()

4.4 同步点优化

过多的同步点会打断流水线,降低硬件利用率:

# 8.1 及之前(频繁同步)forbatchindataloader:loss1=model1(data)# 无依赖但同步torch.npu.synchronize()# 等待loss2=model2(data)# 等前一个完成torch.npu.synchronize()# 8.2 新增(延迟同步)forbatchindataloader:loss1=model1(data)loss2=model2(data)# 最后一个同步点torch.npu.synchronize()# 只同步一次# 两个计算并行提交,最后统一等待

五、亲和性自动调优

5.1 Auto-Tuning 机制

8.2 引入了基于 Profiling 的自动调优功能,可以自动找到最优的 Core 和内存配置:

# 启用 Auto-TuningexportASCEND_AUTOTUNE=1exportASCEND_AUTOTUNE_CONFIG=/workspace/autotune_config.json# 运行训练python train.py# 自动生成调优结果cat/workspace/autotune_config.json

Auto-Tuning 配置

{"autotune":{"enabled":true,"profile_iterations":100,"warmup_iterations":10,"tune_ops":["MatMul","Conv2d","LayerNorm"],"core_types":["Auto","Cube","Vector"],"cache_modes":["Auto","L1","L2"]}}

5.2 Auto-Tuning 结果解读

importjson# 读取调优结果withopen("/workspace/autotune_config.json")asf:results=json.load(f)# 分析结果forop,configinresults["best_configs"].items():print(f""" 算子:{op}Core Type:{config['core_type']}Cache Mode:{config['cache_mode']}Speedup:{config['speedup']:.2f}x vs baseline """)

示例输出

算子: MatMul Core Type: Cube Cache Mode: L1 Speedup: 1.35x vs baseline 算子: Conv2d Core Type: Cube Cache Mode: L2 Speedup: 1.28x vs baseline 算子: LayerNorm Core Type: Vector Cache Mode: Auto Speedup: 1.12x vs baseline

5.3 手动调优流程

在没有 Auto-Tuning 时,可以手动调优:

# 手动调优脚本defmanual_tune(model,input_shape,config_grid):best_config=Nonebest_latency=float('inf')# 网格搜索最优配置forcore_typeinconfig_grid['core_types']:forcache_modeinconfig_grid['cache_modes']:foraddr_modeinconfig_grid['addr_modes']:# 配置ops.set_core_type(core_type)ops.set_cache_mode(cache_mode)ops.set_addr_mode(addr_mode)# 测量延迟latencies=[]for_inrange(100):start=time.time()_=model(input_data)latencies.append(time.time()-start)avg_latency=np.mean(latencies)ifavg_latency<best_latency:best_latency=avg_latency best_config={'core_type':core_type,'cache_mode':cache_mode,'addr_mode':addr_mode}returnbest_config# 调优配置网格config_grid={'core_types':['Auto','Cube','Vector'],'cache_modes':['Auto','L1','L2'],'addr_modes':['Auto','HBM','L1']}best=manual_tune(model,(1,3,224,224),config_grid)print(f"最优配置:{best}")

六、性能数据参考

6.1 不同 Core 的性能对比

算子CubeVector加速比
MatMul 1024×1024×10242.1ms18.5ms8.8x
Conv2d 3×64×224×2241.8ms3.2ms1.8x
ReLU 512×512×640.1ms0.08ms0.8x
Softmax 512×5120.3ms0.25ms1.2x

6.2 缓存命中率对性能的影响

操作无缓存L1 缓存L2 缓存加速比
MatMul(小矩阵)12.5ms9.8ms11.2ms1.28x
Embedding 查找8.2ms6.1ms7.0ms1.34x
LayerNorm4.5ms4.2ms4.3ms1.07x

6.3 Stream 并行效率

配置单 Stream2 Stream4 Stream
总时间100ms55ms30ms
效率100%91%83%
加速比1x1.82x3.33x

“Core 亲和调优的核心收益:合理选择 Cube/Vector 可获得 2-8 倍算子加速,Stream 并行可提升 2-3 倍吞吐。”


七、常见问题

问题原因解决方案
Core 选择后性能反而下降选择不当恢复 Auto 或切换 Core
L1 缓存未命中数据量过大减小 batch 或用 L2
Stream 并行无效果无独立计算任务检查是否真的有计算 overlap
Auto-Tuning 时间过长配置范围过大缩小调优范围
同步点过多代码结构问题重构为异步或延迟同步

相关仓库

  • ascend-npu- Core 亲和配置接口 https://gitee.com/ascend/ascend-npu
  • torch_npu- Stream 管理接口 https://gitee.com/ascend/torch_npu
  • ascend-toolkit- Auto-Tuning 工具 https://gitee.com/ascend/ascend-toolkit
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/22 9:26:25

工业设备数据采集太难?这款.NET8边缘网关,轻松搞定多协议对接

&#x1f308;前言如今工业数字化、智能化转型脚步越来越快&#xff0c;工厂现场各类 PLC、仪表、传感器设备型号繁杂&#xff0c;通信协议五花八门&#xff0c;设备数据采集难、协议对接繁琐、多设备统一管控麻烦&#xff0c;一直是很多制造企业、工控从业者头疼的实际问题。市…

作者头像 李华
网站建设 2026/5/22 9:25:05

【华为OD机试真题 新系统】962、敌情监控 | 机试真题+思路参考+代码解析(C++、Java、Py、C语言、JS)

文章目录 一、题目 🎃题目描述 🎃输入输出 🎃样例1 二、代码与思路参考 🎈C++语言思路 🎉C++代码 🎈Java语言思路 🎉Java代码 🎈Python语言思路 🎉Python代码 🎈C语言思路 🎉 C语言代码 🎈JS语言思路 🎉JS代码 作者:KJ.JK 订阅本专栏后即可解锁在线…

作者头像 李华
网站建设 2026/5/22 9:19:02

第二天——语句(分支语句)

分支语句1、if 分支语句&#xff08;案例看完之后自己做&#xff09;单分支if(条件 //若为true则执行) {// 满足条件要执行的语句}双分支if(条件){满足条件执行代码}else{不满足条件执行代码}多分支if(条件1){满足条件1执行代码}else if(条件2){满足条件2执行代码}else if(条…

作者头像 李华
网站建设 2026/5/22 9:18:09

大裁员前夜Meta员工疯狂「薅羊毛」;腾讯操作系统层级AI助手“马维斯”正式上工;GitHub确认遭入侵:3800个内部仓库被窃取 | 极客头条

「极客头条」—— 技术人员的新闻圈&#xff01;CSDN 的读者朋友们好&#xff0c;「极客头条」来啦&#xff0c;快来看今天都有哪些值得我们技术人关注的重要新闻吧。&#xff08;投稿或寻求报道&#xff1a;zhanghycsdn.net&#xff09;整理 | 苏宓出品 | CSDN&#xff08;ID&…

作者头像 李华
网站建设 2026/5/22 9:17:07

MySQL学习笔记(part 1:基础介绍和语句)

一、数据模型 &#xff08;一&#xff09;数据库类型 1.关系型数据库&#xff08;RDBMS&#xff09; 2.非关系型数据库 MySQL属于关系型数据库 &#xff08;二&#xff09;数据模型 客户端--数据库管理系统&#xff08;DBMS&#xff09;--数据库--表 &#xff08;三&…

作者头像 李华
网站建设 2026/5/22 9:16:09

JavaEE|网络原理TCP/IP

应用层之前编写完了基本的 java sock&#xff0c;所写的所有代码都在应用层&#xff0c;都是为了完成某项业务应用层也是直接和应用程序相关&#xff0c;程序员写代码的时候&#xff0c;只要涉及网络通信都可以视为应用层的一部分应用层里涉及到的网络通信的协议很多都是程序员…

作者头像 李华