聊聊torch-npu插件原理————华为昇腾NPU服务器是如何适配并使用PyTorch机器学习开发框架
仅用于站内搜索,没有排版格式,具体信息请跳转上方微信公众号内链接
华为官方提供的PyTorch插件:torch-npu实现了在华为昇腾服务器上跑PyTorch代码,基于PyTorch的开源生态做AI开发——训练、推理。
虽然目前华为有自己的机器学习开发框架:MindSpore。而类似百度、阿里都有这种框架,比如百度飞桨PaddlePaddle;归根来说,这类框架就是直接对标着PyTorch。但有一个最大的问题,就是开源生态,目前机器学习、深度学习等AI领域,科研领域,主流的开发框架都是基于PyTorch,因此PyTorch的开发生态是最全的。如果一昧的限制在自家的开发框架上,对于其硬件发展和软件生态是很不利的,因此越来越多的硬件厂家,比如国内的华为昇腾,寒武纪等,均在自己的硬件平台上接入PyTorch做开发。
在PyTorch2.1版本发布了一个重要的特性:PrivateUse1;PrivateUse1是PyTorch里的一种设备类型。在PyTorch中,设备类型表明了张量和操作执行的硬件环境,像CPU、GPU等都是常见的设备类型。PrivateUse1属于一种特殊的设备类型,它通常被设计用于自定义或者特定的硬件后端。借助PrivateUse1,开发者能够把PyTorch代码适配到非标准的硬件上,例如特定的加速器或者实验性的硬件平台。
Ascend官方提供的torch-npu[1]插件库源码中,通过PrivateUse1的特定接口,将NPU设备接入了到了PyTorch后端中。
当然仅有这些代码还是不够的,PrivateUse1是PyTorch官方提供了一种特殊的device类型,用于给第三方硬件厂商接入的,利用PyTorch的PrivateUse1特性,将原本面向CUDA的设备操作(如torch.cuda)无缝替换为torch.npu,无需修改大部分原生代码即可切换硬件后端。而如何分发算子到PrivateUse1设备上,还需要其它的机制。
Dispatcher即PyTorch官方的调度分发机制,它是PyTorch核心架构里的一个关键组件。Dispatcher的主要职责是依据操作的输入张量的设备类型、数据类型等信息,把操作分派到合适的内核函数上执行。简单来说,当你在PyTorch中调用一个操作(如加法、乘法等)时,Dispatcher会决定该操作在哪个设备上执行,以及使用哪个具体的实现来完成这个操作。
粗略的来理解,从实现目的来看,dispatch类似于SpringIOC;本质上就是为接口定义找到特定的实现,从而支持扩展。由于Pytorch中默认的算子实现是在CPU、GPU上,而为了算子扩展及接入第三方设备,因此引入dispatcher的方式来实现。
有如下三种方式注册算子,而后dispatcher将分发算子到对应的函数实现中执行调用。
TORCH_LIBRARY_IMPL
m.impl
m.fallback
TORCH_LIBRARY
m.def
在torch-npu插件的源码中,充斥着各种注册函数,用于在华为ascendnpu上调用自身的硬件,运行各种算子。所以这也是在Ascend官方提供的torch-npu插件版本有很多,而且早在Pytorch1.x版本就开始提供,但是在PyTorch2.1开始,Ascend提供的torch-npu插件就可以说是原生支持pytorch了,而且MindSpeed系列的训推加速中间件都是大力的基于torch-npu插件开发的。
PyTorch官方提供了一个示例项目[2],在PyTorch的out-of-tree的场景下,基于PrivateUse1特性与dispatcher分发调度自定义的算子到新的硬件上执行。
csrc是torch._C调用的C++代码,通过pybind实现Python调用C++。
_aten_impl.py文件是在Pytorch原生aten中注册了一些新的算子以及kernel的fallback,如下:
_device_daemon与_meta_parser是处理设备信息以及上下文元数据转换。
OpenReg
通过PrivateUse1促进新的后端集成[3]
Reference
torch-npu:https ://gitee.com/ascend/pytorch
通过PrivateUse1促进新的后端集成:https ://pytorch.ac.cn/tutorials/advanced/privateuseone.html