多卡訓(xùn)練 當(dāng)前短訊
時間:2023-06-24 00:09:45
1、前言
近期做到的一些工作涉及到多卡訓(xùn)練,不得不感慨深度學(xué)習(xí)真的是一個燒錢的活,順便記錄一下,主要記錄用法,不涉及實現(xiàn)原理。
2、單機(jī)多卡并行
官方DDP文檔:
GETTING STARTED WITH DISTRIBUTED DATA PARALLEL
(資料圖)
Github 倉庫:
Github 中文文檔
GETTING STARTED WITH DISTRIBUTED DATA PARALLEL
DataParallel
使用 nn.Dataarallel() 將模型變換一下,一行搞定
model = nn.DataParallel(model)
根據(jù)
為方便說明,我們假設(shè)模型輸入為(32, input_dim),這里的 32 表示batch_size,模型輸出為(32, output_dim),使用 4 個GPU訓(xùn)練。nn.DataParallel起到的作用是將這 32 個樣本拆成 4 份,發(fā)送給 4 個GPU 分別做 forward,然后生成 4 個大小為(8, output_dim)的輸出,然后再將這 4 個輸出都收集到cuda:0上并合并成(32, output_dim)。可以看出,nn.DataParallel沒有改變模型的輸入輸出,因此其他部分的代碼不需要做任何更改,非常方便。但弊端是,后續(xù)的loss計算只會在cuda:0上進(jìn)行,沒法并行,因此會導(dǎo)致負(fù)載不均衡的問題。
針對負(fù)載不均衡問題,一個緩解的方法是將 loss 放入模型內(nèi)部計算,即在 forward 的時候計算 loss。
DistributedDatarallel
分布式數(shù)據(jù)并行方法,通過多進(jìn)程實現(xiàn)。
1、從一開始就會啟動多個進(jìn)程(進(jìn)程數(shù)等于GPU數(shù)),每個進(jìn)程獨享一個GPU,每個進(jìn)程都會獨立地執(zhí)行代碼。這意味著每個進(jìn)程都獨立地初始化模型、訓(xùn)練,當(dāng)然,在每次迭代過程中會通過進(jìn)程間通信共享梯度,整合梯度,然后獨立地更新參數(shù)。2、每個進(jìn)程都會初始化一份訓(xùn)練數(shù)據(jù)集,通過DistributedSampler函數(shù)實現(xiàn),即同樣的模型喂進(jìn)去不同的數(shù)據(jù)做訓(xùn)練,也就是所謂的數(shù)據(jù)并行。3、進(jìn)程通過local_rank變量來標(biāo)識自己,local_rank為0的為master,其他是slave。這個變量是torch.distributed包幫我們創(chuàng)建的,使用方法如下:
import argparse parser = argparse.ArgumentParser()parser.add_argument("--local_rank", type=int, default=-1)args = parser.parse_args()
運行代碼
python -m torch.distributed.launch --nproc_per_node=4 --nnodes=1 train.py
其中,nnodes 表示節(jié)點數(shù)量,單機(jī),即為1,nproc_per_node 為每個節(jié)點的進(jìn)程數(shù)量,與 GPU 數(shù)量一致。
模型保存與加載TODO
3、遇到的問題
1、DistributedDataarallel 方法,有時候會出現(xiàn)進(jìn)程卡死的問題,現(xiàn)象上即為顯卡的利用率卡在 100%,未啟動進(jìn)程組,根據(jù)tjds排查是IO 虛擬化(也稱為 VT-d 或 IOMMU)啟用了ACS導(dǎo)致,具體原因參考 故障排除——NCCL2.16.2 文檔。
方法一:排查原因是BIOS里IO虛擬化(VT-d)默認(rèn)啟動了PCI訪問控制服務(wù)(ACS)導(dǎo)致GPU間無法直接通過P2P方式通信,需在BIOS關(guān)閉此功能,具體操作參考 tjds
1、 查看ACS是否開啟執(zhí)行 lspci -vvv | grep -I acsctl 如果有顯示SrcValid+說明已啟用ACS功能2、 添加iommu=pt參數(shù)到grub(此步驟應(yīng)該可以跳過)編輯/etc/default/grub文件添加iommu=pt,再執(zhí)行update-grub更新grub文件3、 關(guān)閉BIOS里ACS功能重啟操作系統(tǒng)開機(jī)時按 del 進(jìn)入 BIOS 關(guān)閉 ACS 功能,不關(guān) VT-d 只關(guān)閉 ACS 功能,具體路徑:Path: Advanced -> Chipset Configuration -> North Bridge -> IIO Configuration -> Intel VT for Directed I/O (VT-d) -> ACS Control -> Enable / Disable.4、 檢查ACS是否關(guān)閉執(zhí)行l(wèi)spci -vvv | grep -I acsctl 如果全顯示SrcValid-說明已關(guān)閉ACS功能
方法二:仍然使用 ‘nccl‘ 后端,禁用 GPU 的 P2P 通信。
torch.distributed.init_process_group(backend="ncll")
NCCL_P2P_DISABLE=1 CUDA_VISIBLE_DEVICES=0,1,2,3 python -m torch.distributed.launch --nproc_per_node=4 train.py
嫌麻煩可以寫入 bashrc 環(huán)境變量。
方法三:更換后端為 ‘gloo’ , shell命令運行程序,縱享絲滑。
torch.distributed.init_process_group(backend="gloo")
CUDA_VISIBLE_DEVICES=0,1,2,3 python -m torch.distributed.launch --nproc_per_node=4 train.py
缺點就是 gloo 的通信在我用的時候要比 nccl 慢很多。
2、如果訓(xùn)練過程中使用了 Sampler 進(jìn)行數(shù)據(jù)分發(fā), dataloader 的 shuffle 不能設(shè)置為 True。
3、dataloader 設(shè)置 batch_size 時,注意盡量保證每次循環(huán)每張卡至少可以分到一個 sample,不然有時候會因某張卡等待輸入卡死。
4、我在訓(xùn)練時,dataloader的 num_works 通過 CPU 幫助 GPU 加載數(shù)據(jù)能夠提升 GPU 利用率,倒是沒遇到報錯。
5、dataloader 的 pin_memory (鎖頁內(nèi)存) 按道理是可以鎖住一部分內(nèi)存,減少 CPU 內(nèi)存拷貝的,但是我用的時候會極大降低 GPU 利用率,此處存疑。
待更新ing
相關(guān)稿件
OpenAI放大!將推出史上超強(qiáng)「模型商店」,打通所有ChatGPT應(yīng)用|天天熱資訊
每日簡訊:DeepMind 聯(lián)合創(chuàng)始人提出新的圖靈測試:讓 AI 將 10 萬美元變成 100 萬美元
嘉興海寧7.18億掛牌1宗宅地 起始樓面1.17萬元/平米創(chuàng)歷史新高 每日簡訊
環(huán)球今熱點:恭喜發(fā)財廣場舞視頻(恭喜發(fā)財廣場舞)
2023年中考今天拉開序幕|當(dāng)前關(guān)注
中國導(dǎo)演徐磊:“我不擔(dān)心韓國觀眾看不懂中國電影”
當(dāng)前要聞:招生計劃隨手查!2023年黑龍江省全國普通高等學(xué)校招生計劃電子版發(fā)布!
全球?qū)崟r:大學(xué)生第一支香水推薦!平價香水推薦!
第三屆全球饒商大會舉行 現(xiàn)場簽約項目總額超300億元 環(huán)球新資訊
AIGC相關(guān)上市公司龍頭有哪些?(2023/6/23)
每日訊息!山西省萬榮縣發(fā)布雷暴大風(fēng)藍(lán)色預(yù)警
名利圈的潛規(guī)則,趙子琪都吃過虧,秦嵐還在原地打轉(zhuǎn)? 全球聚看點
瑞浦蘭鈞 x TüV萊茵 | 聯(lián)合發(fā)聲,共建綠色能源新未來|當(dāng)前短訊
3元早餐、5元咖啡、10元吃面,血拼價格戰(zhàn),今年餐飲怎么了?