如何在运行MLflow的服务器上存储工件

Dro*_*ror 7 python docker mlflow

我定义了以下docker镜像:

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/
Run Code Online (Sandbox Code Playgroud)

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

docker run --rm -it -p 5000:5000 -v ${PWD}/mlruns/:/mnt/mlruns mlflow-server
Run Code Online (Sandbox Code Playgroud)

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

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()
Run Code Online (Sandbox Code Playgroud)

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

知道我做错了什么吗?

小智 9

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

MLflow中的工件存储

工件与其他运行数据(指标,参数,标签)略有不同,因为客户端而不是服务器负责持久化它们.当前流量(截至MLflow 0.6.0)是:

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

问题

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

修复

使用远程跟踪服务器进行工件存储的最佳做法是将服务器配置为使用客户端和服务器都可访问的工件根(例如,S3存储桶或Azure Blob存储URI).你可以通过这样做mlflow server --default-artifact-root [artifact-root].

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