Programming Error/PyTorch

[Pytorch 에러] RuntimeError: legacy constructor expects device type: cpu but device type: cuda was passed & Input type (torch.cuda.ByteTensor) and weight type (torch.cuda.FloatTensor) should be the same

Barca 2021. 11. 22. 16:18

Pytorch를 Framework으로 사용할 때, 대부분 GPU를 사용하여 학습이나 추론을 수행하실 겁니다.

그러다보면 가끔 아래와 같은 오류를 만날 수 있는데요.

RuntimeError: Input type (torch.cuda.FloatTensor) and weight type (torch.FloatTensor) should be the same

 

여기서 Input type (torch.cuda.FloatTensor)는 입력(이미지, 텍스트 등)이 현재 GPU(cuda)에 올라가있는 상태이면서 Floating point가 Float32라는 것을 의미합니다. 반면에 weight type (torch.FloatTensor)은 사용하는 모델의 가중치 타입을 의미합니다. 따라서, 현재 모델은 .cuda가 안붙어있으므로 cpu에 있는 상태이며 가중치의 타입은 Float32라는 것을 의미합니다. 따라서, 위의 에러는 입력은 GPU에, 모델은 CPU에 올라가 있는 상태라 서로 연산이 되지 않아 에러가 나는 것입니다.

위 에러를 해결하려면 아래와 같은 방법으로 해결할 수 있습니다.

# 모델 to GPU
model.cuda()  # or model.to(device)

# 입력 to GPU
input = input.cuda()

 

그리고 비슷하게 같은 GPU나 CPU에 올라가있지만 아래와 같이 Floating point가 달라서 발생하는 경우도 있는데요.

RuntimeError: Input type (torch.cuda.ByteTensor) and weight type (torch.cuda.FloatTensor) should be the same

해당 에러는 입력이 0~255로 표현되는 Byte(uint8)형태이고, 반면 모델의 가중치는 Float32이기 때문에 발생하는 에러입니다. 따라서, 이런 경우는 입력 값을 아래와 같이 FloatTensor로 바꿔주어야합니다.

torch.FloatTensor(input, device='cuda')
or
torch.tensor(input, dtype=torch.float32, device='cuda')

 

그리고 저는 두 가지 방법 중 위의 방식과 같이 Float16 타입으로 바꾸어 주기위해 torch.HalfTensor()를 사용하다가 아래와 같은 에러를 발견했는데요. github issue에서 답변을 찾을 수 있었습니다.

RuntimeError: legacy constructor expects device type: cpu but device type: cuda was passed

두 가지 중 위의 방법은 모든 유형에 대해서 구현이 되어있지 않아서 발생하는 오류였습니다. 그냥 아래와 같은 방법으로 사용하면 해결되는 문제라고 언급되어 있었습니다.

torch.tensor(input, dtype=torch.float16, device='cuda')