软硬co-design及面向系统设计——谈谈MindSpore和深度学习框架的必由之路

转载地址:https://bbs.huaweicloud.com/forum/thread-61282-1-1.html

作者: OwlLite

深度学习大潮出现之后,AI行业迎来了历史上的又一轮兴奋期。如今也同经历过的历史一样,兴奋已经过去,很多乐观的预言(例如“全自动驾驶”)并没有实现而且被业界认为不可能在当前技术架构下实现。不过技术的进步还是广泛的开花结果,进入了大范围的落地阶段。AI算法在我们今天每个人的生活中扮演着不可或缺的角色,比如几乎每天都要用到的人脸识别、指纹识别,视频和拍照中广泛用到的美颜,智能家居中用到的语音识别、语义理解和语音合成,互联网应用中的信息流推荐等等。目前来看,虽然运用越来越多,AI算法在云端和用户端的部署对行业来说仍然是一个痛点。我们能在网络上看到大量的关于数据搜集和清洗、模型设计和调参训练等方面的问题,但让训练好的模型服务于用户/消费者,也就是模型的部署这个重要问题,却很少被提及。

软硬co-design及面向系统设计——谈谈MindSpore和深度学习框架的必由之路

模型的部署对于越高服务请求频率的应用来说越复杂和重要。一般场景下,我们需要考虑吞吐和时延问题,负载均衡问题和模型的持续升级问题(离线升级或在线训练)。考虑到这些因素,一般需要进行服务端(Server)和用户端(Client)的分离,把算法/模型留在服务端,以ProtoBuf/JSON等格式通过REST/RPC框架与用户端进行相互沟通。基于服务的体验和成本的考虑,很少有人会选择CPU在服务端进行模型的运算,而是一般采用GPU. 用户端则可能是使用X86 CPU, ARM等架构的CPU进行服务请求和部分运算。服务端(云端)和用户端的分离有助于解决架构方面的多样性和适配性问题,减少问题耦合。当然,由于一些应用对时延的高要求,不得不在用户端进行计算(比如美颜,人脸检测),这样的需求使得模型的部署进一步的复杂化。

深度学习算法的云端部署目前还没有统一个架构。TensorFlow在这方面暂时做得比较领先,在工业界也更受欢迎。但在学术界,TensorFlow由于其架构和文档的混乱越来越不受欢迎(特别是新人),最新的模型反而是PyTorch平台的比较多。而后者的云端部署目前还处在比较早期的开发阶段。二者在移动端的部署可以说都做的不够好,而且移动端部署要处理的量化问题也会导致很多麻烦,需要大量时间、经验和人力,成本很高。除了这两个平台之外,其他一些平台目前也被越来越多的开源出来。这些平台的多样化反映了行业应用的火热,但也给模型的通用性带来了挑战。为此目的推出了开源框架共用模型格式ONNX(开放式神经网络交换),。不过各框架对它的支持程度存在一定差异,一些自定义的计算和网络结构也并不能很方便的进行转换。

软硬co-design及面向系统设计——谈谈MindSpore和深度学习框架的必由之路

为解决AI计算和部署两个方面的问题,一要设计更适用于AI计算的处理器,二要建设基于该处理器的服务架构和社区,形成硬件和软件上的联动,打造出一个成功的生态。如此才能实现一次训练多端部署,大幅节省开发和计算成本。对应地,在硬件方面,华为方面设计了昇腾910/310处理器,分别针对服务端和客户端/边缘端应用,为AI计算做了大量的优化。

软硬co-design及面向系统设计——谈谈MindSpore和深度学习框架的必由之路

设计和采用了达芬奇架构,应用cube unit, 矩阵分块计算等技术对模型训练和推理中大量使用的向量、矩阵和张量的计算做大幅加速,优化单位面积下的芯片算力。同样是完成4096次运算,2D结构需要64行*64列才能计算,3D Cube只需要16*16*16的结构就能算出,可大幅改善延迟和利用率。这些技术的应用让昇腾910在300W功耗下实现了250 T FLOPS的半精度运算性能。

