在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

project復現過程踩到坑對應的解決方案

深度學習自然語言處理 ? 來源:深度學習自然語言處理 ? 作者:深度學習自然語言 ? 2022-08-19 11:09 ? 次閱讀

最近做的一個 project 需要復現 EMNLP 2020 Findings 的 TinyBERT,本文是對復現過程對踩到坑,以及對應的解決方案和實現加速的一個記錄。

1. Overview of TinyBERT

BERT 效果雖好,但其較大的內存消耗和較長的推理延時會對其上線部署造成一定挑戰

內存消耗方面,一系列知識蒸餾的工作,例如 DistilBERT[2]、BERT-PKD[3] 和 TinyBERT 被提出來用以降低模型的參數(主要是層數)以及相應地減少時間;

推理加速方面,也有 DeeBERT[4]、FastBERT[5] 及 CascadeBERT[6] 等方案提出,它們動態地根據樣本難度進行模型的執行從而提升推理效率。其中較具備代表性的是 TinyBERT,其核心框架如下:

ca3400ec-1ea7-11ed-ba43-dac502259ad0.png

分為兩個階段:

General Distillation:在通用的語料,例如 BookCorpus, EnglishWiki 上進行知識蒸餾;目標函數包括 Transformer Layer Attention 矩陣以及 Layer Hidden States 的對齊;

Task Distillation:在具體的任務數據集上進行蒸餾,進一步分成兩個步驟:

Task Transformer Disitllation: 在任務數據集上對齊 Student 和已經 fine-tuned Teacher model 的 attention map 和 hidden states;

Task Prediction Distillation:在任務數據集上對 student model 和 teacher model 的 output distritbuion 利用 KL loss / MSE loss 進行對齊。

TinyBERT 提供了經過 General Distillation 階段的 checkpoint,可以認為是一個小的 BERT,包括了 6L786H 版本以及 4L312H 版本。而我們后續的復現就是基于 4L312H v2 版本的。

值得注意的是,TinyBERT 對任務數據集進行了數據增強操作:通過基于 Glove 的 Embedding Distance 的相近詞替換以及 BERT MLM 預測替換,會將原本的數據集擴增到 20 倍。而我們遇到的第一個 bug 就是在數據增強階段。

2. Bug in Data Augmentation

我們可以按照官方給出的代碼對數據進行增強操作,但是在 QNLI 上會報錯:

ca6174dc-1ea7-11ed-ba43-dac502259ad0.png

造成數據增強到一半程序就崩潰了,為什么呢?

很簡單,因為數據增強代碼 BERT MLM 換詞模塊對于超長(> 512)的句子沒有特殊處理,造成下標越界,具體可以參考 #Issue50:error occured when apply data_augmentation on QNLI and QQP dataset[7]。

在對應的函數中進行邊界的判斷即可:

ca73213c-1ea7-11ed-ba43-dac502259ad0.png

3. Acceleration of Data Parallel

當我們費勁愉快地完成數據增強之后,下一步就是要進行 Task Specific 蒸餾里的 Step 1,General Distillation 了。

對于一些小數據集像 MRPC,增廣 20 倍之后的數據量依舊是 80k 不到,因此訓練速度還是很快的,20 輪單卡大概半天也能跑完。但是對于像 MNLI 這樣 GLUE 中最大的數據集(390k),20 倍增廣后的數據集(增廣就花費了大約 2 天時間),如果用單卡訓練個 10 輪那可能得跑上半個月了,到時候怕不是黃花菜都涼咯。

3.1 多卡訓練初步嘗試

遂打算用多卡訓練,一看,官方的實現就通過 nn.DataParal lel 支持了多卡。好嘛,直接 CUDA_VISIBLE_DEVICES="0,1,2,3" 來上 4 塊卡。不跑不知道,一跑嚇一跳:

加載數據(tokenize, padding )花費 1小時;

好不容易跑起來了,一開 nvidia-smi 發現 GPU 的利用率都在 50% 左右;

再一看預估時間,大約 21h 一輪,10 epoch 那四舍五入就是一個半禮拜。

好家伙,這我還做不做實驗了?

3.2 DDP 替換 DP

