CANN ops-nn算子仓体验测评
op_host和op_kernel目录则是算子实现的核心目录,其中op_host下是算子的host侧实现,分为算子定义文件、算子推导和tiling实现,另外还有op_api文件夹,该文件夹用于存放算子调用aclnn接口,如果是基于现有的aclnn接口进行算子开发,可以直接相关的接口复制过来,否则就需要自己重新编写。编译成功后会生成相关的.o文件。,算子的开发并不是一蹴而就的,而是不断经过调试和优化
体验摘要
本次体验测评全面覆盖了从环境配置、算子开发、算子测试、算子调优到社区贡献的完整流程。在环境搭建方面,ops-nn仓提供了Docker 快速部署与手动安装两种方案。Docker方式极大简化了依赖配置显著减少了环境搭建时间,适合快速上手。而手动安装则具备更高的灵活性,比如能够适配notebook等特殊开发场景。在功能支持方面,ops-nn仓已经集成大量成熟的神经网络类算子,为专注模型训练和推理的开发者提供了开箱即用的能力。对于尚未覆盖的算子,仓库也提供了详细的《算子开发指南》和算子模版,有效降低了开发门槛,帮助开发者聚焦于核心算法逻辑的实现,大幅缩短非功能代码编写时间。在开发及调优过程中,日志提示信息也清晰明了,能够高效的辅助定位于与调试,对于复杂或难以解决的问题,提出ISSUES后,社区支持响应也很迅速。总体而言,ops-nn 在易用性、可扩展性与社区生态方面表现优异,是一套成熟、高效的算子开发与管理仓库。
为什么要测评ops-nn仓?
在当下AI快速发展阶段,大模型的应用覆盖了多个领域,而大模型的训练离不开底层算子的支持。随着NPU算力资源在市场中的比例越来越大,大模型的种类越来越多,算子的数量也不断增加。本次选择ops-nn仓测评,正是想测试CANN对于神经网络类算子的支持度,以及基于ops-nn仓算子开发的难易程度。
1.ops-nn仓介绍
ops-nn仓的项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。该仓是一个深度学习算子集合项目,主要包含 conv(卷积)、matmul(矩阵乘)、activation(激活函数)、loss(损失函数)、rnn(循环神经网络)、control(控制流)、index(索引)等核心类型的算子。每个算子都有标准的实现模块,并提供了自定义算子开发支持。项目结构清晰,便于算子的开发、集成与复用。
2.环境安装
本次是在华为云modelarts平台上进行操作,产品链接如下:modelarts。如果是第一次使用modelarts可能需要注册一个华为账号和一些其他配置,操作比较简单,百度搜索即可,这并不是本篇文章的重点。
进入modelarts后,点击创建notebook,镜像选择pytorch2.6-cann8.2.1,资源选择910b,可以根据个人需要是否开启ssh远程登陆,evs空间大小我这里选的是20G,之后点击创建,等待3-5分钟即可创建成功。参考下图:

创建成功后,打开notebook,参考下面的链接开始配置ops-nn仓环境:
https://gitcode.com/cann/ops-nn/blob/master/docs/zh/context/quick_install.md
第一步,下载toolkit和ops环境安装包,命令如下:
wget https://mirror-centralrepo.devcloud.cn-north-4.huaweicloud.com/artifactory/cann-run-release/software/9.0.0/20260127000324761/aarch64/Ascend-cann-toolkit_9.0.0_linux-aarch64.run
wget
https://mirror-centralrepo.devcloud.cn-north-4.huaweicloud.com/artifactory/cann-run-release/software/9.0.0/20260127000324761/aarch64/Ascend-cann-910b-ops_9.0.0_linux-aarch64.run
下载完成后,使用如下命令赋予执行权限:
chmod +x ./Ascend-*
安装toolkit包:
./Ascend-cann-toolkit_9.0.0_linux-aarch64.run --install --force --install-path=/usr/local/Ascend
期间如果弹出Y/N选择项,输入Y即可,出现如下的内容说明安装成功了。

