MLflow 中的工件和模型
本文内容
本文介绍 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 模型是可以做出更有力假设的工件,以便在保存的文件与此类文件的含义之间提供明确的协定。 但是,如果只是将模型的文件记录为工件,则需要知道每个文件的含义,以及如何加载文件进行推理。
可以使用 MLflow SDK 记录 MLflow 模型,例如:
import mlflow
mlflow.sklearn.log_model(sklearn_estimator, "classifier")
在 Azure 机器学习中记录 MLflow 模型具有以下好处:
- 可以将 MLflow 模型部署到实时或批处理终结点,而无需提供评分脚本或环境。
- 部署 MLflow 模型时,部署会自动生成一个 swagger 文件,因此可以使用 Azure 机器学习工作室中的测试功能。
- 可以直接将 MLflow 模型用作管道输入。
- 可以将负责任 AI 仪表板与 MLflow 模型结合使用。
对于记录为简单工件文件的模型,在加载模型以进行推理之前,需要知道模型生成器对于每个文件的预期。 但对于 MLflow 模型,可使用 MLmodel 格式加载模型,以指定工件之间的协定及其表示的内容。
MLmodel 格式会将资产存储在没有特定命名要求的文件夹中。 在资产中有一个名为 MLmodel 的文件,该文件是有关如何加载和使用模型的单一事实来源。
下图显示了 Azure 机器学习工作室中名为 credit_defaults_model 的 MLflow 模型文件夹。 该文件夹包含 MLmodel 文件和其他模型工件。
以下示例显示了一个 MLmodel 文件,该文件用于使用 fastai
训练的计算机视觉模型:
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
对象作为输入。 - 基于张量的签名使用 n 维数组或张量运行。 对于使用此签名的模型,MLflow 提供
numpy.ndarray
作为输入,或为命名张量提供numpy.ndarray
字典。
以下示例显示了使用 fastai
训练的计算机视觉模型的 signature
部分。 此模型会接收一批表示为形状 (300, 300, 3)
张量的图像,其 RGB 表示形式为无符号整数。 该模型会将预测批输出为两个类的概率。
signature:
inputs: '[{"type": "tensor",
"tensor-spec":
{"dtype": "uint8", "shape": [-1, 300, 300, 3]}
}]'
outputs: '[{"type": "tensor",
"tensor-spec":
{"dtype": "float32", "shape": [-1,2]}
}]'
提示
Azure 机器学习会为具有可用签名的 MLflow 模型部署生成一个 swagger 文件。 通过此文件,可以更轻松地使用 Azure 机器学习工作室测试部署。
要运行的模型的要求在 conda.yaml 文件中指定。 MLflow 可以自动检测依赖项,也可以通过调用 mlflow.<flavor>.log_model()
方法手动指示依赖项。 如果 MLflow 在环境中包含的库不是想要使用的库,则调用该方法可能会很有用。
以下 conda.yaml 示例显示了使用 fastai
框架创建的模型的环境:
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 机器学习 CLI 重写此行为,并将 MLflow 模型部署到特定 Azure 机器学习环境。
所有 MLflow 模型都包含一个 predict
函数,在使用无代码部署来部署模型时将调用该函数。 predict
函数返回的内容(例如类、概率或预测)取决于用于训练的框架或风格。 每种风格的文档都描述了其返回的内容。
可以自定义 predict
函数,以更改推理的执行方式。 可以记录具有不同行为的模型,也可以记录自定义模型风格。
可以从以下位置加载 MLflow 模型:
- 直接从记录模型的运行位置
- 从保存模型的文件系统
- 从注册模型的模型注册表
MLflow 提供了一种加载这些模型的一致方法,而无需考虑位置。
有两个工作流可用于加载模型:
重新加载记录的相同对象和类型。 可以使用 MLflow SDK 加载模型,并获取类型属于训练库的模型实例。 例如,Open Neural Network Exchange (ONNX) 模型会返回一个
ModelProto
对象,而使用scikit-learn
训练的决策树模型会返回一个DecisionTreeClassifier
对象。 使用mlflow.<flavor>.load_model()
加载回已记录的相同模型对象和类型。重新加载用于运行推理的模型。 可以使用 MLflow SDK 加载模型,并获取具有有保证
predict
函数的包装器。 使用哪种风格并不重要,因为每个 MLflow 模型都有一个predict
函数。MLflow 保证可以使用类型为
pandas.DataFrame
、numpy.ndarray
或dict[string, numpyndarray]
的参数调用此函数,具体取决于模型签名。 MLflow 会将类型转换为模型预期的输入类型。 使用mlflow.pyfunc.load_model()
加载回模型以运行推理。