天天看點

幾個小實踐帶你快速上手MindSpore

摘要:本文将帶大家通過幾個小實踐快速上手MindSpore,其中包括MindSpore端邊雲統一格式及華為智慧終端背後的黑科技。

MindSpore介紹

MindSpore是一種适用于端邊雲場景的新型開源深度學習訓練/推理架構。 MindSpore提供了友好的設計和高效的執行,旨在提升資料科學家和算法工程師的開發體驗,并為Ascend AI處理器提供原生支援,以及軟硬體協同優化。

同時,MindSpore作為全球AI開源社群,緻力于進一步開發和豐富AI軟硬體應用生态。

幾個小實踐帶你快速上手MindSpore

接下來我将帶大家通過幾個小實踐快速上手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個全連接配接層。每層都包含不同數量的訓練參數,如下圖所示:

幾個小實踐帶你快速上手MindSpore

我們對全連接配接層以及卷積層采用Normal進行參數初始化。

MindSpore支援TruncatedNormal、Normal、Uniform等多種參數初始化方法,預設采用Normal。具體可以參考MindSpore API的mindspore.common.initializer子產品說明。

使用MindSpore定義神經網絡需要繼承mindspore.nn.Cell。Cell是所有神經網絡(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)任務。

幾個小實踐帶你快速上手MindSpore

在這裡我選擇了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)      
幾個小實踐帶你快速上手MindSpore

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,不得不說性能很強

幾個小實踐帶你快速上手MindSpore

這裡對訓練好的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')      
幾個小實踐帶你快速上手MindSpore

為了儲存資料,我把它下載下傳了下來,結果發現原訓練好的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

幾個小實踐帶你快速上手MindSpore

一、設計目标

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在架構的設計上進行了分層設計,将端雲共用的資料結構和子產品解耦出來,在滿足端側輕量化的同時,保持了端雲架構的一緻性

幾個小實踐帶你快速上手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.按要求打開連結找到指定的模型檔案下載下傳下來備用

幾個小實踐帶你快速上手MindSpore

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檔案。

幾個小實踐帶你快速上手MindSpore

三、一鍵部署線上推理服務— —MindSpore Serving

幾個小實踐帶你快速上手MindSpore

MindSpore Serving就是為實作将深度學習部署到生産環境而産生的

MindSpore Serving是一個簡單易用、高性能的服務子產品,旨在幫助MindSpore開發者在生産環境中高效部署線上推理服務

注:MindSpore Serving目前僅支援Ascend 310和Ascend 910環境。

大家可以在MindSpore官網下載下傳對應版本安裝包實踐:https://www.mindspore.cn/versions

特點

(1)簡單易用

提供Python接口配置和啟動Serving服務,對用戶端提供gRPC和RESTful通路接口,提供Python用戶端接口,通過它,大家可以輕松定制、釋出、部署和通路模型服務。

安裝:

pip install mindspore_serving-1.1.0-cp37-cp37m-linux_aarch64.whl      

1)輕量級部署

服務端調用Python接口直接啟動推理程序(master和worker共程序),用戶端直接連接配接推理服務後下發推理任務。 執行master_with_worker.py,完成輕量級部署服務:

import os
from mindspore_serving import master
from mindspore_serving import worker

def start():
    servable_dir = os.path.abspath(".")
    worker.start_servable_in_master(servable_dir, "add", device_id=0)
    master.start_grpc_server("127.0.0.1", 5500)
 
if __name__ == "__main__":
    start()      

當服務端列印日志Serving gRPC start success, listening on 0.0.0.0:5500時,表示Serving服務已加載推理模型完畢。

2)叢集部署

服務端由master程序和worker程序組成,master用來管理叢集内所有的worker節點,并進行推理任務的分發。

部署master:

import os
from mindspore_serving import master

def start():
    servable_dir = os.path.abspath(".")
    master.start_grpc_server("127.0.0.1", 5500)
    master.start_master_server("127.0.0.1", 6500)
 
if __name__ == "__main__":
    start()      

部署worker:

import os
from mindspore_serving import worker