安装CANN ops运行态依赖包,需要注意的是安装路径要跟上面的一致:
./Ascend-cann-910b-ops_9.0.0_linux-aarch64.run --install --force --install-path=/usr/local/Ascend
出现如下图片说明安装成功:

执行环境配置命令:
source /usr/local/Ascend/cann/set_env.sh
体验:下载速度比较快没用太长时间,但安装软件包耗时比较久,大概20分钟。
3.第一个算子---AddExample编译测试
执行算子编译命令:
bash build.sh --pkg --soc=ascend910b --ops=add_example -j16
输出如下图,说明编译成功:

提示:在编译AddExample算子时有可能会弹出"Ascend950"字样的错误,是因为AddExample中有关于昇腾950的配置,修改"examples/add_example/op_host"路径下的add_example_def.cpp文件,将51行关于"ascend950"的配置信息代码行注释一下即可。
部署算子并验证:
./build_out/cann-ops-nn-custom-linux.aarch64.run
export LD_LIBRARY_PATH=/usr/local/Ascend/cann-9.0.0/opp/vendors/custom_nn/op_api/lib/:${LD_LIBRARY_PATH}
bash build.sh --run_example add_example eager cust
算子验证结果如下图所示,说明算子调用成功:

在编译部署该算子时,编译花费的时间比较久,测试比较顺利,可见算子从编译到部署操作的流程都比较简单,简化了很多操作,特别是复杂的环境配置。
4.算子开发及贡献流程
ops-nn仓对于自定义算子有专门的目录experimental,开发者可以将自定义的算子工程放在该目录对应的算子类型子文件夹下。
以仓上算子SwishGrad为例,该算子可以逐元素计算,没有规约和广播操作。算子开发流程一是可以通过msOpGen工具从头生成自定义算子工程进行开发,但是从头开始开发会浪费一些不必要的时间,另一种方式就是通过模板开发,即基于现有的类似算子工程,在此基础上进行开发,可以减少流程上的代码编写,但是仍然需要开发者了解AscendC算子的开发流程,否则对于期间的报错将难以调试解决。
在SwishGrad算子工程下,包含了op_host、op_api、op_kernel、tests、docs、examples、README和CMakeLists文件或文件夹,如下图所示。

其中README文件是关于该算子的介绍,CMakeLists编译文件则是用于编译算子工程,docs目录是关于算子调用接口的介绍,examples目录提供了调用算子示例,tests目录则提供关于算子ut测试的样例。op_host和op_kernel目录则是算子实现的核心目录,其中op_host下是算子的host侧实现,分为算子定义文件、算子推导和tiling实现,另外还有op_api文件夹,该文件夹用于存放算子调用aclnn接口,如果是基于现有的aclnn接口进行算子开发,可以直接相关的接口复制过来,否则就需要自己重新编写。SwishGrad算子是该仓内已有了对应的aclnn接口,可以直接复制过来。
其中tiling的是需要根据算子逻辑具体实现的,其他文件按照模板不需要做太大的改动。op_kernel目录是关于算子的核函数实现,根据算子设计进行编写代码。
在进行SwishGrad的实际开发过程中,我是基于算子样例模板开发的,除了修改算子名称相关信息,还需要修改的是算子功能的实现逻辑。float16和bf16数据类型,为了避免计算过程中数据溢出,要做精度转换,先转换成float32类型,因此核函数实现要分开处理,而精度转换需要用到两个临时变量用来存储转换后的数据,因此tiling策略里面关于int32类型跟int16和uint16的UB_NUM是不一样的,需要分开计算。
在完成了算子开发过程后,就可以执行算子编译流程,在编译过程中会将语法问题识别出来,存放在build文件夹下,开发者可以通过查看该文件夹下的日志发现具体的语法问题并进行修改。编译成功后会生成相关的.o文件。编译及部署命令如下:
bash build.sh --pkg --soc=Ascend910B --ops=swish_grad --experimental
./build_out/cann-ops-nn-custom-linux.aarch64.run
有关ops-nn仓算子开发流程可以参考如下的链接详细了解:算子开发流程
5.算子测试和调优
5.1算子测试
当完成上述操作后算子的实现过程其实就算完成了,但是还需要进行测试算子功能是否正确,性能是否足够达标。而测试算子ops-nn仓提供了两种调用方式进行测试:UT和aclnn调用方式,具体参考文档:算子调用。
首先介绍UT方式,需要在算子工程目录下创建tests目录,编写ut测试代码,不用从0开始编写,可以参考现有算子根据开发算子的类型及实现的功能做出相应进行的修改。在编写完成后即可进行测试,UT提供了针对不同的部分有不同的测试方式:op_api、op_host和op_kernel。如下就是测试kernel侧是否正确的指令:
bash build.sh -u --opkernel --ops=swish_grad --experimental
有如下图的输出,就说明算子测试通过:

