国产精品久久99,51久久成人国产精品麻豆,亚洲欧洲免费三级网站,最近中文字幕mv,重口老太大和小伙乱

首頁>體育 > 正文

環(huán)球熱消息:多卡訓(xùn)練

2023-06-21 16:28:05來源:博客園

1、前言

近期做到的一些工作涉及到多卡訓(xùn)練,不得不感慨深度學(xué)習(xí)真的是一個(gè)燒錢的活,順便記錄一下,主要記錄用法,不涉及實(shí)現(xiàn)原理。

2、單機(jī)多卡并行

官方DDP文檔:

GETTING STARTED WITH DISTRIBUTED DATA PARALLEL


(相關(guān)資料圖)

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 個(gè)GPU訓(xùn)練。nn.DataParallel起到的作用是將這 32 個(gè)樣本拆成 4 份,發(fā)送給 4 個(gè)GPU 分別做 forward,然后生成 4 個(gè)大小為(8, output_dim)的輸出,然后再將這 4 個(gè)輸出都收集到cuda:0上并合并成(32, output_dim)??梢钥闯?,nn.DataParallel沒有改變模型的輸入輸出,因此其他部分的代碼不需要做任何更改,非常方便。但弊端是,后續(xù)的loss計(jì)算只會(huì)在cuda:0上進(jìn)行,沒法并行,因此會(huì)導(dǎo)致負(fù)載不均衡的問題。

針對(duì)負(fù)載不均衡問題,一個(gè)緩解的方法是將 loss 放入模型內(nèi)部計(jì)算,即在 forward 的時(shí)候計(jì)算 loss。

DistributedDatarallel

分布式數(shù)據(jù)并行方法,通過多進(jìn)程實(shí)現(xiàn)。

1、從一開始就會(huì)啟動(dòng)多個(gè)進(jìn)程(進(jìn)程數(shù)等于GPU數(shù)),每個(gè)進(jìn)程獨(dú)享一個(gè)GPU,每個(gè)進(jìn)程都會(huì)獨(dú)立地執(zhí)行代碼。這意味著每個(gè)進(jìn)程都獨(dú)立地初始化模型、訓(xùn)練,當(dāng)然,在每次迭代過程中會(huì)通過進(jìn)程間通信共享梯度,整合梯度,然后獨(dú)立地更新參數(shù)。2、每個(gè)進(jìn)程都會(huì)初始化一份訓(xùn)練數(shù)據(jù)集,通過DistributedSampler函數(shù)實(shí)現(xiàn),即同樣的模型喂進(jìn)去不同的數(shù)據(jù)做訓(xùn)練,也就是所謂的數(shù)據(jù)并行。3、進(jìn)程通過local_rank變量來標(biāo)識(shí)自己,local_rank為0的為master,其他是slave。這個(gè)變量是torch.distributed包幫我們創(chuàng)建的,使用方法如下:

import argparse  parser = argparse.ArgumentParser()parser.add_argument("--local_rank", type=int, default=-1)args = parser.parse_args()

運(yùn)行代碼

python -m torch.distributed.launch --nproc_per_node=4 --nnodes=1 train.py

其中,nnodes 表示節(jié)點(diǎn)數(shù)量,單機(jī),即為1,nproc_per_node 為每個(gè)節(jié)點(diǎn)的進(jìn)程數(shù)量,與 GPU 數(shù)量一致。

模型保存與加載TODO

3、遇到的問題

1、DistributedDataarallel 方法,有時(shí)候會(huì)出現(xiàn)進(jìn)程卡死的問題,現(xiàn)象上即為顯卡的利用率卡在 100%,未啟動(dòng)進(jìn)程組,根據(jù)tjds排查是IO 虛擬化(也稱為 VT-d 或 IOMMU)啟用了ACS導(dǎo)致,具體原因參考 故障排除——NCCL2.16.2 文檔。

方法一:排查原因是BIOS里IO虛擬化(VT-d)默認(rèn)啟動(dòng)了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ī)時(shí)按 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命令運(yùn)行程序,縱享絲滑。

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 

缺點(diǎn)就是 gloo 的通信在我用的時(shí)候要比 nccl 慢很多。

2、如果訓(xùn)練過程中使用了 Sampler 進(jìn)行數(shù)據(jù)分發(fā), dataloader 的 shuffle 不能設(shè)置為 True。

3、dataloader 設(shè)置 batch_size 時(shí),注意盡量保證每次循環(huán)每張卡至少可以分到一個(gè) sample,不然有時(shí)候會(huì)因某張卡等待輸入卡死。

4、我在訓(xùn)練時(shí),dataloader的 num_works 通過 CPU 幫助 GPU 加載數(shù)據(jù)能夠提升 GPU 利用率,倒是沒遇到報(bào)錯(cuò)。

5、dataloader 的 pin_memory (鎖頁內(nèi)存) 按道理是可以鎖住一部分內(nèi)存,減少 CPU 內(nèi)存拷貝的,但是我用的時(shí)候會(huì)極大降低 GPU 利用率,此處存疑。

待更新ing

關(guān)鍵詞:

責(zé)任編輯:

免責(zé)聲明

頭條新聞

精彩推送

新聞推送