def start():
    servable_dir = os.path.abspath(".")
    worker.start_servable(servable_dir, "add", device_id=0,
                          master_ip="127.0.0.1", master_port=6500,
                          worker_ip="127.0.0.1", worker_port=6600)

if __name__ == "__main__":
    start()      

輕量級部署和叢集部署啟動worker所使用的接口存在差異,其中,輕量級部署使用start_servable_in_master接口啟動worker,叢集部署使用start_servable接口啟動worker。

(2)提供定制化服務

支援模型供應商打包釋出模型、預處理和後處理,圍繞模型提供定制化服務,并一鍵部署,服務使用者不需要感覺模型處理細節。

舉個栗子:實作導出兩個tensor相加操作的模型

import os
from shutil import copyfile
import numpy as np

import mindspore.context as context
import mindspore.nn as nn
import mindspore.ops as ops
import mindspore as ms

context.set_context(mode=context.GRAPH_MODE, device_target="Ascend")


class Net(nn.Cell):
    """Define Net of add"""

    def __init__(self):
        super(Net, self).__init__()
        self.add = ops.TensorAdd()

    def construct(self, x_, y_):
        """construct add net"""
        return self.add(x_, y_)


def export_net():
    """Export add net of 2x2 + 2x2, and copy output model `tensor_add.mindir` to directory ../add/1"""
    x = np.ones([2, 2]).astype(np.float32)
    y = np.ones([2, 2]).astype(np.float32)
    add = Net()
    output = add(ms.Tensor(x), ms.Tensor(y))
    ms.export(add, ms.Tensor(x), ms.Tensor(y), file_name='tensor_add', file_format='MINDIR')
    dst_dir = '../add/1'
    try:
        os.mkdir(dst_dir)
    except OSError:
        pass

    dst_file = os.path.join(dst_dir, 'tensor_add.mindir')
    copyfile('tensor_add.mindir', dst_file)
    print("copy tensor_add.mindir to " + dst_dir + " success")

    print(x)
    print(y)
    print(output.asnumpy())


if __name__ == "__main__":
    export_net()      

構造一個隻有Add算子的網絡,并導出MindSpore推理部署模型,該模型的輸入為兩個shape為[2,2]的二維Tensor,輸出結果是兩個輸入Tensor之和。

(3)支援批處理

使用者一次請求可發送數量不定樣本,Serving分割群組合一個或多個請求的樣本以比對模型的實際batch,不僅僅加速了Serving請求處理能力,并且也簡化了用戶端的使用。

幾個小實踐帶你快速上手MindSpore

主要針對處理圖檔、文本等包含batch次元的模型。假設batch_size=2,目前請求有3個執行個體,共3張圖檔,會拆分為2次模型推理,第1次處理2張圖檔傳回2個結果,第2次對剩餘的1張圖檔進行拷貝做一次推理并傳回1個結果,最終傳回3個結果。

對于一個模型,假設其中一個輸入是資料輸入,包括batch次元資訊,另一個輸入為模型配置資訊,沒有包括batch次元資訊,此時在設定with_batch_dim為True基礎上,設定額**數without_batch_dim_inputs指定沒有包括batch次元資訊的輸入資訊。

from mindspore_serving.worker import register
# Input1 indicates the input shape information of the model, without the batch dimension information.
# input0: [N,3,416,416], input1: [2]
register.declare_servable(servable_file="yolov3_darknet53.mindir", model_format="MindIR",
                          with_batch_dim=True, without_batch_dim_inputs=1)      

(4) 高性能高擴充

支援多模型多卡并發,通過client/master/worker的服務體系架構,實作MindSpore Serving的高性能和高擴充性。

幾個小實踐帶你快速上手MindSpore

華為Ascend主打晶片低功耗、高算力等特性,MindSpore提供高效的核心算法、自動融合,自動并行等能力。支援多模型多卡并發,通過client/master/worker的服務體系架構,實作MindSpore Serving的高性能和高擴充性。

