Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 6 Next »

ในบทความนี้จะกล่าวถึงตัวอย่างการติดตั้ง Python package ที่เกี่ยวข้องกับ PyTorch และการทดสอบรันงานบน gpu node ของ TARA HPC โดยใช้ตัวอย่าง Package modules อย่างง่ายจากการทำ 3D-Deep Learning ด้วย PyTorch

ตัวอย่างโปรแกรม basic multi-GPUs PyTorch

ผู้ใช้งานสามารถ copy ไฟล์โปรแกรม ตัวอย่างโปรแกรม basic multi-GPUs PyTorch ที่ใช้ในบทความนี้ได้ในระบบ TARA ที่

/tarafs/data/project/common/AI/examples/basic-multigpu-pytorch.py

import PyTorch modules และกำหนด parameters

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

# Parameters and DataLoaders
input_size = 5
output_size = 2

batch_size = 30
data_size = 100

สร้าง dummy dataset ขึ้นมาด้วยการ random

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)

สร้าง simple model

ที่แค่รับ input แล้วทำ linear operation แล้วส่งออก output เพื่อแสดงการทำงานของ DataParallel ซึ่งก็คือส่วนที่ทำให้เกิดการใช้งาน multi-GPUs ได้ด้วยการแบ่งข้อมูลออกไปที่แต่ละ GPUs

โดยในโปรแกรม เราอยากเห็นขนาดของ input/output tensors จึงได้ให้พิมพ์ออกมา

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

สร้าง object device

ซึ่งจะเป็นจุดที่เราส่ง tensor/model ให้กับ device ที่เรามีเพื่อการทำงาน

โดยในตัวอย่างด้านล่าง เราจะตรวจสอบว่ามี cuda ในเครื่องหรือไม่ หากไม่มีจะสั่งให้ device ใช้งาน cpu

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

สร้าง model instance และการรันงานแบบ nn.DataParallel

โดยจุดที่เราสนใจเป็นพิเศษในบทความนี้คือ หากในเครื่องที่เราได้รันงานมี GPUs หลายตัว เราจะสามารถ wrap model ของเราด้วย nn.DataParallel ได้ จากนั้นจึงนำ model ที่ได้ส่งให้กับ device ที่เรากำหนดไว้ก่อนหน้านี้

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)

ในขั้นตอนนี้ถ้าหากเรามี GPU มากกว่าหนึ่งตัว เช่น gpu node ในระบบ TARA ก็จะได้ผลลัพธ์ออกมาเป็น

Let’s use 2 GPUs!

run the model

สั่งให้พิมพ์ขนาดของ input/output tensors ออกมาให้ดูด้วย

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

ผลลัพธ์เมื่อรันด้วย cpu node

ดังนั้นหาก machine ที่เราใช้ไม่มี GPU เช่น
รันใน compute node (tara-c-001) บนระบบ TARA แบบ sinteract จะได้ output ดังแสดงด้านล่าง ซึ่งจะพบว่าไม่มีการแบ่งข้อมูลออกไปเนื่องจากไม่มี GPU และเป็นการรันงานบน cpu

(venv-3DDL)[apiyatum@tara-c-001 segmed]$ python basic-multigpu-pytorch.py 
torch version :  1.9.0+cu102
cuda available? :  False
cuda version:  10.2
cuda device count:  0
cuda device id: 
	In Model: input size torch.Size([30, 5]) output size torch.Size([30, 2])
Outside: input size torch.Size([30, 5]) output_size torch.Size([30, 2])
	In Model: input size torch.Size([30, 5]) output size torch.Size([30, 2])
Outside: input size torch.Size([30, 5]) output_size torch.Size([30, 2])
	In Model: input size torch.Size([30, 5]) output size torch.Size([30, 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])
Outside: input size torch.Size([10, 5]) output_size torch.Size([10, 2])
(venv-3DDL)[apiyatum@tara-c-001 segmed]$

ผลลัพธ์เมื่อรันด้วย gpu node

และหากเครื่องที่ได้ใช้มี GPUs เช่น รันใน gpu node บนระบบ TARA (tara-g-001) แบบ sinteract จะได้ output แบบนี้

(venv-3DDL) [apiyatum@tara-g-001 segmed]$ python basic-multigpu-pytorch.py  
torch version :  1.9.0+cu102
cuda available? :  True
cuda version:  10.2
cuda device count:  2
cuda device id: , 0, 1
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])
(venv-3DDL) [apiyatum@tara-g-001 segmed]$ 

(big grin) ซึ่งจะเห็นได้ว่ามีการแบ่งข้อมูลไปรันโมเดลที่ GPUs ทั้งสองตัว

ทดสอบโปรแกรมบน HPC ด้วย sinteract

จากตัวอย่างข้างต้นที่ได้ทำการรันโมเดลให้ดู เกิดจากการเข้าถึงทรัพยากรแบบ sinteract เพื่อสามารถใช้งาน compute partition ต่างๆ ได้แบบ interaction สมกับชื่อของ sinteract โดยมีวิธีการดังนี้

[apiyatum@tara-frontend-1 segmed]$ module load Python

เนื่องจากเราจะใช้คำสั่ง python จึงเรียกใช้โมดูลไว้ก่อนเลย แล้วค่อยเลือก environment ที่เราได้ติดตั้งไว้สำหรับการรันโปรแกรมของเราด้วย virtualenv ซึ่งจะพาเราเข้าสู่ environment ที่ activate ขึ้นมา

ในที่นี้คือ venv-3DDL

[apiyatum@tara-frontend-1 segmed]$ source venv-3DDL/bin/activate

(venv-3DDL) [apiyatum@tara-frontend-1 segmed]$

เมื่อโปรแกรมและ package environment ที่ต้องการในการรันโปรแกรมครบถ้วนแล้วจึงเรียก sinteract ไปยัง compute partition ที่เราต้องการ เช่น gpu ด้วยคำสั่ง sinteract -p gpu แล้วทำการเลือกแหล่งตัดยอด Service Unit (SU) ซึ่งในตัวอย่างนี้เลือกโครงการที่ 6 จากนั้น slurm ได้ allocate resource ให้ ทำให้เราได้ย้ายจากเครื่อง tara-frontend-1 ไปยัง tara-g-001 แล้วจึงเริ่มทำการทดสอบโปรแกรมของเราบน compute node ที่ต้องการได้ในตัวอย่างข้างต้น

(venv-3DDL) [apiyatum@tara-frontend-1 segmed]$ sinteract -p gpu

No account specified. Please select account to charge from:

[1] pre0005

...

[6] thaisc

[q] Quit

Please type a selection: 6

Running interactive job using thaisc account

srun: job 1314560 queued and waiting for resources

srun: job 1314560 has been allocated resources

(venv-3DDL) [apiyatum@tara-g-001 segmed]$ python basic-multigpu-pytorch.py

Related articles

  • No labels