AWS部署ML模型报ModuleNotFoundError: 无sklearn.linear_model.base模块
ModuleNotFoundError: No module named 'sklearn.linear_model.base'并非未安装scikit-learn导致,而是scikit-learn版本不兼容引发的内部模块路径变更问题:scikit-learn 0.23版本迭代时做了内部重构,原本放在sklearn.linear_model.base路径下的类被迁移到了私有模块路径sklearn.linear_model._base,如果用高版本scikit-learn加载低版本(≤0.22)训练序列化保存的模型,或是依赖的第三方工具还在引用旧路径,就会触发该报错。单纯升级到最新版scikit-learn反而会进一步拉大版本差,无法解决问题。
实操解决方案
优先对齐模型训练与部署的scikit-learn版本
用joblib/pickle序列化保存的ML模型,对依赖的版本一致性要求极高,部署环境的scikit-learn版本必须和模型训练时的版本完全一致。在AWS部署环境(无论是SageMaker、ECS还是Lambda)中,直接安装和训练时完全匹配的版本即可,比如训练时使用的是0.22.2.post1版本,就执行命令:pip install scikit-learn==0.22.2.post1注意:不要盲目拉取最新版scikit-learn部署旧模型,版本差过大会触发各类内部路径找不到的兼容问题。
必须使用高版本scikit-learn时,做旧路径兼容映射
受环境限制无法降级scikit-learn时,可在所有sklearn相关导入代码的最开头,手动为旧的缺失模块路径添加别名,绕过路径校验,示例代码:# 放在所有sklearn、模型加载代码之前执行 import sklearn.linear_model from sklearn.linear_model import _base sklearn.linear_model.base = _base import sys sys.modules['sklearn.linear_model.base'] = _base该方法通过模块别名让pickle能定位到拆分后的类定义,不需要调整原有环境依赖版本。
排查第三方依赖的路径引用问题
部分老旧的ML辅助工具库(如早期版本的模型解释、模型转换类工具)仍在直接导入sklearn.linear_model.base,就算模型本身的版本完全匹配,只要加载到这类旧库就会触发报错。这类场景要么将辅助库升级到支持新版scikit-learn的版本,要么使用上述的模块映射方法补全缺失路径。
AWS部署场景高频踩坑提示:很多人直接使用官方最新版的推理容器镜像部署本地训练的旧模型,而最新镜像内置的scikit-learn版本往往远高于本地训练版本,是触发该报错的最常见原因。部署前可在推理服务的启动脚本中打印当前环境的scikit-learn版本,和本地训练版本做比对,版本差超过1个小版本就需要主动对齐。
内容的提问来源于stack exchange,提问作者Prabhakar Patra

