Как хранить артефакты на сервере под управлением 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 пытается сохранить файл в локальной файловой системе напрямую.

Есть идеи, что я делаю не так?

3 ответа

Хороший вопрос. Просто чтобы убедиться, звучит так, как будто вы уже настраиваете 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/сервер регистрирует метрики и параметры в /mnt/mlruns в контейнере Docker, а также возвращает пути артефактов в /mnt/mlruns клиенту. Затем клиент пытается зарегистрировать артефакты под /mnt/mlruns в локальной файловой системе, которая не работает с PermissionError вы столкнулись.

Исправление

Рекомендуется настроить хранилище артефактов на удаленном сервере отслеживания для настройки использования корня артефакта, доступного как для клиентов, так и для сервера (например, корзины S3 или URI хранилища BLOB-объектов Azure). Вы можете сделать это через mlflow server --default-artifact-root [artifact-root],

Обратите внимание, что сервер использует этот корень артефакта только при назначении корней артефактов вновь созданным экспериментам - прогоны, созданные в существующих экспериментах, будут использовать корневой каталог артефакта в корне артефакта существующего эксперимента. См. Руководство по отслеживанию MLflow для получения дополнительной информации о настройке сервера отслеживания.

У меня была такая же проблема, попробуйте:

      sudo chmod 755 -R /mnt/mlruns
docker run --rm -it -p 5000:5000 -v /mnt/mlruns:/mnt/mlruns mlflow-server

Пришлось создать папку с точным путем докера и изменить разрешения.

Я сделал то же самое внутри докера.

      FROM python:3.6

RUN pip install --upgrade pip
RUN pip install --upgrade mlflow
RUN mkdir /mnt/mlruns/
RUN chmod 777 -R /mnt/mlruns/

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

Когда мы отправляем запросы REST API для регистрации объектов MLFlow на сервер отслеживания, сервер отвечает местоположениями магазинов в зависимости от того, что установлено в контейнере. Если значения различаются, клиент в конечном итоге будет считать, что пути, относящиеся к контейнеру, доступны на хосте, что приведет к ошибкам разрешений.

Вот файл docker-compose, который устанавливает местоположения магазинов по умолчанию:${HOME}/mnt/mlruns:

      services:
  web:
    restart: always
    build:
      context: ./mlflow
      args:
        - "MLFLOW_TRACKING_DIRECTORY=${HOME}/mnt/mlruns"
    image: mlflow_server
    container_name: mlflow_server
    ports:
      - "${MLFLOW_PORT:-5000}:5000"
    volumes:
      - "${HOME}/mnt/mlruns:${HOME}/mnt/mlruns"

Содержание./mlflow:

Dockerfile:

      FROM python:3.10-slim-buster

ARG MLFLOW_TRACKING_DIRECTORY
ENV MLFLOW_TRACKING_DIRECTORY=${MLFLOW_TRACKING_DIRECTORY}

# Install python packages
COPY requirements.txt /tmp
RUN pip install -r /tmp/requirements.txt
RUN echo ${MLFLOW_TRACKING_DIRECTORY} > test.txt

CMD mlflow server \
    --backend-store-uri ${MLFLOW_TRACKING_DIRECTORY}/tracking \
    --default-artifact-root ${MLFLOW_TRACKING_DIRECTORY}/artifacts \
    --host 0.0.0.0

requirements.txt:

      mlflow==2.3.1

Обязательно установите разрешения для ${HOME}/mnt/mlruns$ соответствующим образом, поскольку клиент будет иметь прямой доступ к локальному хранилищу.

Другие вопросы по тегам