Out Of Memory
딥러닝 모델을 돌리다 보면 종종 OOM 에러가 뜨면서 프로그램이 중단되는 현상이 발생한다.
gpu내부 메모리가 꽉차서 발생하는 현상인데, 해결하기 어려운 이유들은 아래와 같다.
- 왜 발생했나? → 알기 어려움
- 그럼 어디서 발생했나? → 알기 어려움
- 어찌저찌 Error backtracking해봄 → 엉뚱한데로 감
- 실행하자마자 띡 하고 종료되는게 아니라 누적돼서 특정 시점에 빵하고 터진경우일수 있는데,
이럴때 중단 전 메모리 상황파악이 어려움.
등등,, 가지각색의 이유로 발생하는 OOM은 처리하기 까다롭지만 무시할수 있는 에러가 아니기 때문에 해결해야한다.
해결방법
우선, GPUUtil 사용해서 iter마다 메모리 쌓이는지 확인해보자
#!pip install GPUtil
import GPUtil
GPUtil.showUtilization()
GPUtil을 사용하면 각 iteration마다 메모리가 늘어나는지 확인 할 수 있다.
학습은 주로 epoch이란 iteration을 돌기 때문에 메모리가 누적돼서 OOM이 발생할 수 있다.
메모리가 쌓이는게 확인되면, 아래와 같은 조치를 취할 수 있다.
1. torch.cuda.empty.cache() 로 캐시 비우기
사용되지 않고있는 GPU상 cache를 처리하면 그만큼 가용 메모리가 생긴다.
del과는 다르다. 사용한 tensor를 지워도 캐시는 남아있으니 구분해서 사용해야 한다.
- : 느리다. 3-5s
사용한다면, 매 학습전에 torch.cuda.empty_cache()를 호출해 필요없는 캐시를 날려버리자.
2. Training Loos에서 Tensor로 축적되는 변수 바꾸기
total_loss = 0 #loss_sum 초기화
for i in range(100000):
optimizer.zero_grad()
output = model(input)
loss = criterion(output)
loss.backward()
optimizer.step()
total_loss += loss # 문제 지점!!
코드를 보면 total_loss에 loss가 계속 누적된다.
loss만 축적되는것이 아니라 미분에 필요한 computational graph가 계속 생성된다.
total_loss = l1 +l2 +l3 +l4 +....
이런 경우 , 아래와 같이 바꿔주면 된다.
total_loss += float(loss)
total_loss += loss.item()
3. del 명령어 사용
다쓴 변수는 del 키워드를 사용해서 적절하게 삭제해주자.
특히 파이썬은 loop이 끝나도 메모리에 남아있기 때문에 삭제해주면 메모리를 조금 벌 수 있다.
4. Batch size가 너무 클때
가능한 batch size를 실험해보자.
batch size를 1로 해서 실험해보면 배치사이즈에 따른 문제인지 알 수 있다.
oom = False
try:
run_model(batch_size)
except RunTimeError:
oom = True
if oom:
for _ in range(batch_size):
run_model(1)
5. Inference 시점에 torch.no_grad() 사용
학습시에는 BackProp을 위해 gradient를 사용해야하지만,
추론시점에는 gradient가 필요없다. 이럴때, torch.no_grad()를 사용해주자.
with torch.no_grad():
##추론 ~
'2021 네이버 부스트캠프 - Ai tech' 카테고리의 다른 글
Week_6 CV - Object Detection (0) | 2021.09.14 |
---|---|
Week_6 Knowledge Distilation (0) | 2021.09.10 |
Week_3 Pytorch - Dataset & Dataloader (0) | 2021.08.20 |
Week_3 Pytorch - Transfer Learning, 모델 저장 및 불러오기 (0) | 2021.08.19 |
Week_3 Pytorch - view vs. reshape (0) | 2021.08.17 |