Сбой преобразования в Pyinstaller exe - использование lightgbm и sklearn - PullRequest
1 голос
/ 08 апреля 2019

Я пытаюсь преобразовать свой код в исполняемый файл, используя спецификацию pyinstaller. Изначально произошел сбой Pyinstaller по следующей причине:

main__.PyInstallerImportError: Failed to load dynlib/dll 
'C:\\Users\\...\\lightgbm\\../compile\\lib_lightgbm.dll'. Most probably this 
dynlib/dll was not found when the application was frozen.

Я попытался исправить это, добавив следующую строку в мой список pathex в спецификации:

'myenv\\lib\\site-packages\\lightgbm'

Примечание: myenv - это мой virtualenv, созданный для этого проекта.

Что привело к ImportError для sklearn. Я добавил sklearn к скрытому импорту. Это моя последняя спецификация:

# -*- mode: python -*-
import sys
sys.setrecursionlimit(5000)

block_cipher = None


a = Analysis(['myscript.py'],
             pathex=['C:\\project_folder', 'myenv\\lib\\site-packages\\lightgbm'],
             binaries=[],
             datas=[('lib_lightgbm.dll', '.')],
             hiddenimports=['cython', 'sklearn', 'sklearn.feature_extraction','sklearn.pipeline', 'sklearn.ensemble', 'sklearn.neighbors.typedefs', 'sklearn.neighbors.quad_tree', 'sklearn.tree._utils'],
             hookspath=[],
             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='myscript',
          debug=False,
          bootloader_ignore_signals=False,
          strip=False,
          upx=True,
          console=True )
coll = COLLECT(exe,
               a.binaries,
               a.zipfiles,
               a.datas,
               strip=False,
               upx=True,
               name='myscript')

Это приводит к ошибке, которую я нахожу очень странной:

File "myenv\lib\site-packages\lightgbm\sklearn.py", line 9, in <module>
ImportError: attempted relative import with no known parent package
[12692] Failed to execute script myscript

Понятия не имею, зачем искать sklearn.py внутри lightgbm? Внутри lightgbm есть sklearn.py, но я не уверен, как исправить эту ошибку. Кроме того, в папке dist / myscript нет папки sklearn. В идеале это должно было присутствовать. Я попытался вручную скопировать папку sklearn, хотя, как и предполагалось, это не имело никакого значения. Может кто-нибудь, пожалуйста, дайте мне знать, где файл спецификации не так?

1 Ответ

0 голосов
/ 02 июля 2019

Давайте вернемся к первой вашей ошибке.Эта ошибка говорит о том, что lib_lightgbm.dll не было замечено, когда ваше приложение было заморожено.

Предполагая, что вы запускаете pyinstaller из Windows cmd.exe, вы можете исправить это, передав хуй для lightgbm в pyinstaller, чтобы он знал, кудаполучить его, например,

pyinstaller --additional-hooks-dir dir_with_lightgbm_hook --hidden-import lightgbm myscript.py

Имя хука должно быть hook-lightgbm.py, а его содержимое вы можете посмотреть здесь: https://github.com/pyinstaller/pyinstaller/blob/develop/PyInstaller/hooks/hook-numpy.py, оно должно быть примерно таким же.Просто убедитесь, что библиотека добавлена ​​в список двоичных файлов, т.е.

binaries.append((os.path.join(os.path.dirname(
get_module_file_attribute('lightgbm')), "lib_lightgbm.dll"), "lightgbm"))

Второй аргумент "lightgbm" - это место, куда будет скопирован DLL-файл, относительно вашего каталога дистрибутива, так что в вашем случаев итоге он должен выглядеть как dist\myscript\lightgbm\lib_lightgbm.dll.

Примечание : добавление lib_lightgbm.dll через ловушку заставит pyinstaller добавить зависимости для него в дистрибутив, поэтому лучше сделать это следующим образомэто не просто копирование вручную.

Второе примечание : при копировании дистрибутива на другой компьютер вам может потребоваться установить соответствующий распространяемый пакет Visual Studio, используемый библиотекой (например, распространяемый VS 2015)).

РЕДАКТИРОВАТЬ: Забыл упомянуть, что если вы делаете это так, вы можете удалить путь, который вы добавили к своему pathex.

...