日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

python使用Pyinstaller如何打包整個項目_python

作者:Mabel-mql ? 更新時間: 2022-12-26 編程語言

使用Pyinstaller打包整個項目

今天真的被Pyinstaller給坑到了!!!

本文利用spec文件進行對整個項目進行打包,直接輸入命令打包也可以,但會出現比較多的問題。

1 .安裝Pyinstaller

pip install pyinstaller

2. 打開命令窗口

由于我這里是在Anaconda環境下創建的虛擬環境,因此要切換到對應的環境下,避免打包無關的包,同時切換到對于目錄下。

關于目錄,我這里是包含主文件、文件(各數據集的存放)以及同等級的py文件:

3. 生成 spec文件

執行以下命令:

pyi-makespec -w xxx.py(xxx.py文件為要執行的主文件,這里我是Insect_predict.py

4. 打開生成的spec文件

(這里是Insect_predict.spec),如下(一些需要自己添加:

#當出現出現"RecursionError: maximum recursion depth exceeded問題時,可能打包時出現了大量的遞歸超出了python預設的遞歸深度,需要添加如下三行。
import sys
import os.path as osp
sys.setrecursionlimit(5000)
#----------------------------------------------------------------
block_cipher = None

SETUP_DIR ='D:\\ssd-pytorch-mql\\'

#所有項目中的py文件路徑以列表形式寫入Analysis如下
#pathex定義了打包的主目錄,默認生成,只寫文件名
#當出現打包后執行程序時出現類似No Module named xxx,可以將模塊填入到hiddenimports中
#excludes不要什么文件
#data將非py文件的路徑與存放的文件夾名寫在元組里

a = Analysis(
  ['Insect_predict.py',
   'ssd.py','summary.py','voc_annotation.py','get_map.py',
  'D:\\ssd-pytorch-mql\\nets\\mobilenetv2.py',
  'D:\\ssd-pytorch-mql\\nets\\ssd.py',
  'D:\\ssd-pytorch-mql\\nets\\ssd_training.py',
   'D:\\ssd-pytorch-mql\\nets\\vgg.py',
    'D:\\ssd-pytorch-mql\\utils\\anchors.py',
    'D:\\ssd-pytorch-mql\\utils\\callbacks.py',
    'D:\\ssd-pytorch-mql\\utils\\dataloader.py',
    'D:\\ssd-pytorch-mql\\utils\\utils.py',
    'D:\\ssd-pytorch-mql\\utils\\utils_bbox.py',
    'D:\\ssd-pytorch-mql\\utils\\utils_fit.py',
    'D:\\ssd-pytorch-mql\\utils\\utils_map.py'],
  pathex=['D:\ssd-pytorch-mql'],
  binaries=[],
  datas=[(SETUP_DIR+'model_data','model_data'),(SETUP_DIR+'VOCdevkit','VOCdevkit'),(SETUP_DIR+'img','img')],
  hiddenimports=[],
  hookspath=[],
  hooksconfig={},
  runtime_hooks=[],
  excludes=['zmq','pandas','tensorflow'],
  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='Insect_predict',
  debug=False,
  bootloader_ignore_signals=False,
  strip=False,
  upx=True,
  console=False,
  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='Insect_predict',
)

以上內容是在生產spec文件后添加上去的,可根據自己文件內報錯進行修改。

5. 執行spec文件,在命令行輸入

pyinstaller -D xxx.spec或pyinstaller xxx.spec(我的后者才可以運行)

6.生成中出現的問題

若生成中遇到如圖所示,即可在spec文件里面添加 excludes=[zmq]或出現lib not found…含有必要包的,可以將后面的路徑添加到系統環境變量當中,我的這樣是可以的,暫時還沒有遇到模塊的問題,如果有遇到可

以考慮是否版本問題:

當執行完成會生產兩個文件夾dist和build,exe可執行文件就在dist文件里面。

一步一步解決,總是可以的!!!

使用pyinstaller打包pytorch踩的那些坑

花費了點時間,終于在自己的電腦上搞定了pyinstaller的安裝并且讓它成功打包了一些小程序之后,嘗試著用它打包pytorch這樣的復雜程序,結果遇到的問題遠比想象中要多,于是記個筆記,也避免后來人踩坑。

問題1:單個文件打包還是文件夾打包?

用pyinstaller打包pytorch的感覺就是大,這文件真的大……已經盡力用from import代替import之類的方式減少了導入的庫內容,但還是打包出了一個巨大無比的應用程序。

沒有使用upx壓縮的情況下,打包為文件夾需要3G,而打包為單個exe文件則是需要1.3G,怎么看好像都是打包成一個exe比較劃算的樣子……?

大錯特錯!

首先是啟動速度,打包為文件夾的情況下,啟動基本是秒啟動,但是打包為一整個exe文件,啟動就需要將近30s才能print出第一行提示語句……

其次,借著這次機會也正好了解了一下exe的運行機制,打包為整個exe文件之后,它每次運行都會把相當于整個文件夾的內容釋放到一個c盤的臨時文件夾中,而且它不會馬上刪除!

你問我為什么發現了這件事?因為試運行了幾次之后,我的C盤直接裂裂裂裂裂開了……

可憐弱小又無助的系統盤QvQ

經過測試發現,打包為整個文件夾的話,程序就會在當前路徑直接運行,而不會創造一個巨大無比的臨時文件在一次次運行中炸掉C盤,因此最后決定采用打包為一個文件夾的形式。

問題2:一起打包的數據文件找不到?

畢竟……是pytorch嘛,最終打包的肯定是只有測試模式的代碼,而不會把訓練模式的大段代碼都塞進exe里面,所以,希望把一個.pth的模型數據文件一起打包進去,這樣加載的網絡模型只要直接從模型里面讀數據就可以了。

很快,新的問題出現了,當把模型的路徑設置為當前路徑的時候,會出現一種非常詭異的情況:在本地計算機上運行正常,但是把整個打包好的文件夾放在別的電腦上運行的時候,它直接報錯說,找不到該文件!

你總不會是把絕對路徑給打包到exe里面去了吧???

好在查閱了一堆網絡資料后,發現這可能是運行路徑的問題,但是網上給出的寫法五花八門,大部分試了之后發現根本沒卵用, 另一個問題是,打包之后的文件夾過于雜亂,因此甚至想找到啟動程序的exe文件都需要滾輪往下滑好幾頁,尋思之后,干脆在整個文件夾外面寫一個.bat文件作為啟動腳本:

start 文件夾/啟動文件.exe

此時的目錄結構如圖所示:

|-測試工作區
? ? |-打包的整個項目文件夾
? ? ? ? |-打包后的數據文件
? ? ? ? |-打包后的啟動程序.exe
? ? |-用于啟動exe的腳本.bat

但是這又引出了新的問題:這個運行的路徑到底是臨時程序文件路徑,還是exe啟動程序路徑,還是bat腳本路徑???

我沒看懂,但我大受震撼.jpg

猜測半天不如進行實測,于是把網上五花八門的寫法都拉進來寫了個測試代碼打包到exe里面看看結果:

import os

print("當前程序路徑",os.getcwd(), os.path.exists(os.getcwd()+'\\'+G_model_path))
print("當前腳本路徑", sys.path[0], os.path.exists(sys.path[0]+'\\'+G_model_path))
print("當前默認所在路徑", os.path.abspath('.'), os.path.exists(os.path.abspath('.')+'\\'+G_model_path))
print('臨時執行路徑',os.path.split(os.path.realpath(__file__))[0], os.path.exists(os.path.split(os.path.realpath(__file__))[0]+'\\'+G_model_path))

每一行都會顯示這種寫法得到的路徑信息,與能否在這條路徑上找到打包到文件夾里面的數據文件。

首先嘗試直接雙擊exe啟動,得到結果:

當前程序路徑 測試工作區\打包的整個項目文件夾 True
當前腳本路徑 測試工作區\打包的整個項目文件夾\base_library.zip False
當前默認所在路徑 測試工作區\打包的整個項目文件夾 True
臨時執行路徑 測試工作區\打包的整個項目文件夾 True

然后試著用.bat啟動exe,得到結果:

當前程序路徑 測試工作區 False
當前腳本路徑 測試工作區\打包的整個項目文件夾\base_library.zip False
當前默認所在路徑 測試工作區 False
臨時執行路徑 測試工作區\打包的整個項目文件夾 True

實踐出真知,全部測試之后的結果表明,sys.path[0]就是渣渣! 在直接雙擊運行exe的時候,有三種措施都能起效,但是通過bat運行exe的時候,只有最后一種寫法

os.path.split(os.path.realpath(__file__))[0]才能找到正確的數據文件所在路徑。

問題3:GPU訓練的模型要放到CPU環境跑?

這個問題相對來說比較簡單,只需要修改加載模型參數的代碼。

G_model.load_state_dict(load(G_model_path))

改為G_model.load_state_dict(load(G_model_path, map_location=device('cpu')))

問題4:直接打包還是用spec文件配置?

推薦先生成spec文件,完成配置后重新打包

然后在test.spec中修改參數:

4.1 添加PYTHONPATH

如果你需要import項目根目錄中的文件夾作為庫,需要將文件夾路徑添加到該參數

必須用絕對路徑!相對路徑不生效!

pathex=['path']

4.2 添加數據文件

程序調用的相對路徑中的數據文件

datas=[(oldpath1, newpath1), (oldpath2, newpath2)]

4.3 手動添加沒有被識別到的調用庫

hiddenimports=['libs']

問題全部解決之后,程序運行正常√

總結

原文鏈接:https://blog.csdn.net/Rebacca122222/article/details/124440089

欄目分類
最近更新