因为ut仅包含了一种shape方式,因此需要开发者对输入的shape和数据类型进行不断的修改,来确保算子有足够的泛化能力。
测试算子除了ut测试外,还可以通过aclnn调用的方式进行测试,可以使用ascendoptest工具进行算子功能和性能的测试。
体验:从算子开发到测试通过,期间也有过好几次测试失败,但ops-nn仓UT测试会有关于算子报错信息的描述,能够方便的进行问题定位,比如tiling策略问题,关于每个核心的块数算错了,日志里面都会显示出来。
5.2算子调优
ops-nn仓关于算子的调试和调优提供了详细的指导:算子调试调优操作,算子的开发并不是一蹴而就的,而是不断经过调试和优化的,这是一个不断迭代的过程,直到算子符合需求为止,在这个过程中需要不断地进行调试、测试。
在文档中介绍了算子调用过程中日志存放的位置,通过日志我们可以看到算子的具体调用过程,了解到算子是什么原因造成的调用失败,如果看不懂日志也不要紧,可以在ops-nn仓提issue解决。
其次文档中还介绍了如何进行调试调优,提供了两个打印API,一个printf可以用来打印标量或在指定位置插入,打印指定内容,另一个是DumpTensor可以用来打印计算过程中的LocalTensor内容,查看具体的计算操作。
在功能正常的情况下,就需要进行性能调优。调优方面提供了msprof工具,通过执行如下命令会输出算子的执行耗时,以及实际有多少核参加了运算。
msprof op ./test_aclnn_add_example
此外我们还可以进行仿真操作:
#配置环境变量
export LD_LIBRARY_PATH=/usr/local/Ascend/tools/simulator/Ascend910B4/lib:$LD_LIBRARY_PATH
#进入算子可执行文件所在目录,执行仿真命令
msprof op simulator --output=$PWD/pipline_auto --kernel-name"AddExample" ./test_aclnn_add_example
仿真结束后,可以通过MindStudio Insight工具查看仿真流水。根据仿真流水进行算子优化,在调试调优过程中如果遇到解决不了的问题可以在ops-nn仓提issue,会分配专门的负责人进行解决。
体验:在使用msprof工具做性能测试时,可以看到算子的具体运行时间,还有算子不同阶段的耗时及占比,比如做性能测试时,发现scalar计算耗时较长,就要将重点放在减少scalar的计算上,或者尽可能地将scalar计算从kernel侧移动到host侧。
6.算子贡献
在经过算子的调试调优确定算子满足要求后可以通过提pr的方式将算子贡献到ops-nn仓内。贡献指南里面详细描述了算子贡献流程,在这里简要描述:要贡献算子,首先要创建算子对应的issue来对算子功能进行描述,SIG组会进行相关的评审并给出建议。
fork ops-nn仓,然后将fork后的仓pull到本地,将贡献的算子放在对应目录下,push上仓,之后提pr。算子贡献需要先经过门禁,评论commite触发门禁,门禁运行大概要10-20分钟,耗时比较长,耐心等待一下即可。
更多推荐

所有评论(0)