记录模型依赖项

本文介绍如何将模型及其依赖项记录为模型项目,以便它们在环境中可用于模型服务等生产任务。

记录 Python 包模型依赖项

MLflow 原生支持某些 Python ML 库,在这些库中,MLflow 能够可靠地记录使用这些库的模型依赖项。 请参阅内置模型风格

例如,MLflow 支持 mlflow.sklearn 模块中的 scikit-learn,命令 mlflow.sklearn.log_model 记录 sklearn 版本。 这同样适用于使用这些 ML 库的自动日志记录。 有关更多示例,请参阅 MLflow github 存储库

对于可与 pip install PACKAGE_NAME==VERSION 一起安装但没有内置 MLflow 模型风格的 ML 库,可以使用 mlflow.pyfunc.log_model 方法记录这些包。 请务必使用确切的库版本记录要求,例如,使用 f"nltk=={nltk.__version__}" 而不仅仅是 nltk

mlflow.pyfunc.log_model 支持对以下各项进行日志记录:

  • 打包为 Python egg 或 Python wheel 文件的公共库和自定义库。
  • PyPI 上的公共包,以及你自己的 PyPI 服务器上的专用托管包。

使用 mlflow.pyfunc.log_model 时,MLflow 会尝试自动推理依赖项。 MLflow 使用 mlflow.models.infer_pip_requirements 推理依赖项,并将其作为模型项目记录到 requirements.txt 文件中。

在较旧版本中,MLflow 有时不会自动识别所有 Python 要求,尤其是当库不是内置模型风格时。 在这种情况下,你可以在 log_model 命令中使用 extra_pip_requirements 参数来指定其他依赖项。 请参阅使用 extra_pip_requirements 参数的示例。

重要

还可以使用 conda_envpip_requirements 参数覆盖整个要求集,但通常不建议这样做,因为这会替代 MLflow 自动选取的依赖项。 请参阅如何使用 pip_requirements 参数覆盖要求的示例。

自定义模型日志记录

对于需要进行自定义程度更高的模型日志记录的方案,可以:

  • 编写自定义 Python 模型。 这样就可以子类化 mlflow.pyfunc.PythonModel 以自定义初始化和预测。 这种方法非常适合用于自定义仅限 Python 的模型。
  • 编写自定义风格。 在此方案中,你能够以高于一般 pyfunc 风格的程度自定义日志记录,但这样做需要完成更多的工作。

自定义 Python 代码

有可能无法使用 %pip install 命令安装你的 Python 代码依赖项,例如一个或多个 .py 文件。

记录某个模型时,可以使用 mlflow.pyfunc.log_model 中的 code_path 参数告知 MLflow 该模型可在指定路径中找到这些依赖项。 MLflow 会将使用 code_path 作为项目传递的任何文件或目录连同模型一起存储在代码目录中。 加载模型时,MLflow 会将这些文件或目录添加到 Python 路径。 此路由也适用于自定义 Python wheel 文件,可以使用 code_path 将这些 wheel 像 .py 文件一样包含在模型中。

mlflow.pyfunc.log_model( artifact_path=artifact_path,
                         code_path=[filename.py],
                         data_path=data_path,
                         conda_env=conda_env,
                       )

记录非 Python 包模型依赖项

MLflow 不会自动拾取非 Python 依赖项,例如 Java 包、R 包和本机包(如 Linux 包)。 对于这些包,需要记录附加数据。

  • 依赖项列表:Databricks 建议使用指定这些非 Python 依赖项的模型记录项目。 这可能是简单的 .txt.json 文件。 mlflow.pyfunc.log_model 允许使用 artifacts 参数指定此附加项目。
  • 自定义包:与上述自定义 Python 依赖项一样,需要确保这些包在部署环境中可用。 对于位于中心位置(例如 Maven Central)或你自己的存储库中的包,请确保该位置在评分或服务时可用。 对于未托管在其他位置的专用包,可以将包连同模型一起作为项目记录。

部署具有依赖项的模型

从 MLflow 跟踪服务器或模型注册表部署模型时,需要确保部署环境中安装了正确的依赖项。 最简单的路径可能取决于部署模式(批处理/流式处理或联机服务),以及依赖项的类型。

对于所有部署模式,Databricks 建议在训练期间使用的同一运行时版本上运行推理,因为创建模型的 Databricks Runtime 中已安装各种库。 Databricks 中的 MLflow 会自动将该运行时版本保存在 MLmodel 元数据文件的 databricks_runtime 字段中,例如 databricks_runtime: 10.2.x-cpu-ml-scala2.12

联机服务:Databricks 模型服务

Databricks 通过经典 MLflow 模型服务提供模型服务,其中 MLflow 机器学习模型公开为可缩放的 REST API 终结点。

对于 requirements.txt 文件中的 Python 依赖项,Databricks 和 MLflow 将处理公共 PyPI 依赖项方面的所有任务。 同样,如果你在记录模型时通过使用 code_path 参数指定了 .py 文件或 Python wheel 文件,则 MLflow 会自动加载这些依赖项。

联机服务:第三方系统或 Docker 容器

如果你的方案需要为第三方服务解决方案或你自己的基于 Docker 的解决方案提供服务,则你可以将模型导出为 Docker 容器。

对于自动处理 Python 依赖项的第三方服务,Databricks 建议采取以下做法。 但是,对于非 Python 依赖项,需要修改容器以包含这些依赖项。

批处理和流式处理作业

批处理和流式处理评分应作为 Databricks 作业运行。 使用一个笔记本作业通常已足够,而准备代码的最简单方法是使用 Databricks 模型注册表生成评分笔记本。

下面介绍了为确保相应地安装并应用依赖项而要遵循的过程和步骤:

  1. 使用在训练期间所用的同一 Databricks Runtime 版本启动评分群集。 读取 MLmodel 元数据文件中的 databricks_runtime 字段,并使用该运行时版本启动群集。

    • 可以在群集配置中手动执行此操作,也可以使用自定义逻辑自动执行此操作。 对于自动化,可以在作业 API群集 API 中从元数据文件读取运行时版本格式。
  2. 接下来,安装所有非 Python 依赖项。 为确保非 Python 依赖项可供部署环境访问,可以执行以下操作之一:

    • 在运行推理之前,在 Databricks 群集上手动安装模型的非 Python 依赖项作为群集配置的一部分。
    • 或者,可以在评分作业部署中编写自定义逻辑,以自动将依赖项安装到群集。 假设你已按照记录非 Python 包模型依赖项中所述将非 Python 依赖项保存为项目,则此自动化过程可以使用库 API 来安装库。 或者,你可以编写特定的代码,以生成群集范围的初始化脚本来安装依赖项。
  3. 评分作业将在作业执行环境中安装 Python 依赖项。 在 Databricks 中,可以使用模型注册表生成一个推理笔记本,让此笔记本为你执行安装。

    • 使用 Databricks 模型注册表生成评分笔记本时,该笔记本将包含用于安装模型的 requirements.txt 文件中的 Python 依赖项的代码。 对于用于批处理或流式处理评分的笔记本作业,此代码将初始化你的笔记本环境,以便安装模型依赖项并使其随时可供模型使用。
  4. MLflow 将处理 log_modelcode_path 参数包含的任何自定义 Python 代码。 调用模型的 predict() 方法时,会将此代码添加到 Python 路径。 还可以通过以下方式手动执行此操作:

    注意

    如果你在记录模型时使用 code_path 参数指定了 .py 文件或 Python wheel 文件,则 MLflow 会自动加载这些依赖项。