跳到主要内容

MLflow 追踪服务器

MLflow 追踪服务器是一个独立的 HTTP 服务器,提供多个 REST API 端点用于追踪运行/实验。虽然 MLflow 追踪可以在本地环境中使用,但在团队开发工作流程中托管追踪服务器非常强大。

  • 协作:多用户可以向同一个端点记录运行,并查询其他用户记录的运行和模型。
  • 分享结果:追踪服务器还提供追踪 UI 端点,团队成员可以在其中轻松查看彼此的结果。
  • 集中访问:追踪服务器可以作为远程访问元数据和 artifacts 的代理运行,从而更容易保护和审计数据访问。

启动追踪服务器

启动追踪服务器非常简单,只需运行以下命令即可

mlflow server --host 127.0.0.1 --port 8080

服务器启动运行后,您应该看到以下输出

[2023-11-01 10:28:12 +0900] [28550] [INFO] Starting gunicorn 20.1.0
[2023-11-01 10:28:12 +0900] [28550] [INFO] Listening at: http://127.0.0.1:8080 (28550)
[2023-11-01 10:28:12 +0900] [28550] [INFO] Using worker: sync
[2023-11-01 10:28:12 +0900] [28552] [INFO] Booting worker with pid: 28552
[2023-11-01 10:28:12 +0900] [28553] [INFO] Booting worker with pid: 28553
[2023-11-01 10:28:12 +0900] [28555] [INFO] Booting worker with pid: 28555
[2023-11-01 10:28:12 +0900] [28558] [INFO] Booting worker with pid: 28558
...

有许多选项可以配置服务器,请参阅配置服务器了解更多详细信息。

重要

服务器默认监听 http://localhost:5000,并且只接受来自本地机器的连接。要让服务器接受来自其他机器的连接,您需要传递 --host 0.0.0.0 以监听所有网络接口(或特定的接口地址)。这通常是在 Kubernetes pod 或 Docker 容器中运行服务器时所需的配置。

请注意,出于安全原因,不建议在公共网络上运行的服务器执行此操作。您应该考虑使用 NGINX 或 Apache httpd 等反向代理,或通过 VPN 连接(详见安全追踪服务器)。

记录到追踪服务器

