Data/머신러닝 & 딥러닝

OOM (Out Of Memory) 해결 방법

빛날희- 2022. 1. 27. 13:55

▶ OOM

OutOfMemory, 학습을 시키다보면 적지않게 마주치는 에러이다. 이 에러를 보면 배치 사이즈를 줄이거나 캐시를 비우는 방식으로 처리했었는데 그 이외의 방법들(?)도 알게되어 포스팅으로 정리해보려한다. 

 

GPUtil 활용하기 

- iter마다 메모리가 늘어나는지 확인할 수 있는 모듈이다.
- nvidia-smi처럼 GPU 상태를 보여주는 모듈이다. 다만 nvidia-smi는 현재시점의 스냅샷을 보여줄 순 있지만 iteration이 돌아가며 쌓이는 메모리는 보여줄 수 없다. 반면 GPU util은 이를 보여줄 수 있다.

- nvidia smi output 예시

아래와 같이 특정 timestamp에 해당하는 gpu의 상태를 확인할 수 있다.

https://developer.nvidia.com/nvidia-system-management-interface

- GPUtil 예시

아래와 같이 GPU ID, 사용하고 있는 GPU, memory상태를 볼 수 있다. 

import GPUtil
GPUtil.showUtilization()
 ID  GPU  MEM
--------------
  0    0%   0%

 

 

 torch.cuda.empty_cache()

- 사용되지 않는 gpu상의 캐시를 정리해 가용메모리를 확보하는 함수이다. 예시로 backward에서 쌓여 쓰이지 않는 미분값들을 지워줄 때 사용가능하다. 
- 헷갈리지 말자. del은 변수와 메모리간의 관계를 끊어주는 함수다. 

- 예시

우선 del로 lst변수와 리스트에 있는 값의 메모리 주소 간 연결을 끊어주면, 해당 메모리는 어떤 변수도 가리키지 않는 영역이다. pytorch는 이 영역을 자동으로 탐지할 수 있다. 따라서 그 탐지된 영역의 메모리를 해제하는 함수가 empty_cache이다.

lst=[]
for x in range(5):
	lst.append(torch.randn(10000,5).cuda())
# lst와 lst에 담긴 값들의 메모리 연결을 끊어준다. 
del lst
# garbage collection, 필요없어진 메모리를 해제한다.
torch.cuda.empty_Cache()
더보기

 

 trainning loop에 tensor로 축적되는 변수 확인

- tensor 변수는 gpu메모리를 사용한다.
- loop안에 연산이 있으면 computational grpah를 생성해서 메모리를 차지한다. 

더보기

+ computational graph란?

아래와 같이 연산에 해당하는 노드와 그래프로 수학적 표현을 나타내는 방법이다. 

계산 그래프

이 역시 메모리를 차지한다. 따라서 아래 링크에 나와있는 것처럼 메모리가 덜 필요한 모델의 경우, 계산그래프가 메모리에서 차지하는 최댓값을 정해 이를 제한하는 방법도 있는 것 같다. 

https://discuss.pytorch.org/t/memory-consumption-of-computation-graph/50619

 

Memory consumption of computation graph

Is there a way to determine how much memory the computational graph of a tensor occupies in memory? This is important to know sometimes for memory-bottlenecked networks as one can move the network to a less memory hungry model (if such model exists) but wi

discuss.pytorch.org


- 따라서, 1 d tensor의 경우 .item 혹은 float()을 통해 기본 객체로 변환해 처리한다. 
- 또는 필요 없어진 변수는 del 을 통해 적절한 시점에 메모리를 풀어줄 수 도 있다. 

 

 

 torch.no_grad()

inference에선 필요하지 않은 backward pass를 실행시키지 않음으로써 메모리를 확보한다. 

 

 

 이외.. 

device-side assert triggeredCUDNN_STATUS_NOT_INITIALIZED 에러가 뜰 때, 그 원인이 될 수 있는 것들과 해결방안을 정리해놓은 포스팅이 있다. 학습을 시키다가 해당 에러가 발생하면 이 포스팅을 참고하면 될듯하다.

'Data > 머신러닝 & 딥러닝' 카테고리의 다른 글

CNN 모델 훑어보기  (0) 2022.02.08
Partial Dependence Plot (PDP) 란?  (1) 2022.02.04
Custom Dataset tutorial - Fashion MNIST  (0) 2022.01.25
순전파와 역전파  (0) 2022.01.20
그레디언트와 경사하강법  (0) 2021.08.06