Pyinstaller numpy "Intel MKL FATAL ERROR: Cannot load mkl_intel_thread.dll" Pyinstaller numpy "Intel MKL 致命错误:无法加载 mkl_intel_thread.dll"

14

我是新手,正在尝试使用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并因此崩溃,出现以下错误:

Intel MKL FATAL ERROR:无法加载mkl_intel_thread.dll

mkl_intel_thread.dll不在软件目录中;但是,如果将该文件复制到程序的根目录中,我会收到相同的错误。

谢谢您的帮助


我遇到了类似的问题。但是错误显示“Intel MKL FATAL ERROR: Cannot load mkl_intel_thread.1.dll.”。我已经尝试查找mkl_intel_thread.1.dll,但却没有找到。只有mkl_intel_thread.dll。有什么解决方法吗? - RANGGAJAYA CIPTAWAN
我找到的最简单的解决方案是使用pip安装包(主要是numpy),而不是使用conda包。这种pip安装不包括mkl库。你可以在Pyinstaller官方github上找到已解决的问题。参考:https://github.com/pyinstaller/pyinstaller/issues/2270 - ariharan vijayarangam
9个回答

12

我在使用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' 所在的主文件夹中。


3
你能否详细说明一下?我也遇到了同样的问题,但我不理解如果我创建了hook.py并将其保存到C:\Python3*\Lib\site-packages\PyInstaller\hooks中,我该如何在我的代码中调用它以便它也可以读取文件? - muazfaiz
这对我来说几乎起作用了,但正如其他人指出的那样,还需要libiomp5md.dll,因此我修改了最后一行为:binaries = [(mkldir + "/" + mkl, '') for mkl in listdir(mkldir) if mkl.startswith('mkl_') or mkl.startswith('libio')]。 - Raj

3

哦,这就是为什么当我换电脑时,我的.exe突然轻了200MB的原因。它在这台电脑上无法正确找到二进制文件。 - Guimoute

1
我刚刚在Anaconda Navigator 2.1.0,pyinstaller 3.6,python 3.8.8和Windows 10上进行了测试。如上所述,pyinstaller不知道如何安装mkl_intel_thread.1.dll,因此当您运行新程序时会出现致命错误,提示找不到该DLL文件。
告诉pyinstaller从特定位置安装可以解决问题,可以在命令行或.spec脚本中指定。如果您已经安装了numpy,则几乎可以确定已经拥有了该DLL文件。由于Pyinstaller对规格说明很挑剔,因此这里提供两个示例:
  1. .spec script:

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

    pyinstaller  --add-binary '~\anaconda3\pkgs\mkl-2021.4.0-haa95532_640\Library\bin\mkl_intel_thread.1.dll;.' yourmodule.py
    
请注意命令行中的单引号和;.,因为这实际上是一个元组。

1
我刚刚将numpy+mkl更新到最新版本,你可以从这里下载numpy+mkl。

这也是我的解决方案。 - Regi Mathew
我尝试使用conda update numpy进行更新,但是没有成功。 - doublefelix

1
我创建了一个名为 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

谢谢。您的修复解决了我的问题。但是现在我意识到当我的应用程序调用与pyqtgraph相关的函数时,它会因为相同的错误而崩溃:Intel MKL致命错误:无法加载mkl_intel_thread.dll。 - f_ciriolo
这是一个不同的应用程序吗?它是否因相同的错误而崩溃? - LeonidR
不,同一个应用程序也包括pyqtgraph。现在当我执行由pyinstaller生成的exe时,它可以正常运行,直到调用使用pyqtgraph的函数后,就会崩溃并显示Intel MKL FATAL ERROR。在您修复之前,崩溃发生得更早。 - f_ciriolo
令人困惑的是,我的直觉告诉我您正在使用不同的Python软件包管理方案来管理pyqtgraphnumpy。我建议您构建一个单目录应用程序,然后使用跟踪跟踪运行它时加载哪些库。 - LeonidR
我正在使用默认设置的 one-dir 进行构建。抱歉,但我在 Python 中是新手,您所说的“用跟踪跟踪运行它”是什么意思?我需要跟踪可执行文件中的库加载还是原始的 .py 文件中的库加载? - f_ciriolo

1
的回答非常有帮助,但它可能存在错误。对于我来说,compat.base_prefix使用反斜杠,但它们会与"/Lib/site-packages/numpy/core"(正斜杠)连接起来。请注意保留HTML标签。
>>> 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扩展名的文件,然后将它们粘贴到你的程序目录中并重新运行。如果它能工作的话,那就太好了,但你可能需要逐个删除以找出哪些是必需的,哪些是不必要的。

0
我安装了两个版本的Python。一个是基本版本的Python,另一个是通过Anaconda安装的。运行我的机器学习脚本时它抛出了相同的错误。当我卸载其中一个版本(在我的情况下我删除了Anaconda)后,一切都正常了。我使用deeplearning4j作为库,显然它很难解决这个dll,因为有多个Python安装版本。

0

我使用了另一种解决方案。我只是用以下内容替换了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)

0

我更新了代码片段,使其能够与我的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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接