我正在尝试使用 mlflow 保存 sklearn 机器学习模型,这是一个包含我定义的自定义转换器的管道,并将其加载到另一个项目中。
我的自定义转换器继承自 BaseEstimator 和 TransformerMixin。
假设我有 2 个项目:
- train_project:它在 src.ml.transformers.py 中有自定义变压器
- use_project:src中有其他东西,或者根本没有src目录
所以在我的 train_project 中我这样做:
mlflow.sklearn.log_model(preprocess_pipe, 'model/preprocess_pipe')
然后当我尝试将其加载到 use_project 时:
preprocess_pipe = mlflow.sklearn.load_model(f'{ref_model_path}/preprocess_pipe')
出现错误:
[...]
File "/home/quentin/anaconda3/envs/api_env/lib/python3.7/site-packages/mlflow/sklearn.py", line 210, in _load_model_from_local_file
return pickle.load(f)
ModuleNotFoundError: No module named 'train_project'
我尝试使用格式 mlflow.sklearn.SERIALIZATION_FORMAT_CLOUDPICKLE :
mlflow.sklearn.log_model(preprocess_pipe, 'model/preprocess_pipe', serialization_format=mlflow.sklearn.SERIALIZATION_FORMAT_CLOUDPICKLE)
但我在加载过程中遇到同样的错误。
我看到了选项代码路径 into mlflow.pyfunc.log_model但我不清楚它的用途和目的。
我认为 mlflow 提供了一种简单的方法来保存模型并序列化它们,以便它们可以在任何地方使用,只有当你有原生 sklearn 模型(或 keras,...)时,这是真的吗?
看来这个问题与pickle功能更相关(mlflow使用它并且pickle需要安装所有依赖项)。
到目前为止,我找到的唯一解决方案是将我的转换器制作为一个包,将其导入两个项目中。保存我的变压器库的版本康达环境的论证日志模型,并在将模型加载到我的 use_project 时检查它是否是相同的版本。
但如果我必须更改变压器或在其中进行调试,那就很痛苦了......
有人有更好的解决方案吗?
更优雅?也许我会错过一些 mlflow 功能?
其他信息:
在 Linux (ubuntu) 上工作
毫升流量=1.5.0
蟒蛇=3.7.3
我在 mlflow.sklearn api 的测试中看到他们使用自定义变压器进行了测试,但他们将其加载到同一个文件中,因此它似乎无法解决我的问题,但也许它可以帮助其他人:
https://github.com/mlflow/mlflow/blob/master/tests/sklearn/test_sklearn_model_export.py https://github.com/mlflow/mlflow/blob/master/tests/sklearn/test_sklearn_model_export.py