개인 연구를 진행하다가, 연산량을 비교하는 과정이 필요하여 모델의 연산량을 구하는 FLOPS를 사용하고자 함.
https://github.com/NVIDIA/PyProf
GitHub - NVIDIA/PyProf: A GPU performance profiling tool for PyTorch models
A GPU performance profiling tool for PyTorch models - GitHub - NVIDIA/PyProf: A GPU performance profiling tool for PyTorch models
github.com
https://mulkkog.tistory.com/78
[NVIDIA PyProf] FLOPs 측정하기
PyProf란? NVIDIA에서 만든 profile 툴. PyTorch 모델과 GPU 성능을 profile한다. 1. GitHub로 설치하기 클론합니다 git clone https://github.com/NVIDIA/PyProf.git PyProf로 들어간 후 PyProf를 설치합니다 pip install . 잘 설치
mulkkog.tistory.com
https://programtalk.com/python-more-examples/ptflops.get_model_complexity_info/
ptflops.get_model_complexity_info Example
python code examples for ptflops.get_model_complexity_info. Learn how to use python api ptflops.get_model_complexity_info
programtalk.com
위의 블로그를 통해 본 포스팅의 github 코드를 받아 사용하였다.
import torchvision.models as models
import torch
from ptflops import get_model_complexity_info
with torch.cuda.device(0):
net = model명()
flops, params = get_model_complexity_info(net, (3, 32, 32), as_strings=False, print_per_layer_stat=False)
print(' FLOPs: {: < 8}'.format(flops))
print('{:<30} {:<8}'.format('Computational complexity: ', flops))
print('{:<30} {:<8}'.format('Number of parameters: ', params))
초기에 가이드라인(?)대로 적힌 코드를 그대로 사용하였더니 오류들이 발생하였다.
찾아보니, 필자가 비교하려는 모델에는 서로 입력값이 다른 2가지 input이 필요하였고, 그에 맞게 설정하고자 코드를 수정하였다.
https://github.com/sovrasov/flops-counter.pytorch/issues/14
not suport two input image network? · Issue #14 · sovrasov/flops-counter.pytorch
github.com
그렇게 구글링을 통해 찾은 방식이 바로 하단의 방식이다.
이때, 입력값이 서로 다르다면 resolution에 들어가는 값을 사용자가 원하는 입력값으로 변경해주면 된다.
class Siamese(nn.Module):
def __init__(self):
super(Siamese, self).__init__()
self.conv1 = nn.Conv2d(1, 10, 3, 1)
self.conv2 = nn.Conv2d(1, 10, 3, 1)
def forward(self, x):
# assume x is a list
return self.conv1(x[0]) + self.conv2(x[1])
def prepare_input(resolution):
x1 = torch.FloatTensor(1, *resolution)
x2 = torch.FloatTensor(1, *resolution)
return dict(x = [x1, x2])
if __name__ == '__main__':
model = Siamese()
flops, params = get_model_complexity_info(model, input_res=(1, 224, 224),
input_constructor=prepare_input,
as_strings=True, print_per_layer_stat=False)
print(' - Flops: ' + flops)
print(' - Params: ' + params)
ex)
def prepare_input(resolution):
x1 = torch.FloatTensor(1, 1, 512, 512)
x2 = torch.FloatTensor(1, 3, 512, 512)
return dict(x = [x1, x2])
그런데 이렇게 했음에도, 다음과 같은 오류들이 발생하였다.
<class 'TypeError'> : forward() got an unexpected keyword argument 'x’
TypeError: unsupported operand type(s) for //: 'NoneType' and 'int’
이중 하나는 ‘NoneType’이므로 연산이 불가능 하다는 것으로, 첫 번째에 발생한 오류인 forward() 매서드에 들어간 x 라는 인자를 해결해야 될 듯 하다고 판단하여 x가 들어간 위치를 찾아보았다.
생각보다 답은 가까운 곳이었으며 바로 위에서 사용된 dict(x = [x1, x2]) 이 부분을 수정해주면 되었다.
return dict(input_L = x1, denoise_R = x2)
처음에 말 하였듯, 모델에 들어가는 입력값이 총 2가지 인데, 입력값에 맞는 변수명으로 설정해주니 알맞게 동작함.
[최종적으로 사용한 코드]
def prepare_input(resolution):
x1 = torch.FloatTensor(1, 1, 512, 512)
x2 = torch.FloatTensor(1, 3, 512, 512)
return dict(input_L = x1, denoise_R = x2)
input1 = (1,512,512)
input2 = (3,512,512)
input = (input1,input2)
with torch.cuda.device(0):
net = 모델명()
macs, params = get_model_complexity_info(net, input_res=(input1,input2),
input_constructor=prepare_input,
as_strings=True,
print_per_layer_stat=True, verbose=True)
print('{:<30} {:<8}'.format('Computational complexity: ', macs))
print('{:<30} {:<8}'.format('Number of parameters: ', params))
따라서 필자가 최종적으로 사용한 코드는 다음과 같다.
원활하게 동작이 되지않아 fvcore도 사용해보았으나.. 결국은 ptflops로 동작이 되었다.
생각보다 어렵지 않았던 문제를.. (사실 본문에 적은 문제들 외에도 여러가지 문제들이 많이 일어났음)
3일이나 붙들고 있었다니..ㅠ
다른사람들은 나 같은 문제가 발생하지 않기를 바라며 글을 작성한다..
'대학원 > Python' 카테고리의 다른 글
[Linux] 현재 경로 표시가 안 뜰 경우 (0) | 2023.11.21 |
---|