MPS 관련 문의드립니다!

이제 막 파이토치 공부를 시작한 대학원 생입니다.
원래 맥북으로 주로 공부를 해서 맥북으로 torch 공부를 해보고자 하는데 처음부터 막히는 부분이 있어 문의드립니다.

제 개발 환경은 아래와 같습니다.

MacBook Pro 14 with M1pro
PyTorch version == 1.13.1
python version == 3.9.13

책에서 나오는 예제를 따라서 코드를 작성했는데 오류가 있어 이렇게 문의 드립니다!

모델을 생성해서 학습을 진행하는데는 문제가 없는데 검증을 진행하면 아래 오류가 발생합니다.

혹시 해결방법이나 원인을 아시는 분 계시면 답글 부탁드립니다. 감사합니다.

모델 생성

class Model(nn.Module) : 

def __init__(self, embedding_size, output_size, layers, p=0.4):

    super().__init__()
    self.all_embeddings = nn.ModuleList([nn.Embedding(ni,nf) for ni, nf in embedding_size])
    self.embedding_dropout = nn.Dropout(p)

    all_layer = []
    num_cat_cols = sum((nf for ni, nf in embedding_size))
    input_size = num_cat_cols

    for i in layers:
        all_layer.append(nn.Linear(input_size, i))
        all_layer.append(nn.ReLU(inplace=True))
        all_layer.append(nn.BatchNorm1d(i))
        all_layer.append(nn.Dropout(p))
        input_size = i 

    all_layer.append(nn.Linear(layers[-1], output_size))

    self.layers =nn.Sequential(*all_layer)
    
def forward(self, x_cat) : 
    embeddings = []
    
    for i, e in enumerate(self.all_embeddings) :
        embeddings.append(e(x_cat[:,i]))

    x = torch.cat(embeddings, 1)
    x = self.embedding_dropout(x)
    x = self.layers(x)

    return x

모델 객체(instance) 생성

model = Model( cat_embdding_size, 4, [200, 100, 50], p=0.4)

Loss function and Optimizser 정의

loss_function = nn.CrossEntropyLoss()

optimizer = torch.optim.Adam(model.parameters(), lr=0.001)

device 설정

if torch.cuda.is_available() : device = torch.device('cuda')
elif torch.backends.mps.is_available() : device = torch.device('mps')
else : device=torch.device('cpu')
print(f'Using {device}')

모델 학습

epochs = 500 # 반복 횟수
aggregated_losses = []
train_outputs = train_outputs.to(device=device, dtype=torch.int64)

for i in range(epochs) :
    i += 1
    y_pred = model(cat_train_data).to(device)
    single_loss = loss_function(y_pred, train_outputs)
    aggregated_losses.append(single_loss)

    optimizer.zero_grad()
    single_loss.backward()
    optimizer.step()

print(f'epoch : {i:3} loss : {single_loss.item():10.10f}')

epoch : 500 loss : 0.5807338357

예측 실행

test_outputs = test_outputs.to(device=device, dtype=torch.int64)
cat_test_data = cat_test_data.to(device=device, dtype=torch.int64)

with torch.no_grad():
    y_val = model(cat_test_data).to(device)
    loss = loss_function(y_val, test_outputs).to(device)

print(f'Loss :{loss:.8f}')
print(y_val[:5])

RuntimeError Traceback (most recent call last)

9 with torch.no_grad():
—> 10 y_val = model(cat_test_data) # .to(device)
11 loss = loss_function(y_val, test_outputs) # .to(device)
13 print(f’Loss :{loss:.8f}')
RuntimeError: Placeholder storage has not been allocated on MPS device!

안녕하세요
올려 주신 코드에는 model의 device를 설정하는 부분이 없는 것으로 보입니다.
모델 파라미터를 mps로 우선 옮기셔야할 것 같습니다.

1개의 좋아요

답변 감사드립니다! 그런데 제가 처음 공부하는 중이라 혹시 model 파라미터를 mps 옮기라는 의미가 정확히 어떻게 설정을 하라는 말씀이실까요??

model = Model( cat_embdding_size, 4, [200, 100, 50], p=0.4)

이 부분에서 .to(device) 로 보내시면 될거 같아요

1개의 좋아요

답변 감사합니다. 기존에는 '모델 학습' 코드에서는 오류가 발생하지 않고 '예측 실행' 코드에서 오류가 발생 했었습니다. 그런데 말씀주신데로 설정을 바꿨을 때는 오히려 '모델 학습' 코드에서 부터 오류가 발생하고 있습니다. Model을 mps로 옮겼는데도 문제가 해결되지 않습니다 ㅜㅜ

안녕하세요, @kimgs8765 님.

PyTorch에서는 Tensor라는 자료형을 사용하는데요, 이 자료형은 numpy처럼 행렬 연산을 할 수 있으면서 GPU와 같은 장치를 활용하여 연산의 속도를 빠르게 할 수 있는 것이 특징입니다.

그리고, 입력/출력용 데이터 외에 인공 신경망도 내부에는 가중치(weight) 저장과 연산을 위해 Tensor 자료형들을 사용하고 있습니다. (Tensor에 대한 내용은 아래 튜토리얼을 더 참고해주세요.)


위에 올려주신 코드 중에 device 설정이라고 되어 있는 부분의 코드가 현재 사용 가능한 GPU 또는 MPS가 있으면 그것을 사용하고, 없으면 CPU라도 사용하도록 설정하는 부분입니다.


하지만, 이렇게 연산을 하려면 동일한 공간에 데이터들이 위치해야 합니다. (서울에 있는 망치로 대구에 있는 못을 두드릴 수는 없으니까요!)

위에 @Sung_Sue_Hwang 님과 @skywalker 님께서 말씀해주신 내용이 바로 이것인데요,
@kimgs8765 님께서 작성하신 코드의 학습 및 추론용 데이터들과 모델은 모두 동일한 장치에 위치해야 하는데 기존에는 학습용 데이터와 모델은 CPU에, 추론용 데이터는 MPS에 위치해서 발생했던 문제이고, 이후에는 학습용 데이터는 CPU에, 모델과 추론용 데이터는 MPS에 위치해서 발생하는 문제입니다.


설명이 길었는데, 모든 데이터를 사용하시기 전에 아래와 같이 데이터를 device로 옮겨주세요. :slight_smile:

답변 감사합니다. 덕분에 해결됐습니다. 모든 데이터와 모델을 mps로 이동하고 나니 정상 동작하였습니다. 감사합니다. 혹시 추가적으로 여쭤보고 싶은게 있습니다. 현재까지 mps에서 정장 작동하지 않는 model들이 있다고 알고 있는데 그것과 관련된 정보는 어디서 얻을 수 있을까요?

1개의 좋아요

네, MPS 장치에서 각 연산 메소드의 구현 여부를 정리하고 있는 이슈가 있는데, 업데이트나 정리가 엄청 잘 되어 있지는 않습니다;;

아마 궁금하신 것은 연산 레벨보다는 사용하시려는 모델 단위에서 mps 장치의 지원 여부일텐데요, 따로 정리된 문서가 있는지는 잘 모르겠습니다.

개인적으로는... 일단 사용하시려는 모델을 하나씩 돌려보시고, NotImplementedError가 발생한다면 위 공식 저장소의 이슈 목록에서 해당 연산의 구현 진행 여부를 확인해보시는 것이 조금 더 빠르게 진행해보실 수 있는 현실적인 방법이 아닐까 싶습니다. :sweat_smile: