MLflow模型

MLflow模型是用于打包机器学习模型的标准格式,可用于各种下游工具 - 例如,通过REST API实时提供服务或在Apache Spark上进行批量推理。该格式定义了一种约定,允许您以不同的“风格”保存模型,这些“风味”可以被不同的下游工具理解。

目录

  • 存储格式
  • 模型API
  • 内置型号口味
  • 自定义口味
  • 内置部署工具

    存储格式

    每个MLflow模型都是一个包含任意文件MLmodel 的目录,以及目录根目录中的一个文件,该文件可以定义可以查看模型的多种风格
    使MLflow模型功能强大的关键概念:它们是部署工具可用于理解模型的约定,这使得编写可与任何ML库中的模型一起使用的工具成为可能,而无需将每个工具与每个库集成。MLflow定义了所有内置部署工具支持的几种“标准”风格,例如描述如何将模型作为Python函数运行的“Python函数”风格。但是,库也可以定义和使用其他类型。例如,MLflow的mlflow.sklearn库允许将模型加载为scikit-learn Pipeline对象,以便在知道scikit-learn的代码中使用,或者作为通用Python函数用于仅需要应用模型的工具(例如,工具)用于将模型部署到Amazon SageMaker)。
    特定模型支持的所有风格都MLmodel以YAML格式在其文件中定义。例如,mlflow.sklearn输出模型如下:
  1. # Directory written by mlflow.sklearn.save_model(model, "my_model")
  2. my_model/
  3. ├── MLmodel
  4. └── model.pkl

它的MLmodel文件描述了两种风格:

  1. time_created: 2018-05-25T17:28:53.35
  2. flavors:
  3. sklearn:
  4. sklearn_version: 0.19.1
  5. pickled_model: model.pkl
  6. python_function:
  7. loader_module: mlflow.sklearn

该模型然后可以与任何支持工具中使用任一sklearnpython_function模型的味道。例如,该命令可以为具有flavor 的模型提供服务:mlflow sklearn``sklearn

  1. mlflow sklearn serve my_model

此外,命令行工具可以将模型打包并部署到AWS SageMaker,只要它们支持这种风格:mlflow sagemaker``python_function

  1. mlflow sagemaker deploy -m my_model [other options]

MLmodel格式的字段

除了从口味场列出了模型的口味,在MLmodel YAML格式可以包含以下字段:

TIME_CREATED

创建模型的日期和时间,采用UTC ISO 8601格式。

run_id

如果使用MLflow Tracking保存模型,则创建模型的运行的ID 。

模型API

