PyTorch 分布式通訊包-Torch.Distributed

2020-09-15 09:46 更新

原文:PyTorch 分布式通訊包-Torch.Distril

后端

torch.distributed支持三個(gè)后端,每個(gè)后端具有不同的功能。 下表顯示了可用于 CPU / CUDA 張量的功能。 MPI 僅在用于構(gòu)建 PyTorch 的實(shí)現(xiàn)支持 CUDA 的情況下才支持 CUDA。

|

后端

|

gloo

|

mpi

|

nccl

| | --- | --- | --- | --- | |

設(shè)備

|

中央處理器

|

顯卡

|

CPU

|

GPU

|

CPU

|

GPU

| | --- | --- | --- | --- | --- | --- | --- | | 發(fā)送 | ? | ? | ? | ? | ? | ? | | 收錄 | ? | ? | ? | ? | ? | ? | | 廣播 | ? | ? | ? | ? | ? | ? | | all_reduce | ? | ? | ? | ? | ? | ? | | 降低 | ? | ? | ? | ? | ? | ? | | all_gather | ? | ? | ? | ? | ? | ? | | 收集 | ? | ? | ? | ? | ? | ? | | 分散 | ? | ? | ? | ? | ? | ? | | 屏障 | ? | ? | ? | ? | ? | ? |

PyTorch 隨附的后端

當(dāng)前分發(fā)的 PyTorch 僅支持 Linux。 默認(rèn)情況下,會(huì)構(gòu)建 Gloo 和 NCCL 后端并將其包含在 PyTorch 分布式中(僅在使用 CUDA 進(jìn)行構(gòu)建時(shí)才為 NCCL)。 MPI 是可選的后端,僅當(dāng)您從源代碼構(gòu)建 PyTorch 時(shí),才可以包含它。 (例如,在安裝了 MPI 的主機(jī)上構(gòu)建 PyTorch。)

使用哪個(gè)后端?

在過去,我們經(jīng)常被問到:“我應(yīng)該使用哪個(gè)后端?”。

  • 經(jīng)驗(yàn)法則
    • 使用 NCCL 后端進(jìn)行分布式 GPU 訓(xùn)練
    • 使用 Gloo 后端進(jìn)行分布式 CPU 訓(xùn)練。
  • 具有 InfiniBand 互連的 GPU 主機(jī)
    • 使用 NCCL,因?yàn)樗钱?dāng)前唯一支持 InfiniBand 和 GPUDirect 的后端。
  • 具有以太網(wǎng)互連的 GPU 主機(jī)
    • 使用 NCCL,因?yàn)樗壳疤峁┳罴训姆植际?GPU 訓(xùn)練性能,尤其是對(duì)于多進(jìn)程單節(jié)點(diǎn)或多節(jié)點(diǎn)分布式訓(xùn)練。 如果您在使用 NCCL 時(shí)遇到任何問題,請(qǐng)使用 Gloo 作為后備選項(xiàng)。 (請(qǐng)注意,對(duì)于 GPU,Gloo 當(dāng)前的運(yùn)行速度比 NCCL 慢。)
  • 具有 InfiniBand 互連的 CPU 主機(jī)
    • 如果您的 InfiniBand 已啟用 IB IP,請(qǐng)使用 Gloo,否則,請(qǐng)使用 MPI。 我們計(jì)劃在即將發(fā)布的版本中增加 InfiniBand 對(duì) Gloo 的支持。
  • 具有以太網(wǎng)互連的 CPU 主機(jī)
    • 除非有特殊原因要使用 MPI,否則請(qǐng)使用 Gloo。

常見環(huán)境變量

選擇要使用的網(wǎng)絡(luò)接口

默認(rèn)情況下,NCCL 和 Gloo 后端都將嘗試找到要使用的正確網(wǎng)絡(luò)接口。 如果自動(dòng)檢測(cè)到的接口不正確,則可以使用以下環(huán)境變量(適用于各自的后端)覆蓋它:

  • NCCL_SOCKET_IFNAME ,例如export NCCL_SOCKET_IFNAME=eth0
  • GLOO_SOCKET_IFNAME ,例如export GLOO_SOCKET_IFNAME=eth0

如果您使用的是 Gloo 后端,則可以用逗號(hào)分隔多個(gè)接口,例如:export GLOO_SOCKET_IFNAME=eth0,eth1,eth2,eth3。 后端將以循環(huán)方式在這些接口之間調(diào)度操作。 至關(guān)重要的是,所有進(jìn)程都必須在此變量中指定相同數(shù)量的接口。

