首页 > 解决方案 > 如何在运行 MLflow 的服务器上存储工件

问题描述

我定义了以下泊坞窗图像:

FROM python:3.6

RUN pip install --upgrade pip
RUN pip install --upgrade mlflow

ENTRYPOINT mlflow server --host 0.0.0.0 --file-store /mnt/mlruns/

并构建一个名为mlflow-server. 接下来,我从本地计算机启动此服务器:

docker run --rm -it -p 5000:5000 -v ${PWD}/mlruns/:/mnt/mlruns mlflow-server

接下来,我定义以下函数:

def foo(x, with_af=False):
    mlflow.start_run()
    mlflow.log_param("x", x)
    print(x)
    if with_af:
        with open(str(x), 'wb') as fout:
            fout.write(os.urandom(1024))
        mlflow.log_artifact(str(x))
        mlflow.log_artifact('./foo.data')
    mlflow.end_run()

从我运行的同一目录中foo(10),参数被正确记录。但是,foo(10, True)会产生以下错误:PermissionError: [Errno 13] Permission denied: '/mnt'. 似乎log_artifact试图直接将文件保存在本地文件系统上。

知道我在做什么错吗?

标签: pythondockermlflow

解决方案


好问题。只是为了确保,听起来您已经在配置 MLflow 以在运行脚本时与您的跟踪服务器通信,例如通过MLFLOW_TRACKING_URI=http://localhost:5000 python my-script.py.

MLflow 中的工件存储

工件与其他运行数据(指标、参数、标签)的细微差别在于客户端而不是服务器负责持久化它们。当前流程(截至 MLflow 0.6.0)为:

  • 用户代码调用mlflow.start_run
  • MLflow 客户端向跟踪服务器发出 API 请求以创建运行
  • 跟踪服务器为运行确定适当的根工件 URI(当前:运行的工件根是其父实验的工件根目录的子目录)
  • 跟踪服务器持久保存运行元数据(包括其工件根)并向客户端返回一个运行对象
  • 用户代码调用log_artifact
  • 客户端在活动运行的工件根目录下记录工件

问题

当您通过 启动 MLflow 服务器时mlflow server --host 0.0.0.0 --file-store /mnt/mlruns/,服务器会将指标和参数记录在docker/mnt/mlruns容器中,并将工件路径返回/mnt/mlruns给客户端。然后,客户端尝试在本地文件系统上记录工件/mnt/mlrunsPermissionError您遇到的失败。

修复

使用远程跟踪服务器存储工件的最佳实践是将服务器配置为使用客户端和服务器均可访问的工件根(例如 S3 存储桶或 Azure Blob 存储 URI)。您可以通过mlflow server --default-artifact-root [artifact-root].

请注意,服务器仅在将工件根分配给新创建的实验时才使用此工件根 - 在现有实验下创建的运行将使用现有实验的工件根下的工件根目录。有关配置跟踪服务器的更多信息,请参阅MLflow 跟踪指南


推荐阅读