前言:由于工作需求,需要使用Pyinstaller库将Python脚本打包成exe文件,特此花几天时间查找资料,进行实验。将过程做个梳理,记录下来,方便自己和他人日后查询。
目录
- 一、安装PyInstaller包
- 二、打包深度学习模型
- (1) 生成spec文件
- (2) 修改spec文件
- (3) 运行spec文件进行打包
- 三、常见问题分析
- 四、结论
PyInstaller_2">一、安装PyInstaller包
由于需要在Anaconda的虚拟环境中进行打包,因此最好将PyInstaller包安装在虚拟环境中,先激活虚拟环境,再用以下命令进行安装。
python">pip install pyinstaller
二、打包深度学习模型
(1) 生成spec文件
本文是利用spec文件对整个项目进行的打包,直接输入命令进行打包也可以,但是一般只适合简单的脚本文件,像深度学习模型的工程文件一般比较复杂,文件之间的引用会比较多,因此更加适合使用spec文件进行打包。首先切换到工程所在的目录下,然后激活模型运行需要的环境,本文为
python">conda activate aideploy
注:如果没有激活模型运行需要的虚拟环境就进行打包,打包之后的exe运行会出现找不到相关库的报错。
然后执行以下命令生成spec文件
python">pyi-makespec -w xxx.py
(其中xxx.py文件为需要执行的主文件,深度学习模型中一般为推理文件,本文中为demo.py),如下图所示即为在同级目录下生成的spec文件。
(2) 修改spec文件
默认生成的spec文件如下所示,由于我打包的主文件是demo.py,因此生成的spec文件名称为demo.spec,文件和demo.py在同一个文件夹下,初始的内容如下所示。
python"># -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(
['demo.py'],
pathex=[],
binaries=[],
datas=[],
hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
exe = EXE(
pyz,
a.scripts,
[],
exclude_binaries=True,
name='demo',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=True,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
)
coll = COLLECT(
exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='demo',
)
需要更改几个位置内容。
1、将打包文件引用到的文件夹其它文件的路径进行声明,如下图所示使用列表的形式给出。
python">a = Analysis(
['demo.py',
"E:\\深度学习部署相关\\DSFD-VGG16-EfficientNet-master\\data\\config.py",
"E:\\深度学习部署相关\\DSFD-VGG16-EfficientNet-master\\models\\factory.py",
"E:\\深度学习部署相关\\DSFD-VGG16-EfficientNet-master\\utils\\augmentations.py",
"E:\\深度学习部署相关\\DSFD-VGG16-EfficientNet-master\\models\\DSFD_efficient_b0.py",
"E:\\深度学习部署相关\\DSFD-VGG16-EfficientNet-master\\models\\DSFD_efficient_b1.py",
"E:\\深度学习部署相关\\DSFD-VGG16-EfficientNet-master\\models\\DSFD_resnet.py",
"E:\\深度学习部署相关\\DSFD-VGG16-EfficientNet-master\\models\\DSFD_vgg.py",
],
pathex=["E:\深度学习部署相关\DSFD-VGG16-EfficientNet-master"],
binaries=[("E:\深度学习部署相关\DSFD_Demo\weights\dsfd_face.pth", "weights")],
datas=[],
hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False,
)
2、其中pathex给出需要打包的模型文件夹路径。
3、data列表以元组的形式给出需要拷贝的其它非py文件(包括但不限于模型文件或测试图片),其中元组的形式为(“需要拷贝的数据绝对路径”, “拷贝到打包文件夹下的文件夹名称”)。具体如上图所示本文使用的demo.py需要从同级文件夹下的weights\dsfd_face.pth加载模型文件,因此我们打包之后会在打包文件夹下生成weights文件夹以及在其中拷贝过来的dsfd_face.pth模型文件,这样exe文件就可以直接调用模型文件,不用更改路径了。
4、关于hiddenimports以及excludes两个列表的修改,本人在打包过程中并未对其进行额外的修改。但是有些教程反应如果打包提示找不到相对应的包,可能需要添加相应字段。
(3) 运行spec文件进行打包
修改spec文件后直接如下调用如下命令进行打包,需要注意此时必须在激活模型运行所需虚拟环境的前提下进行打包,否者会出现找不到引用第三方库的报错。
python">pyinstaller -D demo.spec
但是上述命令有人反应会运行不成功,可以使用如下命令尝试。
python">pyinstaller demo.spec
打包成功将会在模型工程文件夹下新生成两个如图所示文件夹,build以及dist,我们所需的打包文件就下dist文件夹下。
三、常见问题分析
1、需要将深度学习代码运行环境激活,再进行模型打包,不然将导致找不到对应的包。运行生成的exe文件时也需要将对应的环境激活,不然报错找不到对应的第三方库的模块或者它的依赖文件,第三方库的模块文件在路径下可以找到,那就是未激活环境导致相关依赖文件找不到。
2、直接运行exe文件时如果运行不成功可能会出现闪退的问题,无法看到报错信息进行Debug,我们可以使用命令行运行exe文件,这样就可以看到输出信息,从而可以方便进行改错。
3、关于模型文件中引入的第三方库(比如torch、os、numpy)等库的打包,本人在实验中并不需要进行额外的声明,只要在激活虚拟环境的前提下进行打包,PyInstaller会自动将需要的第三方库打包到dist文件夹下。
四、结论
我们在打包模型的时候是单个文件打包还是文件夹打包?
用pyinstaller打包pytorch的感觉就是大,已经尽力用from import代替import之类的方式减少了导入的库内容,但还是打包出了一个巨大无比的应用程序。我的打模型打包为文件夹需要4.3G,而打包为单个exe文件则是需要1.5G,这样看好像是打包为exe文件更好,结构既简单占用空间又小,但是怎么会有这么十全十美的事呢?
首先是启动速度,打包为文件夹的情况下,启动基本是秒启动,但是打包为一整个exe文件,启动就需要将近30s才能print出第一行提示语句……
其次,打包为整个exe文件之后,它每次运行都会把相当于整个文件夹的内容释放到一个c盘的临时文件夹中,而且它不会马上删除!试运行了几次之后,你的C盘就会爆炸,而打包为文件夹,每次运行就只会再打包的文件夹下运行。
经过几天的研究本人发现使用PyInstaller打包模型文件只是可以方便不会使用Python脚本的研究人员使用,并不适用于工作中实际任务的深度学习模型部署(无论是速度还是占用空间,都不满足要求)。
本文已尽量把具体过程记录详细,但可能各位读者参考教程还是会遇到各种各样的问题,欢迎大家留言讨论。