8/5
문제: M1 macbook Pro에서 MPS로 코드 돌리려고 하는데 에러발생
해결: 저번에 device 를 mps로 설정했을때 계속해서 오류가 나오던 이유는 torchsummary 때문이었습니다.
from torchsummary import summary
model = FCL().to(DEVICE)
summary(model, input_size=(1, 28, 28))
>>> 버그 발생 O
from torchsummary import summary
summary(model, input_size=(1, 28, 28))
model = FCL().to(DEVICE)
>>> 버그 발생 x
summary 와 model의 순서를 바꿨을때 버그가 발생 안하는것을 보고 summary에 문제가 있을거라고 예상했고
아래처럼 torchsummary 의 summary에서 device=”mps”로 설정했을 때
summary(model, input_size(1, 28, 28), device='mps')
>>> AssertionError: Input device is not valid, please specify ‘cuda’ of ‘cpu’
에러메세지가 뜨는것을 보고 문제를 확신했습니다
좀 더 찾아보니 torchsummary에서 업데이트된 torchinfo를 발견했고 이걸로 코드를 실행시켜보니 에러 없이 잘 작동하였으나 gpu 전력사용량이 전혀 올라가지 않는게 이상해서 이것저것 확인해본 결과
model.to(DEVICE)
print('model before summary: ', next(model.parameters()).device)
>>> model before summary: mps:0
summary(model, input_size=(1, 28, 28))
print('model after summary: ', next(model.parameters()).device)
>>> model after summary: cpu
가 출력되어서 이런 결론에 도달했습니다.
summary() 호출 시 모종의 이유로 mps로 넘어간 model이 다시 cpu로 돌아온다. 따라서 summary로 모델을 먼저 확인하고 model.to(DEIVCE) 를 호출하자
그래서 summary를 먼저 확인하고 model.to(DEVICE) (여기서 DEVICE=mps) 로 넘기고 코드를 실행하니 문제없이 작동했고 터미널에 아래 코드로 gpu의 전력사용량을 확인해보니 (GPU idle residency %)
sudo powermetrics —samplers gpu_power -i 1000
GPU 전력사용량이 증가하여 GPU를 사용해서 Pytorch코드를 돌리는것에 성공했습니다.
#성공적으로 MNIST MLP를 M1 Pro Macbook에서 훈련시킨 코드
import torch
import torch.optim as optim
import torch.nn as nn
from torchvision import transforms, datasets
from torchinfo import summary
# from torchsummary import summary 이건 mps device를 지원 안함
class FCL(nn.Module):
def __init__(self):
super().__init__()
self.fc1 = torch.nn.Linear(1 * 28 * 28, 500, bias=True)
self.relu = torch.nn.ReLU()
self.fc2 = torch.nn.Linear(500, 500, bias=True)
self.fc3 = torch.nn.Linear(500, 10, bias=True)
def forward(self, x):
x = torch.flatten(x, 1)
x = self.relu(self.fc1(x))
x = self.relu(self.fc2(x))
out = self.fc3(x)
return out
USE_MPS = torch.backends.mps.is_available()
if USE_MPS:
print("Using MPS as DEVICE")
DEVICE = torch.device("mps")
else:
print("MPS isn't available. Using CPU as DEVICE")
DEVICE = torch.device("cpu")
model = FCL()
print(model)
'''
summary() 호출 시 모종의 이유로 mps로 넘어간 model이 다시 cpu로 돌아온다.
따라서 summary로 모델을 먼저 확인하고 model.to(DEIVCE) 를 호출하자
model.to(DEVICE)
print('model before summary: ', next(model.parameters()).device)
summary(model, input_size=(1, 28, 28))
print('model after summary: ', next(model.parameters()).device)
'''
summary(model, input_size=(1, 28, 28))
model.to(DEVICE)
EPOCHS = 100
BATCH_SIZE = 50
train_loader = torch.utils.data.DataLoader(
datasets.MNIST('../data',train=True, download=False, transform=transforms.Compose(
[transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,))]
)),
batch_size=BATCH_SIZE, shuffle=True)
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.5)
criterion = nn.functional.cross_entropy
print('Batch ', BATCH_SIZE)
print('Total Epoch ', EPOCHS)
print('Total Iterations ', len(train_loader) * EPOCHS)
print()
iteration = 0
min_loss = 10e6
print(min_loss)
for epoch in range(EPOCHS):
for batch_idx, (data, target) in enumerate(train_loader):
data, target = data.to(DEVICE), target.to(DEVICE)
output = model(data)
loss = criterion(output, target)
loss.backward()
optimizer.step()
optimizer.zero_grad()
iteration += 1