其他 NCCL 環(huán)境變量

NCCL 還提供了許多環(huán)境變量以進(jìn)行微調(diào)。

常用的調(diào)試工具包括以下內(nèi)容:

  • export NCCL_DEBUG=INFO
  • export NCCL_DEBUG_SUBSYS=ALL

基本

<cite>torch分布式</cite>程序包提供 PyTorch 支持和通信原語,以實(shí)現(xiàn)在一臺(tái)或多臺(tái)機(jī)器上運(yùn)行的多個(gè)計(jì)算節(jié)點(diǎn)之間的多進(jìn)程并行性。 類 torch.nn.parallel.DistributedDataParallel() 建立在此功能之上,以提供同步的分布式訓(xùn)練,作為圍繞任何 PyTorch 模型的包裝。 這與 Multiprocessing 程序包提供的并行性不同– Torch.multiprocessing 和 torch.nn.DataParallel() 支持多個(gè)聯(lián)網(wǎng)的機(jī)器,并且用戶必須明確啟動(dòng)一個(gè)單獨(dú)的 每個(gè)過程的主要訓(xùn)練腳本的副本。

在單機(jī)同步情況下,<cite>torch分布式</cite>或 torch.nn.parallel.Dist ributedDataParallel() 包裝器可能仍比其他數(shù)據(jù)并行方法(包括 torch.nn.DataParallel())具有優(yōu)勢(shì) ]:

  • 每個(gè)過程都維護(hù)自己的優(yōu)化器,并在每次迭代時(shí)執(zhí)行完整的優(yōu)化步驟。 盡管這看起來可能是多余的,但由于梯度已經(jīng)被收集在一起并在各個(gè)過程之間求平均,因此對(duì)于每個(gè)過程都是相同的,這意味著不需要參數(shù)廣播步驟,從而減少了在節(jié)點(diǎn)之間傳遞張量的時(shí)間。
  • 每個(gè)進(jìn)程都包含一個(gè)獨(dú)立的 Python 解釋器,從而消除了由單個(gè) Python 進(jìn)程驅(qū)動(dòng)多個(gè)執(zhí)行線程,模型副本或 GPU 所帶來的額外解釋器開銷和“ GIL 顛簸”。 這對(duì)于大量使用 Python 運(yùn)行時(shí)的模型尤其重要,包括具有循環(huán)層或許多小組件的模型。

初始化

在調(diào)用任何其他方法之前,需要使用 torch.distributed.init_process_group() 函數(shù)初始化該程序包。 這將阻塞,直到所有進(jìn)程都已加入。

torch.distributed.init_process_group(backend, init_method=None, timeout=datetime.timedelta(0, 1800), world_size=-1, rank=-1, store=None, group_name='')?

初始化默認(rèn)的分布式進(jìn)程組,這還將初始化分布式程序包。

There are 2 main ways to initialize a process group:

  1. 明確指定storerankworld_size。
  2. 指定init_method(URL 字符串),它指示在何處/如何發(fā)現(xiàn)對(duì)等方。 (可選)指定rankworld_size,或在 URL 中編碼所有必需的參數(shù)并忽略它們。

如果兩者均未指定,則將init_method假定為“ env://”。

參數(shù)

  • 后端 (str 后端)–要使用的后端。 根據(jù)構(gòu)建時(shí)配置,有效值包括mpi,gloonccl。 該字段應(yīng)以小寫字符串(例如"gloo")形式給出,也可以通過 Backe nd 屬性(例如Backend.GLOO)進(jìn)行訪問。 如果每臺(tái)具有nccl后端的計(jì)算機(jī)使用多個(gè)進(jìn)程,則每個(gè)進(jìn)程必須對(duì)其使用的每個(gè) GPU 都具有獨(dú)占訪問權(quán)限,因?yàn)樵谶M(jìn)程之間共享 GPU 可能會(huì)導(dǎo)致死鎖。
  • init_method (str 可選)–指定如何初始化進(jìn)程組的 URL。 如果未指定init_methodstore,則默認(rèn)值為“ env://”。 與store互斥。
  • world_size (python:int , 可選)–參與作業(yè)的進(jìn)程數(shù)。 如果指定store,則為必需。
  • 等級(jí) (python:int 可選)–當(dāng)前進(jìn)程的等級(jí)。 如果指定store,則為必需。
  • 存儲(chǔ)區(qū)(存儲(chǔ)區(qū) , 可選)–所有工作人員均可訪問的鍵/值存儲(chǔ),用于交換連接/地址信息。 與init_method互斥。
  • 超時(shí) (timedelta , 可選)–針對(duì)進(jìn)程組執(zhí)行的操作的超時(shí)。 默認(rèn)值等于 30 分鐘。 這適用于gloo后端。 對(duì)于nccl,僅在環(huán)境變量NCCL_BLOCKING_WAIT設(shè)置為 1 時(shí)適用。
  • group_name (str , 可選 , 不推薦使用)–組名。

