본문 바로가기
파이썬 & 머신러닝

[CUDA] GPU 메모리는 할당되어 있는데 프로세스가 안 나올때

by 두재 2021. 5. 4.

사진은 없긴 한데 또 생기면 캡쳐해서 올리겠습니다.

 

nvidia-smi 는 GPU의 사용량을 모니터링하기 위해 사용합니다. 여기에는 GPU가 몇 개인지 어떤 GPU인지, 메모리는 얼마나 사용하고 있는지, 파워나 온도 등 여러 정보가 나옵니다.

추가로 

watch -n 1 nvidia-smi

를 터미널에 치면 1초마다 업데이트 됩니다. nvidia-smi를 1초마다 눌러라 라는 명령이라서요.

우리 연구실의 가장 큰 장점! 3090 두 개짜리랑 2080 Ti 4개짜리 두 서버 내가 다 쓰고 있다.

 

그런데 가끔 코드를 돌리다가 Ctrl + C를 통해서 코드를 Terminate 시킬 때 어떻게 잘못하게 되면 nvidia-smi의 위쪽 부분에서 분명 메모리는 할당되어 있는데 아래에 Process에는 아무것도 없는 상황이 생길 때가 있습니다. 이 때에는 실제로 다시 코드를 돌려보면 GPU Out of Memory가 뜨게 되어 실제로 메모리가 어딘가에 할당되어 있다는 것을 알 수 있습니다.

 

우선 해결법부터 알려드리겠습니다.

for i in $(sudo lsof /dev/nvidia1 | grep python  | awk '{print $2}' | sort -u); do kill -9 $i; done

위 명령어를 터미널에 치면 되고, /dev/nvidia1 에서 1이라는 숫자를 초기화시키고 싶은 GPU 아이디를 넣어주시면 됩니다. 그냥 그 GPU를 사용하는 프로세스들을 모두 죽이는 것입니다. linux에서 grep은 검색을 하는 명령이고 kill -9 는 프로세스 아이디에다가 kill 신호를 보내서 죽여버리는 것이라 위 코드는 단순히 파이썬 프로세스들을 다 찾아서 죽여버리는 것입니다. 그렇다면 왜 파이썬 프로세스들이 여러개가 생기는지를 생각해볼 수 있습니다.

 

 

그러면 언제 이런 일이 발생하느냐. 우선은 Pytorch에서 dataloader, 그 중에서도 num_workers 라는 파라미터가 중요합니다. 만약 num_worker 가 뭔지 모른다면 아마 이런 일을 겪지 않을 것입니다. Pytorch의 데이터로더는 배치 사이즈만큼 데이터를 불러오고 이들을 하나의 배치로 합쳐서 반환을 해줍니다. 그 후 이제 그 배치로 학습을 진행하는 것이죠. num_workers는 데이터를 불러오는 과정을 빠르게 하려는 것입니다. 코드 내에서 프로세스들을 더 여러 개 생성하여 (num_workers만큼) 그 프로세스들이 병렬적으로 데이터를 불러오게 되어 빨라지게 됩니다. num_workers 파라미터를 사용하여 코드를 돌리다가, Ctrl+C를 통해서 만약 코드를 중단시키게 되면 저 작은 프로세스들을 같이 중단시켜야해서 잠깐 시간이 걸립니다. 그래서 Ctrl+C를 누르면 코드가 바로 종료가 안되고 조금 시간이 걸리는데, 한 번 더 Ctrl+C를 누르게 되면 기다리는 그것조차 중단시켜버려서 bash에서 파이썬은 종료가 된 것처럼 보이지만 내부에서 작은 프로세스들이 제대로 종료되지 않게 됩니다. 그런데 Pytorch는 기본적으로 GPU 메모리를 다룰 때 지금 현재 모든 GPU 메모리를 사용하는 게 아니더라도 allocation을 통해서 공간을 미리 차지하게 되어 있습니다. 그래서 작은 프로세스들이 제대로 종료되지 않은 상황에서는 GPU 메모리는 allocation이 되어 있는데, 메인 코드는 아까 중단시켜버렸으니 nvidia-smi에서는 PID가 나오지 않습니다. 이 때 앞서 말한 위 코드를 통해서 직접 모든 process들을 찾아서 죽여버리는 방법이 있는 것입니다.

 

아마 num_workers 파라미터에 대해 전혀 모르신다면 아마 제가 말한 문제에 직면하지 않을 것입니다. 저도 1년 넘게 Pytorch를 쓰면서 최근에 저런 문제를 겪게 되었고 조금 찾아보니 해결법을 알게 되었습니다.

번외로 만약 그냥 nvidia-smi에서 프로세스 아이디가 보이는데 죽이고 싶으면

kill -9 PID숫자

이러면 됩니다.