mlflow 如何使用自定义转换器保存 sklearn 管道?
Posted
技术标签:
【中文标题】mlflow 如何使用自定义转换器保存 sklearn 管道?【英文标题】:mlflow How to save a sklearn pipeline with custom transformer? 【发布时间】: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吗? 【参考方案1】:您可以使用code_path
参数来保存Python 文件依赖项(或包含文件依赖项的目录)。加载模型时,这些文件会附加到系统路径中。
模型文件夹将包含一个目录code
,其中包含所有这些文件。
【讨论】:
【参考方案2】:您要做的是序列化您在train.py
之外的模块中训练的“自定义”内容,对吗?
您可能需要做的是使用mlflow.pyfunc.log_model
和code
参数记录您的模型,该参数包含一个字符串列表,其中包含您需要反序列化和进行预测的模块的路径,如文档所述@ 987654321@.
需要明确的是,每个 mlflow 模型本质上都是 PyFunc。即使您使用mlflow.sklearn
记录模型,您也可以使用mlflow.pyfunc.load_model
加载它。 PyFunc 所做的是以独特的方式标准化所有模型和框架,这将保证您始终声明如何:
-
使用
load_context()
方法对模型进行反序列化
使用predict()
方法进行预测
如果您确定继承 mlflow 的 PythonModel 类的对象中的这两件事,则可以将您的模型记录为 PyFunc。
mlflow.sklearn.log_model
所做的基本上是总结了您声明序列化和反序列化的方式。如果您坚持使用 sklearn 的基本模块,例如基本的转换器和管道,那么您将始终可以使用它。但是当你需要一些自定义的东西时,你可以参考 Pyfuncs。
你可以找到一个非常有用的例子here。请注意,它准确说明了如何进行预测,将输入转换为 XGBoost 的 DMatrix。
【讨论】:
以上是关于mlflow 如何使用自定义转换器保存 sklearn 管道?的主要内容,如果未能解决你的问题,请参考以下文章
如何使方法 JSON 可序列化以在自定义 Pyspark 转换器中使用
如何使用 mlflow.pyfunc.log_model() 通过 Keras 步骤记录 sklearn 管道?类型错误:无法腌制 _thread.RLock 对象