要啟用backend == Backend.MPI,PyTorch 需要從支持 MPI 的系統(tǒng)上的源代碼構(gòu)建。 NCCL 同樣適用。

class torch.distributed.Backend?

類似于枚舉的可用后端類:GLOO,NCCL 和 MPI。

此類的值是小寫字符串,例如"gloo"。 可以將它們作為屬性來訪問,例如Backend.NCCL。

可以直接調(diào)用此類來解析字符串,例如Backend(backend_str)將檢查backend_str是否有效,如果有效,則返回已解析的小寫字符串。 它還接受大寫字符串,例如Backend("GLOO")返回"gloo"。

注意

條目Backend.UNDEFINED存在,但僅用作某些字段的初始值。 用戶既不應(yīng)直接使用它,也不應(yīng)該假定它的存在。

torch.distributed.get_backend(group=<object object>)?

返回給定進(jìn)程組的后端。

Parameters

(ProcessGroup , 可選)–要處理的過程組。 默認(rèn)值為常規(guī)主流程組。 如果指定了另一個(gè)特定組,則調(diào)用過程必須是group的一部分。

退貨

給定進(jìn)程組的后端,為小寫字符串。

torch.distributed.get_rank(group=<object object>)?

返回當(dāng)前進(jìn)程組的等級(jí)

等級(jí)是分配給分布式過程組中每個(gè)過程的唯一標(biāo)識(shí)符。 它們始終是從 0 到world_size的連續(xù)整數(shù)。

Parameters

(ProcessGroup , 可選)–要處理的進(jìn)程組

Returns

進(jìn)程組-1(如果不屬于組)的等級(jí)

torch.distributed.get_world_size(group=<object object>)?

返回當(dāng)前進(jìn)程組中的進(jìn)程數(shù)

Parameters

group (ProcessGroup__, optional) – The process group to work on

Returns

進(jìn)程組-1 的世界大小,如果不是該組的一部分

torch.distributed.is_initialized()?

檢查默認(rèn)進(jìn)程組是否已初始化

torch.distributed.is_mpi_available()?

檢查 MPI 后端是否可用。

torch.distributed.is_nccl_available()?

檢查 NCCL 后端是否可用。

當(dāng)前支持三種初始化方法:

TCP 初始化

有兩種使用 TCP 進(jìn)行初始化的方式,兩種方式都需要所有進(jìn)程都可以訪問的網(wǎng)絡(luò)地址以及所需的world_size。 第一種方法要求指定一個(gè)地址,該地址屬于等級(jí) 0 進(jìn)程。 此初始化方法要求所有進(jìn)程都具有手動(dòng)指定的等級(jí)。

請(qǐng)注意,最新的分布式程序包中不再支持多播地址。 group_name也已棄用。

import torch.distributed as dist


## Use address of one of the machines
dist.init_process_group(backend, init_method='tcp://10.1.1.20:23456',
                        rank=args.rank, world_size=4)

共享文件系統(tǒng)初始化

另一種初始化方法利用了文件系統(tǒng)以及所需的world_size,該文件系統(tǒng)可從組中的所有計(jì)算機(jī)共享并可見。 該 URL 應(yīng)該以file://開頭,并包含一個(gè)指向共享文件系統(tǒng)上不存在的文件(在現(xiàn)有目錄中)的路徑。 如果文件系統(tǒng)初始化不存在,則會(huì)自動(dòng)創(chuàng)建該文件,但不會(huì)刪除該文件。 因此,您有責(zé)任確保在相同文件路徑/名稱的下一個(gè) init_process_group() 調(diào)用之前清除文件。

請(qǐng)注意,最新的分布式軟件包不再支持自動(dòng)等級(jí)分配,并且group_name也已棄用。

