午夜精品人妻久久久-成年美女很黄的网站-在线看片免费人成视久网app-国产精品美女无遮挡一区二区-91精品国产综合久久久久-国产的免费视频又猛又爽又刺激-在线看片免费人成视久网app-久久香蕉国产精品视频-av一区二区三区高清

基于Mindspore2.0的GPT2預(yù)訓(xùn)練模型遷移教程

本文分享自華為云社區(qū)《-基于.0的GPT2預(yù)訓(xùn)練模型遷移教程》,作者:。
原文詳情:
前言動機(jī)
大家好,我是,最近快要上線2.0版本了,由于之前主要是參與的開發(fā)工作,一直想找機(jī)會多用一用 。而自春節(jié)開始也是參與到了一項基于的遷移工作,積攢了一些經(jīng)驗(yàn),所以最近蹭蹭的熱度,搞了一下GPT2的模型遷移工作 。目前初步實(shí)現(xiàn)了最基礎(chǔ)模型的推理,輸出精度能夠和 face中基于的實(shí)現(xiàn)完全對標(biāo) 。整個流程我感覺非常的順利,并且也切實(shí)的體會到目前已經(jīng)可以說是從“可用”進(jìn)化到了“易用”的階段 。出于布道師的職責(zé),同時更是自己想要分享.0的使用感受,寫下這篇基于.0的模型遷移教程,供大家參考 。
目的
這篇文章主要目的是為了讓大家能夠清楚如何用.0來進(jìn)行模型的遷移,因此更加注重整體的開發(fā)流程介紹,針對遷移中代碼的編寫不會詳細(xì)講解,但是會給出樣例以及供查閱的文檔鏈接 。最終希望讀者能夠了解遷移模型需要做什么,每一步應(yīng)該怎么做 , 做完了應(yīng)該怎么驗(yàn)證 。話不多說,直接開始:
1、前期準(zhǔn)備
本章節(jié)介紹開發(fā)的前期準(zhǔn)備工作,簡要介紹環(huán)境配置、安裝和尋找遷移參考代碼的途徑 , 每一部分的詳細(xì)操作大家可以百度搜索一下,相關(guān)博客非常多 , 這里就不贅述 。這一章節(jié)非常的基礎(chǔ),如果已經(jīng)是老手可以直接跳過 。
1.1 尋找參照樣例
既然是遷移工作 , 那么第一件事肯定是確定自己想要遷移的模型,然后找到該模型的開源代碼,提供以下幾個途徑供大家尋找源碼linux 使用情況,基本上比較知名的模型通過以下幾種方式都是可以找到相應(yīng)代碼的:
1.2 Git操作
找到了參考代碼之后 , 大家會發(fā)現(xiàn)這些源碼基本上都是保存在上的,因此為了更方便的查閱我們需要遷移的代碼,以及跳轉(zhuǎn)和搜索可能存在的依賴函數(shù),我建議大家把參考代碼Clone到本地,然后進(jìn)行對照開發(fā):
常用的git操作可以參考這篇博客:Git的下載、安裝與使用(#:~:text=%E4%B8%8B%E7%9A%84Git%E7%9A%84%E4%B8%8B%E8%BD%BD%E3%80%81%E5%AE%89%E8%A3%85%E4%B8%8E%E4%BD%BF%E7%94%A8%E6%95%99%E7%A8%8B)
1.3 環(huán)境配置1.3.1 自有硬件
如果大家自己有硬件資源,比如CPU、GPU、服務(wù)器,那么可以在自己的電腦本地配置神經(jīng)網(wǎng)絡(luò)的運(yùn)行環(huán)境,主要包括以下步驟:
1.3.2 啟智社區(qū)
OpenI 啟智 新一代人工智能開源開放平臺
啟智AI協(xié)作平臺,簡稱啟智社區(qū),是一個開源在線Web應(yīng)用,旨在為人工智能算法、模型開發(fā)提供在線協(xié)同工作環(huán)境,它提供了代碼托管、數(shù)據(jù)集管理與共享、免費(fèi)云端算力資源支持(GPU/NPU)、共享鏡像等功能 。
啟智平臺是可以直接在線創(chuàng)建網(wǎng)絡(luò)運(yùn)行環(huán)境的平臺,里面可以白嫖GPU/NPU資源,配置也非常容易,個人感覺非常的好用,如果大家沒有自己的硬件資源的話可以創(chuàng)建一個賬號,用啟智來進(jìn)行調(diào)試:
GPU調(diào)試參考:/_GPU – OpenI – 啟智AI開源社區(qū)提供普惠算力!
NPU調(diào)試參考:/ NPU – OpenI – 啟智AI開源社區(qū)提供普惠算力!
1.4 安裝.4.1 簡介
安裝之前,請允許我先介紹和宣傳一下:官網(wǎng)介紹
昇思是一個全場景深度學(xué)習(xí)框架,旨在實(shí)現(xiàn)易開發(fā)、高效執(zhí)行、全場景覆蓋三大目標(biāo) 。
其中,易開發(fā)表現(xiàn)為API友好、調(diào)試難度低;高效執(zhí)行包括計算效率、數(shù)據(jù)預(yù)處理效率和分布式訓(xùn)練效率;全場景則指框架同時支持云、邊緣以及端側(cè)場景 。
昇思總體架構(gòu)如下圖所示:
1.4.2 安裝
官網(wǎng)就有非常詳細(xì)的安裝教程,大家可以按照官網(wǎng)的步驟進(jìn)行安裝:
安裝指南
2、網(wǎng)絡(luò)遷移
神經(jīng)網(wǎng)絡(luò)其實(shí)可以理解為搭積木,而不同框架就可以理解為不同品牌的積木包,比如有樂高、森寶、啟蒙等等,不同品牌的積木包中肯定有非常多的積木是類似可代替的 。
比如A品牌推出了一個Super Mario超級馬里奧的積木套裝 , 而我們手頭有B品牌的零散積木,只要我們有了這個Super Mario的搭建步驟圖,我們同樣可以用B品牌的積木構(gòu)造出一個基本相同的Super Mario 。
那么我們將品牌A替換為框架A、品牌B替換為、積木替換為需要用到的API接口,構(gòu)建圖替換為GPT2的論文 。那么:
我們有了基于框架A的GPT2模型,而我們手頭有中大量的可調(diào)用接口,那么我們只需要參照GPT2的網(wǎng)絡(luò)結(jié)構(gòu)圖和原論文 , 就可以用寫出一個基本相同的GPT2模型,這個過程就是模型遷移 。
經(jīng)過上面的例子,大家應(yīng)該大致了解網(wǎng)絡(luò)遷移是在干個什么事情,而實(shí)際上網(wǎng)絡(luò)的遷移工作也非常簡單,主要考驗(yàn)開發(fā)者對于網(wǎng)絡(luò)模型構(gòu)建以及多種深度學(xué)習(xí)框架的熟悉情況 。不過不同的模型網(wǎng)絡(luò)結(jié)構(gòu)肯定是不相同的,因此本章節(jié)只會介紹遷移流程和每一步應(yīng)該做什么,具體怎么遷移就需要大家讀懂源碼,然后參照我給出的api映射表具體問題具體分析 。
首先介紹一下后續(xù)遷移講解用到的資源情況:
2.1 源碼下載2.1.1 參考源碼下載
前往/倉庫下載包
之后找到遷移需要用到的.py配置文件和.py模型文件(沒有后綴的一般是實(shí)現(xiàn),帶tf的是實(shí)現(xiàn),我個人對于更熟悉一些所以選擇版本進(jìn)行遷移)
使用遠(yuǎn)程連接 , 可以直接訪問文件代碼:
2.3.1 倉庫下載
由于遷移之后的源碼是需要合入到倉庫的,因此大家需要去官方倉庫進(jìn)行一鍵三連(watch+fork+star)
目前中已經(jīng)有了Bert模型的遷移代碼,因此我們是可以將這個bert.py與 face中的bert代碼進(jìn)行對比來學(xué)習(xí)應(yīng)該如何遷移的:
下載好之后同樣用打開,剛下載的打開圖示的界面是沒有g(shù)pt2這個文件夾的,這個是大家需要根據(jù)自己的模型創(chuàng)建的,用于存放之后遷移之后的相關(guān)文件 。我的是GPT2所以創(chuàng)建為gpt2,其他模型同理 。
之后在該文件夾下新建.py、.py、gpt2.py三個文件,作用分別是:
2.2 API映射
下載好了參考源碼和倉庫之后我們就可以正式開始網(wǎng)絡(luò)遷移了,經(jīng)過上面搭積木的例子 , 大家其實(shí)應(yīng)該知道我們需要做的其實(shí)就是把參考源碼中所使用框架(我參考的是,之后都以它來講解)的API替換為中的API即可 。
2.2.1 直接API映射
下面舉一個非常簡單的例子:
的遷移:
得益于中API命令的規(guī)范化和統(tǒng)一化,我們可以發(fā)現(xiàn)從左邊基于的實(shí)現(xiàn)遷移到右邊基于的實(shí)現(xiàn)基本上可以直接復(fù)制粘貼 , 圖中的和是左邊 face源碼自己封裝的類別,后面會講解 。而這個中其他的代碼基本上是直接照搬即可 , 唯一的差異就是這個nn.()中的參數(shù)有些許不同,這個在2.3API差異中會介紹 。
通過這一個例子大家會發(fā)現(xiàn)其實(shí)遷移還是非常簡單的 , 只要把代碼邏輯甚至直接把代碼搬過來就行了 。這得益于目前完善的API接口庫,大部分神經(jīng)網(wǎng)絡(luò)需要用到的接口都是有的,并且對于輸入輸出等參數(shù)的設(shè)置也是向大眾的一致標(biāo)準(zhǔn)靠齊的,所以會用其他框架就一定能很快的上手(打波小廣告哈哈哈) 。
【基于Mindspore2.0的GPT2預(yù)訓(xùn)練模型遷移教程】下面是更多直接API映射的例子:
大家會發(fā)現(xiàn),這些直接API映射的例子里面存在一些參數(shù)或者名字不對應(yīng)的情況,這將會在2.3 API差異中為大家講解 。
2.2.2 face自封裝類別和函數(shù)遷移
還是以舉例,其中的類別是 face實(shí)現(xiàn)GPT2時自己封裝好的類別:
那我們需要做的其實(shí)也很簡單,把這個類別也遷移過來就好了 。而關(guān)于這個類別該遷移到哪個文件,這個可以選擇遷移到自己的模型文件(即gpt2.py) , 也可以參照 face中的文件路徑在中相應(yīng)路徑新建文件來保存 。我這里以遷移到gpt2.py為例:
遷移之后呢,這個 face自定義的類別我們也可以直接使用啦:
2.3 API差異
接下來講一下遷移中出現(xiàn)的API名字或者參數(shù)存在差異的問題,API差異主要包括API命名差異、API參數(shù)差異、API功能差異 。
2.3.1 命名差異
命名差異就是說某個接口和等其他框架的功能是一致的,但是API的名字不同,這時候我們就需要查詢等其他框架中某個API在的名字叫啥,而這就需要用到官方給出的/ API映射表:
可以看到其中收納了絕大多數(shù)常用的API接口,我們只需要在網(wǎng)頁中搜索原來/的API名就可以找到這邊對應(yīng)的API名字,并且這邊還非常細(xì)致的給出了每個API映射之間的關(guān)系,是完全一致、還是存在差異,。
與 API映射表
與 API映射表
這兩張映射表非常重要,是遷移的基?。?一定要收藏、一定要收藏、一定要收藏
比如這張圖中的差異nn.是因?yàn)橹芯W(wǎng)絡(luò)都繼承了nn.類別,而網(wǎng)絡(luò)繼承的是nn.Cell類別 , 因此命名有些不同:

