Pyinstaller numpy "Intel MKL FATAL ERROR: Cannot load mkl_intel_thread.dll"

Pyinstaller numpy "Intel MKL FATAL ERROR: Cannot load mkl_intel_thread.dll"

我是 python 个应用程序的新手。我正在尝试使用 pyinstaller 构建我的 python GUI 应用程序。 我的应用程序依赖于以下软件包:PyQt4、numpy、pyqtgraph、h5py。 我正在使用 WinPython-32bit-3.4.4.1.

我使用此命令构建应用程序:

pyinstaller --hidden-import=h5py.defs --hidden-import=h5py.utils --hidden-import=h5py.h5ac --hidden-import=h5py._proxy VOGE.py

我使用 pyinstaller 创建的 dist 目录中的 exe 文件启动我的应用程序,它似乎工作正常,直到程序调用 numpy 并因以下错误而崩溃:

英特尔 MKL 致命错误:无法加载 mkl_intel_thread.dll

软件目录中不存在 mkl_intel_thread.dll;但是将文件复制到程序的根目录后,我得到了同样的错误

感谢您的帮助

我刚 运行 遇到了同样的问题。作为解决方法,我手动复制了 DLL,如

中所述

不过我正在努力寻找更好的解决方案。

我创建了一个hook-numpy.py来处理这个问题:

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

libdir = compat.base_prefix + "/lib"
mkllib = filter(lambda x : x.startswith('libmkl_'), listdir(libdir))
if mkllib <> []: 
   logger = logging.getLogger(__name__)
   logger.info("MKL installed as part of numpy, importing that!")
   binaries = map(lambda l: (libdir + "/" + l, ''), mkllib)

就我而言,conda 正在安装 mkl 库以加快 numpyscipy

我在使用 Pyinstaller 和 Numpy 时遇到了同样的问题。默认情况下,pyinstaller 似乎不考虑 numpy 二进制文件,因此您必须手动指定它。您可以添加编辑“.spec”文件 "binaries" 变量的文件,但这仅适用于您当前的程序。如果你想让它适用于你冻结的所有程序,你应该制作一个 "hook" 并将其保存在 C:\Python3*\Lib\site-packages\PyInstaller\hooks.

我必须修改 LeonidR 的代码才能使 numpy-hook 正常工作。我使用列表理解使用更现代的 pythonic 方法重写了它:

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

mkldir = compat.base_prefix + "/Lib/site-packages/numpy/core" 
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_')] 

"Binaries" 是一个元组列表。元组的第二项对应于要放置 'dlls' 的文件夹。在这种情况下是空的,因此它会将它们直接复制到“.exe”所在的主文件夹中。

j4n7 的回答非常有帮助,但是,它可能有也可能没有错误。 compat.base_prefix 使用反斜杠(至少对我而言),但它们随后与 "/Lib/site-packages/numpy/core"(正斜杠)连接。

>>> from PyInstaller import compat
>>> compat.base_prefix
'C:\Python34'
>>> mkldir = compat.base_prefix + "/Lib/site-packages/numpy/core"
>>> mkldir
'C:\Python34/Lib/site-packages/numpy/core'

如您所见,它在路径中同时生成正斜杠和反斜杠。

以下是我将 numpy mkl 文件捆绑到一个文件中的步骤。请注意,我的特定应用程序使用 matplotlib,我遇到的问题是每次单击按钮 (tkinter) 执行绘图时,应用程序都会崩溃。

步骤

首先:使用以下方法构建您的应用程序:

pyinstaller --onefile --windowed yourpythonappnamehere.py

其次:打开.spec文件,添加这个。显然首先要确保以下文件确实存在。您可能没有 Python34 所以只是一个友好的警告,不要盲目复制。

mkl_dlls = [('C:\Python34\Lib\site-packages\numpy\core\mkl_avx.dll', ''),
 ('C:\Python34\Lib\site-packages\numpy\core\mkl_avx2.dll', ''),
 ('C:\Python34\Lib\site-packages\numpy\core\mkl_avx512.dll', ''),
 ('C:\Python34\Lib\site-packages\numpy\core\mkl_core.dll', ''),
 ('C:\Python34\Lib\site-packages\numpy\core\mkl_def.dll', ''),
 ('C:\Python34\Lib\site-packages\numpy\core\mkl_intel_thread.dll', ''),
 ('C:\Python34\Lib\site-packages\numpy\core\mkl_mc.dll', ''),
 ('C:\Python34\Lib\site-packages\numpy\core\mkl_mc3.dll', ''),
 ('C:\Python34\Lib\site-packages\numpy\core\mkl_rt.dll', ''),
 ('C:\Python34\Lib\site-packages\numpy\core\mkl_sequential.dll', ''),
 ('C:\Python34\Lib\site-packages\numpy\core\mkl_tbb_thread.dll', ''),
 ('C:\Python34\Lib\site-packages\numpy\core\mkl_vml_avx.dll', ''),
 ('C:\Python34\Lib\site-packages\numpy\core\mkl_vml_avx2.dll', ''),
 ('C:\Python34\Lib\site-packages\numpy\core\mkl_vml_avx512.dll', ''),
 ('C:\Python34\Lib\site-packages\numpy\core\mkl_vml_cmpt.dll', ''),
 ('C:\Python34\Lib\site-packages\numpy\core\mkl_vml_def.dll', ''),
 ('C:\Python34\Lib\site-packages\numpy\core\mkl_vml_mc.dll', ''),
 ('C:\Python34\Lib\site-packages\numpy\core\mkl_vml_mc2.dll', ''),
 ('C:\Python34\Lib\site-packages\numpy\core\mkl_vml_mc3.dll', ''),
 ('C:\Python34\Lib\site-packages\numpy\core\libiomp5md.dll', '')]