追踪服务器启动后,通过将 MLFLOW_TRACKING_URI 环境变量设置为服务器的 URI 及其 scheme 和端口(例如,http://10.0.0.1:5000),或调用 mlflow.set_tracking_uri() 来连接您的本地客户端。

然后,mlflow.start_run()mlflow.log_param()mlflow.log_metric() 调用会向您的远程追踪服务器发出 API 请求。

import mlflow

remote_server_uri = "..." # set to your server URI, e.g. http://127.0.0.1:8080
mlflow.set_tracking_uri(remote_server_uri)
mlflow.set_experiment("/my-experiment")
with mlflow.start_run():
mlflow.log_param("a", 1)
mlflow.log_metric("b", 2)
注意

在 Databricks 上,mlflow.set_experiment() 中的实验名称必须是工作区中有效的绝对路径(例如,/Workspace/Users/mlflow-experiments/my-experiment)。

配置服务器

本节介绍如何为一些常见用例配置追踪服务器。请运行 mlflow server --help 以获取完整的命令行选项列表。

后端存储

默认情况下,追踪服务器将运行元数据记录到本地文件系统中的 ./mlruns 目录下。您可以通过添加 --backend-store-uri 选项来配置不同的后端存储。

示例
mlflow server --backend-store-uri sqlite:///my.db

这将在当前目录中创建一个 SQLite 数据库 my.db,来自客户端的日志请求将指向此数据库。

远程 artifacts 存储

使用追踪服务器进行代理 artifacts 访问

默认情况下,追踪服务器将其 artifacts 存储在本地文件系统中的 ./mlartifacts 目录下。要将追踪服务器配置为连接到远程存储并提供 artifacts 服务,请使用 --artifacts-destination 标志启动服务器。

mlflow server \
--host 0.0.0.0 \
--port 8885 \
--artifacts-destination s3://my-bucket

通过此设置,MLflow 服务器充当访问远程 artifacts 的代理。MLflow 客户端向服务器发出 HTTP 请求以获取 artifacts。

重要

如果您正在使用远程存储,则必须配置服务器访问 artifacts 的凭据。请注意,MLflow artifacts 代理访问服务使用户能够以假定角色访问所有追踪服务器可访问的 artifacts。有关更多详细信息,请参阅管理访问

追踪服务器会将客户端追踪请求中的 URI mlflow-artifacts:/ 解析为明确的对象存储目标(例如,“s3:/my_bucket/mlartifacts”),以便与 artifacts 接口。以下模式都将解析为配置的代理对象存储位置(在上面的示例中为 s3://my-root-bucket/mlartifacts)。

  • https://<主机>:<端口>/mlartifacts
  • http://<主机>/mlartifacts
  • mlflow-artifacts://<主机>/mlartifacts
  • mlflow-artifacts://<主机>:<端口>/mlartifacts
  • mlflow-artifacts:/mlartifacts
重要

MLflow 客户端按每次运行缓存 artifacts 位置信息。因此,不建议在运行终止之前更改其 artifacts 位置。

不使用代理访问 artifacts 的追踪服务器

在某些情况下,您可能希望直接访问远程存储,而无需通过追踪服务器进行代理。在这种情况下,您可以使用 --no-serve-artifacts 标志启动服务器,并将 --default-artifact-root 设置为您希望将请求重定向到的远程存储 URI。

mlflow server --no-serve-artifacts --default-artifact-root s3://my-bucket

通过此设置,MLflow 客户端仍然向追踪服务器发出最少的 HTTP 请求以获取正确的远程存储 URI,但可以直接将 artifacts 上传到远程存储或从远程存储下载 artifacts。虽然这可能不是访问和安全治理的好实践,但当您希望避免通过追踪服务器代理 artifacts 的开销时,这可能很有用。

注意

如果 MLflow 服务器未配置 --serve-artifacts 选项,客户端会直接将 artifacts 推送到 artifacts 存储。默认情况下,它不会通过追踪服务器代理这些操作。

因此,客户端需要直接访问 artifacts 存储。有关设置这些凭据的说明,请参阅Artifact 存储文档

注意

创建实验时,将追踪服务器配置中的 artifacts 存储位置记录在实验的元数据中。启用代理 artifacts 存储后,在非代理模式下运行追踪服务器时创建的任何现有实验将继续使用非代理 artifacts 位置。为了使用代理 artifacts 记录,必须创建一个新实验。如果启用 -serve-artifacts 模式下的追踪服务器的目的是消除客户端对底层存储进行身份验证的需要,则应创建新实验供客户端使用,以便在迁移后追踪服务器可以处理身份验证。

可选:专门用于 artifacts 处理的追踪服务器实例

MLflow 追踪服务器可以配置使用不同的后端存储和 artifacts 存储,并为客户端提供单个端点。

但是,如果追踪服务器请求量足够大并注意到性能问题,可以将追踪服务器配置为以 --artifacts-only 模式提供服务,与指定了 --no-serve-artifacts 的实例协同工作。此配置可确保 artifacts 的处理与所有其他追踪服务器事件处理隔离。

当追踪服务器配置为 --artifacts-only 模式时,除了与 artifacts 处理相关的任务(即模型记录、加载模型、记录 artifacts、列出 artifacts 等)之外的任何任务都将返回 HTTPError。以下示例显示了 Python 中的客户端 REST 调用尝试从配置为 --artifacts-only 模式的服务器列出实验

# Launch the artifact-only server
mlflow server --artifacts-only ...
import requests

# Attempt to list experiments from the server
response = requests.get("http://0.0.0.0:8885/api/2.0/mlflow/experiments/list")
输出
>> HTTPError: Endpoint: /api/2.0/mlflow/experiments/list disabled due to the mlflow server running in `--artifacts-only` mode.

使用额外的 MLflow 服务器专门处理 artifacts 对于大规模 MLOps 基础设施非常有用。将运行时间更长、计算量更大的 artifacts 处理任务与更快、数量更多的其他追踪 API 请求的元数据功能解耦,有助于最大程度地减轻原本由单个 MLflow 服务器处理两种类型负载的负担。

注意

如果 MLflow 服务器使用 --artifacts-only 标志运行,客户端应该通过在 artifacts 的 uri 位置引用中明确包含 hosthost:port 定义来与此服务器交互。否则,所有 artifacts 请求都将路由到 MLflow 追踪服务器,从而违背了运行独立 artifacts 服务器的目的。

安全追踪服务器

--host 选项在所有接口上公开服务。如果在生产环境中运行服务器,我们建议不要广泛公开内置服务器(因为它未经身份验证且未加密),而是将其置于 NGINX 或 Apache httpd 等反向代理之后,或通过 VPN 连接。

然后,您可以使用这些环境变量将身份验证头传递给 MLflow。

  • MLFLOW_TRACKING_USERNAMEMLFLOW_TRACKING_PASSWORD - 用于 HTTP Basic 身份验证的用户名和密码。要使用 Basic 身份验证,必须同时设置这两个环境变量。
  • MLFLOW_TRACKING_TOKEN - 用于 HTTP Bearer 身份验证的 token。如果设置了 Basic 身份验证,则 Basic 身份验证优先。
  • MLFLOW_TRACKING_INSECURE_TLS - 如果设置为字面值 true,MLflow 不会验证 TLS 连接,这意味着它不验证 https:// 追踪 URI 的证书或主机名。不建议在生产环境中使用此标志。如果此标志设置为 true,则不得设置 MLFLOW_TRACKING_SERVER_CERT_PATH
  • MLFLOW_TRACKING_SERVER_CERT_PATH - 要使用的 CA 捆绑包的路径。设置 requests.request 函数的 verify 参数(参见requests 主接口)。当您使用自签名服务器证书时,可以使用此参数在客户端进行验证。如果设置了此参数,则不得设置 MLFLOW_TRACKING_INSECURE_TLS(必须为 false)。
  • MLFLOW_TRACKING_CLIENT_CERT_PATH - ssl 客户端证书文件 (.pem) 的路径。设置 requests.request 函数的 cert 参数(参见requests 主接口)。这可用于使用(自签名)客户端证书。

追踪服务器版本控制

可以通过查询 /version 端点来找到服务器上运行的 MLflow 版本。这可用于在运行实验之前检查客户端的 MLflow 版本是否与远程追踪服务器同步。例如

import requests
import mlflow

response = requests.get("http://<mlflow-host>:<mlflow-port>/version")
assert response.text == mlflow.__version__ # Checking for a strict version match

处理上传/下载大型 artifacts 时的超时问题

通过启用了 artifacts 代理的追踪服务器上传或下载大型 artifacts 时,服务器处理请求可能需要很长时间。如果超过超时限制(默认 30 秒),服务器将重启 worker 进程,导致客户端请求失败。

客户端代码示例

import mlflow

mlflow.set_tracking_uri("<TRACKING_SERVER_URI>")
with mlflow.start_run():
mlflow.log_artifact("large.txt")

客户端回溯

Traceback (most recent call last):
File "/Users/user/python3.10/site-packages/requests/adapters.py", line 486, in send
resp = conn.urlopen(
File "/Users/user/python3.10/site-packages/urllib3/connectionpool.py", line 826, in urlopen
return self.urlopen(
...
File "/Users/user/python3.10/site-packages/urllib3/connectionpool.py", line 798, in urlopen
retries = retries.increment(
File "/Users/user/python3.10/site-packages/urllib3/util/retry.py", line 592, in increment
raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='mlflow.example.com', port=443): Max retries exceeded with url: ... (Caused by SSLError(SSLEOFError(8, 'EOF occurred in violation of protocol (_ssl.c:2426)')))
During handling of the above exception, another exception occurred:

追踪服务器日志

[2025-01-10 11:59:00 +0000] [82] [INFO] Starting gunicorn 20.1.0
[2025-01-10 11:59:00 +0000] [82] [DEBUG] Arbiter booted
[2025-01-10 11:59:00 +0000] [82] [INFO] Listening at: http://0.0.0.0:5000 (82)
...
[2025-01-10 11:59:01 +0000] [82] [CRITICAL] WORKER TIMEOUT (pid:86)
[2025-01-10 11:59:01 +0000] [86] [INFO] Worker exiting (pid: 86)
[2025-01-10 11:59:01 +0000] [179] [INFO] Booting worker with pid: 179

为缓解此问题,启动服务器时可以使用 --gunicorn-opts 选项增加超时时长,如下所示

mlflow server --gunicorn-opts "--timeout=60" ...

请参阅 Gunicorn 文档中的timeout