AI 개발 공부 공간

AI, 머신러닝, 딥러닝, Python & PyTorch, 실전 프로젝트

딥러닝/딥러닝: PyTorch

PyTorch 10 : CPU와 GPU사용

qordnswnd123 2025. 1. 19. 13:53

1. CPU와 GPU

1) CPU와 GPU

컴퓨터 시스템에서 가장 핵심적인 구성 요소 중 두 가지는 중앙 처리 장치(Central Processing Unit, CPU)와 그래픽 처리 장치(Graphics Processing Unit, GPU)입니다.

  • CPU : CPU는 컴퓨터의 핵심적인 두뇌로서, 다양한 종류의 작업을 처리할 수 있는 범용 처리 장치입니다. CPU의 코어 수는 일반적으로 제한적이지만, 각 코어는 복잡한 명령어를 빠르게 처리하는 데 최적화되어 있습니다.
  • GPU : GPU는 원래 3D 그래픽스 및 이미지 처리를 위해 개발되었으나, 현재는 딥러닝과 고성능 계산에도 중요한 역할을 합니다. GPU는 수천 개의 작은 코어를 가지고 있으며, 각 코어는 상대적으로 간단한 연산을 수행합니다. 이러한 구조 덕분에 GPU는 병렬 데이터 처리에 매우 효과적이며, 대량의 데이터 병렬 처리에 적합합니다. 딥러닝에서는 많은 양의 데이터를 복잡한 수학적 연산이 필요하기 때문에, GPU는 훈련 시간을 대폭 줄이는 핵심 요소가 됩니다.

2) GPU의 종류

  • CUDA: CUDA는 NVIDIA에서 개발한 GPU 가속 컴퓨팅 플랫폼입니다. 대량의 병렬 연산이 필요한 고성능 계산 작업에 적합합니다. 파이토치에서 CUDA를 사용하려면 먼저 시스템에 NVIDIA GPU가 설치되어 있어야 하며, 해당 GPU가 CUDA를 지원해야 합니다.
  • MPS: MPS는 Apple이 개발한 GPU 기반의 가속 라이브러리로, Metal 프레임워크를 사용하여 iOS, macOS 기기의 GPU에서 고성능 그래픽 및 컴퓨팅 작업을 수행합니다. MPS는 주로 Apple 기기에서 딥러닝 모델과 같은 복잡한 연산을 가속화하는 데 사용됩니다.

3) GPU 확인 코드

  • 'CUDA' 사용 가능 확인
if torch.cuda.is_available():
    device = torch.device('cuda')
else:
    device = torch.device('cpu')

print(device)
  • 'MPS' 사용 가능 확인
if torch.backends.mps.is_available():
    device = torch.device('MPS')
else:
    device = torch.device('cpu')

print(device)

 


2. GPU로 이동

1) 텐서를 GPU로 이동

tensor = torch.randn(1, 2)
tensor_device = tensor.to(device)

print('텐서의 위치: ', tensor_device.device)

 

2) 딥러닝 모델을 GPU로 이동

import torch.nn as nn

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.fc1 = nn.Linear(28*28, 512)
        self.fc2 = nn.Linear(512, 256)
        self.fc3 = nn.Linear(256, 10)

    def forward(self, x):
        x = x.view(-1, 28*28)
        x = torch.relu(self.fc1(x))
        x = torch.relu(self.fc2(x))
        x = self.fc3(x)
        return x

model = Net().to(device)

 

3) 딥러닝 모델 학습을 GPU 사용

import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import TensorDataset, DataLoader

# GPU 사용 설정
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

# 랜덤 데이터 및 레이블 생성
input_size = 100
hidden_size = 128
output_size = 10
num_samples = 1000

# 신경망 모델 정의
class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.fc1 = nn.Linear(input_size, hidden_size)
        self.fc2 = nn.Linear(hidden_size, hidden_size)
        self.fc3 = nn.Linear(hidden_size, output_size)

    def forward(self, x):
        x = torch.relu(self.fc1(x))
        x = torch.relu(self.fc2(x))
        return self.fc3(x)
features = torch.randn(num_samples, input_size)
labels = torch.randint(0, output_size, (num_samples,))

# TensorDataset과 DataLoader 생성
dataset = TensorDataset(features, labels)
train_loader = DataLoader(dataset=dataset, batch_size=64, shuffle=True)

model = Net().to(device)

# 손실 함수 및 옵티마이저 설정
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
features = torch.randn(num_samples, input_size)
labels = torch.randint(0, output_size, (num_samples,))

# TensorDataset과 DataLoader 생성
dataset = TensorDataset(features, labels)
train_loader = DataLoader(dataset=dataset, batch_size=64, shuffle=True)

model = Net().to(device)

# 손실 함수 및 옵티마이저 설정
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
# 학습
model.train()
epochs = 20
for epoch in range(epochs):
    model.train()
    for inputs, labels in train_loader:
        inputs, labels = inputs.to(device), labels.to(device)

        # 순전파
        outputs = model(inputs)
        loss = criterion(outputs, labels)
        
        # 역전파 및 최적화
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        
    print(f'Epoch [{epoch+1}/{epochs}], Loss: {loss.item():.4f}')

# 평가
model.eval()
with torch.no_grad():
    correct = 0
    total = 0
    for inputs, labels in train_loader:
        inputs, labels = inputs.to(device), labels.to(device)
        outputs = model(inputs)
        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()

    print(f'Accuracy of the network on the 1000 random samples: {100 * correct / total}%')
Epoch [1/20], Loss: 2.3096
Epoch [2/20], Loss: 2.2572
Epoch [3/20], Loss: 2.1926
Epoch [4/20], Loss: 2.1574
Epoch [5/20], Loss: 2.0156
Epoch [6/20], Loss: 1.9850
Epoch [7/20], Loss: 1.6819
Epoch [8/20], Loss: 1.6325
Epoch [9/20], Loss: 1.4901
Epoch [10/20], Loss: 1.4094
Epoch [11/20], Loss: 1.3323
Epoch [12/20], Loss: 1.0594
Epoch [13/20], Loss: 0.9573
Epoch [14/20], Loss: 0.7424
Epoch [15/20], Loss: 0.6244
Epoch [16/20], Loss: 0.3884
Epoch [17/20], Loss: 0.3291
Epoch [18/20], Loss: 0.3396
Epoch [19/20], Loss: 0.2331
Epoch [20/20], Loss: 0.1640
Accuracy of the network on the 1000 random samples: 100.0%