警告

此方法假定文件系統(tǒng)支持使用fcntl進(jìn)行鎖定-大多數(shù)本地系統(tǒng)和 NFS 都支持它。

Warning

此方法將始終創(chuàng)建文件,并盡力在程序末尾清理并刪除文件。 換句話說,使用文件 init 方法進(jìn)行的每次初始化都需要一個(gè)全新的空文件,以使初始化成功。 如果再次使用先前初始化使用的同一文件(碰巧不會(huì)被清除),則這是意外行為,通常會(huì)導(dǎo)致死鎖和失敗。 因此,即使此方法將盡最大努力清除文件,但如果自動(dòng)刪除碰巧失敗,您有責(zé)任確保在訓(xùn)練結(jié)束時(shí)將文件刪除,以防止同一文件被刪除。 在下一次再次使用。 如果您計(jì)劃在同一文件名上多次調(diào)用 init_process_group() ,這尤其重要。 換句話說,如果未刪除/清除文件,然后對(duì)該文件再次調(diào)用 init_process_group() ,則可能會(huì)失敗。 經(jīng)驗(yàn)法則是,每次調(diào)用 init_process_group() 時(shí),請(qǐng)確保文件不存在或?yàn)榭铡?/p>

import torch.distributed as dist


## rank should always be specified
dist.init_process_group(backend, init_method='file:///mnt/nfs/sharedfile',
                        world_size=4, rank=args.rank)

環(huán)境變量初始化

該方法將從環(huán)境變量中讀取配置,從而可以完全自定義如何獲取信息。 要設(shè)置的變量是:

  • MASTER_PORT-必填; 必須是等級(jí)為 0 的計(jì)算機(jī)上的空閑端口
  • MASTER_ADDR-必填(0 級(jí)除外); 等級(jí) 0 節(jié)點(diǎn)的地址
  • WORLD_SIZE-必填; 可以在此處或在調(diào)用 init 函數(shù)時(shí)進(jìn)行設(shè)置
  • RANK-必填; 可以在此處或在調(diào)用 init 函數(shù)時(shí)進(jìn)行設(shè)置

等級(jí)為 0 的計(jì)算機(jī)將用于建立所有連接。

這是默認(rèn)方法,這意味著不必指定init_method(也可以是env://)。

團(tuán)體

默認(rèn)情況下,集合體在默認(rèn)組(也稱為世界)上運(yùn)行,并要求所有進(jìn)程進(jìn)入分布式函數(shù)調(diào)用。 但是,某些工作負(fù)載可以從更細(xì)粒度的通信中受益。 這是分布式組起作用的地方。 new_group() 功能可用于創(chuàng)建帶有所有進(jìn)程的任意子集的新組。 它返回一個(gè)不透明的組句柄,該句柄可以作為group參數(shù)提供給所有集合(集合是分布式函數(shù),用于以某些眾所周知的編程模式交換信息)。

torch.distributed.new_group(ranks=None, timeout=datetime.timedelta(0, 1800), backend=None)?

創(chuàng)建一個(gè)新的分布式組。

此功能要求主組中的所有進(jìn)程(即,屬于分布式作業(yè)的所有進(jìn)程)都必須輸入此功能,即使它們不會(huì)成為該組的成員也是如此。 此外,應(yīng)在所有過程中以相同順序創(chuàng)建組。

Parameters

  • 排名(列表 [ python:int ] )–組成員的等級(jí)列表。
  • 超時(shí) (timedelta , 可選)–針對(duì)進(jìn)程組執(zhí)行的操作的超時(shí)。 默認(rèn)值等于 30 分鐘。 這僅適用于gloo后端。
  • 后端 (str 后端 , 可選) –要使用的后端。 根據(jù)構(gòu)建時(shí)配置,有效值為gloonccl。 默認(rèn)情況下,使用與全局組相同的后端。 此字段應(yīng)以小寫字符串(例如"gloo")形式給出,也可以通過 Backend 屬性(例如Backend.GLOO)進(jìn)行訪問。

Returns

可以分配給集體呼叫的分布式組的句柄。

點(diǎn)對(duì)點(diǎn)通訊

torch.distributed.send(tensor, dst, group=<object object>, tag=0)?

同步發(fā)送張量。

Parameters

  • 張量 (tensor)–要發(fā)送的張量。
  • dst (python:int )–目標(biāo)排名。
  • group (ProcessGroup__, optional) – The process group to work on
  • 標(biāo)簽 (python:int , 可選)–與遠(yuǎn)程 recv 發(fā)送匹配的標(biāo)簽

torch.distributed.recv(tensor, src=None, group=<object object>, tag=0)?

同步接收張量。

Parameters

  • 張量 (tensor)–張量以填充接收到的數(shù)據(jù)。
  • src (python:int 可選)–源排名。 如果未指定,將從任何進(jìn)程中接收。
  • group (ProcessGroup__, optional) – The process group to work on
  • 標(biāo)記 (python:int , 可選)–用于將 recv 與遠(yuǎn)程發(fā)送匹配的標(biāo)記

Returns

發(fā)件人等級(jí)-1,如果不屬于該組

isend()irecv() 在使用時(shí)返回分布式請(qǐng)求對(duì)象。 通常,此對(duì)象的類型是不確定的,因?yàn)樗鼈冇肋h(yuǎn)不應(yīng)該手動(dòng)創(chuàng)建,但是可以保證它們支持兩種方法:

  • is_completed()-如果操作完成,則返回 True
  • wait()-將阻止該過程,直到操作完成。 保證is_completed()一旦返回就返回 True。

