You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 06:05:28