python - 使用 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
解决方案
当您像在这里一样使用 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 应该能够找到它。
推荐阅读
- reactjs - 等待 fetchQuery - 反应悬念
- .net-core - 如何在 EFCore5 中查询属性包实体类型?
- spring-boot - 在依赖项 jar 中定位 Amqp
- java - 如何在不创建新对象的情况下使用其他类中的方法
- javascript - Instagram iOS webview 和位置:固定为 100% 高度
- java - 带有导航 ui android 的折叠工具栏
- android - 在 Kotlin 中将位图保存为图像
- java - 如何在 Spring Boot 中创建一个有效的 TCP Server 套接字以及如何处理传入的消息?
- azure - 有没有办法删除在 Android 上使用 Xamarin 进行 Azure Active Directory B2C 注册身份验证期间出现的自定义浏览器框架?
- r - R studio:编写一个 for 循环以将自定义函数应用于输入向量,并为该向量中的每个元素输出一个单独的数据帧