算子开发介绍
AI 算子的定义与核心特性
算子(Operator) 是人工智能领域中对基础计算单元的统称,特指神经网络模型中执行特定运算的原子级节点。每个算子接收输入数据(通常为 Tensor),按预设算法处理后输出计算结果,构成神经网络的计算图结构。它笼统的分为两个大类,第一有数学运算类, 第二是形状变化类。
那么在算子开发过程中有需要了解那些信息呢。下文简单介绍
1.算子语义
目前主流的两大深度学习框架有TensorFlow 和Pytorch,算子基于用户群体来看需要实现类似框架的算子。
这里以一个nn的普通整形算子来阐述开发流程.
下面是pytorch的Padding 语义: 也就是我们算子要做成什么样的,实现什么样的功能。
这是一个tensor整形的算子,这里给出了输入、输出和功能描述。下面附带了使用的程序。从使用上简单看,支持单参数,两个参数。需要注意这里仅仅是部分使用场景
>>> m = nn.ReplicationPad1d(2) >>> input = torch.arange(8, dtype=torch.float).reshape(1, 2, 4) >>> input tensor([[[0., 1., 2., 3.], [4., 5., 6., 7.]]]) >>> m(input) tensor([[[0., 0., 0., 1., 2., 3., 3., 3.], [4., 4., 4., 5., 6., 7., 7., 7.]]]) >>> # using different paddings for different sides >>> m = nn.ReplicationPad1d((3, 1)) >>> m(input) tensor([[[0., 0., 0., 0., 1., 2., 3., 3.], [4., 4., 4., 4., 5., 6., 7., 7.]]])
2.算子组成
算子他不能单独的存在,也需要一些依赖,他基于某个特定的芯片和特定的软件结构工作。
算子在整个结构中行为如下:
这里列出为了使一个算子运行,需要联动的一些框架。
第一层:实现和上文的接口,有的还会有一层wrapper。
第二层:host函数,泛编程实现,为了调度kernel函数做的一些工作。
第三层:真正的算子部分,里面有线程的分配和运算主题部分。
最后一层:虽然我们称这个叫算子,但是他在硬件上并不是最小的实现,软件开发好一些底层在这里可以调用。
3.算子kernel展示
1.标量运算 2.thread分配 3.数据搬运 4.主要运算 5.sync同步
4.算子评估
如何评价一个算子的好坏呢,首先功能要实现,然后要做维度数据类型的泛化,性能上有不同的评价标准,需要结合具体行为来分析。
算子性能提升方向 是带宽上还是计算上:
带宽上:
tensor切分,搬运引擎的分配 乒乓等方式。使得搬运引擎尽量满负荷工作,分配到的资源尽量都利用到。
如果优化计算:
要和编译器开发者一起来看指令排布,手动做循环展开还是自动。
参考资料:
1.pytorch语义 link