티스토리 뷰

한줄 요약 "num_workers" 옵션을 0 또는 1로 주지 않고 임의의 숫자로 지정했다면 0또는 1로 수정하고 다시 돌려볼 것

 

진짜 야랄맞은 경험을 했다.

torch의 dataloader를 이용해서 데이터를 불러올 때 보통 for문을 이용한다. 아래처럼

train_dataset = dataset(df_train ...)
train_loader  = torch.utils.data.DataLoader(train_dataset, 
					    batch_size=4, 
                            	    	    shuffle=True, 
                                            num_workers=0, 
                                            drop_last=True)
                                            
for i, (data) in enumerate(train_loader):
	print(data)

 

그런데 보통 때는 이러면 data가 출력이 되는데, 이건 뭐 에러메세지도 없이 데이터 출력도 안되고, 그렇다고 파이썬이 중단되면서 어떤 에러 메세지를 출력해 주는 것도 아닌 것이 그냥 무한루프를 돌고 있는 것 처럼 아무런 실행 결과가 출력이 안되는 것 아닌가?

for문 내부에서 print(i)를 통해서 for문 자체는 돌아가고 있는지 확인을 해봤으나, 정말 신기하게도 아예 for문 자체가 돌아가지 않고 for문에서 코드가 halt된 채로 영문을 알 수 없이 멈춰버리니 이건 뭐 해결할 방법을 도저히 찾을 수가 없었다.

한참을 고생했고, 해결방안은 DataLoader의 num_workers를 2를 주고 있던 코드가 문제였다. 이것을 0으로 고쳤더니 문제없이 실행이 되었다.

 

왜 이런 현상이 발생하는가? 

일단 이런 현상의 이유는 multithreading issue로 유추함. 내가 비전공자다보니 로그파일같은거 뜯어보고 그런건 일절 할줄 몰라서 명확한 이유는  알 수 없었다. 다만 아마도 Deadlock이 발생하지 않았나 유추한다. 코드 내부에서 데이터를 불러오는 방식에서 multiple threads를 사용할 경우, 다음과 같은 에러들이 발생 할 수 있단다.

1. race condition

: 데이터를 import하는 과정이 check and act라고 하자, check 과정은 내가 불러올 데이터를 확인하는 과정이고, act 과정이 데이터를 import하는 과정이라고 하자, multi thread로 인해 cpu1은 check과정을 진행 후, act로써 import를 하려는데 이 사이에 cpu2가 다른 task로부터 import되려던 데이터를 변경해버리면 cpu1은 엉뚱하게 변한 data를 import하게 된다. 

2. Deadlock

: lock occurs when multiple processes try to access the same resource at the same time. lock은 많은 threads들이 동시에, 같은 데이터에 접근할 때 생긴다고 한다.

예를들어 process가 진행되기 위해서 cpu1과 cpu2, task A와 task B가 필요하다고 하자.

  1. cpu1이 task A를 점유했다.
  2. cpu1과 cpu2가 task B를 시작하려 한다. (lock 발생)
  3. cpu2가 task B를 선점해버린다.
  4. task B는 task A를 통해 이뤄지는데 task A는 cpu1이 선점해버렸다. (Deadlock 발생)
  5. cpu1에 의해 halt된 task A에 의해 task B는 실행되지 않고 무한정 기다린다.
댓글