使用PyInstaller打包含nnUNet的Python脚本时出现EOFError求助
PyInstaller打包nnUNet多进程应用出现EOFError问题咨询
问题背景
基于Windows系统,使用Python 3.8开发应用,依赖支持多进程的nnUNet库。脚本直接运行功能正常,但使用PyInstaller v5.7.0打包为.exe文件后,运行时抛出EOFError: Ran out of input错误。
报错堆栈信息
Traceback (most recent call last): File "main.py", line 344, in <module> File "nnunet\inference\predict.py", line 694, in predict_from_folder File "nnunet\inference\predict.py", line 496, in predict_cases_fastest File "nnunet\inference\predict.py", line 123, in preprocess_multithreaded File "multiprocess\process.py", line 121, in start File "multiprocess\context.py", line 224, in _Popen File "multiprocess\context.py", line 327, in _Popen File "multiprocess\popen_spawn_win32.py", line 93, in __init__ File "multiprocess\reduction.py", line 70, in dump File "dill\_dill.py", line 394, in dump File "pickle.py", line 487, in dump File "dill\_dill.py", line 388, in save File "pickle.py", line 603, in save File "pickle.py", line 717, in save_reduce File "dill\_dill.py", line 388, in save File "pickle.py", line 560, in save File "dill\_dill.py", line 1186, in save_module_dict File "pickle.py", line 971, in save_dict Traceback (most recent call last): File "main.py", line 341, in <module> File "pickle.py", line 997, in _batch_setitems File "D:\MyProject\venv\Lib\site-packages\PyInstaller\hooks\rthooks\pyi_rth_multiprocessing.py", line 49, in _freeze_support File "dill\_dill.py", line 388, in save spawn.spawn_main(**kwds) File "pickle.py", line 560, in save File "pickle.py", line 901, in save_tuple File "dill\_dill.py", line 388, in save File "multiprocessing\spawn.py", line 116, in spawn_main File "pickle.py", line 560, in save File "multiprocessing\spawn.py", line 126, in _main File "dill\_dill.py", line 1427, in save_instancemethod0 EOFError: Ran out of input [588] Failed to execute script 'main' due to unhandled exception! File "pickle.py", line 692, in save_reduce File "dill\_dill.py", line 388, in save File "pickle.py", line 560, in save File "pickle.py", line 886, in save_tuple File "dill\_dill.py", line 388, in save File "pickle.py", line 603, in save File "pickle.py", line 717, in save_reduce File "dill\_dill.py", line 388, in save File "pickle.py", line 560, in save File "dill\_dill.py", line 1186, in save_module_dict File "pickle.py", line 971, in save_dict File "pickle.py", line 997, in _batch_setitems File "dill\_dill.py", line 388, in save File "pickle.py", line 603, in save File "pickle.py", line 687, in save_reduce File "dill\_dill.py", line 388, in save File "pickle.py", line 560, in save File "dill\_dill.py", line 1698, in save_type File "dill\_dill.py", line 1070, in _save_with_postproc File "pickle.py", line 692, in save_reduce File "dill\_dill.py", line 388, in save File "pickle.py", line 560, in save File "pickle.py", line 901, in save_tuple File "dill\_dill.py", line 388, in save File "pickle.py", line 560, in save File "pickle.py", line 886, in save_tuple File "dill\_dill.py", line 388, in save File "pickle.py", line 560, in save File "dill\_dill.py", line 1698, in save_type File "dill\_dill.py", line 1084, in _save_with_postproc File "pickle.py", line 997, in _batch_setitems File "dill\_dill.py", line 388, in save File "pickle.py", line 603, in save File "pickle.py", line 717, in save_reduce File "dill\_dill.py", line 388, in save File "pickle.py", line 560, in save File "dill\_dill.py", line 1186, in save_module_dict File "pickle.py", line 971, in save_dict File "pickle.py", line 997, in _batch_setitems File "dill\_dill.py", line 388, in save File "pickle.py", line 603, in save File "pickle.py", line 717, in save_reduce File "dill\_dill.py", line 388, in save File "pickle.py", line 560, in save File "dill\_dill.py", line 1186, in save_module_dict File "pickle.py", line 971, in save_dict File "pickle.py", line 997, in _batch_setitems File "dill\_dill.py", line 388, in save File "pickle.py", line 578, in save File "PyInstaller\loader\pyimod01_archive.py", line 76, in __getattr__ AssertionError [4392] Failed to execute script 'main' due to unhandled exception!
自定义脚本代码片段
#============================== # main.py #============================== from multiprocessing import freeze_support from nnunet.inference.predict import predict_from_folder if __name__ == "__main__": freeze_support() ... predict_from_folder(...) ...
触发错误的nnUNet库代码片段
#============================== # nnunet\inference\predict.py #============================== def preprocess_multithreaded(trainer, list_of_lists, output_files, num_processes=2, segs_from_prev_stage=None): if segs_from_prev_stage is None: segs_from_prev_stage = [None] * len(list_of_lists) num_processes = min(len(list_of_lists), num_processes) classes = list(range(1, trainer.num_classes)) assert isinstance(trainer, nnUNetTrainer) q = Queue(1) processes = [] for i in range(num_processes): pr = Process( target=preprocess_save_to_queue, args=( trainer.preprocess_patient, q, list_of_lists[i::num_processes], output_files[i::num_processes], segs_from_prev_stage[i::num_processes], classes, trainer.plans['transpose_forward'] ) ) pr.start() ## <------------ 错误触发位置!!!!!!!!!!!!! processes.append(pr) try: end_ctr = 0 while end_ctr != num_processes: item = q.get() if item == "end": end_ctr += 1 continue else: yield item finally: for p in processes: if p.is_alive(): p.terminate() p.join() q.close() def predict_cases_fastest(...): ... pool = Pool(num_threads_nifti_save) ... preprocessing = preprocess_multithreaded( trainer, list_of_lists, cleaned_output_files, num_threads_preprocessing, segs_from_prev_stage ) ... pool.starmap_async(...) ... pool.close() pool.join() def predict_from_folder(...): ... return predict_cases_fastest(...) if __name__ == "__main__": ...
补充说明
已创建可复现问题的公开项目,项目内scripts文件夹包含安装、打包、运行脚本。怀疑问题源于nnUNet库内部,咨询是否可通过配置PyInstaller解决该问题。
内容的提问来源于stack exchange,提问作者El_Merendero
相关产品推荐
相关产品推荐