這時候就去翻看 PyTorch 文檔,發現 PyTorch 現在都不再推薦使用 nn.DataParallel 了,為什么呢?主要原因在于:

DataParallel 的實現是單進程的,每次都是有一塊主卡讀入數據再發給其他卡,這一部分不僅帶來了額外的計算開銷,而且會造成主卡的 GPU 顯存占用會顯著高于其他卡,進而造成潛在的 batch size 限制;

此外,這種模式下,其他 GPU 算完之后要傳回主卡進行同步,這一步又會受限于 Python 的線程之間的 GIL(global interpreter lock),進一步降低了效率。

此外,還有多機以及模型切片等 DataParallel 不支持,但是另一個 DistributedDataParallel 模塊支持的功能。

所以得把原先 TinyBERT DP(DataParallel)改成 DDP(DistributedDataParallel)。把 DP 改成 DDP 可以參考知乎-當代研究生需要掌握的并行訓練技巧[8]。核心的代碼就是做一下初始化,以及用 DDP 替換掉 DP

cabdeab4-1ea7-11ed-ba43-dac502259ad0.png

然后,大功告成,一鍵啟動:

cafeb27e-1ea7-11ed-ba43-dac502259ad0.png

啟動成功了嗎?模型又開始處理數據….

One hours later,機器突然卡住,程序的 log 也停了,打開 htop 一看:好家伙,256G 的內存都滿了,程序都是 D 狀態,這是咋回事?

4. Acceleration of Data Loading

我先試了少量數據,降采樣到 10k,程序運行沒問題, DDP 速度很快;我再嘗試了單卡加載,雖然又 load 了一個小時,但是 ok,程序還是能跑起來,那么,問題是如何發生的呢?

單卡的時候我看了一眼加載全量數據完畢之后的內存占用,大約在 60G 左右,考慮到 DDP 是多進程的,因此,每個進程都要獨立地加載數據,4 塊卡 4個進程,大約就是 250 G 的內存,因此內存爆炸,到后面數據的 io 就卡住了(沒法從磁盤 load 到內存),所以造成了程序 D 狀態。

看了下組里的機器,最大的也就是 250 G 內存,也就是說,如果我只用 3 塊卡,那么是能夠跑的,但是萬一有別的同學上來開程序吃了一部分內存,那么就很可能爆內存,然后就是大家的程序都同歸于盡的局面,不太妙。

一種不太優雅的解決方案就是,把數據切塊,然后讀完一小塊訓練完,再讀下一塊,再訓練,再讀。咨詢了一下組里資深的師兄,還有一種辦法就是實現一種把數據存在磁盤上,每次要用的時候才 load 到內存的數據讀取方案,這樣就能夠避免爆內存的問題。行吧,那就干吧,但是總不能從頭造輪子吧?

臉折師兄提到 huggingface(yyds) 的 datasets[9] 能夠支持這個功能,check 了一下文檔,發現他是基于 pyarrow 的實現了一個 memory map 的數據讀取[10],以我的 huggingface transformers 的經驗,似乎是能夠實現這個功能的,所以摩拳擦掌,準備動手。

首先,要把增廣的數據 load 進來,datasets 提供的 load_dataset 函數最接近的就是 load_dataset('csv', data_file),然后我們就可以逐個 column 的拿到數據并且進行預處理了。

寫了一會,發現總是報讀取一部分數據后 columns 數目不對的錯誤,猜測可能原始 MNLI 數據集就不太能保證每個列都是在的,檢查了一下 MnliProcessor 里處理的代碼,發現其寫死了 line[8] 和 line[9] 作為 sentence_a 和 sentence_b。無奈之下,只能采取最粗暴地方式,用 text mode 讀進來,每一行是一個數據,再 split:

cb1adf4e-1ea7-11ed-ba43-dac502259ad0.png

寫完這個 preprocess_func ,我覺得勝利在望,但還有幾個小坑需要解決s:

map 完之后,返回的還是一個 DatasetDict,得手動取一下 train set;

對于原先存在的列,map 函數并不會去除掉,所以如果不用的列,需要手動 .remove_columns()

