MLflow 中从项目到模型

以下文章介绍了 MLflow 项目与 MLflow 模型之间的差异,以及如何相互进行转换。 还介绍了 Azure 机器学习如何使用 MLflow 模型的概念来启用简化的部署工作流。

项目与模型之间的区别是什么?

如果你不熟悉 MLflow,则可能不知道记录项目或文件与记录 MLflow 模型之间的差异。 两者之间有一些根本的区别:

项目

“项目”是从试验的运行或作业生成(和捕获)的任意文件。 项目可能表示序列化为 Pickle 文件的模型、PyTorch 或 TensorFlow 模型的权重,甚至表示包含线性回归系数的文本文件。 某些项目也可能与模型本身无关;相反,它们可以包含用于运行模型、预处理信息或示例数据等的配置。 项目可能采用各种格式。

你可能已经在记录项目:

filename = 'model.pkl'
with open(filename, 'wb') as f:
  pickle.dump(model, f)

mlflow.log_artifact(filename)

型号

MLflow 中的模型也是一个项目。 但是,我们对此类项目做出更强的假设。 这种假设在保存的文件与它们的含义之间提供明确的协定。 将模型记录为项目(简单文件)时,需要知道模型生成器对每个文件的含义,以便了解如何加载模型进行推理。 相反,可以使用 MLModel 格式中指定的协定来加载 MLflow 模型。

在 Azure 机器学习中,日志记录模型具有以下优势:

  • 可以在实时终结点或批处理终结点上部署它们,而无需提供评分脚本或环境。
  • 部署模型时,部署会自动生成 Swagger,并且可在 Azure 机器学习工作室中使用“测试”功能。
  • 可以直接将模型用作管道输入。
  • 可以将负责任 AI仪表板用于模型。

可以使用 MLflow SDK 记录模型:

import mlflow
mlflow.sklearn.log_model(sklearn_estimator, "classifier")

MLmodel 格式

MLflow 采用 MLModel 格式作为在项目与其代表内容之间创建协定的方法。 MLmodel 格式将资产存储在文件夹中。 在这些资产中,有一个名为 MLmodel 的文件。 此文件是有关如何加载和使用模型的单一可信源。

以下屏幕截图显示了 Azure 机器学习工作室中的一个示例 MLflow 模型的文件夹。 模型放置在名为 credit_defaults_model 的文件夹中。 此文件夹的命名没有具体要求。 该文件夹包含 MLmodel 文件和其他模型项目。

A screenshot showing assets of a sample MLflow model, including the MLmodel file.

以下代码是使用 fastai 训练的计算机视觉模型的 MLmodel 文件示例,其外观可能如下所示:

MLmodel

artifact_path: classifier
flavors:
  fastai:
    data: model.fastai
    fastai_version: 2.4.1
  python_function:
    data: model.fastai
    env: conda.yaml
    loader_module: mlflow.fastai
    python_version: 3.8.12
model_uuid: e694c68eba484299976b06ab9058f636
run_id: e13da8ac-b1e6-45d4-a9b2-6a0a5cfac537
signature:
  inputs: '[{"type": "tensor",
             "tensor-spec": 
                 {"dtype": "uint8", "shape": [-1, 300, 300, 3]}
           }]'
  outputs: '[{"type": "tensor", 
              "tensor-spec": 
                 {"dtype": "float32", "shape": [-1,2]}
            }]'

模型风格

考虑到有大量可用的机器学习框架,MLflow 引入了“风格”概念,作为提供独特协定来处理所有这些机器学习框架的方法。 风格指示了使用特定框架创建的给定模型的预期情况。 例如,TensorFlow 有自己的风格,它指定了如何持久保存和加载 TensorFlow 模型。 由于每个模型风格都指示如何持久保存和加载给定框架的模型,因此 MLmodel 格式不会强制实施所有模型必须支持的单个序列化机制。 此决策允许每种风格都使用根据最佳做法提供最佳性能或最佳支持的方法,而不会影响与 MLmodel 标准的兼容性。

以下代码是 fastai 模型 flavors 部分的示例。

flavors:
  fastai:
    data: model.fastai
    fastai_version: 2.4.1
  python_function:
    data: model.fastai
    env: conda.yaml
    loader_module: mlflow.fastai
    python_version: 3.8.12

模型签名

MLflow 中的模型签名是模型规范的重要组成部分,因为它充当模型与运行模型的服务器之间的数据协定。 模型签名对于在部署时分析和强制实施模型的输入类型也很重要。 如果签名可用,MLflow 会在将数据提交到模型时强制实施输入类型。 有关详细信息,请参阅 MLflow 签名强制实施

