iT邦幫忙

2021 iThome 鐵人賽

DAY 10
1
AI & Data

機器學習與前端網頁系列 第 10

Day 10 打包 python 程式-2

打包 python 程式是個大坑,現在沒有一個 python 打包器能完美打包所有 python 程式,尤其是機器學習函式庫。

我覺得難以打包的其中一個原因是因為 python 的特性...
動態語言,經常使用其他語言的函式庫,以及執行期間 import。
總之,pyinstaller 抓不到一些執行時需要的 dll,那麼來找吧。


我們可以根據這篇的解法,獲得 mkl_ 的 dll 位置,並加入到打包程式中。
https://stackoverflow.com/questions/35478526/pyinstaller-numpy-intel-mkl-fatal-error-cannot-load-mkl-intel-thread-dll

但兩邊的環境不同,他 的mkl_ dll 放在 /Lib/site-packages/numpy/core,而我的在

(以下的 spec 檔是 pyinstaller 在第一次打包時建立的設定檔,雖然附檔名是.spec 但實際上是當 python 執行的。)
打開 a01_flask_server.spec 並修改。

# a01_flask_server.spec
# -*- mode: python ; coding: utf-8 -*-

block_cipher = None


from PyInstaller import log as logging 
from PyInstaller import compat
from os import listdir

mkldir = compat.base_prefix + "\\Library\\bin" 
logger = logging.getLogger(__name__)
logger.info("MKL installed as part of numpy, importing that!")
binaries = [(mkldir + "\\" + mkl, '.') for mkl in listdir(mkldir) if mkl.startswith('mkl_')] 

a = Analysis(['a01_flask_server.py'],
             pathex=['D:\\vscode\\ithelp'],
             binaries=binaries,
             datas=[],
             hiddenimports=[],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher,
             noarchive=False)
...

Analysis 中的 binaries 會在打包時將指定的檔案(二進位檔)放入資料夾,而在這裡我們就是要將缺少的 dll 放進去。
他的參數格式是 [("來源檔案或資料夾路徑", "目標資料夾夾路徑"), ("另一個來源", "另一個目標")...]

重新打包後讓我們再試著執行一次...

工作一樣,在你的 python 安裝路中找到並加進去。
binaries.append((compat.base_prefix +
"\Lib\site-packages\tensorflow\lite\experimental\microfrontend\python\ops",
"tensorflow\lite\experimental\microfrontend\python\ops"))

下一個

這次是函式庫不是檔案,所以要加的是這裡

hiddenimports=["keras.api"]

下一個

hiddenimports=["keras.api", "keras.api._v2"]

下一個...我還以為我需要把 keras 所有子模塊都寫進去。
這次是我程式的問題,它找不到要讀取的模型。

預設情況如果讀取檔案沒寫路徑,會尋找執行時時的當下路徑(如果使用捷徑開啟就會是捷徑的路徑),
這裡要把他改成相對於程式的路徑。
並且在打包時自動包進去。

# a06_mnist_api.py
import os
saved_model_path = os.path.dirname(__file__) + "\\mnist" + "\\mnist"

# a00_flask_server.spec
a = Analysis(['a01_flask_server.py'],
             pathex=['D:\\vscode\\ithelp'],
             binaries=binaries,
             datas=[("mnist", "mnist")],
             hiddenimports=["keras.api", "keras.api._v2"],
             hookspath=[],
             ...

這樣應就好...了?

我想得太美了。

剩下的明天繼續...


上一篇
day 9 打包 python 程式
下一篇
Day 11 打包 python 程式-3
系列文
機器學習與前端網頁30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
長風青雲
iT邦新手 4 級 ‧ 2021-09-25 18:11:34

那你要不要寫一個 可以讓他完美打包的程式啊~

我要留言

立即登入留言