torch.distributed.isend(tensor, dst, group=<object object>, tag=0)?

異步發(fā)送張量。

Parameters

  • tensor (Tensor) – Tensor to send.
  • dst (python:int) – Destination rank.
  • group (ProcessGroup__, optional) – The process group to work on
  • tag (python:int__, optional) – Tag to match send with remote recv

Returns

分布式請(qǐng)求對(duì)象。 無,如果不是該組的一部分

torch.distributed.irecv(tensor, src, group=<object object>, tag=0)?

異步接收張量。

Parameters

  • tensor (Tensor) – Tensor to fill with received data.
  • src (python:int )–源排名。
  • group (ProcessGroup__, optional) – The process group to work on
  • tag (python:int__, optional) – Tag to match recv with remote send

Returns

A distributed request object. None, if not part of the group

同步和異步集體操作

每個(gè)集體操作功能都支持以下兩種操作:

同步操作-async_op設(shè)置為 False 時(shí)的默認(rèn)模式。 當(dāng)函數(shù)返回時(shí),可以確保執(zhí)行了集合操作(如果它是 CUDA op,則不一定要完成,因?yàn)樗?CUDA ops 都是異步的),并且可以根據(jù)集合操作的數(shù)據(jù)調(diào)用任何進(jìn)一步的函數(shù)。 在同步模式下,集合函數(shù)不返回任何內(nèi)容

異步操作-當(dāng)async_op設(shè)置為 True 時(shí)。 集合操作函數(shù)返回一個(gè)分布式請(qǐng)求對(duì)象。 通常,您不需要手動(dòng)創(chuàng)建它,并且可以支持兩種方法:

  • is_completed() - returns True if the operation has finished
  • wait()-將阻止該過程,直到操作完成。

集體職能

torch.distributed.broadcast(tensor, src, group=<object object>, async_op=False)?

向整個(gè)組廣播張量。

tensor在參與集合的所有進(jìn)程中必須具有相同數(shù)量的元素。

Parameters

  • 張量 (tensor)–如果src是當(dāng)前進(jìn)程的等級(jí),則發(fā)送數(shù)據(jù),否則使用張量保存接收到的數(shù)據(jù)。
  • src (python:int) – Source rank.
  • group (ProcessGroup__, optional) – The process group to work on
  • async_op (bool , 可選)–此 op 是否應(yīng)為異步 op

Returns

異步工作句柄(如果 async_op 設(shè)置為 True)。 無,如果不是 async_op 或不是該組的一部分

torch.distributed.all_reduce(tensor, op=ReduceOp.SUM, group=<object object>, async_op=False)?

減少所有機(jī)器上的張量數(shù)據(jù),以使所有機(jī)器都能得到最終結(jié)果。

調(diào)用之后,tensor將在所有進(jìn)程中按位相同。

Parameters

  • 張量 (tensor)–集合的輸入和輸出。 該功能就地運(yùn)行。
  • op (可選)–來自torch.distributed.ReduceOp枚舉的值之一。 指定用于逐元素精簡(jiǎn)的操作。
  • group (ProcessGroup__, optional) – The process group to work on
  • async_op (bool__, optional) – Whether this op should be an async op

Returns

