You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Joblib加载sklearn模型报错scipy.sparse._csr模块缺失如何解决

环境信息
  • Python版本:3.7(必须使用该版本)
  • 操作系统:Linux
  • 云平台:Azure
  • 使用资源:基于Python的Azure Function
  • 实现目标:加载由scikit-learn 1.0.2版本训练生成的模型,当前环境已安装依赖版本如下:

numpy: 1.17.3
joblib: 1.1.0
scipy: 1.7.3

问题描述

使用joblib加载本地Python 3.9环境下训练生成的scikit-learn模型时,抛出如下报错:

Traceback (most recent call last):
File "/home/site/wwwroot/sortierung/__init__.py", line 51, in main
prediction_file_path)
File "/home/site/wwwroot/shared_code/custom_functions_prediction.py", line 255, in predict
result.update(classify_mail(m,s,X, stop_words, model_folder_path))
File "/home/site/wwwroot/shared_code/custom_functions_prediction.py", line 105, in classify_mail
model = load(modelFilePath)
File "/home/site/wwwroot/.python_packages/lib/site-packages/joblib/numpy_pickle.py", line 587, in load
obj = _unpickle(fobj, filename, mmap_mode)
File "/home/site/wwwroot/.python_packages/lib/site-packages/joblib/numpy_pickle.py", line 506, in _unpickle
obj = unpickler.load()
File "/usr/local/lib/python3.7/pickle.py", line 1088, in load
dispatch[key[0]](self)
File "/usr/local/lib/python3.7/pickle.py", line 1385, in load_stack_global
self.append(self.find_class(module, name))
File "/usr/local/lib/python3.7/pickle.py", line 1426, in find_class
__import__(module, level=0)
ModuleNotFoundError: No module named 'scipy.sparse._csr'

检查当前环境scipy安装目录,确认不存在scipy.sparse._csr模块。

问题根因

报错由版本不兼容直接导致:

  1. scipy从1.8.0版本开始调整了稀疏矩阵模块的内部结构,将原本公开路径下的csr/csc/coo等稀疏矩阵实现,移动到了带下划线前缀的私有路径下(即报错中的scipy.sparse._csr)。
  2. 本地训练模型使用的Python 3.9环境中,安装的scipy版本≥1.8.0,模型序列化时记录的是新版私有模块路径;而线上Azure Function环境的scipy版本为1.7.3,仍使用旧版公开路径,反序列化时找不到对应模块就会抛出错误。
  3. 跨Python大版本(3.9→3.7)做pickle序列化/反序列化本身也存在兼容性风险,属于模型部署时的不规范操作。
解决方案

由于运行环境强制要求Python 3.7,无法升级运行时版本,可按优先级选择以下方案修复:

方案1(推荐,长期稳定)

搭建与线上完全一致的依赖环境:Python 3.7 + numpy 1.17.3 + joblib 1.1.0 + scipy 1.7.3 + scikit-learn 1.0.2,在该环境中重新训练并保存模型,再将新生成的模型文件部署到线上。
该方案完全规避跨版本pickle反序列化的所有兼容性问题,是工业界部署scikit-learn模型的标准做法,不会出现隐式的版本适配bug。

方案2(快速修复,无需重训)

如果暂时无法重新训练模型,可以在加载模型的代码最前端,手动为旧版本scipy添加模块别名映射,让反序列化流程可以找到对应对象,代码示例如下:

import scipy.sparse
# 补全新版scipy的稀疏模块路径映射
scipy.sparse._csr = scipy.sparse.csr
scipy.sparse._csc = scipy.sparse.csc
scipy.sparse._coo = scipy.sparse.coo

# 后续再执行原有模型加载逻辑
from joblib import load
model = load(modelFilePath)

该方案属于补丁式修复,如果模型中还包含其他跨版本变动的对象,可能会抛出同类模块缺失错误,需要按需补全映射,仅适合临时紧急修复使用,不建议作为长期方案。

方案3(对齐本地依赖版本)

如果不想搭建线上匹配环境重训,也可以将本地训练环境的scipy降级到1.7.3版本,与线上版本对齐后重新保存模型再部署。注意降级scipy后需要验证scikit-learn 1.0.2功能正常,模型预测结果符合预期。


内容的提问来源于stack exchange,提问作者sergioMoreno

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 00:03:27