MindSpore:自动微分

作为一款「全场景 AI 框架」,MindSpore 是人工智能解决方案的重要组成部分,与 TensorFlow、PyTorch、PaddlePaddle 等流行深度学习框架对标,旨在大幅度降低 AI 应用开发门槛,让人工智能无处不在。

MindSpore 是一款支持端、边、云独立/协同的统一训练和推理框架。希望通过这款完整的软件堆栈,实现一次性算子开发、一致的开发和调试体验,以此帮助开发者实现一次开发,应用在所有设备上平滑迁移的能力。

原生支持 AI 芯片,全场景一致的开发体验——除了这些早已知晓的强大之处外,还着重展示了 MindSpore 的三大创新能力:新编程范式,执行模式和协作方式。

MindSpore 首个开源版本为 0.1.0-alpha 版,主要由自动微分、自动并行、数据处理等功能构成。MindSpore 具备开发算法即代码、运行高效、部署态灵活的特点,其核心分为三层:从下往上分别是后端运行时、计算图引擎及前端表示层。

MindSpore 开源社区:https://www.mindspore.cn/

MindSpore 代码:https://gitee.com/mindspore

从整体上来说,MindSpore 搭建神经网络会以「单元」为中心,其中单元是张量和运算操作的集合。从输入张量开始,MindSpore 会提供各种算子以构造一个「单元」,最后模型封装这个单元就可以用来训练、推理了。

MindSpore 的整体结构,从后端的硬件支持到前端 API,中间会涉及多种优化与特性。例如不采用计算图的自动微分、自动并行与优化计算过程等等。

MindSpore 最大的特点在于,其采用了业界最新的 Source-to-Source 自动微分,能利用编译器及编程语言的底层技术,进一步优化以支持更好的微分表达。

自动微分:不止计算图

自动微分是深度学习框架的灵魂,有了写模型就只需要关注前向传播,将所有复杂的求导、反传过程都留给框架。一般而言,自动微分指一种自动求某个函数其导数的方法。在机器学习中,这些导数可以更新权重。在更广泛的自然科学中,这些导数也能用于各种后续计算。

人类擅长以解析式推导微分,计算机擅长数值微分。

一般而言,自动微分都是需要建立计算图的,有了计算图才能追踪各函数、变量的依赖情况,并进一步根据链式法则传递梯度。然而对于 MindSpore 来说,并不依赖于计算图,而是通过一种名为「基于源码转换」的自动微分方法,支持 if、for 等复杂的控制流结构,以及灵活的函数式编程方式。

自动微分本质上是解析变量间的依赖关系,并利用全微分法则与链式求导法则将梯度传递给不同的变量。

将 Python 代码解析为计算图。

目前主流深度学习框架中主要有三种自动微分技术:

  • 基于静态计算图的转换:将网络在编译时转换为静态数据流图,然后将链式法则应用于数据流图,并实现自动微分。
  • 基于动态计算图的转换:以操作符重载的方式记录网络在前向执行时操作轨迹,然后将链式法则应用于动态生成的数据流图,并实现自动微分。
  • 基于源码转换:该技术源以函数式编程框架为基础,以即时编译(JIT)的方式在中间表达(编译过程中程序的表达形式)上做自动微分变换,支持复杂控制流场景、高阶函数和闭包。

其中 TF 早期采用的是静态计算图,PyTorch 采用的是动态计算图,静态图能利用静态编译技术对网络性能进行优化,然而搭建网络或 Debug 非常复杂。动态图的使用非常便捷,但性能上难以做到极致的优化。

MindSpore 走的是另外一条路,即基于源码转换的自动微分。又支持对自动控制流的自动微分,所以与 PyTorch 一样构建模型非常方便。同时 MindSpore 能对神经网络做静态编译优化,因此性能也非常优秀。

基于源码转换的方法,是自动微分另一条康庄大道。

源码转换的简要工作方式。

假设用 C 语言写函数,那么根据自动微分工具,函数的源代码会自动转换为另一种源代码,这种新生成的源代码包含了用于计算梯度的语句,可以直接编译。这样的源码到源码转换对于编译器非常友好,编译器在计算过程中也能进行优化。

MindSpore 自动微分的实现可以理解为对程序本身进行的符号微分,因为 MindSpore IR 是函数式的中间表达,与基础代数中的复合函数有直观的对应关系,只要已知基础函数的求导公式,就能推导出由任意基础函数组成的复合函数的求导公式。MindSpore IR 中每个原语操作可以对应为基础代数中的基础函数,这些基础函数可以构建更复杂的流程控制。

自动并行训练:一切计算都交给

如今的深度学习模型往往因为体量巨大而必须做并行化,MindSpore 能自动并行按照串行写的代码,自动实现分布式并行训练,并且保持高性能。

