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


