使用joblib加载跨子目录模型时遇ModuleNotFoundError求助
解决joblib加载模型时的ModuleNotFoundError问题
问题原因
用joblib保存模型时,会记录模型类所属的模块路径。如果训练模型时是直接在model_folder目录下运行脚本,模型类的__module__属性会被记录为model_folder.model;但加载模型时,Python的模块搜索路径里找不到直接名为model_folder的模块(它是package下的子包),所以抛出ModuleNotFoundError。另外你之前尝试sys.path.append('package/model_folder/model.pkl')是错的——sys.path要加的是目录路径,不是文件路径。
解决方案
方案1:修改训练时的模块导入方式(推荐)
训练模型时,从根目录运行训练脚本,用完整包路径导入模型类,确保joblib保存的模块路径正确:
比如在根目录新建训练脚本train.py:
from package.model_folder.model import YourModelClass # 训练模型 model = YourModelClass() # ...执行训练逻辑... # 保存模型 import joblib joblib.dump(model, 'package/model_folder/model.pkl')
这样保存的模型会记录模块路径为package.model_folder.model,加载时Python能通过包结构找到对应模块。
方案2:加载模型时临时映射模块路径
如果没法重新训练模型,可以在加载前临时把model_folder模块映射到正确的包路径:
修改package/predict_folder/predict.py:
import joblib import sys from importlib.util import spec_from_file_location, module_from_spec import os def predict(model_path): # 获取model.py的绝对路径 model_py_path = os.path.join(os.path.dirname(os.path.abspath(model_path)), 'model.py') # 临时创建model_folder.model模块,映射到实际的model.py文件 spec = spec_from_file_location("model_folder.model", model_py_path) model_module = module_from_spec(spec) sys.modules["model_folder.model"] = model_module spec.loader.exec_module(model_module) # 加载模型 model = joblib.load(model_path) return model
这样joblib加载时会用我们临时创建的model_folder.model模块,避免找不到模块的错误。
方案3:调整sys.path并导入模块
另一种简单方式是,加载模型前把package的父目录(根目录)加入sys.path,再导入对应模块:
修改package/predict_folder/predict.py:
import joblib import sys import os def predict(model_path): # 获取根目录(loader.py所在的目录) root_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) if root_dir not in sys.path: sys.path.append(root_dir) # 导入model_folder模块,让Python识别它 import model_folder.model # 加载模型 model = joblib.load(model_path) return model
验证测试
运行loader.py时,确保从根目录执行命令:
python loader.py
内容的提问来源于stack exchange,提问作者Sam Bui
相关产品推荐
相关产品推荐