一般而言,并行训练可以分为模型并行与数据并行,数据并行比较好理解,每一个样本可以独立地完成前向传播,最后再汇总传播结果。相比之下,模型并行就比较复杂了,需要以「并行思维」这样的逻辑手动编写所有需要并行的部分。

MindSpore 自动并行的目标是构建一种融合了数据并行、模型并行和混合并行的训练方式。会自动选择一种代价最小的模型切分方式,实现自动分布式并行训练。

目前 MindSpore 采用了切分算子细粒度的并行方式,即把图中每个算子都切分到集群而完成并行运算。这期间切分方式可能非常复杂,但作为崇尚 Pythonic 的开发者,并不需要关心底层实现,只需要顶层 API 计算高效就行了。

除了自动微分与自动并行,MindSpore 还有很多优秀的特性与组件,完整的数据预处理模块、高效的图计算引擎都值得去探索。例如在数据预处理模块中,MindSpore 需要考虑如何提升数据预处理的能力,从而使其跟得上昇腾芯片消耗数据的速度。

当然可视化工具、模型评估工具等常用模块也都配齐了,除了常见的计算图、标量曲线等可视化,MindSpore 还能实现新颖的「模型溯源」,会把学习率、损失值、模型大小等众多超参配置都画在一起,方便开发者调参。

MindSpore 代码什么样?

用 MindSpore 写模型,代码风格还是挺有特色的。MindSpore 主要概念就是张量、算子、单元和模型,提供的同样也是 Python 编程范式,因为采用 Source-to-Source 自动微分,Python 常用的元组、列表等数据结构还能用,匿名函数 Lambda 也没问题。

张量大家都了解了,MindSpore 中的算子可以是卷积,也可以是简单的加法。与张量一起可以构成「单元」,单元是所有神经网络单元的基本类。单元再封装就成了模型了,MindSpore 可以直接调用模型来训练与推理,也可以使用更底层的 API 构建复杂模型。

如下所示,可以发现写 MindSpore 有两个比较突出的亮点。首先当然是计算图的调整,动态图与静态图可以一行代码切换。在正常情况下,MindSpore 使用的是 PyNative 动态图,然而在需要静态图的时候,设置个 context 上下文管理器就可以了。

importnumpy asnp

importmindspore.context ascontext

importmindspore.nn asnn

frommindspore importTensor

# Initialize the network

net = Net

x = Tensor(np.random.rand( 1, 1, 4, 1024).astype(np.float32))

# Predict the network in PyNative mode, by default

out = net(x)

# Change to Graph mode to predict the network

context.set_context(mode=context.GRAPH_MODE)

out = net(x)

对于自动并行特性,写的串行代码,只需要多加一行就能完成自动并行,这背后的复杂并行逻辑完全不需要花费精力去理解。

如下所示,只要设置运行环境为图模式,并允许使用分布式接口 HCCL(集合通信库),那么在初始化后 MindSpore 就能自动优化写的模型,以最好的并行策略加速整个训练过程。

importos

frommindspore importcontext

frommindspore.communication.management importinit

if__name__ == "__main__":

context.set_context(mode=context.GRAPH_MODE,

device_target= "Ascend",

enable_hccl= True,

device_id=int(os.environ[ "DEVICE_ID"]))

init

...

表示,MindSpore 原生适应所有的 AI 应用场景,并能在按需协同的基础上通过实现 AI 算法即代码,显著减少模型开发时间。以典型的 Transformer 为例,MindSpore 可降低核心代码量 20%,开发门槛大大降低,效率整体提升 50% 以上。

随着框架的开源,MindSpore 相关文档和教程均已在官网上线,并欢迎开发者提供反馈意见。

至于未来的发展方向,表示在开源后大部分工作都将交由社区自主完成:MindSpore 社区会按照社区章程进行运作,未来新版本计划会由各个特别兴趣组 (Special Interest Group, 简称 SIG) 输出,并交技术治理委员会 (Technical Steering Committee,简称 TSC) 决策并公示。

目前,MindSpore 技术治理委员会由来自依瞳科技、Conic AI、哈尔滨工业大学、、工商银行、帝国理工、中科院计算所、北京大学、清华大学、中国科技大学、爱丁堡大学、University Paris-Saclay、Universität Münster、西安电子科技大学等 14 名不同机构的代表组成。