记录模型时会指示签名,它们持久保存在 MLmodel 文件的 signature 部分中。 MLflow 中的 Autolog 功能以最佳方式自动推断签名。 但是,如果推断的签名不是所需的签名,你可能需要手动记录模型。 有关详细信息,请参阅如何使用签名记录模型

有两种类型的签名:

  • 基于列的签名:此签名对表格数据进行操作。 对于具有此签名的模型,MLflow 提供 pandas.DataFrame 对象作为输入。
  • 基于 Tensor 的签名:此签名使用 n 维数组或张量进行操作。 对于具有此签名的模型,MLflow 提供 numpy.ndarray 作为输入(或在命名张量的情况下提供 numpy.ndarray 的字典)。

以下示例对应于使用 fastai 训练的计算机视觉模型。 此模型接收一批图像,这些图像表示为形状为 (300, 300, 3) 的张量,并带有其 RGB 表示形式(无符号整数)。 该模型输出两个类的批量预测(概率)。

MLmodel

signature:
  inputs: '[{"type": "tensor",
             "tensor-spec": 
                 {"dtype": "uint8", "shape": [-1, 300, 300, 3]}
           }]'
  outputs: '[{"type": "tensor", 
              "tensor-spec": 
                 {"dtype": "float32", "shape": [-1,2]}
            }]'

提示

Azure 机器学习会生成一个 Swagger 文件,用于部署具有可用签名的 MLflow 模型。 这样可以更轻松地使用 Azure 机器学习工作室测试部署。

模型环境

conda.yaml 文件中指定了模型运行的要求。 MLflow 可以自动检测依赖项,你也可以通过调用 mlflow.<flavor>.log_model() 方法手动指示依赖项。 如果环境中包含的库不是你打算使用的库,则后者可能很有用。

以下代码是用于使用 fastai 框架创建的模型的环境示例:

conda.yaml

channels:
- conda-forge
dependencies:
- python=3.8.5
- pip
- pip:
  - mlflow
  - astunparse==1.6.3
  - cffi==1.15.0
  - configparser==3.7.4
  - defusedxml==0.7.1
  - fastai==2.4.1
  - google-api-core==2.7.1
  - ipython==8.2.0
  - psutil==5.9.0
name: mlflow-env

注意

MLflow 环境和 Azure 机器学习环境有何区别?

MLflow 环境在模型级别运行,而 Azure 机器学习环境在工作区(对于已注册环境)或作业/部署(对于匿名环境)级别运行。 在 Azure 机器学习中部署 MLflow 模型时,将生成模型的环境并用于部署。 或者,可以使用 Azure 机器学习CLI v2 替代此行为,并使用特定的 Azure 机器学习环境部署 MLflow 模型。

Predict 函数

所有 MLflow 模型都包含 predict 函数。 使用无代码部署体验部署模型时会调用此函数。 predict 函数返回的内容(例如类、概率或预测)取决于用于训练的框架(即风格)。 阅读每个风格的文档,了解它们返回的内容。

同样的情况下,可能需要自定义此 predict 函数以更改推理的执行方式。 在这些情况下,需要在预测方法中记录具有不同行为的模型记录自定义模型的风格

用于加载 MLflow 模型的工作流

可以从多个位置加载创建为 MLflow 模型的模型,包括:

  • 直接从记录模型的运行位置
  • 从保存模型的文件系统
  • 从注册模型的模型注册表。

无论位置如何,MLflow 都提供一致的方式来加载这些模型。

有两个工作流可用于加载模型:

  • 加载回已记录的相同对象和类型:可以使用 MLflow SDK 加载模型,并获取具有属于训练库的类型的模型实例。 例如,ONNX 模型返回 ModelProto,而 scikit-learn 训练的决策树模型返回 DecisionTreeClassifier 对象。 使用 mlflow.<flavor>.load_model() 加载回已记录的相同模型对象和类型。

  • 加载回模型以运行推理:可使用 MLflow SDK 加载模型,并获取一个包装器,其中 MLflow 保证将有一个 predict 函数。 使用哪种风格并不重要,每个 MLflow 模型都有一个 predict 函数。 此外,MLflow 保证可使用 pandas.DataFramenumpy.ndarraydict[string, numpyndarray] 类型的参数调用此函数(具体类型取决于模型的签名)。 MLflow 会将类型转换为模型预期的输入类型。 使用 mlflow.pyfunc.load_model() 加载回模型以运行推理。