PyTorch Data Parrallel数据并行
PyTorch Data Parrallel數據并行
? 可選擇:數據并行處理
? 本文將學習如何用 DataParallel 來使用多 GPU。 通過 PyTorch 使用多個 GPU 非常簡單。可以將模型放在一個 GPU:
? device = torch.device(“cuda:0”)
? model.to(device)
? 可以復制所有的張量到 GPU:
?
? mytensor = my_tensor.to(device)
?
? 調用 my_tensor.to(device) 返回一個 my_tensor, 新的復制在GPU上,而不是重寫 my_tensor。需要分配一個新的張量并且在 GPU 上使用這個張量。
? 在多 GPU 中執行前饋,后繼操作是非常自然的。盡管如此,PyTorch 默認只會使用一個 GPU。通過使用 DataParallel 讓模型并行運行,可以很容易的在多 GPU 上運行操作。
? model = nn.DataParallel(model)
?
? 這是整個教程的核心,接下來將會詳細講解。 引用和參數
? 引入 PyTorch 模塊和定義參數
? import torch
? import torch.nn as nn
? from torch.utils.data import Dataset, DataLoader
?
? 參數
? input_size = 5
? output_size = 2
?
? batch_size = 30
? data_size = 100
? 設備
? device = torch.device(“cuda:0” if torch.cuda.is_available() else “cpu”)
?
? 實驗(玩具)數據
? 生成一個玩具數據。只需要實現 getitem.
?
? class RandomDataset(Dataset):
?
? def init(self, size, length):
? self.len = length
? self.data = torch.randn(length, size)
?
? def getitem(self, index):
? return self.data[index]
?
? def len(self):
? return self.len
?
? rand_loader = DataLoader(dataset=RandomDataset(input_size, data_size),batch_size=batch_size, shuffle=True)
? 簡單模型
? 做一個小 demo,模型只是獲得一個輸入,執行一個線性操作,然后給一個輸出。可以使用 DataParallel 在任何模型(CNN, RNN, Capsule Net 等等.)
? 放置了一個輸出聲明在模型中,檢測輸出和輸入張量的大小。在 batch rank 0 中的輸出。
?
? class Model(nn.Module):
? # Our model
?
? def init(self, input_size, output_size):
? super(Model, self).init()
? self.fc = nn.Linear(input_size, output_size)
?
? def forward(self, input):
? output = self.fc(input)
? print("\tIn Model: input size", input.size(),
? “output size”, output.size())
?
? return output
? 創建模型并且數據并行處理
? 這是本文的核心。首先需要一個模型的實例,然后驗證是否有多個 GPU。如果有多個 GPU,可以用 nn.DataParallel 來包裹模型。然后使用 model.to(device) 把模型放到多 GPU 中。
? model = Model(input_size, output_size)
? if torch.cuda.device_count() > 1:
? print(“Let’s use”, torch.cuda.device_count(), “GPUs!”)
? # dim = 0 [30, xxx] -> [10, …], [10, …], [10, …] on 3 GPUs
? model = nn.DataParallel(model)
?
? model.to(device)
? 輸出:
?
? Let’s use 2 GPUs!
?
? 運行模型: 現在可以看到輸入和輸出張量的大小了。
? for data in rand_loader:
? input = data.to(device)
? output = model(input)
? print(“Outside: input size”, input.size(),
? “output_size”, output.size())
? 輸出:
? In Model: input size torch.Size([15, 5]) output size torch.Size([15, 2])
? In Model: input size torch.Size([15, 5]) output size torch.Size([15, 2])
? Outside: input size torch.Size([30, 5]) output_size torch.Size([30, 2])
? In Model: input size torch.Size([15, 5]) output size torch.Size([15, 2])
? In Model: input size torch.Size([15, 5]) output size torch.Size([15, 2])
? Outside: input size torch.Size([30, 5]) output_size torch.Size([30, 2])
? In Model: input size torch.Size([15, 5]) output size torch.Size([15, 2])
? In Model: input size torch.Size([15, 5]) output size torch.Size([15, 2])
? Outside: input size torch.Size([30, 5]) output_size torch.Size([30, 2])
? In Model: input size torch.Size([5, 5]) output size torch.Size([5, 2])
? In Model: input size torch.Size([5, 5]) output size torch.Size([5, 2])
? Outside: input size torch.Size([10, 5]) output_size torch.Size([10, 2])
? 結果:
? 如果沒有 GPU 或者只有一個 GPU,當獲取 30 個輸入和 30 個輸出,模型將期望獲得 30 個輸入和 30 個輸出。但是如果有多個 GPU ,會獲得這樣的結果。
? 多 GPU
? 如果有 2 個GPU,會看到:
? # on 2 GPUs
? Let’s use 2 GPUs!
? In Model: input size torch.Size([15, 5]) output size torch.Size([15, 2])
? In Model: input size torch.Size([15, 5]) output size torch.Size([15, 2])
? Outside: input size torch.Size([30, 5]) output_size torch.Size([30, 2])
? In Model: input size torch.Size([15, 5]) output size torch.Size([15, 2])
? In Model: input size torch.Size([15, 5]) output size torch.Size([15, 2])
? Outside: input size torch.Size([30, 5]) output_size torch.Size([30, 2])
? In Model: input size torch.Size([15, 5]) output size torch.Size([15, 2])
? In Model: input size torch.Size([15, 5]) output size torch.Size([15, 2])
? Outside: input size torch.Size([30, 5]) output_size torch.Size([30, 2])
? In Model: input size torch.Size([5, 5]) output size torch.Size([5, 2])
? In Model: input size torch.Size([5, 5]) output size torch.Size([5, 2])
? Outside: input size torch.Size([10, 5]) output_size torch.Size([10, 2])
?
? 如果有 3個GPU,會看到:
? Let’s use 3 GPUs!
? In Model: input size torch.Size([10, 5]) output size torch.Size([10, 2])
? In Model: input size torch.Size([10, 5]) output size torch.Size([10, 2])
? In Model: input size torch.Size([10, 5]) output size torch.Size([10, 2])
? Outside: input size torch.Size([30, 5]) output_size torch.Size([30, 2])
? In Model: input size torch.Size([10, 5]) output size torch.Size([10, 2])
? In Model: input size torch.Size([10, 5]) output size torch.Size([10, 2])
? In Model: input size torch.Size([10, 5]) output size torch.Size([10, 2])
? Outside: input size torch.Size([30, 5]) output_size torch.Size([30, 2])
? In Model: input size torch.Size([10, 5]) output size torch.Size([10, 2])
? In Model: input size torch.Size([10, 5]) output size torch.Size([10, 2])
? In Model: input size torch.Size([10, 5]) output size torch.Size([10, 2])
? Outside: input size torch.Size([30, 5]) output_size torch.Size([30, 2])
? In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])
? In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])
? In Model: input size torch.Size([2, 5]) output size torch.Size([2, 2])
? Outside: input size torch.Size([10, 5]) output_size torch.Size([10, 2])
? 如果有 8個GPU,會看到:
? Let’s use 8 GPUs!
? In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])
? In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])
? In Model: input size torch.Size([2, 5]) output size torch.Size([2, 2])
? In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])
? In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])
? In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])
? In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])
? In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])
? Outside: input size torch.Size([30, 5]) output_size torch.Size([30, 2])
? In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])
? In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])
? In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])
? In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])
? In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])
? In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])
? In Model: input size torch.Size([2, 5]) output size torch.Size([2, 2])
? In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])
? Outside: input size torch.Size([30, 5]) output_size torch.Size([30, 2])
? In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])
? In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])
? In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])
? In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])
? In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])
? In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])
? In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])
? In Model: input size torch.Size([2, 5]) output size torch.Size([2, 2])
? Outside: input size torch.Size([30, 5]) output_size torch.Size([30, 2])
? In Model: input size torch.Size([2, 5]) output size torch.Size([2, 2])
? In Model: input size torch.Size([2, 5]) output size torch.Size([2, 2])
? In Model: input size torch.Size([2, 5]) output size torch.Size([2, 2])
? In Model: input size torch.Size([2, 5]) output size torch.Size([2, 2])
? In Model: input size torch.Size([2, 5]) output size torch.Size([2, 2])
? Outside: input size torch.Size([10, 5]) output_size torch.Size([10, 2])
? 總結
? 數據并行自動拆分了數據并,將任務單發送到多個 GPU 上。當每一個模型都完成任務之后,DataParallel 收集并且合并這些結果,然后再返回。
總結
以上是生活随笔為你收集整理的PyTorch Data Parrallel数据并行的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: NVIDIA 自动驾驶软件平台
- 下一篇: PyTorch 自动微分示例