在配合 DDP 使用的時候,因為 DistributedSample 取數據的維度是在第一維取的,所以取到的數據可能是個 seq_len 長的列表,里面的 tensor 是 [bsz] 形狀的,需要在交給 model 之前 stack 一下:

cb45577e-1ea7-11ed-ba43-dac502259ad0.png

至此,只要把之前代碼的 train_data 都換成現在的版本即可。

此外,為了進一步加速,我還把混合精度也整合了進來,現在 Pytorch 以及自帶對混合精度的支持,代碼量也很少,但是有個坑就是loss 的計算必須被 auto() 包裹住,同時,所有模型的輸出都要參與到 loss 的計算,這對于只做 prediction 或者是 hidden state 對齊的 loss 很不友好,所以只能手動再額外計算一項為系數為 0 的 loss 項(這樣他參與到訓練但是不會影響梯度)。

總結

最后,改版過的代碼在我的 GitHubfork[11]版本中,我不要臉地起名為fast_td。實際上,改版后的有點有一下幾個:

數據加載方面:第一次加載/處理 780w 大約耗時 50m,但是不會多卡都消耗內存,實際占用不到 2G;同時,得益于 datasets 的支持,后續加載不會重復處理數據而是直接讀取之前的 cache;

模型訓練方面:得益于 DDP 和 混合精度,在 MNLI 上訓增強數據 10 輪,3 塊卡花費的時間大約在 20h 左右,提速了 10 倍。

審核編輯:彭靜
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 模型
    +關注

    關注

    1

    文章

    3317

    瀏覽量

    49238
  • project
    +關注

    關注

    0

    文章

    35

    瀏覽量

    13324
  • 數據集
    +關注

    關注

    4

    文章

    1209

    瀏覽量

    24838

原文標題:4. Acceleration of Data Loading

