新聞中心

        EEPW首頁 > 智能計算 > 設計應用 > GPU如何訓練大批量模型?方法在這里

        GPU如何訓練大批量模型?方法在這里

        作者: 時間:2018-10-22 來源:網絡 收藏

          分布式訓練:在多臺機器上訓練

        本文引用地址:http://www.104case.com/article/201810/393173.htm

          在更大的批量上訓練時,我們要如何控制多個服務器的算力呢?

          最簡單的選擇是使用 PyTorch 的 DistributedDataParallel,它幾乎可以說是以上討論的 DataParallel 的直接替代元件。

          但要注意:盡管代碼看起來很相似,但在分布式設定中訓練模型要改變工作流程,因為你必須在每個節點上啟動一個獨立的 訓練腳本。正如我們將看到的,一旦啟動,這些訓練腳本可以通過使用 PyTorch 分布式后端一起同步化。

          在實踐中,這意味著每個訓練腳本將擁有:

          它自己的優化器,并在每次迭代中執行一個完整的優化步驟,不需要進行參數傳播(DataParallel 中的步驟 2);

          一個獨立的 解釋器:這也將避免 GIL-freeze,這是在單個 解釋器上驅動多個并行執行線程時會出現的問題。

          當多個并行前向調用由單個解釋器驅動時,在前向傳播中大量使用 Python 循環/調用的模型可能會被 Python 解釋器的 GIL 放慢速度。通過這種設置,DistributedDataParallel 甚至在單臺機器設置中也能很方便地替代 DataParallel。

          現在我們直接討論代碼和用途。

          DistributedDataParallel 是建立在 torch.distributed 包之上的,這個包可以為同步分布式運算提供低級原語,并能以不同的性能使用多種后端(tcp、gloo、mpi、nccl)。在這篇文章中,我將選擇一種簡單的開箱即用的方式來使用它,但你應該閱讀文檔和 Séb Arnold 寫的教程來深入理解這個模塊。

          文檔:https://pytorch.org/docs/stable/distributed.html

          教程:https://pytorch.org/tutorials/intermediate/dist_tuto.html

          我們將考慮使用具有兩個 4 - 服務器(節點)的簡單但通用的設置:



          主服務器(服務器 1)擁有一個可訪問的 IP 地址和一個用于通信的開放端口。

          改寫 Python 訓練腳本以適應分布式訓練

          首先我們需要改寫腳本,從而令其可以在每臺機器(節點)上獨立運行。我們將實現完全的分布式訓練,并在每個節點的每塊 上運行一個獨立的進程,因此總共需要 8 個進程。

          我們的訓練腳本有點長,因為需要為同步化初始化分布式后端,封裝模型并準備數據,以在數據的一個子集上來訓練每個進程(每個進程都是獨立的,因此我們需要自行處理)。以下是更新后的代碼:

          from torch.utils.data.distributed import DistributedSampler

          from torch.utils.data import DataLoader

          # Each process runs on 1 device specified by the local_rank argument.

          parser = argparse.ArgumentParser()

          parser.add_argument("--local_rank", type=int)

          args = parser.parse_args()

          # Initializes the distributed backend which will take care of sychronizing nodes/GPUs

          torch.distributed.init_process_group(backend='nccl')

          # Encapsulate the model on the GPU assigned to the current process

          device = torch.device('cuda', arg.local_rank)

          model = model.to(device)

          distrib_model = torch.nn.parallel.DistributedDataParallel(model,

          device_ids=[args.local_rank],

          output_device=args.local_rank)

          # Restricts data loading to a subset of the dataset exclusive to the current process

          sampler = DistributedSampler(dataset)

          dataloader = DataLoader(dataset, sampler=sampler)

          for inputs, labels in dataloader:

          predictions = distrib_model(inputs.to(device)) # Forward pass

          loss = loss_function(predictions, labels.to(device)) # Compute loss function

          loss.backward() # Backward pass

          optimizer.step() # Optimizer step

          啟動 Python 訓練腳本的多個實例

          我們就快完成了,只需要在每個服務器上啟動訓練腳本的一個實例。

          為了運行腳本,我們將使用 PyTorch 的 torch.distributed.launch 工具。它將用來設置環境變量,并用正確的 local_rank 參數調用每個腳本。

          第一臺機器是最主要的,它應該對于所有其它機器都是可訪問的,因此擁有一個可訪問的 IP 地址(我們的案例中是 192.168.1.1)以及一個開放端口(在我們的案例中是 1234)。在第一臺機器上,我們使用 torch.distributed.launch 來運行訓練腳本:

          python -m torch.distributed.launch --nproc_per_node=4 --nnodes=2 --node_rank=0 --master_addr="192.168.1.1" --master_port=1234 OUR_TRAINING_SCRIPT.py (--arg1 --arg2 --arg3 and all other arguments of our training script) # Optimizer step

          在第二臺機器上,我們類似地啟動腳本:

          python -m torch.distributed.launch --nproc_per_node=4 --nnodes=2 --node_rank=1 --master_addr="192.168.1.1" --master_port=1234 OUR_TRAINING_SCRIPT.py (--arg1 --arg2 --arg3 and all other arguments of our training script)

          這兩個命令是相同的,除了—node_rank 參數,其在第一臺機器上被設為 0,在第二臺機器上被設為 1(如果再加一臺機器,則設為 2,以此類推…)。


        上一頁 1 2 3 下一頁

        關鍵詞: GPU Python

        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 平江县| 张家界市| 西贡区| 汝州市| 萨迦县| 云安县| 营口市| 彝良县| 曲周县| 遂昌县| 长顺县| 丽江市| 昌宁县| 习水县| 西宁市| 深水埗区| 英超| 集安市| 永寿县| 汉寿县| 富裕县| 丰镇市| 宽城| 湘阴县| 靖江市| 沧州市| 武宣县| 建宁县| 渭源县| 临沂市| 阳曲县| 内乡县| 民丰县| 长春市| 防城港市| 平陆县| 嘉鱼县| 吴堡县| 巴马| 尉犁县| 格尔木市|