本文将会介绍华为自研AI框架昇思MindSpore,这是一个面向全场景设计的AI计算框架,旨在为AI算法研究和生产部署提供一个统一、高效、安全的平台。接下来,将详细阐述MindSpore的定位、架构、特性、以及其在端边云全场景下的应用和优势。
MindSpore 基本介绍
MindSpore定位
昇思MindSpore是面向“端-边-云”全场景设计的AI框架,旨在弥合AI算法研究与生产部署之间的鸿沟。在算法研究阶段,为开发者提供动静统一的编程体验以提升算法的开发效率;生产阶段,自动并行可以极大加快分布式训练的开发和调试效率,同时充分挖掘异构硬件的算力;在部署阶段,基于“端-边-云”统一架构,应对企业级部署和安全可信方面的挑战。开源以来,秉持全场景协同、全流程极简、全架构统一三大价值主张,致力于增强开发易用性、提升原生支持大模型和AI+科学计算的体验。” 向上使能AI模型创新,对下兼容多样性算力(NPU、GPU、CPU)。
昇思MindSpore架构
昇思MindSpore整体架构分为四层(如图 1所示):
-
模型层,为开发者提供开箱即用的功能,该层主要包含预置的模型和开发套件,以及图神经网络(GNN)、深度概率编程等热点研究领域拓展库;
-
表达层(MindExpression),为开发者提供AI模型开发、训练、推理的接口,支持开发者用原生Python语法开发和调试神经网络,其特有的动静态图统一能力使开发者可以兼顾开发效率和执行性能,同时该层在生产和部署阶段提供全场景统一的C++接口;
-
编译优化(MindCompiler),作为AI框架的核心,以全场景统一中间表达(MindIR)为媒介,将前端表达编译成执行效率更高的底层语言,同时进行全局性能优化,包括自动微分、代数化简等硬件无关优化,以及图算融合、算子生成等硬件相关优化;
-
运行时,按照上层编译优化的结果对接并调用底层硬件算子,同时通过“端 - 边 - 云”统一的运行时架构, 支持包括联邦学习在内的“端 - 边 - 云”AI 协同。
昇思MindSpore特性
昇思MindSpore为开发者提供Python等语言的编程范式。借助基于源码转换,开发者可以使用原生Python控制语法和其他一些高级API,如元组(Tuple)、列表(List)和Lambda表达。
前端编程
昇思MindSpore提供面向对象和面向函数的编程范式。开发者可以基于nn.cell类派生定义所需功能的AI网络或网络的某一层(layer),并可通过对象的嵌套调用的方式将已定义的各种layer进行组装,完成整个AI网络的定义。同时开发者也可以定义一个可被昇思MindSpore源到源编译转换的Python纯函数,通过昇思MindSpore提供的函数或装饰器,将其加速执行。
下面分别介绍昇思MindSpore支持的三类编程范式及其简单示例。
面向对象编程
面向对象编程(Object-oriented programming,OOP),是指一种将程序分解为封装数据及相关操作的模块(类)而进行的编程方式,对象为类(class)的实例。面向对象编程将对象作为程序的基本单元,将程序和数据封装其中,以提高软件的重用性、灵活性和扩展性,对象里的程序可以访问及经常修改对象相关联的数据。
在一般的编程场景中,代码(code)和数据(data)是两个核心构成部分。面向对象编程是针对特定对象(Object)来设计数据结构,定义类(Class)。类通常由以下两部分构成,分别对应了code和data:
- 方法(Methods)
- 属性(Attributes)
对于同一个Class实例化(instantiation)后得到的不同对象而言,方法和属性相同,不同的是属性的值。不同的属性值决定了对象的内部状态,因此OOP能够很好地进行状态管理。
下面为Python构造简单类的示例:
class Sample: #class declaration
def __init__(self, name): # class constructor (code)
self.name = name # attribute (data)
def set_name(self, name): # method declaration (code)
self.name = name # method implementation (code)
对于构造神经网络来说,首要的组件就是网络层(Layer),一个神经网络层包含以下部分:
- Tensor操作(Operation)
- 权重(Weights)
此二者恰好与类的Methods和Attributes一一对应,同时权重本身就是神经网络层的内部状态,因此使用类来构造Layer天然符合其定义。此外,我们在编程时希望使用神经网络层进行堆叠,构造神经网络,使用OOP编程可以很容易地通过Layer对象组合构造新的Layer类。
下面为使用昇思MindSpore构造神经网络类的示例:
from mindspore import nn, Parameter
from mindspore.common.initializer import initializer
class Linear(nn.Cell):
def __init__(self, in_features, out_features,
has_bias): # class constructor (code)
super().__init__()
self.weight = Parameter(
initializer('normal', [out_features, in_features],
mindspore.float32), 'weight') # layer weight (data)
self.bias = Parameter(
initializer('zeros', [out_features], mindspore.float32),
'bias') # layer weight (data)
def construct(self, inputs): # method declaration (code)
output = ops.matmul(inputs, self.weight.transpose(
0, 1)) # tensor transformation (code)
output = output + self.bias # tensor transformation (code)
return output
除神经网络层的构造使用面向对象编程范式外,昇思MindSpore支持纯面向对象编程方式构造神经网络训练逻辑,此时神经网络的正向计算、反向传播、梯度优化等操作均使用类进行构造。下面是纯面向对象编程的示例:
import mindspore
import mindspore.nn as nn
from mindspore import value_and_grad
class TrainOneStepCell(nn.Cell):
def __init__(self, network, optimizer):
super().__init__()
self.network = network
self.optimizer = optimizer
self.grad_fn = value_and_grad(self.network, None,
self.optimizer.parameters)
def construct(self, *inputs):
loss, grads = self.grad_fn(*inputs)
self.optimizer(grads)
return loss
network = nn.Dense(5, 3)
loss_fn = nn.BCEWithLogitsLoss()
network_with_loss = nn.WithLossCell(network, loss_fn)
optimizer = nn.SGD(network.trainable_params(), 0.001)
trainer = TrainOneStepCell(network_with_loss, optimizer)
此时,不论是神经网络及其训练过程均使用继承nn.Cell的类进行管理,可以方便地作为计算图进行编译加速。
函数式编程
函数式编程(Functional programming)是一种将计算机运算视为函数运算,并且避免使用程序状态以及可变对象的编程范式。
在函数式编程中,函数被视为一等公民,这意味着它们可以绑定到名称(包括本地标识符)