CANN_CV算子架构介绍
CANN CV算子体系的三大特点:分层清晰基础算子 → 高级算子简单任务 → 复杂任务易于理解和扩展模块化设计接口定义清晰(InferShape、Tiling、SLN等)代码组织合理(文档、测试、实现分离)便于维护和优化应用广泛智能驾驶、平安城市、医疗等多领域YOLO、Mask R-CNN、U-Net等多算法覆盖主流CV应用场景。
CANN CV算子架构
训练营简介
2025年昇腾CANN训练营第二季,基于CANN开源开放全场景,推出0基础入门系列、码力全开特辑、开发者案例等专题课程,助力不同阶段开发者快速提升算子开发技能。获得Ascend C算子中级认证,即可领取精美证书,完成社区任务更有机会赢取华为手机,平板、开发板等大奖
报名链接:https://www.hiascend.com/developer/activities/cann20252#cann-camp-2502-intro
思维导图
mindmap
root((CV算子架构课堂笔记))
为什么学习CV算子
AI核心组件
性能关键
CANN架构
异构计算
完善生态
高性能优化
算子分类体系
基础算子层
图像预处理
Upsample
Grid Sample
几何变换
高级算子层
ROI Align
旋转ROI Align
点云算子
插值类算子
1D插值::时序数据
2D插值::图像处理
3D插值::医学影像
代码结构
快速体验
build.sh脚本
目录组织
Box::接口文档
Ramp::性能测试
OP Graph::图模式
核心组件
InferShape::形状推导
Tiling::数据分块
SLN::C接口
OpKernel::核心逻辑
应用场景
智能驾驶
实时检测
安全关键
平安城市
视频处理
多路并发
医学影像
3D数据
高精度要求
典型算法
YOLO::上采样
Mask R-CNN::几何变换
U-Net::插值融合
课程总结
学习路径
知识点回顾
实践计划
一、为什么要学习CV算子?
1.1 CV算子在AI中的重要性
这节课老师首先强调了CV算子的核心地位。老师说,计算机视觉(CV)算子是深度学习框架中的核心组件,直接影响着AI模型的性能和效率。
我的理解:
就像汽车的发动机一样,算子性能好坏直接决定了整个AI应用的速度。如果算子慢,再好的模型也跑不快。
1.2 CANN是什么?
老师介绍说,CANN(Compute Architecture for Neural Networks)是华为昇腾的异构计算架构,为CV算子提供了完善的支持体系。
关键特点:
- 异构计算:支持CPU、NPU等不同计算单元
- 完善生态:覆盖从算子开发到应用部署的全流程
- 高性能:针对昇腾NPU深度优化
二、CV算子分类体系详解
2.1 整体架构概览
老师画了一个非常清晰的分层图,我这里用文字整理一下:
┌─────────────────────────────────┐
│ 高级算子层(复杂任务) │
│ ROI Align / 旋转ROI / 点云 │
├─────────────────────────────────┤
│ 基础算子层(基础操作) │
│ 插值 / 几何变换 / 像素处理 │
└─────────────────────────────────┘
老师强调: 基础算子是地基,高级算子是建筑。地基不牢,地动山摇!
2.2 基础算子层详解
(1)图像预处理类操作
这是最基础的一层,老师说这层算子在任何CV应用中都会用到。
主要包含:
- 几何变换:旋转、缩放、平移等
- 像素级处理:归一化、颜色空间转换等
- 预测类算子:为后续处理做准备
(2)Upsample算子
老师特别详细地讲了这个算子,因为它使用频率非常高。
功能: 上采样,把小图放大
应用场景:
- 图像超分辨率
- 语义分割中的特征图恢复
- 目标检测的多尺度特征融合
我的笔记:
Upsample就像放大镜,可以把10×10的特征图放大到100×100,但要保证放大后的质量。
(3)Grid Sample算子
老师的比喻:
Grid Sample像一个"智能采样器",可以根据指定的坐标网格从输入图像中采样。
核心作用:
- 坐标系统到图像坐标的转换
- 支持任意形状的采样
- 常用于图像矫正、仿射变换等
实际应用示例:
输入:原始图像 + 采样网格坐标
输出:按照网格坐标采样后的图像
用途:图像扭曲矫正、透视变换
2.3 高级算子层详解
(1)ROI Align算子
老师说这个算子在目标检测中非常重要!
ROI是什么?
- Region of Interest,感兴趣区域
- 就是目标检测框出来的那块区域
ROI Align的作用:
- 从特征图中精确提取感兴趣区域
- 相比ROI Pooling更精确(没有量化误差)
- Mask R-CNN等网络的核心组件
老师的例子:
假设特征图是32×32,检测到一个物体在(10.5, 15.3, 20.7, 25.6)这个位置,ROI Align可以精确提取这块区域,不会因为小数坐标而丢失精度。
(2)旋转ROI Align
这是ROI Align的升级版!
新增能力:
- 支持任意角度的目标检测
- 不再局限于水平/垂直的矩形框
应用场景:
- 遥感图像分析:建筑物、道路往往是倾斜的
- 文字检测:文字方向可能是任意角度
- 工业缺陷检测:缺陷形状不规则
我的理解:
普通ROI Align只能处理正的矩形框,旋转ROI Align可以处理斜着的框,大大提升了检测能力。
(3)Cyclic Group Point算子
老师说这个算子比较特殊,是专门用于点云处理的。
点云是什么?
- 三维空间中的离散点集合
- 每个点有(x, y, z)坐标,可能还有颜色等属性
- 常见于激光雷达扫描数据
算子功能:
- 点云聚合:将相近的点聚合在一起
- 特征提取:从点云中提取有用信息
- 应用:自动驾驶的环境感知、三维重建等
2.4 插值类算子的维度支持
老师重点讲了插值算子支持的三种维度:
(1)1D插值
数据形状: (Batch, Channel, Length)
应用场景:
- 时序数据处理:音频信号重采样
- 传感器数据:温度、压力等时间序列
- 一维信号处理
(2)2D插值
数据形状: (Batch, Channel, Height, Width)
应用场景:
- 图像缩放:最常用的场景
- 特征图尺寸调整
- RGB图像处理
老师强调: 2D插值是使用最广泛的,90%的CV任务都用它!
(3)3D插值
数据形状: (Batch, Channel, Depth, Height, Width)
应用场景:
- 医学影像:CT、MRI扫描数据
- 视频处理:时间维度+空间维度
- 三维重建
我的笔记:
根据具体的网络结构和应用场景选择合适的维度,不要用2D去处理3D数据!
三、代码结构与工程实践
3.1 快速上手体验
老师演示了如何快速体验CANN CV算子:
# 执行构建脚本
./build.sh
# 脚本会自动完成:
# 1. 编译算子代码
# 2. 运行测试用例
# 3. 生成性能报告
# 4. 打开文档说明
老师的建议:
新手第一次学习,先运行build.sh体验一下整个流程,有了感性认识再深入学习。
3.2 目录结构详解
老师详细讲解了代码的目录组织:
cann_cv_ops/
├── docs/ # 文档目录
│ ├── box/ # Box目标:算子接口文档
│ ├── ramp/ # Ramp目标:性能测试文档
│ └── op_graph/ # OP Graph:图模式开发文档
├── op_kernel/ # 算子核心实现
│ ├── tiling/ # Tiling分块策略
│ ├── infer_shape/ # 形状推导
│ └── kernel/ # 核函数实现
├── tests/ # 测试代码
└── build.sh # 构建脚本
(1)Box目标:算子接口文档
老师说这是最重要的参考资料!
包含内容:
- API接口说明
- 参数详细解释
- 使用示例代码
- 注意事项和限制
我的使用经验:
开发算子前一定要先看Box文档,了解接口定义和参数含义,避免走弯路。
(2)Ramp目标:算子性能测试
功能:
- 性能基准测试
- 不同场景下的性能对比
- 性能瓶颈分析
测试维度:
- 不同输入尺寸
- 不同channel数
- 不同数据类型(FP16/FP32)
老师的经验分享:
“做性能优化,一定要有数据支撑。Ramp测试可以帮你找到真正的瓶颈。”
(3)OP Graph目标:图模式开发文档
什么是图模式?
老师解释说,深度学习框架通常用计算图来表示网络结构,多个算子连接成图。
文档内容:
- 如何在计算图中使用算子
- 算子融合优化
- 图优化技巧
3.3 核心组件深入讲解
(1)InferShape接口
老师说这个接口经常被忽视,但其实很重要!
作用: 推导输出张量的形状和类型
为什么需要?
因为输入输出的形状/类型可能不一致。
经典例子:equal算子
# 输入
a = [1.0, 2.0, 3.0] # float类型
b = [1.0, 2.5, 3.0] # float类型
# 输出
result = [True, False, True] # bool类型
InferShape的工作:
- 接收输入的形状和类型信息
- 根据算子逻辑推导输出形状
- 确定输出数据类型
- 返回shape和dtype信息
老师强调:
InferShape在构建计算图阶段执行,不涉及实际计算,所以要快速、准确。
(2)Tiling接口
这是老师花时间最多的部分,因为Tiling是性能优化的关键!
什么是Tiling?
老师的比喻:就像铺瓷砖一样,把大任务切成小块,每块分配给一个计算核心。
为什么需要Tiling?
- 硬件限制: 局部内存容量有限,大数据无法一次处理
- 多核并行: NPU有多个计算核心,Tiling让它们并行工作
- 性能优化: 合理分块可以提升缓存利用率
Tiling策略示例:
原始任务:处理1024×1024的图像
Tiling策略:切分成16个256×256的块
每个核心:处理1-2个块
总耗时:原来的1/8(假设8核并行)
老师的经验:
Tiling是个技术活,块太大放不下内存,块太小并行度不够。需要根据具体硬件特性调整。
(3)SLN接口
SLN = Standard Library Native接口
作用: 提供C语言级别的调用接口
使用场景:
- 应用程序直接调用算子
- 不需要经过复杂的框架层
- 追求极致性能的场景
调用示例(伪代码):
// C语言调用
void* input = malloc(size);
void* output = malloc(size);
// 直接调用算子
upsample_sln(input, output, params);
free(input);
free(output);
老师的提醒:
SLN接口更底层,灵活性高但使用也更复杂。一般场景用框架接口就够了,特殊需求才用SLN。
(4)OpKernel核心实现层
这是算子的"心脏"!
位置: op_kernel/kernel/目录下
内容:
- 算子的核心计算逻辑
- 硬件指令调用
- 内存管理
- 性能优化代码
老师的讲解:
OpKernel是真正干活的地方,前面的接口都是为它服务的。这里的代码质量直接决定性能。
模块化设计:
kernel/
├── upsample_kernel.cpp # 上采样核函数
├── grid_sample_kernel.cpp # 采样核函数
├── roi_align_kernel.cpp # ROI对齐核函数
└── utils/ # 公共工具函数
├── coord_transform.h # 坐标转换
└── interpolation.h # 插值计算
四、实际应用场景深度解析
4.1 智能驾驶场景
老师举了一个自动驾驶的实际例子:
场景描述:
自动驾驶车辆需要实时识别道路上的行人、车辆、交通标志等。
用到的CV算子:
-
Upsample算子
- 作用:将低分辨率特征图放大
- 场景:检测远处的小目标(行人)
- 要求:速度快(实时性)、精度高(安全性)
-
ROI Align算子
- 作用:精确提取检测到的目标区域
- 场景:对检测框内的物体进行分类
- 要求:精度极高(毫米级误差可能导致事故)
-
Grid Sample算子
- 作用:图像畸变矫正
- 场景:鱼眼摄像头的图像矫正
- 要求:低延迟(<10ms)
老师的总结:
智能驾驶对算子的要求是:快、准、稳!一个算子慢了10ms,可能就是生死之别。
4.2 平安城市场景
场景描述:
城市监控系统需要处理数千个摄像头的海量视频数据。
技术挑战:
- 数据量大: 同时处理上千路视频流
- 持续运行: 7×24小时不间断
- 多种任务: 人脸识别、车辆识别、行为分析等
算子应用:
-
几何变换算子
- 处理不同角度的摄像头画面
- 统一到标准视角
-
Upsample算子
- 放大远处的人脸/车牌
- 提高识别准确率
-
旋转ROI Align
- 提取任意角度的人脸区域
- 适应各种头部姿态
我的理解:
平安城市场景更注重吞吐量和稳定性,需要算子能高效处理大批量数据。
4.3 医学影像分析场景
老师说这个场景比较特殊,因为涉及3D数据。
典型任务:CT/MRI图像分析
数据特点:
- 三维数据:(Depth, Height, Width)
- 精度要求极高:关系到诊断准确性
- 数据量大:一次CT扫描可能上百层
用到的算子:
-
3D插值算子
- 统一不同设备的扫描分辨率
- 将各向异性数据转为各向同性
-
3D几何变换
- 配准:将不同时间的扫描对齐
- 旋转:从不同角度观察病灶
老师的提醒:
医学影像对精度要求极高,宁可慢一点,也要保证准确。这和智能驾驶的侧重点不同。
4.4 具体算法应用案例
(1)YOLO系列目标检测
老师详细讲解了YOLO中Upsample的使用:
网络结构(简化):
输入图像(640×640)
↓
主干网络提取特征
↓
特征金字塔
├─ 小特征图(20×20) ──Upsample×2→ (40×40) ─┐
├─ 中特征图(40×40) ──Upsample×2→ (80×80) ─┤─→ 融合 → 检测
└─ 大特征图(80×80) ─────────────────────┘
Upsample的作用:
- 将低分辨率特征图放大
- 与高分辨率特征融合
- 提高小目标检测能力
性能要求:
- YOLO强调实时性
- Upsample必须快速(<1ms)
- 这就是为什么需要优化算子
(2)Mask R-CNN实例分割
几何变换的应用:
流程:
1. 检测到物体 → 得到检测框(可能是倾斜的)
2. 使用旋转ROI Align提取区域
3. 统一到固定尺寸(如14×14)
4. 进行分类和分割
老师的比喻:
“就像拍照时,不管人脸是正的还是斜的,都要裁剪成标准的证件照尺寸。”
为什么要对齐?
- 分类网络要求固定输入尺寸
- 对齐后的图像更容易识别
- 提高识别准确率
(3)U-Net医学图像分割
插值类算子的大量应用:
U-Net结构特点:
编码器(下采样) 解码器(上采样)
↓ ↑
下采样 ←─────跳跃连接─────→ 上采样
↓ ↑
下采样 ←─────跳跃连接─────→ 上采样
↓ ↑
插值算子的使用:
- 下采样:降低分辨率(可用池化或插值)
- 上采样:恢复分辨率(必须用插值)
- 跳跃连接:需要尺寸对齐(可能需要插值)
老师强调:
U-Net中插值算子被调用非常多次,如果每次都慢1ms,整个网络就慢了几十ms,所以优化很重要!
五、目标检测类算子专题
5.1 IoU计算算子
IoU是什么?
老师解释:Intersection over Union,交并比。
数学定义:
IoU = 交集面积 / 并集面积
= (A ∩ B) / (A ∪ B)
用途:
- 训练阶段: 判断预测框和真实框的匹配程度
- 推理阶段: NMS(非极大值抑制)需要计算IoU
- 评估指标: mAP计算的基础
计算流程:
输入:两个矩形框 Box1(x1,y1,x2,y2), Box2(x1,y1,x2,y2)
步骤1:计算交集矩形
inter_x1 = max(Box1.x1, Box2.x1)
inter_y1 = max(Box1.y1, Box2.y1)
inter_x2 = min(Box1.x2, Box2.x2)
inter_y2 = min(Box1.y2, Box2.y2)
步骤2:计算交集面积
inter_area = (inter_x2 - inter_x1) × (inter_y2 - inter_y1)
步骤3:计算并集面积
union_area = Box1.area + Box2.area - inter_area
步骤4:计算IoU
iou = inter_area / union_area
5.2 旋转IoU算子
升级点:支持旋转矩形!
应用场景:
- 遥感图像:建筑物检测
- 文字检测:OCR中的文字框
- 医学图像:器官边界检测
技术难点:
老师说,旋转矩形的交集计算比正矩形复杂得多!
计算方法:
- 将旋转矩形转换为多边形
- 计算多边形交集(用多边形裁剪算法)
- 计算交集面积
- 计算IoU
性能挑战:
- 计算复杂度高
- 需要大量浮点运算
- 边界情况多(完全不相交、包含、部分重叠等)
老师的经验:
旋转IoU算子的优化空间很大,通过向量化和查找表优化,可以提速5-10倍。
5.3 Cyclic Group Point点云聚合算子
点云处理的特殊性:
数据特点:
- 无序性:点的顺序无意义
- 稀疏性:三维空间中点分布稀疏
- 不规则:不像图像那样规则排列
算子功能:
- 点云聚合: 将相近的点组成群组
- 特征提取: 从点群中提取代表性特征
- 下采样: 减少点的数量,保留关键信息
应用实例:自动驾驶的激光雷达处理
原始点云(100,000点)
↓
Cyclic Group Point聚合
↓
关键点云(10,000点)
↓
目标检测/分割
老师的总结:
点云算子和图像算子的优化思路不同,因为数据结构完全不一样,需要专门的算法。
六、课程总结与学习收获
6.1 老师的总结
老师在课程最后做了精彩的总结:
CANN CV算子体系的三大特点:
-
分层清晰
- 基础算子 → 高级算子
- 简单任务 → 复杂任务
- 易于理解和扩展
-
模块化设计
- 接口定义清晰(InferShape、Tiling、SLN等)
- 代码组织合理(文档、测试、实现分离)
- 便于维护和优化
-
应用广泛
- 智能驾驶、平安城市、医疗等多领域
- YOLO、Mask R-CNN、U-Net等多算法
- 覆盖主流CV应用场景
6.2 我的个人收获
知识层面:
- 理解了CV算子的分类体系和设计思想
- 掌握了CANN算子的代码结构和核心组件
- 了解了实际应用场景中的算子使用
技能层面:
- 学会了如何快速上手CANN算子开发
- 理解了Tiling、InferShape等关键接口的作用
- 知道了如何根据应用场景选择合适的算子
思维层面:
- 算子是AI应用的基础,性能优化很重要
- 工程化设计(模块化、文档化)同样关键
- 理论联系实际,学以致用
6.3 后续学习计划
老师建议的学习路径:
第一阶段:熟悉环境
- 搭建CANN开发环境
- 运行示例代码
- 阅读算子接口文档
第二阶段:动手实践
- 实现一个简单算子(如Upsample)
- 进行性能测试
- 尝试优化
第三阶段:深入优化
- 学习向量化、矩阵化技术
- 掌握Tiling分块策略
- 实现高性能算子
第四阶段:综合应用
- 将算子集成到实际网络
- 端到端性能优化
- 参与社区贡献
6.4 重要知识点回顾
| 知识点 | 核心内容 | 重要程度 |
|---|---|---|
| 算子分类 | 基础层、高级层、插值类 | ⭐⭐⭐⭐⭐ |
| InferShape | 形状和类型推导 | ⭐⭐⭐⭐ |
| Tiling | 数据分块、多核并行 | ⭐⭐⭐⭐⭐ |
| SLN接口 | C语言级调用 | ⭐⭐⭐ |
| OpKernel | 核心计算逻辑 | ⭐⭐⭐⭐⭐ |
| 应用场景 | 驾驶、安防、医疗 | ⭐⭐⭐⭐ |
七、课后思考题
思考题1:为什么需要旋转ROI Align?普通ROI Align不够用吗?
我的思考:
普通ROI Align只能处理水平矩形,但实际应用中很多目标是倾斜的(如文字、建筑物)。旋转ROI Align可以更精确地提取倾斜目标,减少背景干扰,提高识别准确率。
思考题2:Tiling分块策略如何影响性能?
我的理解:
- 块太大:超出局部内存,性能下降
- 块太小:并行度不够,核心利用率低
- 合适大小:充分利用内存和计算资源
需要根据具体硬件(内存大小、核心数)和任务(数据量、计算复杂度)来确定最优分块策略。
思考题3:为什么医学影像需要3D插值,2D不够吗?
我的想法:
CT/MRI扫描是三维数据,直接用3D插值可以:
- 保持三维空间的连续性
- 避免分层处理的累积误差
- 更准确地恢复三维结构
如果用2D逐层处理,层与层之间可能出现不连续,影响诊断准确性。
八、参考资料与拓展阅读
8.1 官方资料
- CANN官方文档:https://www.hiascend.com/document
- 昇腾社区:https://www.hiascend.com/forum
- 算子开发指南:https://www.hiascend.com/document/detail/zh/CANNCommunityEdition/80RC1alpha003/operatordev/
8.2 相关论文
- ROI Align: Mask R-CNN论文
- 双线性插值: 经典图像处理教材
- 点云处理: PointNet系列论文
8.3 开源项目
- CANN算子开源仓库
- PyTorch算子实现参考
- 昇腾社区示例代码
课堂笔记整理人: [你的名字]
课程日期: 2025年X月X日
讲师: 周期龙老师 / CANN团队
备注:本笔记为个人课堂记录,包含个人理解和标注。部分内容为课后查阅资料补充。如有错误欢迎指正!
笔记心得:
这节课干货满满,从宏观架构到微观实现都有涉及。特别是Tiling和OpKernel的讲解,让我理解了高性能算子的设计思路。后续要动手实践,才能真正掌握!💪
昇腾计算产业是基于昇腾系列(HUAWEI Ascend)处理器和基础软件构建的全栈 AI计算基础设施、行业应用及服务,https://devpress.csdn.net/organization/setting/general/146749包括昇腾系列处理器、系列硬件、CANN、AI计算框架、应用使能、开发工具链、管理运维工具、行业应用及服务等全产业链
更多推荐


所有评论(0)