Async work handle, if async_op is set to True. None, if not async_op or if not part of the group

torch.distributed.reduce(tensor, dst, op=ReduceOp.SUM, group=<object object>, async_op=False)?

減少所有機(jī)器上的張量數(shù)據(jù)。

只有等級(jí)為dst的進(jìn)程才能收到最終結(jié)果。

Parameters

  • tensor (Tensor) – Input and output of the collective. The function operates in-place.
  • dst (python:int )–目標(biāo)排名
  • op (optional) – One of the values from torch.distributed.ReduceOp enum. Specifies an operation used for element-wise reductions.
  • group (ProcessGroup__, optional) – The process group to work on
  • async_op (bool__, optional) – Whether this op should be an async op

Returns

Async work handle, if async_op is set to True. None, if not async_op or if not part of the group

torch.distributed.all_gather(tensor_list, tensor, group=<object object>, async_op=False)?

在列表中收集整個(gè)組的張量。

Parameters

  • tensor_list (列表 [ tensor ] )–輸出列表。 它應(yīng)包含正確大小的張量以用于集合的輸出。
  • 張量 (tensor)–要從當(dāng)前進(jìn)程廣播的張量。
  • group (ProcessGroup__, optional) – The process group to work on
  • async_op (bool__, optional) – Whether this op should be an async op

Returns

Async work handle, if async_op is set to True. None, if not async_op or if not part of the group

torch.distributed.gather(tensor, gather_list=None, dst=0, group=<object object>, async_op=False)?

在單個(gè)過程中收集張量列表。

Parameters

  • 張量 (tensor)–輸入張量。
  • collect_list (列表 [ tensor ] , 可選)–用于收集數(shù)據(jù)的適當(dāng)大小的張量列表(默認(rèn)為 None,必須在目標(biāo)等級(jí)上指定)
  • dst (python:int , 可選)–目標(biāo)排名(默認(rèn)為 0)
  • group (ProcessGroup__, optional) – The process group to work on
  • async_op (bool__, optional) – Whether this op should be an async op

Returns

Async work handle, if async_op is set to True. None, if not async_op or if not part of the group

torch.distributed.scatter(tensor, scatter_list=None, src=0, group=<object object>, async_op=False)?

將張量列表分散到組中的所有進(jìn)程。

每個(gè)進(jìn)程將僅接收一個(gè)張量并將其數(shù)據(jù)存儲(chǔ)在tensor參數(shù)中。

Parameters

  • 張量 (tensor)–輸出張量。
  • scatter_list (列表 [ tensor ] )–分散的張量列表 (默認(rèn)為無,必須在源排名上指定)
  • src (python:int )–源排名(默認(rèn)為 0)
  • group (ProcessGroup__, optional) – The process group to work on
  • async_op (bool__, optional) – Whether this op should be an async op

Returns

Async work handle, if async_op is set to True. None, if not async_op or if not part of the group

torch.distributed.barrier(group=<object object>, async_op=False)?

同步所有進(jìn)程。

如果 async_op 為 False,或者在 wait()上調(diào)用了異步工作句柄,則該集合將阻塞進(jìn)程,直到整個(gè)組都進(jìn)入該函數(shù)。

Parameters

  • group (ProcessGroup__, optional) – The process group to work on
  • async_op (bool__, optional) – Whether this op should be an async op

Returns

Async work handle, if async_op is set to True. None, if not async_op or if not part of the group

class torch.distributed.ReduceOp?

可用還原操作的類枚舉類:SUM,PRODUCT,MIN,MAX,BAND,BORBXOR

此類的值可以作為屬性訪問,例如ReduceOp.SUM。 它們用于指定減少集合體的策略,例如 reduce() , all_reduce_multigpu() 等。

成員:



產(chǎn)品

最小

最大值



BOR

異或

class torch.distributed.reduce_op?

減少操作的不推薦枚舉類:SUM,PRODUCT,MINMAX

建議改用 ReduceOp 。

多 GPU 集合功能

如果每個(gè)節(jié)點(diǎn)上有多個(gè) GPU,則在使用 NCCL 和 Gloo 后端時(shí), broadcast_multigpu() all_reduce_multigpu() reduce_multigpu()all_gather_multigpu() 支持在每個(gè)節(jié)點(diǎn)內(nèi)的多個(gè) GPU 之間進(jìn)行分布式集體操作。 這些功能可以潛在地改善整體分布式訓(xùn)練性能,并且可以通過傳遞張量列表輕松使用。 傳遞的張量列表中的每個(gè)張量必須位于調(diào)用該函數(shù)的主機(jī)的單獨(dú) GPU 設(shè)備上。 請(qǐng)注意,在所有分布式過程中,張量列表的長(zhǎng)度必須相同。 另請(qǐng)注意,當(dāng)前只有 NCCL 后端支持多 GPU 集合功能。