文章出處:【微信號:zenRRan,微信公眾號:深度學習自然語言處理】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    立體智慧倉儲解決方案.#云計算

    解決方案智能設備
    學習電子知識
    發布于 :2022年10月06日 19:45:47

    IAP功能實現過程遇到的

    花了四天時間才把IAP功能做好。其中也遇到許多的,這次把這次IAP功能實現過程遇到的把它分享出來。一開始做iap的時候也是先從網上看別人的實現方法,其中就下載了一套別人的程序,不過主控芯片
    發表于 08-05 07:51

    Linux學習過程踩過的與如何解決踩

    Linux踩記錄記錄Linux學習過程踩過的與如何解決踩1解決方法:F10進入BIOS使能虛擬化技術
    發表于 11-04 08:44

    mongoose開發中遇到的解決方案

    1. 本文不對mongoose的功能作陳述,只記錄下自己開發中遇到的,及解決方案。嵌入了mongoose的代碼編譯通過,在調試運行(gdb)時候,卻發生了段錯誤(Segmentation fault),如下所示:...
    發表于 12-16 06:56

    STC8H8K64U芯片學習過程中遇到的問題及對應解決方案

    STC8H8K64U芯片該怎樣進行封裝呢?STC8H8K64U芯片學習過程中遇到的問題及對應解決方案
    發表于 12-21 06:59

    分享基于STM32 4x4鍵盤掃描嘗試過程踩到的雷

    解決嗎??有,當然有了,那就是矩陣鍵盤掃描,在查閱許多大神博客、資料后有了點眉目便開始嘗試,歷經千辛萬苦終于弄出來了!那喜悅!那開心!下面給大家分享嘗試過程踩到的雷。矩陣鍵盤掃描原理瀏覽過多篇文章后決定嘗試翻轉法來進行矩陣鍵盤掃描,丟出鍵盤原理圖:四行四列共八個IO口,
    發表于 01-05 07:56

    在RT-Thread開發過程中引入watchdog踩到

    今天在RT-Thread完整版開發過程中引入watchdog,踩到一個,系統一直重啟,喂狗一直失敗,搞了一天才解決,總結一下。我的RT-Thread完整版系統是最新版4.0.3(截止2020年12
    發表于 02-17 06:05

    記錄一個在使用BlackBox中parameter踩到

    踩到在很早之前,曾寫過如何在SpinalHDL中例化之前用Verilog/SystemVerilog所寫的代碼,可參照文章《[SpinalHDL——集成你的RTL代碼]》一文。在
    發表于 08-31 14:58

    記錄BL808 BSP添加GPIO驅動時踩到的一些解決方案

    該文主要記錄為 BL808 BSP 添加 GPIO 驅動時踩到的一些解決方案。這是我第一次對接 RT-Thread BSP 的驅動,整理出本文避免之后踩到同樣的
    發表于 02-03 14:36

    光端機在使用過程中遇到的常見問題及對應解決方案

    光端機,就是光信號傳輸的終端設備,我們在使用的過程中難免會碰到一些問題,接下來杭州飛暢的小編為大家詳細列舉了光端機在使用過程中遇到的一些常見問題以及對應解決方案,感興趣的朋友就一起來
    的頭像 發表于 09-08 15:35 ?3709次閱讀

    使用Redis時可能遇到哪些「」?

    這篇文章,我想和你聊一聊在使用 Redis 時,可能會踩到的「」。 如果你在使用 Redis 時,也遇到過以下這些「詭異」的場景,那很大概率是踩到」了: 明明一個 key 設置了
    的頭像 發表于 04-09 11:19 ?2352次閱讀
    使用Redis時可能遇到哪些「<b class='flag-5'>坑</b>」?

    模型調優和復現算法遇到的一些

    的數據增強方式與代碼的實現不一樣等。(這些可能發生在開源復現者沒有“一比一”復現論文的情況,也可能發生在論文作者自己沒有實現的情況)
    的頭像 發表于 05-18 15:03 ?1284次閱讀

    RLHF實踐中的框架使用與一些 (TRL, LMFlow)

    我們主要用一個具體的例子展示如何在兩個框架下做RLHF,并且記錄下訓練過程中我們踩到的主要的。這個例子包括完整的SFT,獎勵建模和 RLHF, 其中RLHF包括通過 RAFT 算法(Reward rAnked FineTuni
    的頭像 發表于 06-20 14:36 ?2026次閱讀
    RLHF實踐中的框架使用與一些<b class='flag-5'>坑</b> (TRL, LMFlow)

    記錄為BL808添加GPIO驅動

    該文主要記錄為 BL808 BSP 添加 GPIO 驅動時踩到的一些解決方案。這是我第一次對接 RT-Thread BSP 的驅動,整理出本文避免之后踩到同樣的
    的頭像 發表于 10-13 11:18 ?675次閱讀

    樹莓派Pico Flash驅動踩記錄

    樹莓派 pico 帶有 2MB 的 Flash 資源,以下是我基于官方 Pico C/C++ SDK 對接 Flash 驅動時踩到的一些和解決辦法。
    的頭像 發表于 10-20 11:44 ?1635次閱讀
    主站蜘蛛池模板: 欧美午夜网 | 人人爽天天爽夜夜爽曰 | 婷婷亚洲五月琪琪综合 | 天天综合久久久网 | 亚洲黄色在线网站 | 天天摸天天看天天爽 | 久久精品国产福利 | 日本特黄视频 | 给个网站可以在线观看你懂的 | 尤物啪啪 | 成人a毛片在线看免费全部播放 | 欧美视频精品一区二区三区 | 三级视频网站 | 黄色国产网站 | avtom影院永久地址人人影院 | 免费观看激色视频网站bd | 全免费一级午夜毛片 | 日本不卡在线一区二区三区视频 | 香港三级在线视频 | 天天久久影视色香综合网 | 国产美女久久 | 高清欧美一级在线观看 | 色女人在线视频 | 色猫成人网| 天天爱天天插 | 日韩无| 免费视频网站在线观看 | 日韩一级片免费在线观看 | 欧美性色生活片天天看99 | 羞羞色院91精品网站 | 天天视频国产免费入口 | 激情六月丁香婷婷 | 国产精欧美一区二区三区 | 人人干人人模 | 欧美成人性色xxxxx视频大 | 制服丝袜国产精品 | 久久精品第一页 | 久久香蕉国产精品一区二区三 | china国语对白刺激videos chinese国产videoxx实拍 | 日本亚洲欧美国产日韩ay高清 | 亚洲区在线播放 |