MindSpore设计概览杂谈

 MindSpore设计概览杂谈

https://www.mindspore.cn/docs/zh-CN/r2.3.0rc2/index.html

概述

人工智能(AI)框架已经有近10年的发展历史,四条主线驱动着AI框架不停地演进和发展:

  1. 面向开发者:兼顾算法开发的效率和运行性能。
  2. 面向硬件:充分发挥芯片和集群的性能。
  3. 面向算法和数据:从计算规模看,需要应对模型越来越大的挑战;从计算范式看,需要处理不断涌现的新的计算负载。
  4. 面向部署:需要将AI能力部署到每个设备、每个应用、每个行业。

MindSpore是面向“端-边-云”全场景设计的AI框架,旨在弥合AI算法研究与生产部署之间的鸿沟。

在算法研究阶段,为开发者提供动静统一的编程体验以提升算法的开发效率;在生产阶段,自动并行可以极大加快分布式训练的开发和调试效率,同时充分挖掘异构硬件的算力;在部署阶段,基于“端-边-云”统一架构,应对企业级部署和安全可信方面的挑战。

整体架构

MindSpore整体架构分为四层:

  1. 模型层,为用户提供开箱即用的功能,该层主要包含预置的模型和开发套件,以及图神经网络(GNN)、深度概率编程、科学计算库等热点研究领域拓展库;
  2. 表达层(MindExpression),为用户提供AI模型开发、训练、推理的接口,支持用户用原生 Python语法开发和调试神经网络,其特有的动静态图统一能力使开发者可以兼顾开发效率和执行性能,同时该层在生产和部署阶段提供全场景统一的C++/Python接口;
  3. 编译优化(MindCompiler),作为AI框架的核心,以全场景统一中间表达(MindIR)为媒介,将前端表达编译成执行效率更高的底层语言,同时进行全局性能优化,包括自动微分、代数化简等硬件无关优化,以及图算融合、算子生成等硬件相关优化;
  4. 运行时,按照上层编译优化的结果对接并调用底层硬件算子,同时通过“端-边-云”统一的运行时架构,支持包括联邦学习在内的“端-边-云”AI协同。

 

设计理念

昇思MindSpore是一个全场景深度学习框架,旨在实现易开发、高效执行、全场景统一部署三大目标。其中易开发表现为API友好,调试难度低;高效执行包括计算效率、数据预处理效率和分布式训练效率;全场景则指框架同时支持云、边缘以及端侧场景。

函数式和对象式融合编程范式

MindSpore提供面向对象和面向函数的编程范式,二者都可用来构建网络算法和训练流程。

用户可以基于nn.Cell类派生定义所需功能的AI网络或网络的某一层(layer),并可通过对象的嵌套调用的方式将已定义的各种layer进行组装,完成整个AI网络的定义。

同时用户也可以定义一个可被MindSpore源到源编译转换的Python纯函数,通过MindSpore提供的函数或装饰器,将其加速执行。在满足MindSpore静态语法的要求下,Python纯函数可以支持子函数嵌套、控制逻辑甚至是递归函数表达。因此基于此编程范式,用户可灵活使能一些功能特性,更易于表达业务逻辑。

MindSpore实现了函数式微分编程,对可被微分求导的函数对象,按照调用关系,基于调用链进行求导。采取这样自动微分策略更符合数学语义,与基本代数中的复合函数有直观的对应关系,只要已知基础函数的求导公式,就能推导出由任意基础函数组成的复合函数的求导公式。

同时基于函数式编程范式,MindSpore提供了丰富高阶函数如vmap、shard等内置高阶函数功能。与微分求导函数grad一样,可以让用户方便的构造一个函数或对象,作为高阶函数的参数。高阶函数经过内部编译优化,生成针对用户函数的优化版本,实现如向量化变换、分布式并行切分等特点功能。

动静统一的编程体验

传统AI框架主要有两种编程执行形态,静态图模式和动态图模式。

静态图模式会基于用户调用的框架接口,在编译执行时先生成神经网络的图结构,然后再执行图中涉及的计算操作。

静态图模式能有效感知神经网络各层算子间的关系情况,基于编译技术进行有效的编译优化以提升性能。但传统静态图需要用户感知构图接口,组建或调试网络比较复杂,且难于与常用Python库、自定义Python函数进行穿插使用。

动态图模式,能有效解决静态图的编程较复杂问题,但由于程序按照代码的编写顺序执行,不做整图编译优化,导致相对性能优化空间较少,特别是面向DSA等专有硬件的优化比较难于使能。

MindSpore基于原生Python构建神经网络的图结构,相比于传统的静态图模式,能有更易用、更灵活的表达能力。MindSpore创新性的构建源码转换能力,基于Python语句提取AST进行计算图构建,因此可以支持用户使用的Python原生控制语法(条件语句,循环语句等)和其他一些高级API,如元组(Tuple)、列表(List)和Lambda表达构建计算图,并对计算图进行自动微分。因此也能更好地兼容动态图和静态图的编程接口,比如面向控制流写法保持一致等。