第三个:其中显示binaries=None,更改为binaries=mkl_dlls

a = Analysis(['yourpythonappnamehere.py'],
             pathex=['C:\Users\...\Documents\...'],
             binaries=mkl_dlls,
             datas=None,
             ....

第四步:重新运行第一步。构建应用程序后,进入 dist 文件夹并启动您的应用程序。希望对你有用!

更新:如果你得到 Intel MKL FATAL ERROR: Cannot load mkl_intel_thread.dll 但你可以清楚地看到 mkl_intel_thread.dll 在您的程序目录中,转到 numpy/core 并复制所有您没有的扩展名为 .dll 的文件并将它们粘贴到您的程序目录中,然后重新 运行。如果有效,那就太好了,但您可能希望一次删除一个,以确定哪些是您需要的,哪些不需要。

我更新了代码片段以使其与我的 anaconda 安装一起使用(路径不同):

from PyInstaller import log as logging
from PyInstaller import compat
from os import listdir
from os.path import join

mkldir = join(compat.base_prefix, "Library", "bin")
binaries = [(join(mkldir, mkl), '') for mkl in listdir(mkldir) if mkl.startswith('mkl_')]

更新:这仅适用于 windows。我还看到 github 上有一个 PR 有更准确的修复。看到这个 Commit

我安装了 2 个版本的 Python。 Python 的一种基本版本和 Anaconda 安装的一种。当 运行 我的机器学习脚本时,它抛出了同样的错误。当我卸载两个版本之一(在我的例子中我删除了 Anaconda)时,一切都再次正常工作。我使用 deeplearning4j 作为库,显然它很难解析这个 dll,因为安装了多个 Python 安装。

我刚刚更新了numpy+mkl到最新版本,你可以从here

下载numpy+mkl

我使用了另一种解决方案。我只是将 hok-numpy.core.py 替换为以下内容,这基本上是在完成其他所有操作后手动获取 mkl dll 路径。

#-----------------------------------------------------------------------------
# Copyright (c) 2013-2020, PyInstaller Development Team.
#
# Distributed under the terms of the GNU General Public License (version 2
# or later) with exception for distributing the bootloader.
#
# The full license is in the file COPYING.txt, distributed with this software.
#
# SPDX-License-Identifier: (GPL-2.0-or-later WITH Bootloader-exception)
#-----------------------------------------------------------------------------
# If numpy is built with MKL support it depends on a set of libraries loaded
# at runtime. Since PyInstaller's static analysis can't find them they must be
# included manually.
#
# See
# https://github.com/pyinstaller/pyinstaller/issues/1881
# https://github.com/pyinstaller/pyinstaller/issues/1969
# for more information
import os
import os.path
import re
from PyInstaller.utils.hooks import get_package_paths
from PyInstaller import log as logging 
from PyInstaller import compat

binaries = []

# look for libraries in numpy package path
pkg_base, pkg_dir = get_package_paths('numpy.core')
re_anylib = re.compile(r'\w+\.(?:dll|so|dylib)', re.IGNORECASE)
dlls_pkg = [f for f in os.listdir(pkg_dir) if re_anylib.match(f)]
binaries += [(os.path.join(pkg_dir, f), '.') for f in dlls_pkg]

# look for MKL libraries in pythons lib directory
# TODO: check numpy.__config__ if numpy is actually depending on MKL
# TODO: determine which directories are searched by the os linker
if compat.is_win:
    lib_dir = os.path.join(compat.base_prefix, "Library", "bin")
else:
    lib_dir = os.path.join(compat.base_prefix, "lib")
if os.path.isdir(lib_dir):
    re_mkllib = re.compile(r'^(?:lib)?mkl\w+\.(?:dll|so|dylib)', re.IGNORECASE)
    dlls_mkl = [f for f in os.listdir(lib_dir) if re_mkllib.match(f)]
    if dlls_mkl:
        logger = logging.getLogger(__name__)
        logger.info("MKL libraries found when importing numpy. Adding MKL to binaries")
        binaries += [(os.path.join(lib_dir, f), '.') for f in dlls_mkl]
        logger.info(lib_dir)

libdir = 'C:/Users/bcubrich/.conda/envs/pyInstPermit/Library/bin' #<--- path to mkl dlls
for path in os.listdir(libdir):
    if path.startswith('mkl'):
        mkl=libdir+'/'+path
        final_path=os.path.normpath(mkl.replace('/','\'))
        binaries.append((final_path,'.'))
        logger = logging.getLogger(__name__)    
#logger.info(binaries)
#logger.info(final_path)

刚刚使用 Anaconda Navigator 2.1.0、pyinstaller 3.6、python 3.8.8、Windows 10 进行了测试。如上所述,pyinstaller 不知道安装 mkl_intel_thread.1.dll 所以当您 运行 新程序提示找不到 DLL 时出现致命错误。

它可以在命令行或 .spec 脚本中告诉 pyinstaller 从特定位置安装。如果你已经安装了 conda numpy,你几乎肯定有 DLL。 Pyinstaller 对规范很挑剔,所以这里有两个例子:

  1. .spec 脚本:

    binaries=[('~\anaconda3\pkgs\mkl-2021.4.0-haa95532_640\Library\bin\mkl_intel_thread.1.dll', '.')]
    
  2. 命令行:

    pyinstaller  --add-binary '~\anaconda3\pkgs\mkl-2021.4.0-haa95532_640\Library\bin\mkl_intel_thread.1.dll;.' yourmodule.py
    

注意命令行上的单引号和 ;. 因为这实际上是一个元组。