将 MLflow 模型部署为本地推理服务器
MLflow 允许您仅通过一条命令在本地部署模型。这种方法非常适合轻量级应用程序,或者在将模型迁移到测试或生产环境之前进行本地测试。
如果您是 MLflow 模型部署的新手,请先阅读 MLflow 部署指南,以了解 MLflow 模型和部署的基本概念。
部署推理服务器
在部署之前,您必须拥有一个 MLflow 模型。如果您还没有,可以按照 MLflow 追踪入门创建一个示例 scikit-learn 模型。请记住记下模型 URI,例如 models:/<model_id>(如果您已在 MLflow 模型注册表中注册了该模型,则为 models:/<model_name>/<model_version>)。
模型准备就绪后,部署到本地服务器非常简单。使用 mlflow models serve 命令进行一键部署。此命令将启动一个监听指定端口并为您提供模型服务的本地服务器。有关可用选项,请参阅 CLI 参考。
mlflow models serve -m runs:/<run_id>/model -p 5000
然后,您可以按照如下方式向服务器发送测试请求
curl http://127.0.0.1:5000/invocations -H "Content-Type:application/json" --data '{"inputs": [[1, 2], [3, 4], [5, 6]]}'
有多种命令行选项可用于自定义服务器的行为。例如,--env-manager 选项允许您选择特定的环境管理器(如 Anaconda)来创建虚拟环境。mlflow models 模块还提供其他有用的命令,例如构建 Docker 镜像或生成 Dockerfile。有关详细信息,请参阅 MLflow CLI 参考。
推理服务器规范
端点
推理服务器提供 4 个端点
-
/invocations:接收带有输入数据的 POST 请求并返回预测结果的推理端点。 -
/ping:用于健康检查。 -
/health:与 /ping 相同。 -
/version:返回 MLflow 版本。
支持的输入格式
/invocations 端点接受 CSV 或 JSON 输入。输入格式必须在 Content-Type 请求头中指定为 application/json 或 application/csv。
CSV 输入
CSV 输入必须是有效的 pandas.DataFrame CSV 表示形式。例如
curl http://127.0.0.1:5000/invocations -H 'Content-Type: application/csv' --data '1,2,3,4'
JSON 输入
您可以传递与所需模型负载相对应的扁平字典,或者将负载包装在一个指定了负载格式的字典键中。
包装好的负载字典
如果您的模型格式不受上述支持,或者您想避免将输入数据转换为所需的负载格式,则可以利用以下字典负载结构。
| 字段 | 描述 | 示例 |
|---|---|---|
dataframe_split | split 格式的 Pandas DataFrame。 | text |
dataframe_records | records 格式的 Pandas DataFrame。我们不建议使用此格式,因为它无法保证保留列顺序。 | text |
instances | 张量输入,格式如 TF Serving API 文档中所述,提供的输入将被转换为 Numpy 数组。 | text |
inputs | 与 instances 相同,但键不同。 | text |
# Prerequisite: serve a custom pyfunc OpenAI model (not mlflow.openai) on localhost:5678
# that defines inputs in the below format and params of `temperature` and `max_tokens`
import json
import requests
payload = json.dumps({
"inputs": {"messages": [{"role": "user", "content": "Tell a joke!"}]},
"params": {
"temperature": 0.5,
"max_tokens": 20,
},
})
response = requests.post(
url=f"https://:5678/invocations",
data=payload,
headers={"Content-Type": "application/json"},
)
print(response.json())
JSON 输入还可以包含一个可选的 params 字段,用于传递附加参数。有效的参数类型为 Union[DataType, List[DataType], None],其中 DataType 为 MLflow 数据类型。要传递参数,必须定义一个带有 params 的有效 模型签名 (Model Signature)。
curl http://127.0.0.1:5000/invocations -H 'Content-Type: application/json' -d '{
"inputs": {"question": ["What color is it?"],
"context": ["Some people said it was green but I know that it is pink."]},
"params": {"max_answer_len": 10}
}'
由于 JSON 会丢失类型信息,MLflow 会将 JSON 输入转换为模型 schema 中指定的输入类型(如果可用)。如果您的模型对输入类型敏感,建议为模型提供 schema,以确保在推理时不发生类型不匹配错误。特别是深度学习模型,它们通常对输入类型非常严格,需要模型 schema 才能正确评分。对于复杂数据类型,请参阅下文的 编码复杂数据。
原始负载字典
如果您的负载格式是您所部署的 MLflow 模型可以接受的格式,并且属于下方支持的模型,则可以传递原始负载字典。
| 支持的请求格式 | 描述 | 示例 |
|---|---|---|
| OpenAI Chat | OpenAI 聊天请求负载† | text |
† 请注意,使用 OpenAI API 时不应包含 model 参数,因为其配置由 MLflow 模型实例设置。只要在记录的模型签名中的 params 参数内定义了其他所有参数,就可以自由使用它们。
# Prerequisite: serve a Pyfunc model accepts OpenAI-compatible chat requests on localhost:5678 that defines
# `temperature` and `max_tokens` as parameters within the logged model signature
import json
import requests
payload = json.dumps({
"messages": [{"role": "user", "content": "Tell a joke!"}],
"temperature": 0.5,
"max_tokens": 20,
})
requests.post(
url=f"https://:5678/invocations",
data=payload,
headers={"Content-Type": "application/json"},
)
print(requests.json())
编码复杂数据
复杂数据类型(例如日期或二进制)没有原生的 JSON 表示形式。如果您包含模型签名,MLflow 可以自动从 JSON 解码支持的数据类型。支持以下数据类型转换:
-
binary:预期数据为 base64 编码,MLflow 将自动进行 base64 解码。
-
datetime:预期数据按照 ISO 8601 规范编码为字符串。MLflow 将在给定平台上将其解析为相应的日期时间表示形式。
示例请求
# record-oriented DataFrame input with binary column "b"
curl http://127.0.0.1:5000/invocations -H 'Content-Type: application/json' -d '[
{"a": 0, "b": "dGVzdCBiaW5hcnkgZGF0YSAw"},
{"a": 1, "b": "dGVzdCBiaW5hcnkgZGF0YSAx"},
{"a": 2, "b": "dGVzdCBiaW5hcnkgZGF0YSAy"}
]'
# record-oriented DataFrame input with datetime column "b"
curl http://127.0.0.1:5000/invocations -H 'Content-Type: application/json' -d '[
{"a": 0, "b": "2020-01-01T00:00:00Z"},
{"a": 1, "b": "2020-02-01T12:34:56Z"},
{"a": 2, "b": "2021-03-01T00:00:00Z"}
]'
服务框架
MLflow 使用 FastAPI(一种现代的 Python ASGI Web 框架)来提供推理端点。FastAPI 异步处理请求,被公认为最快的 Python 框架之一。这个生产就绪的框架适用于大多数使用场景。
运行批处理推理
除了运行在线推理端点外,您还可以使用 mlflow models predict 命令在本地文件上执行单个批处理推理作业。以下命令对 input.csv 运行模型预测并将结果输出到 output.csv。
- Bash
- Python
mlflow models predict -m models:/<model_id> -i input.csv -o output.csv
import mlflow
model = mlflow.pyfunc.load_model("models:/<model_id>")
predictions = model.predict(pd.read_csv("input.csv"))
predictions.to_csv("output.csv")