【发布时间】:2020-06-17 04:31:45
【问题描述】:
我正在尝试使用 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)
但我在加载过程中遇到同样的错误。
我在 mlflow.pyfunc.log_model 中看到了选项 code_path,但我不清楚它的用途和目的。
我认为 mlflow 提供了一种简单的方法来保存模型并对其进行序列化,以便它们可以在任何地方使用,只有当您拥有本机 sklearn 模型(或 keras,...)时才如此吗?
似乎这个问题与pickle功能更相关(mlflow使用它并且pickle需要安装所有依赖项)。
到目前为止,我发现的唯一解决方案是将我的转换器制作成一个包,并将其导入两个项目中。使用 log_model 的 conda_env 参数保存我的转换器库的版本,并在我将模型加载到我的 use_project 时检查它是否是相同的版本。 但是,如果我必须更换变压器或在其中调试,那就太痛苦了……
有人有更好的解决方案吗? 更优雅?也许我会错过一些 mlflow 功能?
其他信息:
在 Linux (ubuntu) 上工作
mlflow=1.5.0
蟒蛇=3.7.3
我在 mlflow.sklearn api 的测试中看到他们使用自定义转换器进行了测试,但他们将其加载到同一个文件中,因此它似乎无法解决我的问题,但也许它可以帮助其他人:
https://github.com/mlflow/mlflow/blob/master/tests/sklearn/test_sklearn_model_export.py
【问题讨论】:
-
您解决了这个问题吗?我们有类似的过程。你试过mlflow.pyfunc吗?
标签: python machine-learning scikit-learn pickle mlflow