原生Python表达可基于Python控制流关键字,直接使能静态图模式的执行,使得动静态图的编程统一性更高。同时用户基于MindSpore的接口,可以灵活的对Python代码片段进行动静态图模式控制。即可以将程序局部函数以静态图模式执行而同时其他函数按照动态图模式执行。从而使得在与常用Python库、自定义Python函数进行穿插执行使用时,用户可以灵活指定函数片段进行静态图优化加速,而不牺牲穿插执行的编程易用性。

分布式并行

MindSpore针对DL网络越来越大,需要复杂而多种分布式并行策略的问题,框架内置提供了多维分布式训练策略,可供用户灵活组装使用。并通过并行抽象,隐藏通讯操作,简化用户并行编程的复杂度。

通过自动的并行策略搜索,提供透明且高效分布式训练能力。“透明”是指用户只需更改一行配置,提交一个版本的Python代码,就可以在多个设备上运行这一版本的Python代码进行训练。“高效”是指该算法以最小的代价选择并行策略,降低了计算和通信开销。

MindSpore在并行化策略搜索中引入了张量重排布技术(Tensor Redistribution,TR),这使输出张量的设备布局在输入到后续算子之前能够被转换。MindSpore识别算子在不同输入数据切片下的输出数据overlap情况,并基于此进行切片推导,自动生成对应的张量重排计划。基于此计划,可以统一表达数据并行、模型并行等多种并行策略。

同时MindSpore面向分布式训练,还提供了pipeline并行、优化器并行、重计算等多种并行策略供用户使用。

硬件高性能发挥

MindSpore基于编译技术,提供了丰富的硬件无关优化,如IR融合、代数化简、常数折叠、公共子表达式消除等。同时MindSpore针对NPU、GPU等不同硬件,也提供各种硬件优化能力,从而更好的发挥硬件的大规模计算加速能力。

MindSpore除了提供传统AI框架常用优化,还提供了一些比较有特色的技术:

图算融合

MindSpore等主流AI计算框架对用户提供的算子通常是从用户可理解、易使用角度进行定义。每个算子承载的计算量不等,计算复杂度也各不相同。但从硬件执行角度看,这种天然的、基于用户角度的算子计算量划分,并不高效,也无法充分发挥硬件资源计算能力。主要体现在:

  1. 计算量过大、过复杂的算子,通常很难生成切分较好的高性能算子,从而降低设备利用率;
  2. 计算量过小的算子,由于计算无法有效隐藏数据搬移开销,也可能会造成计算的空等时延,从而降低设备利用率;
  3. 硬件Device通常为多核、众核结构,当算子shape较小或其它原因引起计算并行度不够时,可能会造成部分核的空闲,从而降低设备利用率。特别是基于专用处理器架构(Domain Specific Architecture,后文简称DSA)的芯片对这些因素更为敏感。如何最大化发挥硬件算力性能的同时使算子也能具备较好的易用性,一直以来是一个很大的挑战。

在AI框架设计方面,目前业界主流采用图层和算子层分层的实现方法。图层负责对计算图进行融合或重组,算子层负责将融合或重组后的算子编译为高性能的可执行算子。图层通常采用基于Tensor的High-Level IR的处理和优化,算子层则采用基于计算指令的Low-Level IR进行分析和优化。这种人为分层处理显著增加了图、算两层进行协同优化的难度。

MindSpore在过去几年的技术实践中,采用了图算融合的技术来较好的解决了这个问题。NLP、推荐等不同类别的典型网络在使能图算融合后训练速度都有明显收益。主要原因之一就是这些网络中存在大量小算子组合,具有较多的融合优化机会。

面向昇腾硬件的竞争力优化

On Device中的Device通常指Ascend(昇腾)AI处理器。昇腾芯片上集成了AI CORE、AI CPU和CPU。其中,AICORE负责大型Tensor Vector运算,AICPU负责标量运算,CPU负责逻辑控制和任务分发。

Host侧CPU负责将图或算子下发到昇腾芯片。昇腾芯片由于具备了运算、逻辑控制和任务分发的功能,所以不需要与Host侧的CPU进行频繁的交互,只需要将计算完的最终结果返回给Host侧,实现整图下沉到Device执行,避免Host-Device频繁交互,减小了开销。

计算图整图下沉到Device上执行,减少Host-Device交互开销。可以结合循环下沉实现多个Step下沉,进一步减少Host和Device的交互次数。

循环下沉是在On Device执行的基础上的优化,目的是进一步减少Host侧和Device侧之间的交互次数。通常情况下,每个step都返回一个结果,循环下沉是控制每隔多少个step返回一次结果。

数据下沉即数据通过通道直接传送到Device上。

算法优化

算法优化包括二阶优化、boost优化等。

全场景统一部署

MindSpore是训推一体的AI框架,同时支持训练和推理等功能。同时MindSpore支持CPU、GPU、NPU等多种芯片,并且在不同芯片上提供统一的编程使用接口以及可生成在多种硬件上加载执行的离线模型。

