首页 > 解决方案 > 使用 PyInstaller 打包时找不到 SpaCy 模型

问题描述

我正在使用 PyInstaller 将 python 脚本打包到 .exe 中。该脚本使用 spacy 加载以下模型:en_core_web_sm. 我已经跑到python -m spacy download en_core_web_sm本地下载模型了。问题是当 PyInstaller 尝试打包我的脚本时,它找不到模型。我收到以下错误:Can't find model 'en_core_web_sm'. It doesn't seem to be a Python package or a valid path to a data directory.我想这可能意味着我需要在我的 python 脚本中运行下载命令以确保它具有模型,但是如果我让我的脚本下载模型它只是说要求已经满足. 我还有一个处理引入隐藏导入的钩子文件,并且应该也引入模型:

from PyInstaller.utils.hooks import collect_all, collect_data_files

datas = []
datas.extend(collect_data_files('en_core_web_sm'))

# ----------------------------- SPACY -----------------------------
data = collect_all('spacy')

datas.extend(data[0])
binaries = data[1]
hiddenimports = data[2]

# ----------------------------- THINC -----------------------------
data = collect_all('thinc')

datas.extend(data[0])
binaries += data[1]
hiddenimports += data[2]

# ----------------------------- CYMEM -----------------------------
data = collect_all('cymem')

datas.extend(data[0])
binaries += data[1]
hiddenimports += data[2]

# ----------------------------- PRESHED -----------------------------
data = collect_all('preshed')

datas.extend(data[0])
binaries += data[1]
hiddenimports += data[2]

# ----------------------------- BLIS -----------------------------

data = collect_all('blis')

datas.extend(data[0])
binaries += data[1]
hiddenimports += data[2]

# ----------------------------- STDNUM -----------------------------

data = collect_all('stdnum')

datas.extend(data[0])
binaries += data[1]
hiddenimports += data[2]

# ----------------------------- OTHER -------------------------------

hiddenimports += ['srsly.msgpack.util']

我使用以下代码下载模型,然后使用 PyInstaller 打包脚本:

os.system('python -m spacy download en_core_web_sm')
PyInstaller.__main__.run([path_to_script, '--onefile', '--additional-hooks-dir=.'])

hook-spacy.py 脚本与 PyInstaller 正在打包的脚本位于同一目录中。

如果我在本地运行脚本,所有这些都有效。它会找到应有的模型。如果我尝试使用 PyInstaller 打包脚本并尝试运行 .exe,我只会收到此错误。

我正在使用 Python v3.8.7、PyInstaller v4.2 和 spacy v3.0.3 和 en_core_web_sm v3.0.0

标签: pythonpyinstallerspacy

解决方案


当您像在这里一样使用 PyInstaller 将数据文件收集到包中时,这些文件实际上被编译到生成的 exe 本身中。在评估导入语句时,PyInstaller 会透明地处理 Python 代码。

但是,对于数据文件,您必须自己处理。例如,spacy 可能会在当前工作目录中寻找模型。它不会找到您的模型,因为它被编译到 .exe 中,因此不存在于当前工作目录中。

您将需要使用此 API:

https://pyinstaller.readthedocs.io/en/stable/spec-files.html#using-data-files-from-a-module

这允许您从 PyInstaller 创建的 exe 中读取数据文件。然后您可以将其写入当前工作目录,然后 spacy 应该能够找到它。


推荐阅读