torch.distributed.init_process_group(backend=None,
init_method=None,
timeout=None,
world_size=-1,
rank=-1,
store=None,
group_name='',
pg_options=None,
device_id=None)
初始化默認分布式進程組,同時也會初始化分布式包。
-
初始化進程組主要有兩種方式
顯式指定
store,rank, 和world_size。指定init_method(一個 URL 字符串),指明在哪里/如何發(fā)現對等方。可以選擇指定rank和world_size,或將所有必需參數編碼在 URL 中并省略它們。
如果兩者都未指定,則假定 init_method 為“env://”。
-
參數
backend (
init_method (
world_size (
rank (
store (
timeout (timedelta**, optional) – 對進程組執(zhí)行的操作的超時時間。NCCL 的默認值為 10 分鐘,其他后端的默認值為 30 分鐘。這是集合操作將異步中止并導致進程崩潰的持續(xù)時間。這樣做是因為 CUDA 執(zhí)行是異步的,并且由于失敗的異步 NCCL 操作可能導致后續(xù)的 CUDA 操作在損壞的數據上運行,繼續(xù)執(zhí)行用戶代碼已不再安全。設置 TORCH_NCCL_BLOCKING_WAIT 時,進程將阻塞并等待此超時。
group_name (
pg_options (ProcessGroupOptions**, optional) – 進程組選項,指定在構建特定進程組時需要傳入的額外選項。目前,我們唯一支持的選項是針對
nccl后端的ProcessGroupNCCL.Options,可以指定is_high_priority_stream,以便 nccl 后端在有計算內核等待時能夠選擇高優(yōu)先級 CUDA 流。有關配置 nccl 的其他可用選項,請參閱 https://docs.nvda.net.cn/deeplearning/nccl/user-guide/docs/api/types.html#ncclconfig-tdevice_id (
方法1:指定 init_method
我現在要解釋一下PyTorch中torch.distributed.init_process_group()函數的init_method參數。這個參數看起來是用來初始化分布式進程組的,但我得先理解它的具體作用和不同的選項。
首先,我記得在分布式訓練中,不同的進程需要相互通信,所以必須有一種方法來協(xié)調它們的啟動和通信方式。init_method參數應該就是用來指定這種協(xié)調方法的。可能的選項包括環(huán)境變量、共享文件或者TCP地址之類的。
PyTorch文檔里提到過幾種初始化方法,比如使用環(huán)境變量(env://),或者一個共享的文件系統(tǒng)(file://path),還有通過TCP連接到一個主進程(比如tcp://IP:port)。不同的初始化方法適用于不同的場景,比如在單機多卡的情況下可能用環(huán)境變量更方便,而多機訓練可能需要TCP或者共享文件。
讓我再仔細想想。當使用init_method='env://'時,進程會從環(huán)境變量中獲取MASTER_ADDR和MASTER_PORT等信息,這樣每個進程只需要正確設置這些環(huán)境變量,就能找到主節(jié)點并建立通信。這可能是在使用像torch.distributed.launch或者torchrun這樣的啟動腳本時自動處理的,因為它們會設置這些環(huán)境變量。
另一種情況是使用文件系統(tǒng),比如init_method='file:///path/to/file'。這時,所有進程都會訪問同一個文件,通過文件來同步信息。這種方法可能適用于共享存儲環(huán)境,但需要注意文件鎖的問題,避免競爭條件。如果文件被刪除或者無法訪問,可能會導致初始化失敗。
然后是TCP方式,比如init_method='tcp://10.1.1.20:23456'。這里需要指定一個主進程的IP地址和端口,其他進程通過這個地址連接到主進程進行協(xié)調。這種方法適合多臺機器之間的通信,但需要確保網絡通暢,端口開放,并且所有機器都能訪問指定的IP和端口。
另外,可能還有其他初始化方法,比如使用NCCL或者Gloo后端時的不同設置,但init_method主要處理的是如何找到和協(xié)調進程之間的通信參數,而后端(backend參數)則處理實際的通信協(xié)議,比如Gloo用于CPU,NCCL用于GPU。
需要注意的是,不同的初始化方法可能對不同的后端支持程度不同。例如,文件初始化方法可能在Gloo后端下工作良好,但在NCCL中可能有問題。或者TCP方法在跨機器時更可靠。因此,選擇合適的init_method需要結合訓練的環(huán)境和后端類型。
還有一個要點是,當使用多臺機器時,每個進程的RANK和WORLD_SIZE需要正確設置,無論是通過環(huán)境變量還是通過啟動參數手動傳遞。而init_method則是告訴進程如何找到主節(jié)點或者共享的協(xié)調點,以便交換這些信息。
例如,當使用TCP方式時,主節(jié)點的IP地址必須是所有機器都能訪問的,端口要開放,并且所有進程在初始化時都連接到這個地址。主節(jié)點負責協(xié)調各個進程的rank和world_size,確保它們正確同步。
而使用環(huán)境變量方式時,每個進程可能已經通過啟動腳本設置了RANK、WORLD_SIZE、MASTER_ADDR和MASTER_PORT,這樣在調用init_process_group時,只需要指定env://,就會自動讀取這些變量。
不過,可能還有其他參數需要配合,比如backend、rank和world_size,這些是否需要在init_process_group中顯式傳遞,還是通過環(huán)境變量自動獲取?例如,如果使用env://,是否還需要在函數參數中指定rank和world_size?可能需要看具體的文檔說明。比如,當使用env://時,PyTorch會從環(huán)境變量中獲取RANK和WORLD_SIZE,所以可能不需要在函數中傳遞,但如果顯式傳遞了,可能會覆蓋環(huán)境變量。這點需要注意。
總結一下,init_method參數用于指定進程組初始化的方法,不同的方法對應不同的協(xié)調機制。常見的有env://(環(huán)境變量)、file://(共享文件)、tcp://(TCP連接)。選擇哪種方法取決于運行環(huán)境和需求,比如單機用env或file,多機用tcp,共享存儲用file等。同時需要配合正確設置相關參數,如MASTER_ADDR、MASTER_PORT、RANK、WORLD_SIZE等,無論是通過環(huán)境變量還是直接傳遞參數。
可能還需要注意一些細節(jié),例如使用文件方法時,所有進程需要有權限讀寫該文件;使用TCP時防火墻設置等。另外,不同后端對初始化方法的支持可能不同,例如NCCL可能更傾向于使用TCP而不是文件,尤其是在多GPU情況下。
此外,初始化進程組是分布式訓練的第一步,必須正確執(zhí)行,否則進程會掛起或報錯。例如,如果某個進程無法連接到指定的TCP地址,或者無法訪問共享文件,初始化就會失敗,導致整個訓練無法開始。
最后,可能還需要考慮不同初始化方法的性能和可靠性。例如,TCP可能在多機情況下更高效,而文件系統(tǒng)方法可能在特定存儲系統(tǒng)中存在延遲或鎖競爭問題。因此,根據實際環(huán)境選擇最合適的初始化方法很重要。
在PyTorch的分布式訓練中,torch.distributed.init_process_group()函數的init_method參數用于指定進程組初始化的方法,確保不同進程能夠協(xié)調通信。以下是該參數的詳細說明及常見選項:
init_method參數的作用
-
協(xié)調通信:分布式訓練需要多個進程(可能跨機器)同步彼此的地址、端口和配置信息。
init_method定義了進程間如何交換這些信息。 -
初始化后端:與
backend參數配合使用(如NCCL、Gloo),確定通信協(xié)議,而init_method則決定進程如何發(fā)現彼此。
常見的init_method選項
1. env://(環(huán)境變量)
-
機制:從環(huán)境變量中讀取配置,如
MASTER_ADDR(主節(jié)點IP)、MASTER_PORT(端口)、RANK(進程編號)、WORLD_SIZE(總進程數)。 -
適用場景:單機或多機訓練,配合啟動工具(如
torchrun或torch.distributed.launch)自動設置環(huán)境變量。 -
示例:
-
import os
os.environ["MASTER_ADDR"] = "localhost"
os.environ["MASTER_PORT"] = "12355"
os.environ["RANK"] = "0"
os.environ["WORLD_SIZE"] = "2"
torch.distributed.init_process_group(backend="gloo", init_method="env://")
2. file://(共享文件)
-
機制:所有進程通過讀寫共享文件同步信息。文件路徑需對所有進程可見(如NFS)。
-
適用場景:共享存儲環(huán)境,但需注意文件鎖和并發(fā)問題。
-
示例:
-
# 所有進程使用同一文件路徑
torch.distributed.init_process_group(
backend="gloo",
init_method="file:///path/to/shared/file",
rank=0, # 必須顯式指定rank和world_size
world_size=2
)
3. tcp://(TCP協(xié)議)
-
機制:所有進程連接到指定的主節(jié)點(通過IP和端口)交換信息。
-
適用場景:多機訓練,需確保網絡互通且防火墻開放端口。
-
示例:
-
# 主節(jié)點(rank=0)的IP為10.1.1.20,端口23456
torch.distributed.init_process_group(
backend="nccl",
init_method="tcp://10.1.1.20:23456",
rank=0, # 必須顯式指定rank和world_size
world_size=2
)
選擇init_method的建議
-
單機訓練:推薦
env://,簡單且與啟動工具集成。 -
多機訓練:使用
tcp://指定主節(jié)點IP和端口,確保網絡可達。 -
共享存儲環(huán)境:可嘗試
file://,但需注意文件權限和鎖機制。
注意事項
-
顯式參數 vs 環(huán)境變量:若在
init_process_group()中顯式傳遞rank和world_size,會覆蓋環(huán)境變量。 -
后端兼容性:
-
NCCL后端多用于GPU,對
tcp://和env://支持較好。 -
Gloo后端支持CPU,兼容所有
init_method。
-
-
端口沖突:使用
tcp://時,確保端口未被占用且防火墻允許。
完整示例(多機TCP初始化)
import torch
import argparse
?
parser = argparse.ArgumentParser()
parser.add_argument("--rank", type=int)
parser.add_argument("--world_size", type=int)
parser.add_argument("--master_addr", type=str, default="10.1.1.20")
parser.add_argument("--master_port", type=str, default="23456")
args = parser.parse_args()
?
torch.distributed.init_process_group(
backend="nccl",
init_method=f"tcp://{args.master_addr}:{args.master_port}",
rank=args.rank,
world_size=args.world_size
)
運行命令:
# 機器1(主節(jié)點)
python script.py --rank 0 --world_size 2 --master_addr 10.1.1.20
?
# 機器2
python script.py --rank 1 --world_size 2 --master_addr 10.1.1.20
通過合理配置init_method,可以確保分布式訓練正確初始化進程組,為后續(xù)的跨進程通信(如all_reduce)奠定基礎。
方法2:顯式指定 store, rank, 和 world_size。
store 參數的作用
store 是一個實現了鍵值存儲(Key-Value Store)接口的對象,核心功能是同步所有進程的元數據(如地址、端口、rank、world_size 等)。所有進程通過訪問同一個 store 來交換必要的信息,從而完成進程組的初始化。
在 PyTorch 的分布式訓練中,torch.distributed.init_process_group() 的 store 參數是用于定義進程間通信的底層存儲機制的。它替代了早期版本中通過 init_method 直接指定初始化方式的做法,提供了更靈活、更底層的方式控制分布式進程的協(xié)調和通信。
store參數是在PyTorch的后續(xù)版本中引入的,補充了init_method的功能。用戶可能在使用較新的PyTorch版本使用store參數,store參數的具體作用用于存儲分布式訓練中進程間的通信信息,比如地址和端口。與init_method不同,store提供了更靈活的配置方式,支持多種后端存儲,如HashStore、TCPStore、FileStore等。這可能讓用戶更容易在不同環(huán)境下配置分布式訓練。
在較新的版本中,推薦使用store來替代init_method,因為store提供了更多的選項和更好的擴展性。同時,需要明確如何正確初始化store對象,并將其傳遞給init_process_group。
需要注意,當同時指定store和init_method時,可能會出現沖突,因此需要建議用戶只使用其中一種方式。
下面提供具體的代碼示例更好地理解如何使用store參數,比如如何創(chuàng)建TCPStore實例并傳遞給初始化函數。
PyTorch 提供了多種內置的 store 類型,適用于不同的場景:
常見的 store 類型
1. HashStore(默認)
-
機制:基于內存的簡單鍵值存儲,僅適用于單機多進程(同一臺機器上的多個進程)。
-
用途:本地調試或單機訓練。
-
示例:
python
-
import torch.distributed as dist
?
# 默認使用 HashStore
dist.init_process_group(backend="gloo")
2. TCPStore
-
機制:基于 TCP 協(xié)議的鍵值存儲,需要一個中心化的主節(jié)點(通過 IP 和端口訪問)。
-
用途:多機訓練(跨機器的分布式訓練)。
-
示例:
python
-
import torch.distributed as dist
?
# 主節(jié)點(rank=0)的配置
if rank == 0:
store = dist.TCPStore(
host_name="10.1.1.20", # 主節(jié)點 IP
port=12345, # 主節(jié)點端口
world_size=4, # 總進程數
is_master=True # 主節(jié)點標記
)
else:
store = dist.TCPStore(
host_name="10.1.1.20", # 主節(jié)點 IP
port=12345, # 主節(jié)點端口
world_size=4, # 總進程數
is_master=False # 非主節(jié)點
)
?
dist.init_process_group(backend="nccl", store=store, rank=rank, world_size=4)
3. FileStore
-
機制:通過共享文件系統(tǒng)(如 NFS)同步元數據。所有進程讀寫同一個文件。
-
用途:有共享存儲的多機環(huán)境,但需注意文件鎖問題。
-
示例:
python
-
store = dist.FileStore("/path/to/shared/file", world_size=4)
dist.init_process_group(backend="gloo", store=store, rank=rank, world_size=4)
4. C10dStore
-
機制:PyTorch 內部的默認存儲實現,兼容多種后端(如
env://的初始化方式)。 -
用途:通過環(huán)境變量自動配置(如
MASTER_ADDR和MASTER_PORT)。 -
示例:
python
-
# 隱式使用 C10dStore(等價于 init_method="env://")
dist.init_process_group(backend="nccl")
store vs init_method
-
init_method是舊版參數,通過字符串直接指定初始化方式(如tcp://或file://)。 -
store是新版參數,通過顯式傳遞存儲對象(如TCPStore)實現更精細的控制。 -
兼容性:
-
如果同時指定
store和init_method,PyTorch 會優(yōu)先使用store。 -
新版代碼推薦優(yōu)先使用
store,因為它的接口更清晰且支持更多功能。
-
為什么需要 store?
-
靈活性:可以自定義存儲后端(例如集成第三方分布式協(xié)調服務如 etcd、Redis)。
-
顯式控制:直接管理存儲對象的生命周期(如關閉端口或清理文件)。
-
多后端支持:支持 TCP、文件、內存等多種同步機制,適應不同環(huán)境。
使用 store 的完整流程
以下是一個多機訓練中使用 TCPStore 的示例:
import torch
import torch.distributed as dist
def main():
# 假設通過命令行參數傳入 rank 和 world_size
parser = argparse.ArgumentParser()
parser.add_argument("--rank", type=int)
parser.add_argument("--world_size", type=int)
parser.add_argument("--master_addr", type=str, default="10.1.1.20")
parser.add_argument("--master_port", type=int, default=12345)
args = parser.parse_args()
# 創(chuàng)建 TCPStore
store = dist.TCPStore(
args.master_addr, # 主節(jié)點 IP
args.master_port, # 主節(jié)點端口
args.world_size, # 總進程數
is_master=(args.rank == 0) # 主節(jié)點標記
)
# 初始化進程組
dist.init_process_group(
backend="nccl",
store=store,
rank=args.rank,
world_size=args.world_size
)
# 后續(xù)分布式訓練代碼...
if __name__ == "__main__":
main()
注意事項
-
主節(jié)點標記:只有主節(jié)點(
rank=0)需要設置is_master=True,其他節(jié)點設為False。 -
端口占用:確保
TCPStore的端口未被防火墻阻止且未被占用。 -
同步問題:所有進程必須在初始化時訪問同一個
store,否則會卡死。 -
后端兼容性:
-
NCCL后端通常與TCPStore配合使用。 -
Gloo后端支持FileStore和TCPStore。
-
總結
-
store參數提供了對分布式進程元數據同步的底層控制,適用于復雜場景(如多機訓練)。 -
優(yōu)先使用
TCPStore進行多機訓練,FileStore適合有共享存儲的環(huán)境,HashStore用于單機調試。 -
新版 PyTorch 推薦使用
store替代init_method,以獲得更好的靈活性和兼容性。
浙公網安備 33010602011771號