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