深入浅出PyTorch(算子篇)

简单适配torch_npu不支持的ATen算子 阅读详情

Tensor

自从张量(Tensor)计算这个概念出现后,神经网络的算法就可以看作是一系列的张量计算。所谓的张量,它原本是个数学概念,表示各种向量或者数值之间的关系。PyTorch的张量(torch.Tensor)表示的是N维矩阵与一维数组的关系。

http://web.mit.edu/~ezyang/Public/pytorch-internals.pdf

torch.Tensor的使用方法和numpy很相似(https://pytorch.org/…tensor-tutorial-py),两者唯一的区别在于torch.Tensor可以使用GPU来计算,这就比用CPU的numpy要快很多。

张量计算的种类有很多,比如加法、乘法、矩阵相乘、矩阵转置等,这些计算被称为算子(Operator),它们是PyTorch的核心组件。

算子的backend一般是C/C++的拓展程序,PyTorch的backend是称为"ATen"的C/C++库,ATen是"A Tensor"的缩写。

Operator

PyTorch所有的Operator都定义在Declarations.cwrap和native_functions.yaml这两个文件中,前者定义了从Torch那继承来的legacy operator(aten/src/TH),后者定义的是native operator,是PyTorch的operator。

相比于用C++开发的native code,legacy code是在PyTorch编译时由gen.py根据Declarations.cwrap的内容动态生成的。因此,如果你想要trace这些code,需要先编译PyTorch。

legacy code的开发要比native code复杂得多。如果可以的话,建议你尽量避开它们。

aten/src/ATen/Declarations.cwrap

MatMul

本文会以矩阵相乘–torch.matmul()为例来分析PyTorch算子的工作流程。

我在深入浅出全连接层(fully connected layer)中有讲在GPU层面是如何进行矩阵相乘的。Nvidia、AMD等公司提供了优化好的线性代数计算库–cuBLAS/rocBLAS/openBLAS,PyTorch只需要调用它们的API即可。

Figure 1: function flow of torch.matmul()

Figure 1是torch.matmul()在ATen中的function flow。可以看到,这个flow可不短,这主要是因为不同类型的tensor(2d or Nd, batched gemm or not,with or without bias,cuda or cpu)的操作也不尽相同。

at::matmul()主要负责将Tensor转换成cuBLAS需要的格式。前面说过,Tensor可以是N维矩阵,如果tensor A是3d矩阵,tensor B是2d矩阵,就需要先将3d转成2d;如果它们都是>=3d的矩阵,就要考虑batched matmul的情况;如果bias=True,后续就应该交给at::addmm()来处理;总之,matmul要考虑的事情比想象中要多。

除此之外,不同的dtype、device和layout需要调用不同的操作函数,这部分工作交由c10::dispatcher来完成。

Dispatcher

dispatcher主要用于动态调用dtype、device以及layout等方法函数。用过numpy的都知道,np.array()的数据类型有:float32, float16,int8,int32,… 如果你了解C++就会知道,这类程序最适合用模板(template)来实现。

很遗憾,由于ATen有一部分operator是用C语言写的(从Torch继承过来),不支持模板功能,因此,就需要dispatcher这样的动态调度器。

类似地,PyTorch的tensor不仅可以运行在GPU上,还可以跑在CPU、mkldnn和xla等设备,Figure 1中的dispatcher4就根据tensor的device调用了mm的GPU实现。

layout是指tensor中元素的排布。一般来说,矩阵的排布都是紧凑型的,也就是strided layout。而那些有着大量0的稀疏矩阵,相应地就是sparse layout。

Figure 2: strided layout example

Figure 2是strided layout的演示实例,这里创建了一个2行2列的矩阵a,它的数据实际存放在一维数组(a.storage)里,2行2列只是这个数组的视图。

stride充当了从数组到视图的桥梁,比如,要打印第2行第2列的元素时,可以通过公式: 1 ∗ s t r i d e ( 0 ) + 1 ∗ s t r i d e ( 1 ) 1 * stride(0) + 1 * stride(1) 1stride(0)+1stride(1)来计算该元素在数组中的索引。

除了dtype、device、layout之外,dispatcher还可以用来调用legacy operator。比如说addmm这个operator,它的GPU实现就是通过dispatcher来跳转到legacy::cuda::_th_addmm。

aten/src/ATen/native/native_functions.yaml

END

到此,就完成了对PyTorch算子的学习。如果你要学习其他算子,可以先从aten/src/ATen/native目录的相关函数入手,从native_functions.yaml中找到dispatch目标函数,详情可以参考前文的flowchart。


更多精彩文章,欢迎扫码关注下方的公众号

欢迎转发至朋友圈,公众号转载请后台留言申请授权~

AI修炼手册:一个有料有深度的公众号

PyTorch框架使用DSL进行TBE算子开发全流程 PyTorch框架使用DSL进行TBE算子开发全流程 1. DSL算子基本概念介绍 1.1 什么是算子 深度学习算法由一个个计算单元组成,我们称这些计算单元为算子(Operator,简称 OP)。在网络模型中,算子对应层中的计算逻辑,例如:卷积层(Convolution Layer)是一个算子;全连接层(Fully-connected Layer, FC layer)中的权值求和过 程,是一个算子。 对每一个独立的算子,用户需要编写算子描述文件,描述算子的整体逻辑、计算步骤以及相关硬件平台信息等。然后用深度 阅读详情

相关推荐

Ascend Pytorch算子适配层开发

Ascend Pytorch算子适配层开发 适配方法 找到和PyTorch算子功能对应的NPU TBE算子,根据算子功能计算出输出Tensor的size,再根据TBE算子原型构造对应的input/output/attr,传递给ACL完成TBE算子的执行。 说明: TBE算子实现的源文件存放路径由开发套件包Toolkit的安装方式决定: • 若使用root用户安装,则存放在:/usr/local/Ascend/ascend-toolkit/latest/opp/op_impl/built-in/ai_core

吴建明wujianming_110117 1512

onnx支持的pytorch(aten)算子

【代码】onnx支持的pytorch(aten)算子

juluwangriyue的博客 1499

pytorch 官方接口 自定义算子注册

pytorch官方提供了注册自己的自定义算子的接口,不需要像native_functions.yaml那样每次改源码,再编译 在pytorch仓库下找一个地方,创建新的文件夹 我建议在/pytorch/aten/src/ATen/core/op_registration下创建 创建的文件夹假设叫做myrelu 在myrelu下继续创建myrelu.cpp CMakeLists.txt 和 build文件夹 myrelu.cpp: #include <torch/script.h> torch:

weixin_43561808的博客 2140

使用过的pytorch算子总结

总结一些pytorch常用算子 1. torch.reciprocal(input, out=None) 说明:返回一个新张量,包含输入input张量每个元素的倒数。(单词reciprocal的意思是倒数) 参数: input(Tensor) – 输入张量 out(Tensor, 可选) – 输出张量 import torch if __name__ == '__main__': a = torch.randn(5) print(a) b = torch.reciprocal(

juluwangriyue的博客 1820

PyTorch详细教程

为了加速计算,一些框架会使用对神经网络“先编译,后执行”的静态图来描述网络。静态图的缺点是难以描述控制流(比如 if-else 分支语句和 for 循环语句),直接对其引入控制语句会导致产生不同的计算图。比如循环执行 n 次 a=a+b,对于不同的 n,会生成不同的计算图。

IT菜鸟 1万+

Pytorch : 模型部署

将模型导出为torchscript或onnx,使用libtorch C++API部署或Onnx Runtime部署

Shilong的博客 3778

pytorch 矩阵相乘_深入浅出PyTorch算子

Tensor自从张量(Tensor)计算这个概念出现后,神经网络的算法就可以看作是一系列的张量计算。所谓的张量,它原本是个数学概念,表示各种向量或者数值之间的关系。PyTorch的张量(torch.Tensor)表示的是N维矩阵与一维数组的关系。http://web.mit.edu/~ezyang/Public/pytorch-internals.pdftorch.Tensor的使用方法...

weixin_39598135的博客 734

pytorch 中支持更多的 onnx 算子

首先,需要获得asinh推理接口的输入参数定义。在和这两个文件中搜索相应的算子名称(一般来说 ATen 中的函数名称都是全小写,因此在搜索算子名的时候尽量忽略大小写这两个文件是编译 PyTorch 时本地自动生成的文件,里面包含了 ATen 算子PyTorch 调用接口。搜索结果,def asinh定义在文件中。onnx 没有支持的 onnx 算子,需要自定义该 onnx 算子。g.op()函数可以用来自定义 onnx 算子的函数。对于 onnx 官方支持的算子,使用g.op()

哦豁灬 1万+

PyTorch 框架 AICPU 算子开发全流程

PyTorch 框架 AICPU 算子开发全流程 文章目录PyTorch 框架 AICPU 算子开发全流程一.AICPU算子基本概念介绍二.算子开发流程介绍三. LogSpace算子分析四. LogSpace算子工程创建五.LogSpace算子原型定义和代码开发六.LogSpace算子逻辑实现部分代码开发七.LogSpace算子编译和部署八.LogSpace算子UT测试九.LogSpace算子ST测试十.经验总结十一.关于MindStudio更多的内容 详情指路视频专栏:https://www.bilibi

qq_44821958的博客 4026

干货 | Pytorch底层算子扩展最详细的总结

欢迎关注“计算机视觉研究院”计算机视觉研究院专栏作者:Edison_G一般情况下,pytorch推荐使用python层的前端语言来构建新的算子。因为pytorch在python层的api已...

gzq0723的博客 3678

CANN算子PyTorch自定义算子示例

This example demonstrates how to register a custom operator using the torch.library mechanism in PyTorch, based on the Add operator. ## Supported Products and CANN Versions | Product | CANN Version

gitblog_00299的博客 999

庖丁解牛PyTorch算子

本文深入解析PyTorch算子的核心机制与实现细节,涵盖张量计算、算子实现双轨制、矩阵乘法调用链、动态分派机制等内容。通过实际案例和性能分析技巧,帮助开发者优化算子性能并开发自定义算子,提升深度学习模型效率。

weixin_30696427的博客 417

Pytorch实现的卷积算子

本文的一个很大目的,就是让我自己学会怎么扩展Pytorch算子,从官方文档了解到,需要实现一个继承的函数,并且实现forward和backwardforward和backward函数的第一个参数都是ctx,就是context的意思,与self类似,一般如果在backward过程中要用到forward的参数,在forward时就要调用保存起来;forward有多少个输入,backward就要有多少个输出,这个看计算图就能明白了,如果不需要求梯度的入边,可以返回None;梯度求解。 whaosoft aiot

whaosoft143ai的博客 1772

pytorch导出onnx时遇到不支持的算子怎么解决

然后再自己实现custom_domain::customOp2这个算子,如果用TensorRT,就需要自己实现一个插件。

zhaoyqcsdn的博客 3717

pytorch自定义算子导出onnx

1、没有现成可用的算子,需要根据自己的接口重写。2、现有的算子接口不兼容,需要在原有的算子上进行封装。继承类,实现其forward()和backward()方法,就可以成为一个pytorch自定义算子。就可以在模型训练推理中完成前向推理和反向传播。forward() 函数的第一个参数必须是ctx, 后面是输出。在工程部署上,一般为了加快计算,自定义算子需要用cuda 实现forward()、backward()kernel 函数。实现其symbolic 静态方法。

MAX的专栏 1875

onnx模型可视化以及pytorch算子与onnx节点对应关系

pytorch模型转成onnx时会产生很多意想不到的错误,然而对onnx模型进行Debug是非常麻烦的事,往往采用可视化onnx模型然后找到报错节点之后确定报错节点在源码中的错误位置的方法进行Debug,然而将可视化的onnx图与源代码对应起来可不是一件简单的事,本文主要记录pytorch算子与可视化的onnx节点的对应关系以方便对onnx节点在源代码中进行溯源,本文中的onnx模型使用Netron软件进行可视化,记录会随时补充。 1.onnx中Gather节点对应pytorch中对tensor的索引操作

lhyyhlfornew的博客 8119

通过PyTorch调用算子:从基础到进阶的全面指南

本文深入探讨PyTorch算子的调用技巧与优化策略。首先介绍PyTorch算子体系,包括内置算子分类和调用注意事项;随后通过transpose和矩阵乘法等典型算子,解析维度变换、批量处理等优化方法;进而从内存管理、并行计算、算子融合等方面提出高级优化技巧;最后介绍自定义算子开发及工程实践指南。文章结合代码实例,为开发者提供从基础调用到性能优化的完整解决方案,帮助构建高效、可扩展的AI系统。

2501_93738366的博客 991

这可能是关于Pytorch底层算子扩展最详细的总结了!

1、前言​ ​一般情况下,pytorch推荐使用python层的前端语言来构建新的算子。因为pytorch在python层的api已经足够丰富,可以构造出很多自定义的算子。但是有时候出于一些其他方面的考虑,会需要增加底层算子。例如有时候对性能要求很高,python不满足需求,又或者是需要链接其他的动态库(blas,mkl等),因此pytorch也提供了直接扩展底层C++算子的能力。主要有三种方式,native_functions.yaml、C++ extension方式、OP register方式。 ..

cjnewstar111的专栏 1935
上一篇: 深入浅出Transformer
下一篇: 深入浅出腾讯BERT推理模型--TurboTransformers
A君来了
博客等级 码龄10年 18粉丝 14原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值