您可以通过多种方式保存和加载MLflow模型。首先,MLflow包括与几个公共库的集成。例如,scikit-learn模型的[mlflow.sklearn](https://mlflow.org/docs/latest/python_api/mlflow.sklearn.html#module-mlflow.sklearn)包括save_modellog_modelload_model函数。其次,您可以使用mlflow.models.Model该类来创建和编写模型。这个类有四个关键功能:

  • add_flavor为模型添加味道。每个flavor都有一个字符串名称和一个键值属性字典,其中值可以是任何可以序列化为YAML的对象。
  • save 将模型保存到本地目录。
  • log 使用MLflow Tracking将模型记录为当前运行中的工件。
  • load 从本地目录或先前运行中的工件加载模型。

    内置型号口味

    MLflow提供了几种可能在您的应用程序中有用的标准风格。具体来说,它的许多部署工具都支持这些风格,因此您可以将这些风格导出自己的模型,以便从所有这些工具中受益。

    Python函数(python_function

    python_function模型的味道定义了一个通用的文件系统格式为Python模型和保存和加载模型,并从该格式提供了工具。该格式是自包含的,因为它包含加载和使用模型所需的所有信息。依赖关系直接存储在模型中或通过Conda环境引用。
    python_function模型的约定是具有predict以下签名的方法或函数:
  1. predict(data: pandas.DataFrame) -> [pandas.DataFrame | numpy.array]

其他MLflow组件期望python_function模型遵循此约定。
python_function模型格式定义为包含所有所需的数据的目录结构,代码和配置:

  1. ./dst-path/
  2. ./MLmodel: configuration
  3. <code>: code packaged with the model (specified in the MLmodel file)
  4. <data>: data packaged with the model (specified in the MLmodel file)
  5. <env>: Conda environment definition (specified in the MLmodel file)

一个python_function模式目录必须包含MLmodel在其与“python_function”格式和下列参数的根文件:

loader_module [required]:

可以加载模型的Python模块。期望是mlflow.sklearn可导入的模块标识符(例如)importlib.import_module。导入的模块必须包含具有以下签名的函数:
> _load_pyfunc(path:string) - >

path参数由data参数指定,可以引用文件或目录。

code [optional]:

包含此模型打包的代码的目录的相对路径。在导入模型加载器之前,此目录中的所有文件和目录都将添加到Python路径中。

data [optional]:

包含模型数据的文件或目录的相对路径。路径传递给模型加载器。

env [可选]:

导出的Conda环境的相对路径。如果存在,则在运行模型之前激活此环境。

案例

  1. tree example/sklearn_iris/mlruns/run1/outputs/linear-lr
  1. ├── MLmodel
  2. ├── code
  3. ├── sklearn_iris.py
  4. ├── data
  5. └── model.pkl
  6. └── mlflow_env.yml
  1. cat example/sklearn_iris/mlruns/run1/outputs/linear-lr/MLmodel
  1. python_function:
  2. code: code
  3. data: data/model.pkl
  4. loader_module: mlflow.sklearn
  5. env: mlflow_env.yml
  6. main: sklearn_iris

有关更多信息,请参阅mlflow.pyfunc

H O(h2o

H2O模型风味可以记录和加载H2O模型。这些模型将通过使用保存mlflow.h2o.save_model。使用mlflow.h2o.log_model也将启用有效的味道。Python Function
将H2O模型作为PyFunc模型加载时,h2o.init(...)将调用。因此,正确版本的h2o(-py)必须在环境中。给出的参数h2o.init(...)可以model.h2o/h2o.yaml在键下定制init。有关更多信息,请参阅mlflow.h2o

Keras(keras

keras模型味道启用日志记录和装载Keras模型。该模型将通过Keras提供的model_save功能以HDF5文件格式保存。此外,模型可以加载为。有关更多信息,请参阅。Python Functionmlflow.keras

MLeap(mleap

mleap模型风味支持使用MLeap持久性机制保存模型。该mlflow/java软件包中提供了一个用于加载具有MLeap风格格式的MLflow模型的配套模块。有关更多信息,请参阅mlflow.mleap

PyTorch(pytorch

pytorch模型味道启用日志记录和装载PyTorch模型。模型使用torch.save(模型)方法以.pth格式完全存储。给定包含已保存模型的目录,您可以将模型记录到MLflow via 。然后可以加载保存的模型以进行推理。有关更多信息,请参阅。log_saved_model``mlflow.pyfunc.load_pyfunc()mlflow.pytorch

Scikit-learn(sklearn

sklearn模型的味道提供了一个简单易用的界面来处理scikit学习模式,没有外部的依赖关系。它使用Python的pickle模块保存和加载模型,并生成有效的 python_functionflavor模型。有关更多信息,请参阅mlflow.sklearn

Spark MLlib(spark

spark模型的味道能使出口星火MLlib模型作为MLflow模型。导出的模型使用Spark MLLib的本机序列化进行保存,然后可以作为MLlib模型加载回来或作为python_function模型进行部署。当部署为a时python_function,模型会创建自己的SparkContext,并在评分之前将pandas DataFrame输入转换为Spark DataFrame。虽然这不是最有效的解决方案,尤其是对于实时评分,但它使您能够轻松地将任何MLlib PipelineModel(只要PipelineModel没有外部JAR依赖性)部署到MLflow支持的任何端点。有关更多信息,请参阅mlflow.spark

TensorFlow(tensorflow

tensorflow模型的味道使记录TensorFlow 并加载它们早在模型上大熊猫DataFrames推断。给定包含已保存模型的目录,您可以将模型记录到MLflow ,然后使用加载保存的模型进行推理。有关更多信息,请参阅。Saved Models``Python Function``log_saved_model``mlflow.pyfunc.load_pyfuncmlflow.tensorflow

自定义口味

您可以在MLmodel文件中添加一种风格,可以通过直接编写或使用mlflow.models.Model类构建它。为您的风味选择一个任意的字符串名称。MLflow工具忽略他们不理解的MLmodel文件中的风格。

内置部署工具

MLflow提供了在本地计算机和多个生产环境中部署模型的工具。并非所有部署方法都适用于所有型号的风格。Python函数格式和所有兼容格式支持部署。

  • python_function模型部署为本地REST API端点
  • python_function在Microsoft Azure ML上部署模型
  • python_function在Amazon SageMaker上部署模型
  • python_function模型导出为Apache Spark UDF

    python_function模型部署为本地REST API端点

    MLflow可以在本地部署模型作为本地REST API端点,或直接对CSV文件进行评分。在部署到远程模型服务器之前,此功能是测试模型的便捷方式。您可以使用CLI界面在本地部署Python函数flavor到mlflow.pyfunc模块。本地REST API服务器接受以下数据格式作为输入:
    • JSON序列化的pandas DataFrames的split方向。例如, 。使用 请求标头值指定此格式。从MLflow 0.9.0开始,如果是(即没有格式规范),这将是默认格式。data = pandas_df.to_json(orient='split')``Content-Type``application/json; format=pandas-split``Content-Type``application/json
    • JSON序列化的pandas DataFrames的records方向。我们不建议使用此格式,因为无法保证保留列顺序。目前,使用 或的Content-Type请求标头值 指定此格式。从MLflow 0.9.0开始,将参考 格式。为了向前兼容,我们建议使用格式或指定内容类型。application/json; format=pandas-records``application/json``application/json``split``split``application/json; format=pandas-records
    • CSV序列化的pandas DataFrames。例如,。使用请求标头值指定此格式。data = pandas_df.to_csv()``Content-Type``text/csv

有关序列化pandas DataFrames的更多信息,请参阅 pandas.DataFrame.to_json

命令

  • serve 将模型部署为本地REST API服务器。
  • predict 使用该模型生成本地CSV文件的预测。

有关详细信息,请参阅:

  1. mlflow pyfunc - help
  2. mlflow pyfunc serve - help
  3. mlflow pyfunc predict - help

python_function在Microsoft Azure ML上部署模型

mlflow.azureml模块可以将python_function模型打包到Azure ML容器映像中。这些映像可以部署到Azure Kubernetes服务(AKS)和Azure容器实例(ACI)平台,以实现实时服务。生成的Azure ML ContainerImage包含一个Web服务器,它接受以下数据格式作为输入:

  • JSON序列化的pandas DataFrames的split方向。例如,。使用请求标头值指定此格式。data = pandas_df.to_json(orient='split')``Content-Type``application/json
  • build_image向现有Azure ML工作区注册MLflow模型,并构建Azure ML容器映像以部署到AKS和ACI。在Azure的ML SDK要求才能使用此功能。Azure ML SDK需要Python 3.它不能与早期版本的Python一起安装。

使用Python API的示例工作流程

  1. import mlflow.azureml
  2. from azureml.core import Workspace
  3. from azureml.core.webservice import AciWebservice, Webservice
  4. # Create or load an existing Azure ML workspace. You can also load an existing workspace using
  5. # Workspace.get(name="<workspace_name>")
  6. workspace_name = "<Name of your Azure ML workspace>"
  7. subscription_id = "<Your Azure subscription ID>"
  8. resource_group = "<Name of the Azure resource group in which to create Azure ML resources>"
  9. location = "<Name of the Azure location (region) in which to create Azure ML resources>"
  10. azure_workspace = Workspace.create(name=workspace_name,
  11. subscription_id=subscription_id,
  12. resource_group=resource_group,
  13. location=location,
  14. create_resource_group=True,
  15. exist_okay=True)
  16. # Build an Azure ML container image for deployment
  17. azure_image, azure_model = mlflow.azureml.build_image(model_path="<path-to-model>",
  18. workspace=azure_workspace,
  19. description="Wine regression model 1",
  20. synchronous=True)
  21. # If your image build failed, you can access build logs at the following URI:
  22. print("Access the following URI for build logs: {}".format(azure_image.image_build_log_uri))
  23. # Deploy the container image to ACI
  24. webservice_deployment_config = AciWebservice.deploy_configuration()
  25. webservice = Webservice.deploy_from_image(
  26. image=azure_image, workspace=azure_workspace, name="<deployment-name>")
  27. webservice.wait_for_deployment()
  28. # After the image deployment completes, requests can be posted via HTTP to the new ACI
  29. # webservice's scoring URI. The following example posts a sample input from the wine dataset
  30. # used in the MLflow ElasticNet example:
  31. # https://github.com/mlflow/mlflow/tree/master/examples/sklearn_elasticnet_wine
  32. print("Scoring URI is: %s", webservice.scoring_uri)
  33. import requests
  34. import json
  35. # `sample_input` is a JSON-serialized pandas DataFrame with the `split` orientation
  36. sample_input = {
  37. "columns": [
  38. "alcohol",
  39. "chlorides",
  40. "citric acid",
  41. "density",
  42. "fixed acidity",
  43. "free sulfur dioxide",
  44. "pH",
  45. "residual sugar",
  46. "sulphates",
  47. "total sulfur dioxide",
  48. "volatile acidity"
  49. ],
  50. "data": [
  51. [8.8, 0.045, 0.36, 1.001, 7, 45, 3, 20.7, 0.45, 170, 0.27]
  52. ]
  53. }
  54. response = requests.post(
  55. url=webservice.scoring_uri, data=json.dumps(sample_input),
  56. headers={"Content-type": "application/json"})
  57. response_json = json.loads(response.text)
  58. print(response_json)

Example workflow using the MLflow CLI

  1. mlflow azureml build-image -w <workspace-name> -m <model-path> -d "Wine regression model 1"
  2. az ml service create aci -n <deployment-name> --image-id <image-name>:<image-version>
  3. # After the image deployment completes, requests can be posted via HTTP to the new ACI
  4. # webservice's scoring URI. The following example posts a sample input from the wine dataset
  5. # used in the MLflow ElasticNet example:
  6. # https://github.com/mlflow/mlflow/tree/master/examples/sklearn_elasticnet_wine
  7. scoring_uri=$(az ml service show --name <deployment-name> -v | jq -r ".scoringUri")
  8. # `sample_input` is a JSON-serialized pandas DataFrame with the `split` orientation
  9. sample_input='
  10. {
  11. "columns": [
  12. "alcohol",
  13. "chlorides",
  14. "citric acid",
  15. "density",
  16. "fixed acidity",
  17. "free sulfur dioxide",
  18. "pH",
  19. "residual sugar",
  20. "sulphates",
  21. "total sulfur dioxide",
  22. "volatile acidity"
  23. ],
  24. "data": [
  25. [8.8, 0.045, 0.36, 1.001, 7, 45, 3, 20.7, 0.45, 170, 0.27]
  26. ]
  27. }'
  28. echo $sample_input | curl -s -X POST $scoring_uri\
  29. -H 'Cache-Control: no-cache'\
  30. -H 'Content-Type: application/json'\
  31. -d @-

For more info, see:

  1. mlflow azureml --help
  2. mlflow azureml build-image --help

python_function在Amazon SageMaker上部署模型

mlflow.sagemaker模块可以python_function在具有SageMaker兼容环境的Docker容器中本地部署模型,并在SageMaker上远程部署模型。要远程部署到SageMaker,您需要设置环境和用户帐户。要将自定义模型导出到SageMaker,您需要在Amazon ECR上提供与MLflow兼容的Docker镜像。MLflow提供默认的Docker镜像定义; 但是,由您来构建映像并将其上载到ECR。MLflow包括build_and_push_container执行此步骤的效用函数。构建和上传后,您可以将MLflow容器用于所有MLflow模型。使用该mlflow.sagemaker 模块部署的模型Web服务器接受以下数据格式作为输入,具体取决于部署风格:

  • python_function:对于此部署风格,端点接受与pyfunc服务器相同的格式。pyfunc部署文档中描述了这些格式 。
  • mleap:对于此部署风格,端点仅接受split方向上的 JSON序列化pandas DataFrame 。例如, 。使用 请求标头值指定此格式。data = pandas_df.to_json(orient='split')``Content-Type``application/json

命令

  • run-local在Docker容器中本地部署模型。图像和环境应与模型远程运行的方式相同,因此在部署之前测试模型非常有用。
  • build-and-push-containerCLI命令构建一个MLfLow多克尔图像并上传到ECR。调用者必须设置正确的权限。图像是本地构建的,并且需要Docker存在于执行此步骤的计算机上。
  • deploy在Amazon SageMaker上部署模型。MLflow将Python Function模型上传到S3并启动为该模型提供服务的Amazon SageMaker端点。

使用MLflow CLI的示例工作流程

  1. mlflow sagemaker build-and-push-container - build the container (only needs to be called once)
  2. mlflow sagemaker run-local -m <path-to-model> -
  3. remotely

For more info, see:

  1. mlflow sagemaker --help
  2. mlflow sagemaker build-and-push-container --help
  3. mlflow sagemaker run-local --help
  4. mlflow sagemaker deploy --help

python_function模型导出为Apache Spark UDF

您可以将python_function模型输出为Apache Spark UDF,可以将其上载到Spark群集并用于对模型进行评分。

  1. pyfunc_udf = mlflow.pyfunc.spark_udf(<path-to-model>)
  2. df = spark_df.withColumn("prediction", pyfunc_udf(<features>))

生成的UDF基于Spark的Pandas UDF,目前仅限于为每个观察生成单个值或相同类型的值数组。默认情况下,我们将第一个数字列作为double返回。您可以通过提供result_type 参数来控制返回的结果。支持以下值:

  • 'int'IntegerTypeint32返回可以适合结果的最左边的整数, 如果没有,则引发异常。
  • 'long'LongTypeint64 返回可以适合结果的最左边的长整数,如果没有则引发异常。
  • 数组类型IntegerType | LongType):返回一个可以放入所需尺寸的所有整数列。
  • 'float'FloatTypefloat32如果没有数字列,则返回最左边的数字结果转换 为或引发异常。
  • 'double'DoubleTypedouble如果没有数字列,则返回最左边的数字结果转换 为或引发异常。
  • ArrayTypeFloatType | DoubleType):返回强制转换为请求的所有数字列。类型。如果存在数字列,则会引发异常。
  • 'string'StringType:Result是最左边的列转换为字符串。
  • ArrayTypeStringType):返回转换为字符串的所有列。
  1. from pyspark.sql.types import ArrayType, FloatType
  2. pyfunc_udf = mlflow.pyfunc.spark_udf(<path-to-model>, result_type=ArrayType(FloatType()))
  3. # The prediction column will contain all the numeric columns returned by the model as floats
  4. df = spark_df.withColumn("prediction", pyfunc_udf(<features>))