PyTorch 數(shù)據(jù)并行處理

  • PyTorch 數(shù)據(jù)并行處理

可選擇:數(shù)據(jù)并行處理(文末有完整代碼下載) 作者:Sung Kim 和 Jenny Kang

在這個教程中,我們將學(xué)習(xí)如何用 DataParallel 來使用多 GPU。 通過 PyTorch 使用多個 GPU 非常簡單玻靡。你可以將模型放在一個 GPU:

 device = torch.device("cuda:0")
 model.to(device)

然后蛆封,你可以復(fù)制所有的張量到 GPU:


mytensor = my_tensor.to(device)

請注意层玲,只是調(diào)用 my_tensor.to(device) 返回一個 my_tensor 新的復(fù)制在GPU上杖们,而不是重寫 my_tensor夷狰。你需要分配給他一個新的張量并且在 GPU 上使用這個張量宰闰。

在多 GPU 中執(zhí)行前饋茬贵,后饋操作是非常自然的。盡管如此移袍,PyTorch 默認(rèn)只會使用一個 GPU解藻。通過使用 DataParallel 讓你的模型并行運行,你可以很容易的在多 GPU 上運行你的操作葡盗。

model = nn.DataParallel(model)

這是整個教程的核心螟左,我們接下來將會詳細講解啡浊。 引用和參數(shù)

引入 PyTorch 模塊和定義參數(shù)

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

參數(shù)

 input_size = 5
 output_size = 2

 batch_size = 30
 data_size = 100

設(shè)備

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

實驗(玩具)數(shù)據(jù)

生成一個玩具數(shù)據(jù)。你只需要實現(xiàn) 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胶背,我們的模型只是獲得一個輸入巷嚣,執(zhí)行一個線性操作,然后給一個輸出钳吟。盡管如此廷粒,你可以使用 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

創(chuàng)建模型并且數(shù)據(jù)并行處理

這是整個教程的核心坝茎。首先我們需要一個模型的實例,然后驗證我們是否有多個 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!

運行模型: 現(xiàn)在我們可以看到輸入和輸出張量的大小了次酌。

for data in rand_loader:
    input = data.to(device)
    output = model(input)
    print("Outside: input size", input.size(),
          "output_size", output.size())

輸出:

<pre style="box-sizing: border-box; font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", Courier, monospace; font-size: 1em; white-space: pre;">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])</pre>

結(jié)果:

如果你沒有 GPU 或者只有一個 GPU,當(dāng)我們獲取 30 個輸入和 30 個輸出舆乔,模型將期望獲得 30 個輸入和 30 個輸出和措。但是如果你有多個 GPU ,你會獲得這樣的結(jié)果蜕煌。

多 GPU

如果你有 2 個GPU派阱,你會看到:

<pre style="box-sizing: border-box; font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", Courier, monospace; font-size: 1em; white-space: pre;"># 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])</pre>

如果你有 3個GPU,你會看到:

<pre style="box-sizing: border-box; font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", Courier, monospace; font-size: 1em; white-space: pre;">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])</pre>

如果你有 8個GPU斜纪,你會看到:

<pre style="box-sizing: border-box; font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", Courier, monospace; font-size: 1em; white-space: pre;">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])</pre>

總結(jié)

數(shù)據(jù)并行自動拆分了你的數(shù)據(jù)并且將任務(wù)單發(fā)送到多個 GPU 上贫母。當(dāng)每一個模型都完成自己的任務(wù)之后,DataParallel 收集并且合并這些結(jié)果盒刚,然后再返回給你腺劣。

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

下載 Python 版本完整代碼:

data_parallel_tutorial.py

下載 jupyter notebook 版本完整代碼:

data_parallel_tutorial.ipynb

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末因块,一起剝皮案震驚了整個濱河市橘原,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌涡上,老刑警劉巖趾断,帶你破解...
    沈念sama閱讀 223,002評論 6 519
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異吩愧,居然都是意外死亡芋酌,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,357評論 3 400
  • 文/潘曉璐 我一進店門雁佳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來脐帝,“玉大人同云,你說我怎么就攤上這事《赂梗” “怎么了炸站?”我有些...
    開封第一講書人閱讀 169,787評論 0 365
  • 文/不壞的土叔 我叫張陵,是天一觀的道長疚顷。 經(jīng)常有香客問我旱易,道長,這世上最難降的妖魔是什么荡含? 我笑而不...
    開封第一講書人閱讀 60,237評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮届垫,結(jié)果婚禮上谱轨,老公的妹妹穿的比我還像新娘备畦。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 69,237評論 6 398
  • 文/花漫 我一把揭開白布傻铣。 她就那樣靜靜地躺著,像睡著了一般卵渴。 火紅的嫁衣襯著肌膚如雪兑障。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,821評論 1 314
  • 那天登淘,我揣著相機與錄音箫老,去河邊找鬼。 笑死黔州,一個胖子當(dāng)著我的面吹牛耍鬓,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播流妻,決...
    沈念sama閱讀 41,236評論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼牲蜀,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了绅这?” 一聲冷哼從身側(cè)響起涣达,我...
    開封第一講書人閱讀 40,196評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎证薇,沒想到半個月后度苔,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,716評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡浑度,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,794評論 3 343
  • 正文 我和宋清朗相戀三年林螃,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片俺泣。...
    茶點故事閱讀 40,928評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡疗认,死狀恐怖完残,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情横漏,我是刑警寧澤谨设,帶...
    沈念sama閱讀 36,583評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站缎浇,受9級特大地震影響扎拣,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜素跺,卻給世界環(huán)境...
    茶點故事閱讀 42,264評論 3 336
  • 文/蒙蒙 一二蓝、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧指厌,春花似錦刊愚、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,755評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至箕憾,卻和暖如春牡借,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背袭异。 一陣腳步聲響...
    開封第一講書人閱讀 33,869評論 1 274
  • 我被黑心中介騙來泰國打工钠龙, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人御铃。 一個月前我還...
    沈念sama閱讀 49,378評論 3 379
  • 正文 我出身青樓俊鱼,卻偏偏與公主長得像,于是被迫代替她去往敵國和親畅买。 傳聞我的和親對象是個殘疾皇子并闲,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,937評論 2 361