高可靠性設計(某個服務節點當機,不影響用戶端正常服務),負載均衡(如何更合理的使用所有資源資訊),彈性擴容縮容(根據業務的高峰低谷,動态調整資源)

四、AI資料高速加載直通車— —單節點資料緩存

Cache單節點緩存子產品可用于緩存預處理後的訓練資料,加速資料加載,提升資料複用率,降低資料預處理所需的CPU算力

對于需要重複通路遠端的資料集或需要重複從磁盤中讀取資料集的情況,可以使用單節點緩存算子将資料集緩存于本地記憶體中,以加速資料集的讀取。 緩存算子依賴于在目前節點啟動的緩存伺服器,緩存伺服器作為守護程序獨立于使用者的訓練腳本而存在,主要用于提供緩存資料的管理,支援包括存儲、查找、讀取以及發生緩存未命中時對于緩存資料的寫入等操作。

幾個小實踐帶你快速上手MindSpore

對比使用資料緩存和不使用資料緩存的資料加載流程pipeline,第一個,是不使用資料緩存服務的正常資料處理流程

1.緩存加載後的原始資料,使用者可以在資料集加載算子中使用緩存。這将把加載完成的資料存到緩存伺服器中,後續若需相同資料則可直接從中讀取,避免從磁盤中重複加載。

2.緩存經過資料增強操作後的資料,使用者也可在Map算子中使用緩存。這将允許我們直接緩存資料增強(如圖像裁剪、縮放等)處理後的資料,避免資料增強操作重複進行,減少了不必要的計算量。

3. 以上兩種類型的緩存本質上都是為了提高資料複用,以減少資料處理過程耗時,提高網絡訓練性能。

Cache的三個重要元件

(1)緩存算子

幾個小實踐帶你快速上手MindSpore

1.對于mappable的資料集(如ImageFolder)的pipeline,Cache将建立名為CacheLookupOp和CacheMergeOp的兩個緩存算子,并對pipeline做出相應的調整。

2.見于上圖Mappable資料集圖示,左邊的資料處理pipeline,當使用者在MapOp後插入緩存算子後,經過Cache變換調整過程,将對pipeline進行變換并最終将其調整為右圖中包含CacheLookupOp和CacheMergeOp兩個緩存算子的結構

3.對于包含non-mappable的資料集(如TFRecord)的pipeline,我們将建立名為CacheOp的緩存算子,并在pipeline相應位置插入CacheOp。見于上圖Non-mappable資料集圖示,左邊的資料處理pipeline,當使用者在MapOp後插入緩存算子後,經過Cache變換調整過程,将對pipeline進行變換并最終将其調整為右圖中包含CacheOp緩存算子的結構。

(2)緩存伺服器

幾個小實踐帶你快速上手MindSpore

主要負責響應緩存用戶端所發送的請求,提供緩存資料的查找、讀取,以及發生緩存未命中時對于緩存資料的寫入等功能。緩存伺服器擁有自己的工作隊列,不斷循環從工作隊列中擷取一個請求去執行并将結果傳回給用戶端。同一個緩存伺服器可以為多個緩存用戶端提供服務,且緩存伺服器通過緩存用戶端的session_id以及該緩存用戶端所對應的資料處理pipeline的crc碼來唯一确定該緩存用戶端。是以,兩個完全一緻的pipeline可以通過指定相同的session_id來共享同一個緩存服務,而不同的pipeline若試圖共享同一個緩存用戶端則會報錯。

1.Cache_server如何啟動?

Cache Server的服務由一個外部守護程序提供,在使用者使用Cache服務之前,需要先在mindspore外部啟動一個伺服器守護程序,來與緩存客戶進行互動溝通;

ms_cache_server start|session [–m <mem_size>] [-d <spill_path>] [-nospill] [-h <host>] [-p <port>]

#Command: start | session
#start
#– starts the service
#session
#– creates a new caching session, returning the session_id as output      

然後啟動

cache_admin --start      
幾個小實踐帶你快速上手MindSpore

2.cache_server建立時預設的port端口号是多少?

預設對IP為127.0.0.1(localhost)且端口号為50052的伺服器執行操作

