PyTorch 60 分鐘入門教程:數據並行處理

可選擇:數據並行處理(文末有完整代碼下載)
做者:Sung Kim 和 Jenny Kanghtml

在這個教程中,咱們將學習如何用 DataParallel 來使用多 GPU。
經過 PyTorch 使用多個 GPU 很是簡單。你能夠將模型放在一個 GPU:dom

device = torch.device("cuda:0")
model.to(device)
而後,你能夠複製全部的張量到 GPU:ide

mytensor = my_tensor.to(device)
請注意,只是調用 my_tensor.to(device) 返回一個 my_tensor 新的複製在GPU上,而不是重寫 my_tensor。你須要分配給他一個新的張量而且在 GPU 上使用這個張量。學習

在多 GPU 中執行前饋,後饋操做是很是天然的。儘管如此,PyTorch 默認只會使用一個 GPU。經過使用 DataParallel 讓你的模型並行運行,你能夠很容易的在多 GPU 上運行你的操做。code

model = nn.DataParallel(model)
這是整個教程的核心,咱們接下來將會詳細講解。
引用和參數orm

引入 PyTorch 模塊和定義參數htm

import torch
import torch.nn as nn
from torch.utils.data import Dataset, DataLoader教程

參數

input_size = 5
output_size = 2get

batch_size = 30
data_size = 100
設備input

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 收集而且合併這些結果,而後再返回給你。

更多信息,請訪問:
https://pytorch.org/tutorials/beginner/former_torchies/parallelism_tutorial.html

下載 Python 版本完整代碼:

http://pytorchchina.com/2018/12/11/optional-data-parallelism/

相關文章
相關標籤/搜索