PyInstaller打包含torch/torchvision项目遇RecursionError求助
PyInstaller打包torch/torchvision项目时RecursionError及程序无法正常关闭的解决方案
问题背景
打包人工智能项目时,执行pyinstaller --collect-all torchvision "/path/main-file.py"触发RecursionError: maximum recursion depth exceeded,排查确认只要代码中包含import torch就会报错,即使注释所有业务代码仅保留库导入也无法解决。环境配置如下:
pyinstaller 5.7.0, pyinstaller-hooks-contrib 2022.15, torch 1.13.1, torchvision 0.14.1, Python 3.10.6 Desktop: Xfce 4.16.0 Distro: Linux Mint 21 Vanessa base: Ubuntu 22.04 jammy
尝试在.spec文件中调高递归深度(如sys.setrecursionlimit(sys.getrecursionlimit() * 5))可完成打包,但程序启动后无法通过常规方式关闭;在主脚本中调整递归深度则无法解决原递归错误。
解决方案
1. 升级PyInstaller及钩子库
旧版本的PyInstaller钩子对torch的打包支持存在缺陷,优先升级依赖:
pip install --upgrade pyinstaller pyinstaller-hooks-contrib
新版本钩子通常已修复torch相关的递归打包问题,多数情况下升级后即可解决RecursionError。
2. 合理设置递归深度+添加资源清理逻辑
若升级后仍需调整递归深度,避免过度调高数值,同时添加退出清理逻辑解决程序无法关闭的问题:
- 修改.spec文件开头:
import sys sys.setrecursionlimit(2000) # 设为合理值,避免过度放大递归深度 - 在主脚本中添加退出清理函数:
该逻辑会在程序退出时自动清理torch资源,避免因资源泄漏导致的无法关闭问题。import atexit import torch import os import signal def cleanup_resources(): # 清理CUDA缓存(如果使用GPU) if torch.cuda.is_available(): torch.cuda.empty_cache() # 发送终止信号确保进程正常退出 os.kill(os.getpid(), signal.SIGTERM) atexit.register(cleanup_resources)
3. 排除不必要的torch子模块
部分torch子模块可能触发递归打包,根据项目需求排除冗余模块,减少打包压力:
pyinstaller --collect-all torchvision --exclude-module torch.distributed --exclude-module torch.testing "/path/main-file.py"
可根据项目实际使用情况调整排除的模块,比如不使用分布式训练则排除torch.distributed。
4. 使用干净虚拟环境打包
全局环境中多余的库可能干扰打包流程,创建虚拟环境重新安装依赖后再打包:
# 创建并激活虚拟环境 python -m venv torch-pack-env source torch-pack-env/bin/activate # 安装必要依赖 pip install torch==1.13.1 torchvision==0.14.1 pyinstaller pyinstaller-hooks-contrib # 执行打包命令 pyinstaller --collect-all torchvision "/path/main-file.py"
内容的提问来源于stack exchange,提问作者krolaper
相关产品推荐
相关产品推荐