(3)緩存用戶端

主要負責與緩存伺服器建立通訊,向緩存伺服器發起資料讀取、資料寫入、狀态查詢等請求。緩存用戶端與伺服器之間通過gRPC進行通訊,如下圖所示:當用戶端需要發起請求時,僅需要将請求添加到gRPC函數庫所提供的gRPC隊列,由gRPC線程不斷循環從gRPC隊列中擷取一個請求并将該請求發送到緩存伺服器的工作隊列中。當緩存伺服器需要将處理後的響應資料傳回給用戶端時,也通過類似的方式将響應資料添加到gRPC隊列中,并依賴gRPC實際将資料傳輸至用戶端。

3.cache_client實體在建立時,其<session_id>如何擷取?

唯一辨別與緩存服務的連接配接session。應該從ms_cache_service session指令傳回的session_id。當給出該選項時,緩存的大小和溢出行為取自session。如果未給出值,則假設這是唯一的通道,沒有其他通道将共享此緩存。在這種情況下,将自動生成一個session_id。

ms_cache_server start|session [–m <mem_size>] [-d <spill_path>] [-nospill] [-h <host>] [-p <port>]

#Command: start | session
#– creates a new caching session, returning the session_id as output      
幾個小實踐帶你快速上手MindSpore

若緩存伺服器中不存在緩存會話,則需要建立一個緩存會話,得到緩存會話id:

其中3231564523為端口50052的伺服器配置設定的緩存會話id,緩存會話id由伺服器配置設定。

五、快速定位模型精度問題— —MindSpore調試器

在圖模式下,使用者難以從Python層擷取到計算圖中間節點的結果。MindSpore調試器是為圖模式訓練提供的調試工具,可以用來檢視并分析計算圖節點的中間結果。

使用MindSpore調試器,可以:

(1)在MindInsight調試器界面結合計算圖,檢視圖節點的輸出結果;

(2)設定監測點,監測訓練異常情況(比如檢查張量溢出),在異常發生時追蹤錯誤原因;

(3)檢視權重等參數的變化情況。

幾個小實踐帶你快速上手MindSpore

一、常見精度問題和定位思路

(1)常見現象

  1. loss:跑飛,不收斂,收斂慢
  2. metrics:accuracy、precision等達不到預期
  3. 梯度:梯度消失、梯度爆炸
  4. 權重:權重不更新、權重變化過小、權重變化過大
  5. 激活值:激活值飽和、dead relu

(2)常見問題

  1. 模型結構問題:算子使用錯誤、權重共享錯誤、權重當機錯誤、節點連接配接錯誤、 loss函數錯誤、優化器錯誤等
  2. 超參問題:超參設定不合理等
  3. 資料問題:缺失值過多、異常值、未歸一化等

(3)常用定位思路

幾個小實踐帶你快速上手MindSpore

1)定位準備

回顧算法設計,全面熟悉模型

•算法設計、超參、loss、優化器、資料處理等

•參考論文、其它實作

熟悉可視化工具

•安裝MindInsight https://www.mindspore.com/install

•加入SummaryCollector callback,收集訓練資訊

•在summary_dir的父目錄中啟動MindInsight

•mindinsight start

•熟悉調試器使用

熟悉調試器

•MindSpore調試器是為圖模式訓練提供的調試工具

•在MindInsight調試器界面結合計算圖,檢視圖節點的輸出結果;

•設定監測點,監測訓練異常情況(比如檢查張量溢出),在異常發生時追蹤錯誤原因;

•檢視權重等參數的變化情況。

使用指南請見 https://www.mindspore.cn/tutorial/training/zh-CN/master/advanced_use/summary_record.html

•debugger使用指南請見https://www.mindspore.cn/tutorial/training/zh-CN/r1.1/advanced_use/debugger.html

2)檢查代碼、超參、模型結構

1.走讀腳本,檢查代碼

•小黃鴨調試法

•檢查代碼同模型設計、論文、參考腳本等是否一緻

2.超參常見問題:

•學習率不合理

•權重初始化參數不合理等