软硬co-design及面向系统设计——谈谈MindSpore和深度学习框架的必由之路

在软件和生态方面,华为建设和开源了通用AI模型训练/推理架构MindSpore. 自首次发布以来保持着约每月一次的快速迭代(目前更新到0.3.0-alpha)。除如其他架构一样支持CPU/GPU的训练和推理之外,还优化支持昇腾处理器的部署和推理。后者在训练和推理速度/效率上具有一定的优势,尤其适合云顿应用。由于时间上的后发,MindSpore支持很多用户友好的特性,如动态图、AutoParallel、ONNX等,还支持PyTorch模型向MindSpore模型的一键转换。其代码 Pythonic,学习成本很低。这些硬件和软件上的支持,让MindSpore支持云-边缘-端的全场景一致化应用。

如果有使用过TensorFlow或PyTorch的经验, 用户可以很快的使用Anaconda或者pip安装MindSpore并实现一个简单的demo应用:

pip install

验证安装:

import mindspore as ms
print(ms.__version__)
#如果成功,则打印MindSpore版本号,比如0.3.0

验证无误后可以简单运行demo代码,比如使用LeNet实现图像分类:

git clone https://github.com/mindspore-ai/docs.git

其中对网络的定义方式如下:

class LeNet5(nn.Cell):	
 	    """Lenet network structure."""
 	    # define the operator required
 	    def __init__(self):
 	        super(LeNet5, self).__init__()
 	        self.conv1 = conv(1, 6, 5)
 	        self.conv2 = conv(6, 16, 5)
 	        self.fc1 = fc_with_initialize(16 * 5 * 5, 120)
 	        self.fc2 = fc_with_initialize(120, 84)
 	        self.fc3 = fc_with_initialize(84, 10)
 	        self.relu = nn.ReLU()
 	        self.max_pool2d = nn.MaxPool2d(kernel_size=2, stride=2)
 	        self.flatten = nn.Flatten()
  
 	    # use the preceding operators to construct networks
 	    def construct(self, x):
 	        x = self.conv1(x)
 	        x = self.relu(x)
 	        x = self.max_pool2d(x)
 	        x = self.conv2(x)
 	        x = self.relu(x)
 	        x = self.max_pool2d(x)
 	        x = self.flatten(x)
 	        x = self.fc1(x)
 	        x = self.relu(x)
 	        x = self.fc2(x)
 	        x = self.relu(x)
 	        x = self.fc3(x)
 	        return x

使用MindSpore定义神经网络需要继承mindspore.nn.cell.Cell, 神经网络的各层预先在__init__()方法中定义,然后通过定义construct()方法来完成神经网络的前向构造(相当于PyTorch的forward()). 之后就可以下载训练数据开始训练了.

当然,上面的过程用户也可以通过申请基于昇腾910芯片的ModelArts华为云昇腾集群服务来运行(需要先注册华为云:华为云昇腾集群服务公测申请):

软硬co-design及面向系统设计——谈谈MindSpore和深度学习框架的必由之路

软硬co-design及面向系统设计——谈谈MindSpore和深度学习框架的必由之路

具体使用方法可参考此分类教程:使用ModelArts实现花卉图像分类

软硬co-design及面向系统设计——谈谈MindSpore和深度学习框架的必由之路

结合ModelArts,可以充分发挥MindSpore的自动并行能力。要注意这里的自动并行并不是其他框架所指的多机/卡并行,而是指从众多的并行可能性里面,使用动态规划(dynamic programming)和递归算法(recursive programming)搜寻出一种最优的并行执行方式,比如将部分算子进行自动拆分从而达到一个比较好的并行效果(这自然包括多GPU/CPU并行),使得多机并行的加速比达到0.95左右(多机并行训练加速比)。上文中我们提到的Cube Unit对应的向量、矩阵和张量算子就可以充分发力了。MindSpore通过set_auto_parallel_context这个接口来指定不同的并行策略,通过其定义可一窥其功能和复杂性:

