PyInstaller打包可执行文件时修改Stanza模型加载路径的问询
解决方案
1. 让Stanza从可执行文件所在目录加载预打包模型
你报错的核心原因是两个:一是未显式指定Stanza的模型加载路径,默认会读取当前设备的用户目录;二是之前的打包参数只打包了对应语言的模型文件夹,遗漏了根目录下的resources.json文件。按以下步骤修改即可:
- 首先在代码中添加动态获取打包后模型路径的逻辑
import os import sys def get_packaged_stanza_path(): # PyInstaller打包运行时会自动生成_MEIPASS变量,指向临时解压目录 if getattr(sys, '_MEIPASS', False): base_path = sys._MEIPASS # 开发环境下直接读取本地模型目录 else: base_path = os.path.dirname(os.path.abspath(__file__)) # 路径要和打包参数里的目标路径一致 return os.path.join(base_path, 'Stanza')
- 初始化Stanza Pipeline时显式指定模型目录,关闭自动下载
nlp = stanza.Pipeline( lang='pt', model_dir=get_packaged_stanza_path(), download_method=None # 禁止自动下载,避免无网环境报错 )
- 修改PyInstaller打包参数,将整个模型根目录的所有内容打包
原参数只打包了pt文件夹,现在改为:--add-data "C:\Users\Laila\stanza_resources\*;Stanza"
确保resources.json和对应语言的模型文件夹都被打包进程序。
2. 内置stanza.download的可行性与路径修改
如果不想提前打包大体积的模型文件,让用户首次运行时自动下载是可行的,按以下方法修改下载路径到可执行文件同级目录:
- 先定义获取可执行文件所在目录的逻辑
import os import sys def get_custom_model_dir(): # 打包后取exe所在的目录 if getattr(sys, '_MEIPASS', False): exe_root = os.path.dirname(sys.executable) # 开发环境取脚本所在目录 else: exe_root = os.path.dirname(os.path.abspath(__file__)) # 自定义模型存放文件夹,会自动创建 save_path = os.path.join(exe_root, 'stanza_models') os.makedirs(save_path, exist_ok=True) return save_path
- 下载和初始化时都指定这个路径即可
model_path = get_custom_model_dir() # 下载模型到指定路径 stanza.download('pt', model_dir=model_path) # 初始化时读取同一路径的模型 nlp = stanza.Pipeline(lang='pt', model_dir=model_path)
注意:该方案要求用户首次运行时处于联网环境,且如果用户移动可执行文件到其他目录,下次运行会重新下载模型。
内容的提问来源于stack exchange,提问作者Laila Campos
相关产品推荐
相关产品推荐