MindSpore按照实际执行环境和业务需求,提供多种规格的版本形态,支持部署在云端、服务器端、手机等嵌入式设备端以及耳机等超轻量级设备端上的部署执行。

三方硬件接入

MindSpore基于统一MindIR构建了开放式AI架构,支持第三方芯片插件化、标准化、低成本快速对接,可接入GPU系列芯片亦可接入各类DSA芯片。MindSpore提供Kernel模式对接和Graph模式对接两种芯片接入方式,芯片产商可根据自身特点进行接入方式选择。

安全可信

MindSpore考虑到企业部署使用时,对安全可信的丰富需求。在不断演进和完善各种面向安全可信方向的技术,并内置框架:

  1. 对抗性攻击防御

对抗性攻击对机器学习模型安全的威胁日益严重。攻击者可以通过向原始样本添加人类不易感知的小扰动来欺骗机器学习模型。

为了防御对抗性攻击,MindSpore安全组件MindSpore Armour提供了攻击(对抗样本生成)、防御(对抗样本检测和对抗性训练)、评估(模型鲁棒性评估和可视化)等功能。给定模型和输入数据,攻击模块提供简单的API,能够在黑盒和白盒攻击场景下生成相应的对抗样本。这些生成的对抗样本被输入防御模块,以提高机器学习模型的泛化能力和鲁棒性。防御模块还实现了多种检测算法,能够根据恶意内容或攻击行为来区分对抗样本和正常样本。评估模块提供了多种评估指标,开发者能够轻松地评估和可视化模型的鲁棒性。

  1. 隐私保护人工智能

隐私保护也是人工智能应用的一个重要课题。MindSpore Armour考虑了机器学习中的隐私保护问题,并提供了相应的隐私保护功能。

针对已训练模型可能会泄露训练数据集中的敏感信息问题,MindSpore Armour实现了一系列差分隐私优化器,自动将噪声加入反向计算生成的梯度中,从而为已训练模型提供差分隐私保障。特别地,优化器根据训练过程自适应地加入噪声,能够在相同的隐私预算下实现更好的模型可用性。同时提供了监测模块,能够对训练过程中的隐私预算消耗进行动态监测。用户可以像使用普通优化器一样使用这些差分隐私优化器。

  1. 端侧学习和联邦学习

虽然在大型数据集上训练的深度学习模型在一定程度上是通用的,但是在某些场景中,这些模型仍然不适用于用户自己的数据或个性化任务。MindSpore提供端侧训练方案,允许用户训练自己的个性化模型,或对设备上现有的模型进行微调,同时避免了数据隐私、带宽限制和网络连接等问题。端侧将提供多种训练策略,如初始化训练策略、迁移学习、增量学习等。MindSpore支持联邦学习,通过向云侧发送模型更新/梯度来共享不同的数据,模型可以学习更多的通用知识。

张量视图

张量视图(Tensor Views)是指一个Tensor经过view类算子的返回值,与该Tensor共享内存数据,避免了数据复制,从而可以进行快速且内存高效的重塑、切片和逐元素操作。

例如,要获取Tensor t的视图,可以用t.view(…)。

from mindspore import Tensor

import numpy as np

t = Tensor(np.array([[1, 2, 3], [2, 3, 4]], dtype=np.float32))

b = t.view((3, 2))

# Modifying view Tensor changes base Tensor as well.

b[0][0] = 100

print(t[0][0])

# 100

由于视图与其原来的Tensor共享底层数据,因此如果在视图中修改数据,它也会反映在原来的Tensor中。

通常,MindSpore算子操作会返回一个新的Tensor作为输出,例如add()。 但在视图操作的情况下,输出是输入Tensor的视图,以避免不必要的数据复制。创建视图时不会发生数据移动,视图Tensor只是改变它解析相同数据的方式。 使用Tensor Views可能会使内存储存连续的Tensor产生内存存储非连续的Tensor。用户应格外注意,因为连续性可能会对性能产生隐式影响。transpose()是一个常见的例子。

from mindspore import Tensor

import numpy as np

base = Tensor([[0, 1], [2, 3]])

base.is_contiguous()

# True

t = base.transpose(1, 0) # t is a view of base. No data movement happened here.

t.is_contiguous()

# False

# To get a contiguous Tensor, call `.contiguous()` to enforce

# copying data when `t` is not contiguous.

c = t.contiguous()

c.is_contiguous()

# True

view类算子

作为参考,以下是MindSpore中支持view特性算子的完整列表:

broadcast_to()

diagonal()

expand_as()

movedim()

narrow()

permute()

squeeze()

transpose()

t()

T

unsqueeze()

view()

view_as()

unbind()

split()

hsplit()

vsplit()

tensor_split()

swapaxes()

swapdims()
posted @ 2024-05-26 03:39  吴建明wujianming  阅读(45)  评论(0编辑  收藏  举报