基于Mindspore2.0的GPT2預(yù)訓(xùn)練模型遷移教程

文章插圖
這個差異是可以在映射表中查到的 , 并且沒有顯示存在差異,所以我們直接給它替換掉就解決啦:
2.3.2 參數(shù)差異
(1)參數(shù)值差異
參數(shù)值差異是指/與中API的名字相同,但是一些參數(shù)的名字或者參數(shù)的含義不同,導(dǎo)致API在使用時功能會產(chǎn)生差異,比如最經(jīng)典的nn.§差異:
中默認(rèn)輸入nn.(0.2)時代表有每個參數(shù)有20%的概率被丟棄,而如果在中不指定參數(shù)名直接輸入nn.(0.2)的話代表每個參數(shù)有(1 – 0.2)即80%的概率被丟棄 。這就是一個非常經(jīng)典,如果大家有長期使用的話肯定知道的差異 , 當(dāng)然最新的版本中已經(jīng)提示這種默認(rèn)寫法將會刪除,之后就也可以直接使用nn.(0.2)啦:
(2)參數(shù)初始化差異
這一塊主要是有一些網(wǎng)絡(luò)API的參數(shù)在初始化時存在不同,不要小看初始化的差異,有時候網(wǎng)絡(luò)結(jié)構(gòu)都是對的,但是結(jié)果就是對標(biāo)補(bǔ)上,很有可能就是某些網(wǎng)絡(luò)的參數(shù)初始化不一樣,導(dǎo)致結(jié)果大相徑庭 。
比如將線性層nn.()映射為線性層nn.Dense():
從的官網(wǎng)來看,他的nn.線性層中的和bias應(yīng)該是用均勻分布初始化的
而中的nn.Dense線性層中使用初始化的,而bias使用zeros初始化的
2.3.3 功能差異
其實(shí)大部分的功能差異都是因?yàn)?.3.2中參數(shù)沒設(shè)置好,但是也存在一小部分API確實(shí)是功能有差異 , 這里舉一個很簡單的例子:
torch中的.在中應(yīng)該是
而中的.實(shí)際上對應(yīng)torch..
所以如果不仔細(xì)檢查,看到中有 API就直接遷移過來的話最后的結(jié)果往往是不正確 。因此大家在遷移時一定要仔細(xì)核對每一步遷移的API是否是正確的映射linux 使用情況,多查表、多查表、多查表?。。?
2.4 API缺失
極少出的情況會出現(xiàn)/中的API在查不到的情況:
我們可以用numpy.finfo得到相同的數(shù)據(jù)之后包裝成.
2.5 注意事項3、遷移驗(yàn)證
清楚了網(wǎng)絡(luò)遷移應(yīng)該干什么,以及如何查找對應(yīng)的API之后,我們就可以對自己遷移的網(wǎng)絡(luò)進(jìn)行驗(yàn)證了,驗(yàn)證主要包括兩個方面:輸出shape驗(yàn)證、輸出精度驗(yàn)證 , 驗(yàn)證流程從小到大依次為單模塊驗(yàn)證、整網(wǎng)驗(yàn)證、驗(yàn)證 。
3.1 單模塊驗(yàn)證
單模塊驗(yàn)證就是對網(wǎng)絡(luò)中每個單獨(dú)的模塊進(jìn)行驗(yàn)證,比如對于遷移好的:
我們需要對它進(jìn)行測試驗(yàn)證 , 那怎么做呢?實(shí)際上網(wǎng)絡(luò)說復(fù)雜了是網(wǎng)絡(luò) , 說簡單點(diǎn)就是一堆函數(shù)的拼接,我們測試的一個模塊就是一個小的函數(shù),只不過它是一個類別的正向運(yùn)行函數(shù)(/,只是命名差異 , 中叫 , 中叫)罷了 。所以想要驗(yàn)證遷移結(jié)果是否正確,我們只需要實(shí)例化遷移前和遷移后的兩個類別,然后給他們的正向運(yùn)行函數(shù)輸入相同的數(shù)值,再對標(biāo)兩個函數(shù)的輸出結(jié)果即可 。以下給出簡單的實(shí)現(xiàn):
import numpy as npimport modeling_gpt2, gpt2, configuration_gpt2, config_gpt2if __name__ == "__main__":config_pt = configuration_gpt2.GPT2Config()// 獲取pytorch的配置config_ms = config_gpt2.GPT2Config()// 獲取mindspore的配置pt_net = modeling_gpt2.GPT2MLP(config_pt)// 實(shí)例化pytorch的GPT2MLP模塊ms_net = gpt2.GPT2MLP(config_ms)// 實(shí)例化mindsproe的GPT2MLP模塊input_np = np.random.randint(0, 10, (2, 512))// 使用numpy隨機(jī)生成一個shape為(2, 512)的numpy.arraypt_input = torch.tensor(input_np)// 將numpy.array轉(zhuǎn)化為pytorch.Tensorms_input = mindspore.Tensor(input_np)// 將numpy.array轉(zhuǎn)化為mindspore.Tensorpt_out = pt_net(pt_input)// 調(diào)用pytorch正向函數(shù)GPT2MLP.forward()計算結(jié)果ms_out = ms_net(ms_input)// 調(diào)用mindspore正向函數(shù)GPT2MLP.construct()計算結(jié)果assert pt_out.size() == ms_out.shape// 對比pytorch和mindspore輸出的shape,必須相同否則遷移出錯loss = 1e-3// 精度誤差一般為1e-5,最大為1e-3,必須小于1e-3否則遷移出錯assert np.allclose(pt_out.detach().numpy(), ms_out.asnumpy(), loss, loss) // 將結(jié)果全部轉(zhuǎn)成array然后對比精度最終我們的目的就是要給和的兩個模塊輸入相同的數(shù)據(jù),他們的輸出shape完全一致,精度誤差在1e-3之內(nèi)就代表該模塊基本遷移成功了 。每個模塊都這樣子驗(yàn)證正確之后,我們就可以嘗試把整個網(wǎng)絡(luò)搭建起來然后進(jìn)行驗(yàn)證了
3.2 整網(wǎng)驗(yàn)證
整網(wǎng)驗(yàn)證其實(shí)和每個模塊測試驗(yàn)證沒啥區(qū)別,網(wǎng)絡(luò)說白了就是個大函數(shù),所以就把改成其實(shí)就差不多了,無非就是輸出可能多幾個 。
當(dāng)然我說的僅僅只是測試代碼很好寫,和模塊測試沒啥區(qū)別,但是整個網(wǎng)絡(luò)連起來之后可能會出現(xiàn)單模塊測試時未出現(xiàn)的bug,這也很正常 , 如果出現(xiàn)bug一點(diǎn)點(diǎn)debug檢查就好了 。
import numpy as npimport modeling_gpt2, gpt2, configuration_gpt2, config_gpt2if __name__ == "__main__":config_pt = configuration_gpt2.GPT2Config()// 獲取pytorch的配置config_ms = config_gpt2.GPT2Config()// 獲取mindspore的配置pt_net = modeling_gpt2.GPT2Model(config_pt)// 實(shí)例化pytorch的GPT2MLP模塊ms_net = gpt2.GPT2Model(config_ms)// 實(shí)例化mindsproe的GPT2MLP模塊input_np = np.random.randint(0, 10, (2, 512))// 使用numpy隨機(jī)生成一個shape為(2, 512)的numpy.arraypt_input = torch.tensor(input_np)// 將numpy.array轉(zhuǎn)化為pytorch.Tensorms_input = mindspore.Tensor(input_np)// 將numpy.array轉(zhuǎn)化為mindspore.Tensorpt_out = pt_net(pt_input)// 調(diào)用pytorch正向函數(shù)GPT2MLP.forward()計算結(jié)果ms_out = ms_net(ms_input)// 調(diào)用mindspore正向函數(shù)GPT2MLP.construct()計算結(jié)果assert pt_out.size() == ms_out.shape// 對比pytorch和mindspore輸出的shape,必須相同否則遷移出錯loss = 1e-3// 精度誤差一般為1e-5,最大為1e-3,必須小于1e-3否則遷移出錯assert np.allclose(pt_out.detach().numpy(), ms_out.asnumpy(), loss, loss) // 將結(jié)果全部轉(zhuǎn)成array然后對比精度最終我們需要達(dá)到的目的和模塊驗(yàn)證一致 , 向和的整個網(wǎng)絡(luò)輸入相同的數(shù)據(jù),最終要求網(wǎng)絡(luò)輸出的個數(shù)相同、shape一致、精度誤差在1e-3以內(nèi) 。滿足以上要求我們就可以進(jìn)行最后的驗(yàn)證了 。
3.3 驗(yàn)證
以上的驗(yàn)證都是在檢查網(wǎng)絡(luò)的流程以及計算是否正確,而其中網(wǎng)絡(luò)的參數(shù)都是隨機(jī)初始化的 , 而為了達(dá)到遷移的最終目的:”直接調(diào)用訓(xùn)練好的預(yù)訓(xùn)練模型,可以達(dá)到與原論文相同的結(jié)果“ 。我們必須將預(yù)訓(xùn)練好的模型參數(shù)導(dǎo)入進(jìn)來,然后在”指定參數(shù)“的情況下再進(jìn)行一次整網(wǎng)驗(yàn)證,如果也能夠滿足網(wǎng)絡(luò)輸出的個數(shù)相同、shape一致、精度誤差在1e-3以內(nèi)的要求,那么我們的驗(yàn)證也就成果啦,這就說明這個真正遷移成功了 。下面我簡要介紹一下應(yīng)該如何進(jìn)行驗(yàn)證
3.3.1 下載
一般NLP這邊的大模型官方是有預(yù)訓(xùn)練的參數(shù)的,但是有些官方放出來的網(wǎng)站死活就是打不開,因此我還是推薦大家使用 face中來下載:
以GPT2為例,我們前往GPT2的 face網(wǎng)址gpt2 at main (.co),點(diǎn)擊其中的Files and  , 這個界面存放了gpt2不同版本的配置文件以及模型預(yù)訓(xùn)練參數(shù) , 我使用的是版本,因此我下載.bin以及和通用的.json配置文件 。
將.bin和.json上傳到服務(wù)器的同一個文件夾內(nèi):
接下來進(jìn)行的導(dǎo)入和轉(zhuǎn)換
3.3.2 導(dǎo)入與轉(zhuǎn)換
由于我們手上的是的預(yù)訓(xùn)練參數(shù),所以我們先參照 face中提供的使用樣例將這個.bin導(dǎo)入
(1)導(dǎo)入預(yù)訓(xùn)練參數(shù)
import torchfrom transformers import GPT2Model, GPT2Configmodel_name = '/home/xxxxxx/wzb/mindnlp/pt_pretrained'// pytorch checkpoint存放路徑model_config = GPT2Config.from_pretrained(model_name)// 導(dǎo)入GPT2配置pt_net = GPT2Model.from_pretrained(model_name, config=model_config) // 導(dǎo)入GPT2 checkpoint中的參數(shù)(2)創(chuàng)建的模型
import mindsporefrom mindnlp.models.gpt2 import gpt2, config_gpt2ms_config = config_gpt2.GPT2Config()// 獲取mindspore GPT2配置ms_net = gpt2.GPT2Model(config=ms_config)// 創(chuàng)建mindspore GPT2Model(3)核對參數(shù)是否對應(yīng)
獲取和的網(wǎng)絡(luò)參數(shù)字典,而由于和中有部分網(wǎng)絡(luò)參數(shù)的命名不同,所以我們需要核對一下兩邊的參數(shù)是不是都能對應(yīng)的上:
pt_dict = pt_net.state_dict()// 獲取pytorch整網(wǎng)參數(shù)字典ms_dict = ms_net.parameters_dict()// 獲取mindspore整網(wǎng)參數(shù)字典常見參數(shù)命名差異對比
(層)
gamma(Dense線性層)
bias
beta(Dense線性層)
獲取了和之后我們可以將他們打印出來看看參數(shù)是否能夠?qū)?yīng):
for pt_key in pt_dict:// 打印pytorch所有參數(shù)名print(pt_key)print("+++++++++++++++++++++++++++++++++++++++++")// 分界線for ms_key in ms_dict:// 打印mindspore所有參數(shù)名 print(ms_key)打印出來之后自己人眼核對那可太累了,我推薦大家使用excel來進(jìn)行比對 。由于print()會自動換行,所以我們將和的參數(shù)復(fù)制之后直接粘貼到excel表格中的兩列,復(fù)制好之后第一件事就是直接看一下兩邊的參數(shù)個數(shù)是否相同(查看這兩列的行數(shù)是否相同):
粘貼之后,由于我們知道存在一些命名的差異,因此我們點(diǎn)擊這一列然后ctrl+f之后選擇替換,將gamma換成,將beta換成bias , 得到:
之后我們利用Excel的Exact()函數(shù)直接比較和每一行的字符串是否相同:
可以看到,除了前兩行 , 后面的參數(shù)都是一致的,而前兩行不一致其實(shí)也是正常的,因?yàn)橹挥幸粋€層,所以我就沒有將替換為,實(shí)際上是對的,至此參數(shù)全部對應(yīng)正確后核對結(jié)束 。
(4)參數(shù)導(dǎo)入
參數(shù)對應(yīng)一致后,我們需要將網(wǎng)絡(luò)的參數(shù)導(dǎo)入的網(wǎng)絡(luò),同時需要注意對名稱不一致參數(shù)的替換處理:
for key, parameter in ms_net.parameters_and_names():// 獲取ms模型的參數(shù)名和數(shù)值if 'embedding_table' in key:// 參數(shù)名中的embedding_table替換為weightkey = key.replace('embedding_table', 'weight')elif 'gamma' in key:key = key.replace('gamma', 'weight')// 參數(shù)名中的gamma替換為weightelif 'beta' in key:key = key.replace('beta', 'bias')// 參數(shù)名中的beta替換為bias// 依據(jù)key獲取pytorch中相應(yīng)參數(shù)的數(shù)值并賦給mindspore當(dāng)前參數(shù)parameter,上面替換參數(shù)名就是為了get(key)的時候不會找不到parameter.set_data(mindspore.Tensor(pt_dict.get(key).detach().numpy()))參數(shù)全部正確導(dǎo)入之后我們就可以進(jìn)入最終的整網(wǎng)驗(yàn)證了
3.3.3 整網(wǎng)驗(yàn)證
獲取了和導(dǎo)入了參數(shù)的網(wǎng)絡(luò)后,我們就可以和之前的3.2整網(wǎng)驗(yàn)證一樣,構(gòu)造輸入然后驗(yàn)證輸出是否對標(biāo),最終整體代碼如下:
import torchimport mindsporeimport numpy as npfrom transformers import GPT2Model, GPT2Configfrom mindnlp.models.gpt2 import gpt2, config_gpt2if __name__ == "__main__":model_name = '/home/xxxxxx/wzb/mindnlp/pt_pretrained'model_config = GPT2Config.from_pretrained(model_name)pt_net = GPT2Model.from_pretrained(model_name, config=model_config)ms_config = config_gpt2.GPT2Config()ms_net = gpt2.GPT2Model(config=ms_config)pt_dict = pt_net.state_dict()ms_dict = ms_net.parameters_dict()for key, parameter in ms_net.parameters_and_names():if 'embedding_table' in key:key = key.replace('embedding_table', 'weight')elif 'gamma' in key:key = key.replace('gamma', 'weight')elif 'beta' in key:key = key.replace('beta', 'bias')parameter.set_data(mindspore.Tensor(pt_dict.get(key).detach().numpy()))input_ids = np.random.randint(0, 10, (2, 512))pt_input = torch.tensor(input_ids)ms_input = mindspore.Tensor(input_ids)pt_out = pt_net(pt_input)ms_out = ms_net(ms_input)assert pt_out.size() == ms_out.shapeprint("shape對標(biāo)通過")loss = 1e-3assert np.allclose(pt_out.detach().numpy(), ms_out.asnumpy(), loss, loss)print("精度對標(biāo)通過,誤差:%f", loss)如果最終輸出個數(shù)、shape和精度全部通過,那么恭喜你網(wǎng)絡(luò)遷移成功,之后你只需要重復(fù)以上的操作,把其他的GPT2變形全部遷移成功,本次的預(yù)訓(xùn)練模型遷移工作就做完成了,完結(jié)撒花?。。?
總結(jié)
通過本文的閱讀 , 大家應(yīng)該是能夠了解的預(yù)訓(xùn)練模型遷移工作需要做什么,怎么做以及怎么驗(yàn)證結(jié)果 。而如果大家能夠獨(dú)立完成一個Model的遷移工作,就會發(fā)現(xiàn)目前的.0.0實(shí)際上已經(jīng)比較好用了,API豐富并且映射表格非常詳細(xì),對于差異的描述也非常清晰,報錯信息也比之前精準(zhǔn)多了(當(dāng)然還是需要努力) 。看來在大家共同的努力下,還是取得了非常顯著的提升,當(dāng)然距離最初設(shè)想的動靜統(tǒng)一目標(biāo)還是有不小的差距,還是需要不斷的查漏補(bǔ)缺 。
綜合來說,國產(chǎn)深度學(xué)習(xí)框架的發(fā)展道阻且長、任重而道遠(yuǎn),很開心自己能夠?yàn)槠湄暙I(xiàn)自己的一份力 。同時作為昇思的布道師我想說:從未使用過的同學(xué)可以基于這篇文章來體驗(yàn)一下,曾經(jīng)使用過但是因?yàn)楦鞣N原因“退坑”了的同學(xué)也不妨試一下.0,真的比以前的體驗(yàn)好了很多!
本文到此結(jié)束,希望對大家有所幫助 。