MindSpore:自动微分的更多相关文章

  1. MindSpore多元自动微分

    技术背景 当前主流的深度学习框架,除了能够便捷高效的搭建机器学习的模型之外,其自动并行和自动微分等功能还为其他领域的科学计算带来了模式的变革.本文我们将探索如何用MindSpore去实现一个多维的自动 ...

  2. 附录D——自动微分(Autodiff)

    本文介绍了五种微分方式,最后两种才是自动微分. 前两种方法求出了原函数对应的导函数,后三种方法只是求出了某一点的导数. 假设原函数是$f(x,y) = x^2y + y +2$,需要求其偏导数$\fr ...

  3. pytorch学习-AUTOGRAD: AUTOMATIC DIFFERENTIATION自动微分

    参考:https://pytorch.org/tutorials/beginner/blitz/autograd_tutorial.html#sphx-glr-beginner-blitz-autog ...

  4. 自动微分(AD)学习笔记

    1.自动微分(AD) 作者:李济深链接:https://www.zhihu.com/question/48356514/answer/125175491来源:知乎著作权归作者所有.商业转载请联系作者获 ...

  5. <转>如何用C++实现自动微分

    作者:李瞬生转摘链接:https://www.zhihu.com/question/48356514/answer/123290631来源:知乎著作权归作者所有. 实现 AD 有两种方式,函数重载与代 ...

  6. (转)自动微分(Automatic Differentiation)简介——tensorflow核心原理

    现代深度学习系统中(比如MXNet, TensorFlow等)都用到了一种技术——自动微分.在此之前,机器学习社区中很少发挥这个利器,一般都是用Backpropagation进行梯度求解,然后进行SG ...

  7. PyTorch自动微分基本原理

    序言:在训练一个神经网络时,梯度的计算是一个关键的步骤,它为神经网络的优化提供了关键数据.但是在面临复杂神经网络的时候导数的计算就成为一个难题,要求人们解出复杂.高维的方程是不现实的.这就是自动微分出 ...

  8. 【tensorflow2.0】自动微分机制

    神经网络通常依赖反向传播求梯度来更新网络参数,求梯度过程通常是一件非常复杂而容易出错的事情. 而深度学习框架可以帮助我们自动地完成这种求梯度运算. Tensorflow一般使用梯度磁带tf.Gradi ...

  9. PyTorch 自动微分示例

    PyTorch 自动微分示例 autograd 包是 PyTorch 中所有神经网络的核心.首先简要地介绍,然后训练第一个神经网络.autograd 软件包为 Tensors 上的所有算子提供自动微分 ...

随机推荐

  1. PHP版DES算法加密数据

    php7之后的版本 php的mcrypt 扩展已经过时了大约10年,并且用起来很复杂.因此它被废弃并且被 OpenSSL 所取代. 从PHP 7.2起它将被从核心代码中移除并且移到PECL中.PHP手 ...

  2. 【参数校验】 自定义校验器 (实现ConstraintValidator)

    日常工作中写接口时,往往需要校验前端传来的枚举状态码,例如"1","2"等等, 这里使用java 303规范的参数校验框架封装一个自定义参数校验器: /** * ...

  3. UVA11991第k次出现的v的下标

    题意:      给你一个有n个数的数字序列,然后有m组询问,每组询问是问第k次出现的v在序列里的小标是多少? 思路:      简单题目,直接开个二维的容器就行了,标记出现次数可以开个数组或者是一维 ...

  4. 记一次 .NET 医院CIS系统 内存溢出分析

    一:背景 1. 讲故事 前几天有位朋友加wx求助说他的程序最近总是出现内存溢出,很崩溃,如下图: 和这位朋友聊下来,发现他也是搞医疗的,哈哈,.NET 在医疗方面还是很有市场的,不过对于内存方面出的问 ...

  5. Day002 Hello,World!!!

    Hello,World! 随便新建一个文件,存放代码 新建一个java文件 文件后缀名为.java Hello.java [注意点] 系统可能没有显示文件后缀名,我们需要手动打开 编写代码 publi ...

  6. upload

    File saveDir=new File("D:/Test/UPLOAD"); if(!saveDir.isDirectory()){ saveDir.mkdirs(); } F ...

  7. MySQL模糊查询,查询语句是对的。但是就是没有查询结果

    问题 解决 当我用其他非中文的值去查询,发现可以查询到结果 所以问题就出现在数据库的配置中 spring.datasource.url=jdbc:mysql://localhost:3306/data ...

  8. thinkphp 中区块block和模板继承extend用法举例

    1.介绍 模板继承其实并不难理解,就好比类的继承一样,模板也可以定义一个基础模板(或者是布局),并且其中定义相关的区块(block),然后继承(extend)该基础模板的子模板中就可以对基础模板中定义 ...

  9. PHP 判断当前日期是否是法定节假日或者休息日

    1.代码如下 $date = date("Ymd",time()); $url = "http://api.goseek.cn/Tools/holiday?date=&q ...

  10. CCNA 第二章 以太网回顾

    1:半双工和全双工 (1):半双工:类似于单车道: (2):全双工:类似是双向多车道: 2:思科三层模型 (1): (2):核心层.集散层(汇聚层).接入层各功能: 1:核心层:大量数据快速交换:不要 ...