几个小实践带你两天快速上手MindSpore(上)

MindSpore介绍

      MindSpore是一种适用于端边云场景的新型开源深度学习训练/推理框架。 MindSpore提供了友好的设计和高效的执行,旨在提升数据科学家和算法工程师的开发体验,并为Ascend AI处理器提供原生支持,以及软硬件协同优化。

      同时,MindSpore作为全球AI开源社区,致力于进一步开发和丰富AI软硬件应用生态。

接下来我将带大家通过几个小实践快速上手MindSpore:

      1.MindSpore端边云统一格式— — MindIR

      2.华为智慧终端背后的黑科技— —超轻量AI引擎MindSpore Lite

一、MindSpore端边云统一格式

                          — — MindIR

     MindIR • 全称MindSpore IR,是MindSpore的一种基于图表示的函数式IR,定义了可扩展的图 结构以及算子的IR表示。它消除了不同后端的模型差异,一般用于跨硬件平台执行推理任务。

    (1)MindSpore通过统一IR定义了网络的逻辑结构和算子的属性,将MindIR格式的模型文件 与硬件平台解耦,实现一次训练多次部署。

    (2)MindIR作为MindSpore的统一模型文件,同时存储了网络结构和权重参数值。同时支持 部署到云端Serving和端侧Lite平台执行推理任务。 

    (3)同一个MindIR文件支持多种硬件形态的部署:

                                         - Serving部署推理 

                                         - 端侧Lite推理部署

1-1导出LeNet网络的MindIR格式模型

于是我参照着大佬的简单的写了一个py解决了这题

1.定义网络

LeNet网络不包括输入层的情况下,共有7层:2个卷积层、2个下采样层(池化层)、3个全连接层。每层都包含不同数量的训练参数,如下图所示:

我们对全连接层以及卷积层采用Normal进行参数初始化。

MindSpore支持TruncatedNormalNormalUniform等多种参数初始化方法,默认采用Normal。具体可以参考MindSpore API的mindspore.common.initializer模块说明。

使用MindSpore定义神经网络需要继承mindspore.nn.CellCell是所有神经网络(Conv2d等)的基类。

神经网络的各层需要预先在__init__方法中定义,然后通过定义construct方法来完成神经网络的前向构造。按照LeNet的网络结构,定义网络各层如下:

import mindspore.nn as nn
from mindspore.common.initializer import Normal

class LeNet5(nn.Cell):
    """
    Lenet network structure
    """
    #define the operator required
    def __init__(self, num_class=10, num_channel=1):
        super(LeNet5, self).__init__()
        self.conv1 = nn.Conv2d(num_channel, 6, 5, pad_mode='valid')
        self.conv2 = nn.Conv2d(6, 16, 5, pad_mode='valid')
        self.fc1 = nn.Dense(16 * 5 * 5, 120, weight_init=Normal(0.02))
        self.fc2 = nn.Dense(120, 84, weight_init=Normal(0.02))
        self.fc3 = nn.Dense(84, num_class, weight_init=Normal(0.02))
        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.max_pool2d(self.relu(self.conv1(x)))
        x = self.max_pool2d(self.relu(self.conv2(x)))
        x = self.flatten(x)
        x = self.relu(self.fc1(x))
        x = self.relu(self.fc2(x))
        x = self.fc3(x)
        return x

MindSpore官网为我们提供了LeNet的Checkpoint文件,提供了不同版本的:https://download.mindspore.cn/model_zoo/official/cv/lenet/

*Checkpoint • 采用了Protocol Buffers格式,存储了网络中所有的参数值。一般用于训练任务中断后恢复训练,或训练后的微调(Fine Tune)任务。在这里我选择了CPU,因为题目说可以不用训练,所以定义完网络我就直接使用了

2.模型转换

import time
import mindspore.nn as nn
from datetime import datetime
from mindspore.common.initializer import Normal

lenet = LeNet5()
# 返回模型的参数字典
param_dict = load_checkpoint("./lenet.ckpt")
# 加载参数到网络
load_param_into_net(lenet, param_dict)
input = np.random.uniform(0.0, 1.0, size=[32, 1, 32, 32]).astype(np.float32)
# 以指定的名称和格式导出文件
export(lenet, Tensor(input), file_name='lenet.mindir', file_format='MINDIR',)

t = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
print(" ")
print("============== Model conversion succeeded ==============")
print(t)

