728x90
Traceback (most recent call last):
File "C:\\Users\\Administrator\\Desktop\\gpf\\GPF_24_team\\pretrain-gnns\\chem\\pretrain_edgepred.py", line 112, in <module>
main()
File "C:\\Users\\Administrator\\Desktop\\gpf\\GPF_24_team\\pretrain-gnns\\chem\\pretrain_edgepred.py", line 103, in main
train_acc, train_loss = train(args, model, device, loader, optimizer)
File "C:\\Users\\Administrator\\Desktop\\gpf\\GPF_24_team\\pretrain-gnns\\chem\\pretrain_edgepred.py", line 32, in train
for step, batch in enumerate(tqdm(loader, desc="Iteration")):
File "C:\\ProgramData\\anaconda3\\envs\\gpf_3_9_19\\lib\\site-packages\\tqdm\\std.py", line 1181, in __iter__
for obj in iterable:
File "C:\\ProgramData\\anaconda3\\envs\\gpf_3_9_19\\lib\\site-packages\\torch\\utils\\data\\dataloader.py", line 368, in __iter__
return self._get_iterator()
File "C:\\ProgramData\\anaconda3\\envs\\gpf_3_9_19\\lib\\site-packages\\torch\\utils\\data\\dataloader.py", line 314, in _get_iterator
return _MultiProcessingDataLoaderIter(self)
File "C:\\ProgramData\\anaconda3\\envs\\gpf_3_9_19\\lib\\site-packages\\torch\\utils\\data\\dataloader.py", line 927, in __init__
w.start()
File "C:\\ProgramData\\anaconda3\\envs\\gpf_3_9_19\\lib\\multiprocessing\\process.py", line 121, in start
self._popen = self._Popen(self)
File "C:\\ProgramData\\anaconda3\\envs\\gpf_3_9_19\\lib\\multiprocessing\\context.py", line 224, in _Popen
return _default_context.get_context().Process._Popen(process_obj)
File "C:\\ProgramData\\anaconda3\\envs\\gpf_3_9_19\\lib\\multiprocessing\\context.py", line 327, in _Popen
return Popen(process_obj)
File "C:\\ProgramData\\anaconda3\\envs\\gpf_3_9_19\\lib\\multiprocessing\\popen_spawn_win32.py", line 93, in __init__
reduction.dump(process_obj, to_child)
File "C:\\ProgramData\\anaconda3\\envs\\gpf_3_9_19\\lib\\multiprocessing\\reduction.py", line 60, in dump
ForkingPickler(file, protocol).dump(obj)
AttributeError: Can't pickle local object 'DataLoaderAE.__init__.<locals>.<lambda>'
PS C:\\Users\\Administrator\\Desktop\\gpf\\GPF_24_team\\pretrain-gnns\\chem> Traceback (most recent call last):
File "<string>", line 1, in <module>
File "C:\\ProgramData\\anaconda3\\envs\\gpf_3_9_19\\lib\\multiprocessing\\spawn.py", line 116, in spawn_main
exitcode = _main(fd, parent_sentinel)
File "C:\\ProgramData\\anaconda3\\envs\\gpf_3_9_19\\lib\\multiprocessing\\spawn.py", line 126, in _main
self = reduction.pickle.load(from_parent)
EOFError: Ran out of input
원인
- Python - multiprocessing 모듈 사용할 때 발생
- multiprocessing 모듈이 로컬 함수 or 람다 함수 같이 피클 (pickle)할 수 없는 객체를 직렬화하려 시도할 때 발생
코드
def train(args, model, device, loader, optimizer):
model.train()
train_acc_accum = 0
train_loss_accum = 0
for step, batch in enumerate(tqdm(loader, desc="Iteration")):
- train() 함수에서 loader 호출
loader = DataLoaderAE(dataset, batch_size=args.batch_size, shuffle=True, num_workers = args.num_workers)
- loader는 DataLoaderAE 클래스
- num_workers = 8 (default) 로 설정되어있음. → 멀티프로세싱
class DataLoaderAE(torch.utils.data.DataLoader):
def __init__(self, dataset, batch_size=1, shuffle=True, **kwargs):
super(DataLoaderAE, self).__init__(
dataset,
batch_size,
shuffle,
collate_fn=lambda data_list: BatchAE.from_data_list(data_list),
**kwargs)
dataloader.py > class DataLoaderAE
- 람다 함수는 피클링 불가하기 때문에 멀티프로세싱 환경에서 전달하면 안 됨.
- 그런데 DataLoaderAE 클래스에서 collate_fn 에 람다 함수가 사용되고 있던 것!
해결1: 멀티프로세싱 하지마.
- num_workers = 0 으로 셋팅하면 됨.
- 단, 데이터 로드-전처리 병렬 처리 불가 ⇒ 학습 속도 느려짐 ⇒ 싫어 !!
해결2: 람다 함수를 일반 함수로 변경하기
# dataloader.py line 56 ~, DataLoaderAE 부분
def __init__(self, dataset, batch_size=1, shuffle=True, **kwargs):
super(DataLoaderAE, self).__init__(
dataset,
batch_size,
shuffle,
collate_fn=self.my_collate_fn,
**kwargs)
@staticmethod
def my_collate_fn(data_list):
return BatchAE.from_data_list(data_list)
- collate_fn 에서 람다 함수 제거하고 함수로 바로 매핑
- 이 때 이 함수 my_collate_fn()는 정적 메서드로 정의
- 정적 메서드 → 피클링 가능함.
피클링이란?
python에서 객체를 직렬화(serialize)하는 과정.
직렬화: python 객체(리스트, 딕셔너리, 클래스 인스턴스 등) → 바이트 스트림 형태
역직렬화: 바이트 스트림 → python 객체 (→ 언피클링)
직렬화된 바이트 스트림은 파일로 저장하거나 네트워크를 통해 전송할 수 있음.
언제 사용하는가?
- 데이터 저장, 네트워크 통신, 병렬 처리 시에 사용
- 병렬 처리 - 멀티프로세싱 환경에서 프로세스 간 객체 전달할 때 사용됨!
제한 사항
- 피클링할 수 없는 객체: 파이썬 파일 핸들, 네트워크 소켓, 람다 함수
- → 실행 환경에 종속적 or 메모리 주소에 기반한 객체이기 때문!
- 보안 위험: 신뢰할 수 없는 데이터 언피클링 하는 것 조심 ~~
파이썬 multiprocessing 모듈
- 프로세스 간 데이터 주고받을 때 피클링 사용.
- → 멀티프로세싱 환경에서 전달되는 모든 객체는 피클링 가능해야 함.
- → 람다 함수, 로컬 함수 등 있으면 오류
'Programming Language > Python' 카테고리의 다른 글
[파이썬] 문자 아스키코드 구하기/알파벳 순서대로 번호 붙이기/문자<-> 숫자 바꾸기 - ord(), chr(), int(), str() (0) | 2023.07.17 |
---|