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

華為雲開發者社群發表於2021-02-24
摘要:本文將帶大家通過幾個小實踐快速上手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 。

 

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

相關文章