例如,如果我們用于分布式訓(xùn)練的系統(tǒng)有 2 個(gè)節(jié)點(diǎn),每個(gè)節(jié)點(diǎn)都有 8 個(gè) GPU。 在 16 個(gè) GPU 的每個(gè) GPU 上,都有一個(gè)我們想全部減少的張量。 以下代碼可以作為參考:

在節(jié)點(diǎn) 0 上運(yùn)行的代碼

import torch
import torch.distributed as dist


dist.init_process_group(backend="nccl",
                        init_method="file:///distributed_test",
                        world_size=2,
                        rank=0)
tensor_list = []
for dev_idx in range(torch.cuda.device_count()):
    tensor_list.append(torch.FloatTensor([1]).cuda(dev_idx))


dist.all_reduce_multigpu(tensor_list)

在節(jié)點(diǎn) 1 上運(yùn)行的代碼

import torch
import torch.distributed as dist


dist.init_process_group(backend="nccl",
                        init_method="file:///distributed_test",
                        world_size=2,
                        rank=1)
tensor_list = []
for dev_idx in range(torch.cuda.device_count()):
    tensor_list.append(torch.FloatTensor([1]).cuda(dev_idx))


dist.all_reduce_multigpu(tensor_list)

調(diào)用之后,兩個(gè)節(jié)點(diǎn)上的所有 16 張量將具有全部約簡(jiǎn)值 16

torch.distributed.broadcast_multigpu(tensor_list, src, group=<object object>, async_op=False, src_tensor=0)?

將張量廣播到整個(gè)組,每個(gè)節(jié)點(diǎn)具有多個(gè) GPU 張量。

tensor在參與集合的所有進(jìn)程的所有 GPU 中必須具有相同數(shù)量的元素。 列表中的每個(gè)張量必須在不同的 GPU 上

當(dāng)前僅支持 nccl 和 gloo 后端張量應(yīng)僅是 GPU 張量

Parameters

  • tensor_list (列表 [ tensor ] )–參與集體的張量 操作。 如果src是等級(jí),則tensor_list(tensor_list[src_tensor])的指定src_tensor元素將在 src 進(jìn)程中廣播給所有其他張量(在不同 GPU 上),而在其他非張量中tensor_list的所有張量 -src 進(jìn)程。 您還需要確保所有調(diào)用此函數(shù)的分布式進(jìn)程的len(tensor_list)相同。
  • src (python:int) – Source rank.
  • group (ProcessGroup__, optional) – The process group to work on
  • async_op (bool__, optional) – Whether this op should be an async op
  • src_tensor (python:int , 可選)–在tensor_list內(nèi)的源張量等級(jí)

Returns

Async work handle, if async_op is set to True. None, if not async_op or if not part of the group

torch.distributed.all_reduce_multigpu(tensor_list, op=ReduceOp.SUM, group=<object object>, async_op=False)?

減少所有機(jī)器上的張量數(shù)據(jù),以使所有機(jī)器都能得到最終結(jié)果。 此功能可減少每個(gè)節(jié)點(diǎn)上的張量數(shù)量,而每個(gè)張量位于不同的 GPU 上。 因此,張量列表中的輸入張量必須是 GPU 張量。 同樣,張量列表中的每個(gè)張量都需要駐留在不同的 GPU 上。

調(diào)用之后,tensor_list中的所有tensor在所有進(jìn)程中都將按位相同。

當(dāng)前僅支持 nccl 和 gloo 后端張量應(yīng)僅是 GPU 張量

Parameters

  • 列表(tensor)–集合的輸入和輸出張量的列表。 該函數(shù)在原位運(yùn)行,并且要求每個(gè)張量都是不同 GPU 上的 GPU 張量。 您還需要確保所有調(diào)用此函數(shù)的分布式進(jìn)程的len(tensor_list)相同。
  • op (optional) – One of the values from torch.distributed.ReduceOp enum. Specifies an operation used for element-wise reductions.
  • group (ProcessGroup__, optional) – The process group to work on
  • async_op (bool__, optional) – Whether this op should be an async op

