短期網(wǎng)站建設(shè)培訓(xùn)百度sem是什么意思
大家好,我是劉明,明志科技創(chuàng)始人,華為昇思MindSpore布道師。
技術(shù)上主攻前端開發(fā)、鴻蒙開發(fā)和AI算法研究。
努力為大家?guī)沓掷m(xù)的技術(shù)分享,如果你也喜歡我的文章,就點個關(guān)注吧
MindSpore官網(wǎng)提供了一份在使用MindSpore過程中的 FAQ ,本章也整理了一下在遷移文檔中提及的常見問題及解決方法。
環(huán)境準(zhǔn)備
Q: 如何搭建MindSpore環(huán)境?
A: MindSpore目前支持在昇騰、GPU、CPU等多種設(shè)備上運(yùn)行,但在安裝過程中需要注意選擇配套的硬件平臺、操作系統(tǒng)、Python版本,否則會出現(xiàn)很多不可預(yù)測的報錯。詳細(xì)可參考 安裝指導(dǎo) 。
更多環(huán)境準(zhǔn)備常見問題請參考 環(huán)境準(zhǔn)備常見問題分析 。
模型分析與準(zhǔn)備
Q: 如何查看MindSpore對遷移代碼中的API支持程度?
A: 可以使用API自動掃描工具M(jìn)indSpore Dev Toolkit(推薦),或手動查詢API映射表進(jìn)行分析。詳細(xì)可參考 分析API滿足度 。
數(shù)據(jù)處理
Q: 怎么將PyTorch的dataset
轉(zhuǎn)換成MindSpore的dataset
?
A: MindSpore和PyTorch的自定義數(shù)據(jù)集邏輯是比較類似的,首先需要用戶先定義一個自己的 dataset 類,該類負(fù)責(zé)定義 init 、 getitem 、 len 來讀取自己的數(shù)據(jù)集,然后將該類實例化為一個對象(如: dataset/dataset_generator ),最后將這個實例化對象傳入 GeneratorDataset (mindspore用法)/ DataLoader (pytorch用法),至此即可以完成自定義數(shù)據(jù)集加載了。
而MindSpore在 GeneratorDataset 的基礎(chǔ)上提供了進(jìn)一步的 map -> batch 操作,可以很方便地讓用戶在 map 內(nèi)添加一些其他的自定義操作,并將其 batch 起來。
對應(yīng)的MindSpore的自定義數(shù)據(jù)集加載如下:
# 1 Data enhancement,shuffle,sampler.
class Mydata:def __init__(self):np.random.seed(58)self.__data = np.random.sample((5, 2))self.__label = np.random.sample((5, 1))def __getitem__(self, index):return (self.__data[index], self.__label[index])def __len__(self):return len(self.__data)
dataset_generator = Mydata()
dataset = ds.GeneratorDataset(dataset_generator, ["data", "label"], shuffle=False)
# 2 Customized data enhancement
dataset = dataset.map(operations=pyFunc, {other_params})
# 3 batch
dataset = dataset.batch(batch_size, drop_remainder=True)
Q: 為什么在迭代數(shù)據(jù)的時候會報錯:“The actual amount of data read from generator xx is different from generator.len xx, you should adjust generator.len to make them match” ?
A: 在定義可隨機(jī)訪問數(shù)據(jù)集時, len 方法返回的結(jié)果一定要是真實的數(shù)據(jù)集大小,設(shè)置大了在 getitem 取值時會有越界問題。如數(shù)據(jù)集大小未確定,可以使用可迭代數(shù)據(jù)集,詳見 自定義數(shù)據(jù)集 。
Q: 為什么在迭代數(shù)據(jù)的時候會報錯:“Invalid Python function, the ‘source’ of ‘GeneratorDataset’ should return same number of NumPy arrays as specified in column_names, the size of column_names is:xx and number of returned NumPy array is:xx” ?
A: 這是因為GeneratorDataset的 column_names 參數(shù)指定的列名數(shù)量與 source 參數(shù)輸出的數(shù)據(jù)數(shù)量不匹配。
Q: 使用 GeneratorDataset 或 map 進(jìn)行加載/處理數(shù)據(jù)時,可能會因為語法錯誤、計算溢出等問題導(dǎo)致數(shù)據(jù)報錯,如何進(jìn)行排查和調(diào)試?
A: 觀察報錯棧信息,由報錯棧信息大概定位到出錯代碼塊,在出錯的代碼塊附近添加打印或調(diào)試點,進(jìn)一步調(diào)試。詳細(xì)可參考 數(shù)據(jù)處理調(diào)試方法一 。
Q: 數(shù)據(jù)增強(qiáng) map 操作出錯,如何調(diào)試 map 操作中各個數(shù)據(jù)處理算子?
A: 可以通過單個算子執(zhí)行的方式調(diào)試或者通過數(shù)據(jù)管道調(diào)試模式調(diào)試 map 操作。
Q: 在訓(xùn)練的時候,會獲得非常多warning提示我們數(shù)據(jù)集性能較慢應(yīng)該怎么處理?
A: 可以單獨(dú)迭代數(shù)據(jù)集,查看每條數(shù)據(jù)的處理時間,以此判斷數(shù)據(jù)集的性能如何。詳細(xì)可參考 數(shù)據(jù)處理調(diào)試方法三 。
Q: 在對數(shù)據(jù)進(jìn)行處理的過程中,如果因為計算錯誤、數(shù)值溢出等因素,產(chǎn)生了異常的結(jié)果數(shù)值,從而導(dǎo)致訓(xùn)練網(wǎng)絡(luò)時算子計算溢出、權(quán)重更新異常等問題該怎么排查?
A: 關(guān)閉混洗,固定隨機(jī)種子,確??芍噩F(xiàn)性,然后利用NumPy等工具快速校驗結(jié)果。詳細(xì)可參考 數(shù)據(jù)處理調(diào)試方法四 。
更多數(shù)據(jù)處理常見問題請參考 數(shù)據(jù)處理常見問題分析 以及遷移中的數(shù)據(jù)處理差異請參考 MindSpore和PyTorch的數(shù)據(jù)處理差異 。
梯度求導(dǎo)
Q: 如何自己實現(xiàn)算子的反向計算?
A: MindSpore提供了自動的梯度求導(dǎo)接口,該功能對用戶屏蔽了大量的求導(dǎo)細(xì)節(jié)和過程。但如果有某些特殊場景,用戶需要手動控制其反向的計算,用戶也可以通過Cell.bprop接口對其反向進(jìn)行定義。詳細(xì)可參考 自定義Cell反向 。
Q: 如何處理梯度溢出造成訓(xùn)練不穩(wěn)定的問題?
A: 網(wǎng)絡(luò)溢出一般表現(xiàn)為loss Nan/INF,loss突然變得很大等。MindSpore提供 dump數(shù)據(jù) 獲取到溢出算子信息。當(dāng)網(wǎng)絡(luò)中出現(xiàn)梯度下溢時,可使用loss scale配套梯度求導(dǎo)使用,詳細(xì)可參考 loss scale ;當(dāng)網(wǎng)絡(luò)出現(xiàn)梯度爆炸時,可考慮添加梯度裁剪,詳細(xì)可參考 梯度裁剪 。
調(diào)試調(diào)優(yōu)
Q: 請問想加載PyTorch預(yù)訓(xùn)練好的模型用于MindSpore模型finetune有什么方法?
A: 需要把PyTorch和MindSpore的參數(shù)進(jìn)行一一對應(yīng),因為網(wǎng)絡(luò)定義的靈活性,所以沒辦法提供統(tǒng)一的轉(zhuǎn)化腳本。
一般情況下,CheckPoint文件中保存的就是參數(shù)名和參數(shù)值,調(diào)用相應(yīng)框架的讀取接口后,獲取到參數(shù)名和數(shù)值后,按照MindSpore格式,構(gòu)建出對象,就可以直接調(diào)用MindSpore接口保存成MindSpore格式的CheckPoint文件了。
其中主要的工作量為對比不同框架間的parameter名稱,做到兩個框架的網(wǎng)絡(luò)中所有parameter name一一對應(yīng)(可以使用一個map進(jìn)行映射),下面代碼的邏輯轉(zhuǎn)化parameter格式,不包括對應(yīng)parameter name。
import torch
import mindspore as msdef pytorch2mindspore(default_file = 'torch_resnet.pth'):# read pth filepar_dict = torch.load(default_file)['state_dict']params_list = []for name in par_dict:param_dict = {}parameter = par_dict[name]param_dict['name'] = nameparam_dict['data'] = ms.Tensor(parameter.numpy())params_list.append(param_dict)ms.save_checkpoint(params_list, 'ms_resnet.ckpt')
Q: loss不收斂或精度不達(dá)標(biāo),該怎么定位?
A: 精度不達(dá)標(biāo)一般體現(xiàn)在loss不收斂上。但是有很多復(fù)雜的原因可導(dǎo)致精度達(dá)不到預(yù)期,定位難度較大。這里提供幾個指導(dǎo)鏈接供用戶逐一排查問題。
Q: 模型訓(xùn)練過程中,第一個step耗時很長,該怎么優(yōu)化?
A: 模型訓(xùn)練過程中,第一個step包含網(wǎng)絡(luò)編譯時長,如果想要優(yōu)化第一個step的性能,可分析模型編譯是否能進(jìn)行優(yōu)化。詳細(xì)可參考 靜態(tài)圖網(wǎng)絡(luò)編譯性能優(yōu)化 。
Q: 模型訓(xùn)練過程中,非首個step耗時很長,該怎么優(yōu)化?
A: 模型訓(xùn)練過程中,非首個step的耗時包括迭代間隙、前反向計算和迭代拖尾,如果想要優(yōu)化非首step的性能,需要先獲取網(wǎng)絡(luò)的迭代軌跡,再分析哪部分是性能瓶頸,最近進(jìn)行性能優(yōu)化。
詳細(xì)可參考 性能調(diào)優(yōu)指南 ;和 性能調(diào)試案例 。
Q: 加載標(biāo)桿權(quán)重進(jìn)行模型推理驗證正向流程時,有warning警告顯示權(quán)重未加載成功,該如何解決?
A: load_checkpoint過程中,如果有權(quán)重未加載上,MindSpore會給出warning提示,一般加載失敗有兩種原因:1、權(quán)重名稱對不上;2、權(quán)重在網(wǎng)絡(luò)中缺失。
如果權(quán)重名稱對不上,需要打印MindSpore的權(quán)重名稱和標(biāo)桿的權(quán)重名稱,看是否MindSpore的權(quán)重名稱多了backbone或network等前綴,如果是,檢查MindSpore在初始化 Cell 時是否加上auto_prefix=False。
如果權(quán)重名稱缺失,需要分析是否合理,如果合理,可忽略告警提示,如果不合理,需要分析網(wǎng)絡(luò)定義是否錯誤,進(jìn)行定位修改。
Q: 遷移過程使用PyNative進(jìn)行調(diào)測,流程成功,切換成Graph模式,為什么會出現(xiàn)一堆的報錯?
A: PyNative模式下模型進(jìn)行推理的行為與一般Python代碼無異。但是切換成Graph模式時,MindSpore通過源碼轉(zhuǎn)換的方式,將Python的源碼轉(zhuǎn)換成中間表達(dá)IR(Intermediate Representation),并在此基礎(chǔ)上對IR圖進(jìn)行優(yōu)化,最終在硬件設(shè)備上執(zhí)行優(yōu)化后的圖。
而這一步操作中MindSpore目前還未能支持完整的Python語法全集,所以construct函數(shù)的編寫會存在部分限制。
如:PyNative模式下可直接判斷某個Tensor值是否為0,但切換成Graph模式則會報錯不支持。
if response == 0:return loss
return loss/response
遇到類似情況,可將代碼修改為:
response_gt = max(response, ms.Tensor(1))
loss = loss/response_gt
return loss