3.MindInsight輔助檢查:訓練清單->訓練參數詳情

4.模型結構常見問題:

•算子使用錯誤(使用的算子不适用于目标場景,如應該使用浮點除,錯誤地使用了整數除),

•權重共享錯誤(共享了不應共享的權重),

•權重當機錯誤(當機了不應當機的權重),

•節點連接配接錯誤(應該連接配接到計算圖中的block未連接配接),

•loss函數錯誤,

•優化器算法錯誤(如果自行實作了優化器)等。

5.MindInsight輔助檢查:訓練清單->訓練看闆->計算圖

3)檢查輸入資料

1.輸入資料常見問題:

•資料缺失值過多

•每個類别中的樣本數目不均衡

•資料中存在異常值

•資料标簽錯誤

•訓練樣本不足

•未對資料進行标準化,輸入模型的資料不在正确的範圍内

•finetune和pretrain的資料處理方式不同

•訓練階段和推理階段的資料處理方式不同

•資料處理參數不正确等。

2.MindInsight輔助檢查:訓練清單->訓練看闆->資料抽樣

4)檢查loss曲線

1.常見現象

•loss跑飛

回顧腳本、模型結構和資料,

•檢查超參是否有不合理的特别大/特别小的取值,

•檢查模型結構是否實作正确,特别是檢查loss函數是否實作正确,

•檢查輸入資料中是否有缺失值、是否有特别大/特别小的取值。

使用參數分布圖檢查參數更新是否有劇烈變化

使用調試器功能對訓練現場進行檢查

•配置“檢查張量溢出”監測點,定位NAN/INF出現位置

•配置“檢查過大張量”監測點,定位出現大值的算子

•配置“檢查權重變化過大”、“檢查梯度消失”、“檢查梯度過大”監測點,定位異常的權重或梯度

幾個小實踐帶你快速上手MindSpore

•loss收斂慢

2.MindInsight輔助檢查:訓練清單->訓練看闆->标量曲線/參數分布圖

幾個小實踐帶你快速上手MindSpore

3.調試器定位

5)檢查精度是否達到預期

1.回顧代碼、模型結構、輸入資料和loss曲線,

•檢查超參是否有不合理的值

•檢查模型結構是否實作正确

•檢查輸入資料是否正确

•檢查loss曲線的收斂結果和收斂趨勢是否存在異常

2.嘗試使用“溯源分析”和調參器優化超參

•mindoptimizer --config ./config.yaml --iter 10

3.嘗試模型解釋

4.嘗試優化模型算法

幾個小實踐帶你快速上手MindSpore

注意事項

1.場景支援

•調試器暫不支援分布式訓練場景。

•調試器暫不支援推斷場景。

•調試器暫不支援單機多卡/叢集場景。

•調試器暫不支援連接配接多個訓練程序。

•調試器暫不支援CPU場景。

2.性能影響

•使用調試器時,會對訓練性能産生一定影響。

•設定的監測點數目過多時,可能會出現系統記憶體不足(Out-of-Memory)的異常。

3.GPU場景

•在GPU場景下,隻有滿足條件的參數節點可以與自身的上一輪次結果作對比:使用下一個節點執行過的節點、使用運作到該節點時選中的節點、作為監測點輸入的參數節點。其他情況均無法使用上一輪次對比功能。

•由于GPU上一個輪次是一個子圖(而非完整的圖),GPU上多圖做重新檢查時,隻能重新檢查目前的子圖。

4.重新檢查隻檢查目前有張量值的監測點。

5.檢查計算過程溢出需要使用者開啟異步Dump的全部溢出檢測功能,開啟方式請參照異步Dump功能介紹

6.調試器展示的圖是優化後的最終執行圖。調用的算子可能已經與其它算子融合,或者在優化後改變了名稱。

參考

[1]www.mindspore.cn

[2]gitee.com/mindspore

[3]github.com/mindspore-ai

本文分享自華為雲社群《幾個小實踐帶你兩天快速上手MindSpore 》,原文作者:Jack20 。

點選關注,第一時間了解華為雲新鮮技術~