Returns

Async work handle, if async_op is set to True. None, if not async_op or if not part of the group

torch.distributed.reduce_multigpu(tensor_list, dst, op=ReduceOp.SUM, group=<object object>, async_op=False, dst_tensor=0)?

減少所有計(jì)算機(jī)上多個(gè) GPU 上的張量數(shù)據(jù)。 tensor_list中的每個(gè)張量應(yīng)駐留在單獨(dú)的 GPU 上

排名為dst的進(jìn)程中只有tensor_list[dst_tensor]的 GPU 會(huì)收到最終結(jié)果。

當(dāng)前僅支持 nccl 后端張量應(yīng)僅是 GPU 張量

Parameters

  • tensor_list (列表 [ tensor ] )–輸入和輸出的 GPU 張量 集體。 該功能就地運(yùn)行。 您還需要確保所有調(diào)用此函數(shù)的分布式進(jìn)程的len(tensor_list)相同。
  • dst (python:int) – Destination rank
  • op (optional) – One of the values from torch.distributed.ReduceOp enum. Specifies an operation used for element-wise reductions.
  • group (ProcessGroup__, optional) – The process group to work on
  • async_op (bool__, optional) – Whether this op should be an async op
  • dst_tensor (python:int , 可選)– tensor_list中的目標(biāo)張量等級(jí)

Returns

異步工作句柄(如果 async_op 設(shè)置為 True)。 無,否則

torch.distributed.all_gather_multigpu(output_tensor_lists, input_tensor_list, group=<object object>, async_op=False)?

在列表中收集整個(gè)組的張量。 tensor_list中的每個(gè)張量應(yīng)駐留在單獨(dú)的 GPU 上

Only nccl backend is currently supported tensors should only be GPU tensors

Parameters

  • output_tensor_lists (列表 [ 列表 [ Tensor [ ] ] )–

輸出列表。 它應(yīng)該在每個(gè) GPU 上包含正確大小的張量,以用于集合的輸出,例如 output_tensor_lists[i]包含位于input_tensor_list[i]的 GPU 上的 all_gather 結(jié)果。

請(qǐng)注意,output_tensor_lists的每個(gè)元素的大小均為world_size * len(input_tensor_list),因?yàn)樵摵瘮?shù)都從組中的每個(gè) GPU 收集結(jié)果。 要解釋output_tensor_lists[i]的每個(gè)元素,請(qǐng)注意,排名為 k 的input_tensor_list[j]將出現(xiàn)在output_tensor_lists[i][k * world_size + j]

還要注意,對(duì)于所有調(diào)用此函數(shù)的分布式進(jìn)程,len(output_tensor_lists)output_tensor_lists中每個(gè)元素的大小(每個(gè)元素是一個(gè)列表,因此len(output_tensor_lists[i]))必須相同。

  • input_tensor_list (列表 [ tensor ] )–張量列表(不同) GPU)從當(dāng)前進(jìn)程中廣播。 注意,對(duì)于所有調(diào)用此函數(shù)的分布式進(jìn)程,len(input_tensor_list)必須相同。

  • group (ProcessGroup__, optional) – The process group to work on

  • async_op (bool__, optional) – Whether this op should be an async op

Returns

Async work handle, if async_op is set to True. None, if not async_op or if not part of the group

啟動(dòng)實(shí)用程序

<cite>torch.distributed</cite> 程序包還在 <cite>torch.distributed.launch</cite> 中提供了啟動(dòng)實(shí)用程序。 此幫助程序?qū)嵱贸绦蚩捎糜跒槊總€(gè)節(jié)點(diǎn)啟動(dòng)多個(gè)進(jìn)程以進(jìn)行分布式訓(xùn)練。 該實(shí)用程序還支持 python2 和 python3。

Spawn 實(shí)用程序

Multiprocessing 軟件包-Torch.multiprocessing 軟件包還在 torch.multiprocessing.spawn() 中提供了spawn功能。 此輔助函數(shù)可用于產(chǎn)生多個(gè)進(jìn)程。 它通過傳入要運(yùn)行的函數(shù)并產(chǎn)生 N 個(gè)進(jìn)程來運(yùn)行它而起作用。 這也可以用于多進(jìn)程分布式訓(xùn)練。

請(qǐng)注意,此功能需要 Python 3.4 或更高版本。

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)