1-2训练一个ResNet50网络。使用训练好的checkpoint文件,导出MindIR格式模型

训练ResNet50网络生成checkpoint

参照着官网的教程使用MindSpore训练了一个ResNet50网络图像分类模型,官网的教程里那个文档适用于CPU、GPU和Ascend AI处理器环境。使用ResNet-50网络实现图像分类:https://www.mindspore.cn/tutorial/training/zh-CN/r1.1/advanced_use/cv_resnet50.html

(1)数据集的准备,这里使用的是CIFAR-10数据集。

(2)构建一个卷积神经网络,这里使用ResNet-50网络。

这里担心自己电脑跑不起来,使用了ModelArts平台提供的Notebook来跑 8vCPU+64G+1 x Tesla V100-PCIE-32G,不得不说性能很强这里对训练好的ResNet50网络导出为MindIR 格式

import numpy as np
from resnet import resnet50

from mindspore.train.serialization import export, load_checkpoint, load_param_into_net
from mindspore import Tensor

resnet = resnet50(batch_size=32, num_classes=10)
# return a parameter dict for model
param_dict = load_checkpoint("./models/ckpt/mindspore_vision_application/train_resnet_cifar10-10_1562.ckpt")
# load the parameter into net
load_param_into_net(resnet, param_dict)
input = np.random.uniform(0.0, 1.0, size=[32, 3, 224, 224]).astype(np.float32)
export(resnet, Tensor(input), file_name='resnet_Jack20.mindir', file_format='MINDIR')

为了保存数据,我把它下载了下来,结果发现原训练好的Checkpoint文件文件过大超过了100MB不能直接下载,于是找到了另一种解决方法:

在Notebook中,新建一个“ipynb”文件,使用MoXing先将大文件从Notebook上传到OBS中,然后我再从我OBS桶了下载不就完了嘛

import moxing as mox
mox.file.copy('./train_resnet_cifar10-10_1562.ckpt', 'obs://bucket_name/train_resnet_cifar10-10_1562.ckpt')

注:其中"./train_resnet_cifar10-10_1562.ckpt”为文件在Notebook中的存储路径,"train_resnet_cifar10-10_1562.ckpt”为该文件上传到OBS的存储路径。

二、华为智慧终端背后的黑科技

                                                 — —超轻量AI引擎MindSpore Lite

      MindSpore Lite 1.1 在端侧模型训练、算子性能优化、模型小型化、加速库自动裁剪工具、语音类模型支持、Java接口开放、模型可视化等方面进行了全面升级,升级后的版本更轻、更快、更易用

大家可以到官网下载对应的MindSpore Lite: https://www.mindspore.cn/tutorial/lite/zh-CN/r1.1/use/downloads.html

一、设计目标

1.端云一体化

         端云IR统一,云侧训练模型可直接支持端侧重训云侧混合精度训练与端侧推理协同提升推理性能

2.极致性能/轻量化

         通过NPU/CPU/GPU异构并行最大化发挥硬件算力,高效内核算法+汇编指令优化缩短推理时延不依赖任何第三方库,底层算子库使用C语言+汇编开发。

3.快捷部署

        支持第三方模型TensorFlow Lite、Caffe、ONNX离线转换,使用户可快速切换后端;提供量化工具、图片数据处理等功能方便用户的部署和使用;

4.全场景覆盖

        覆盖手机、IoT等各种智能设备;支持ARM CPU、GPU、NPU等多种硬件平台、支持Android/iOS操作系统;支持端侧推理及训练;


二、关键特性

1.性能优化

(1)算子融合:支持多达20+常见的融合,减少内存读写和计算量

(2)算子替换:支持常见的算子替换,通过参数值替换减少计算量

(3)算子前移:移动slice相关算动到计算图前,减少冗余计算

2.算子优化

     对于CPU硬件,影响算子指令执行速度的关键因素包括了L1/L2缓存的命中率以及指令的流水布,MindSpore端侧CPU算子优化手段包括:

       (1)数据的合理排布:MindSpore CPU算子采用NHWC的数据排布格式,相比NC4HW,channel方向不需要补齐至4,更省内存;相比NCHW,卷积单元的点更加紧凑,对缓存更友好;此外,算子间也不再涉及layout转换。

      (2)寄存器的合理分配:将寄存器按照用途,划分为feature map寄存器、权重寄存器和输出寄存器,寄存器的合理分配可以减少数据加载的次数。

      (3)数据的预存取,通过prefetch/preload等指令,可以提前将数据读到cache中。

      (4)指令重排,尽量减少指令的pipeline stall。

      (5)向量化计算,使用SIMD指令,如ARM NEON指令,X86 SSE/AVX指令等

