继夫的玩弄H辣文的小说|女人与拘性猛交视频|精品欧美高清不卡高清|一起做亏亏的事情的视频|啦啦啦在线视频观看|望月直播下载ios版本|国产日韩欧美一区二区三区

基于Mindspore2.0的GPT2預訓練模型遷移教程

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

基于Mindspore2.0的GPT2預訓練模型遷移教程

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