使用 PyInstaller 打包时找不到 SpaCy 模型

Can't find SpaCy model when packaging with PyInstaller

我正在使用 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

当您像此处那样使用 PyInstaller 将数据文件收集到捆绑包中时,这些文件实际上会编译成生成的 exe 本身。当评估 import 语句时,PyInstaller 对 Python 代码进行透明处理。

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

您将需要使用这个 API:

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

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