3.训练后量化

      丰富的量化策略,精度接近无损

      MindSpore Lite训练后量化工具提供权重量化和全量化两种方法,支持1~16bit量化,支持分类,检测,NLP等多种模型

4.Micro for IoT

      移动终端上的推理框架,通过模型解释的方式来进行推理,这样的方式可以支持多个模型以及跨硬件平台,但是需要额外的运行时内存(MCU中最昂贵的资源)来存储元信息(例如模型结构参数)。MindSpore for Micro的CodeGen方式,将模型中的算子序列从运行时卸载到编译时,并且仅生成将模型执行的代码。它不仅避免了运行时解释的时间,而且还释放了内存使用量,以允许更大的模型运行。这样生成的二进制大小很轻,因此具有很高的存储效率。

5.异构自动并行

6.端云统一

MindSpore在框架的设计上进行了分层设计,将端云共用的数据结构和模块解耦出来,在满足端侧轻量化的同时,保持了端云架构的一致性

(1)统一IR:MindSpore core的统一lR,保证了端云模型/算子定义的一致性,使得云侧训练的模型可以无缝的部署在端侧。同时,对于端侧训练,可以和云侧使用一致的R进行模型的重训。

(2)公共pass:为了提升性能,训练好的模型在执行推理前,需要提前做一些优化手段,这些优化包括了融合、常量折叠、数据排布的调整等等。对于端云共享的优化,同样也是包含在MindSporecore模块中,只不过对于云侧推理,这些优化是在线推理时去执行的,而对于移动终端这些优化在执行推理前离线完成。

(3)统一接口:MindSpore设计了端云统一的C++接口。统一的C++接口的用法尽量与Python接口保持了一致,降低了学习成本。通过统一接口,用户可以使用一套代码在不同的硬件上进行推理。

7.端侧训练

(1)支持30+反向算子,提供SGD、ADAM等常见优化器及CrossEntropy/SparsCrossEntropy/MSE等损失函数;既可从零训练模型,也可指定特定网络层微调,达到迁移学习目的;

(2)已支持LeNet/AlexNet/ResNet/MobileNetV1/V2/V3和EffectiveNet等网络训练,提供完整的模型加载,转换和训练脚本,方便用户使用和调测;

(3)MindSpore云侧训练和端侧训练实现无缝对接,云侧模型可直接加载到端侧进行训练;

(4)支持checkpoint机制,训练过程异常中断后可快速恢复继续训练;


实践一下:

2-1在 MindSpore model_zoo下载模型mobilenetv2.mindir( https://download.mindspore.cn/model_zoo/official/lite/mobilenetv2_openimage_lite), 使用MindSpore lite converter 转成.ms 模型,请保留所使用的模型转换命令和模型转换截图

1.按要求打开链接找到指定的模型文件下载下来备用

2.把文件放到MindSpore lite converter文件夹下

因为我这里是直接把文件夹放到了桌面,在CMD中进到这个文件环境目录里


cd c: \Users\Administrator\Desktop\MindSporePetClassification\converter

3.将.mindir模型转换为.ms 模型

call converter_lite --fmk=MINDIR --modelFile=c:\Users\Administrator\Desktop\MindSporePetClassification\converter\mobilenetv2.mindir --outputFile=Jack20

    注意:其中c:\Users\Administrator\Desktop\MindSporePetClassification\converter\mobilenetv2.mindir代表生成的mindir文件,而--outputFile定义转换后MS文件的名称。

成功后,会在converter文件夹中生成对应的.ms文件。


明天我将继续为大家带来:

1.一键部署在线推理服务— —MindSpore Serving

2.AI数据高速加载直通车— —单节点数据缓存

3.快速定位模型精度问题— —MindSpore调试器

参考

[1]www.mindspore.cn

[2]gitee.com/mindspore

[3]github.com/mindspore-ai

合智互联客户成功服务热线:400-1565-661

admin
admin管理员

上一篇:十个Demo进行讲解Java中IO流的常用操作
下一篇:2021年的十五个DevOps趋势预测

留言评论

暂无留言
取消
扫码支持