def set_auto_parallel_context(**kwargs):
 """
 Set auto parallel context.
 Note:
 Attribute name is required for setting attributes.
 If a program has tasks with different parallel modes, then before setting new parallel mode for
 next task, interface mindspore.context.reset_auto_parallel_context() needs to be called to reset
 the configuration.
 Args:
 device_num (int): Available device number, the value must be in [1, 4096]. Default: 1.
 global_rank (int): Global rank id, the value must be in [0, 4095]. Default: 0.
 mirror_mean (bool): Whether to perform mean operator after all-reduce of mirror.
 "stand_alone" do not support mirror_mean. Default: False.
 cast_before_mirror (bool): Insert Mirror Op after the cast if this flag is True.
 "stand_alone", "data_parallel" and "hybrid_parallel" do not support
 cast_before_mirror. Default: True.
 parallel_mode (str): There are five kinds of parallel modes, "stand_alone", "data_parallel",
 "hybrid_parallel", "semi_auto_parallel" and "auto_parallel". Default: "stand_alone".
 - stand_alone: Only one processor working.
 - data_parallel: Distributing the data across different processors.
 - hybrid_parallel: Achieving data parallelism and model parallelism manually.
 - semi_auto_parallel: Achieving data parallelism and model parallelism by
 setting parallel strategies.
 - auto_parallel: Achieving parallelism automatically.
 parameter_broadcast (bool): Indicating whether to broadcast parameters before training.
 "stand_alone", "semi_auto_parallel" and "auto_parallel" do not support parameter
 broadcast. Default: False.
 strategy_ckpt_load_file (str): The path to load parallel strategy checkpoint. Default: ''
 strategy_ckpt_save_file (str): The path to save parallel strategy checkpoint. Default: ''
 Raises:
 ValueError: If input key is not attribute in auto parallel context.
 Examples:
 >>> context.set_auto_parallel_context(device_num=8)
 >>> context.set_auto_parallel_context(global_rank=0)
 >>> context.set_auto_parallel_context(mirror_mean=True)
 >>> context.set_auto_parallel_context(cast_before_mirror=False)
 >>> context.set_auto_parallel_context(parallel_mode="auto_parallel")
 >>> context.set_auto_parallel_context(parameter_broadcast=False)
 >>> context.set_auto_parallel_context(strategy_ckpt_load_file="./strategy_stage1.ckpt")
 >>> context.set_auto_parallel_context(strategy_ckpt_save_file="./strategy_stage1.ckpt")
 """
  _set_auto_parallel_context(**kwargs)

作为优化重点,模型的部署自然会被大幅简化。在ModelArts后台完成模型的训练之后,只需要在管理控制平台完成几次点击即可部署为在线服务(模型在线部署):

软硬co-design及面向系统设计——谈谈MindSpore和深度学习框架的必由之路

这将自动支持分布式推理运算,实现服务的高吞吐、低延时。甚至可以在ModelArts后台购买已经开发完成共享的免费/付费模型,加速产品落地。当然,也可以选择使用WASM于Rust实现自定义的服务部署(MindSpore WebAssembly Backend),或使用Volcano和Kubeflow进行分布式部署(MindSpore Volcano Example).

软硬co-design及面向系统设计——谈谈MindSpore和深度学习框架的必由之路

MindSpore当前版本在架构设计和功能支持上体现了核心目标——一个在端-云/边缘协同的高性能AI训练和推理架构。其多机协同性能、服务部署的高度可扩展性和便捷性、低学习门槛 都是力图解决中小企业在AI服务方面的痛点。当然,由于后发,在架构和特性优势背后也有一定的功能不完善性,如Model Zoo还比较少,用户如果想部署最新的模型可能从零开始训练。让更多的开发者用起来,补足这些短板,也提出更多业界的开发需求,或许正是MindSpore开源的目的。

声明:图片来源网络 侵删

上一篇:Java 8 parallel 性能测试


下一篇:服务发现框架Consul的使用