Часть 2 — Серверная часть MLflow и хранилище артефактов. Сценарии 1, 2 и 3

В этой статье:

1. Введение
2. Сценарий 1. Клиент MLflow отслеживает папки. Нет HTTP-сервера отслеживания.
2.1 Настройте «Внутреннее хранилище» и «Хранилище артефактов» клиента MLflow
2.2 Запустите сервер «UI MLflow»
2.3 Пример «Быстрый запуск» в сценарии 1
3. Сценарий 2: отслеживание клиента MLflow в SQLite. Нет HTTP-сервера отслеживания.
3.1 Установите "Внутреннее хранилище" клиента MLflow в локальной базе данных SQLite и "Хранилище артефактов" в локальной папке
3.2 Запустите сервер "UI MLflow"
3.3 Пример "Быстрый запуск" в разделе Сценарий 2
4. Сценарий 3. Клиент MLflow + отслеживание HTTP-сервера
4.1. Настройте «внутреннее хранилище» сервера отслеживания HTTP и «хранилище артефактов» клиента MLflow
4.2. Запустите новое локальное отслеживание MLflow. сервер (сценарий 3b)
4.3 Пример быстрого запуска в сценарии 3b
5. Выполнение примера Palmer pinguins в соответствии со сценарием 3b
5.1 Notebook 1_Run_and_track_experiments.ipynb
5.2 Обучение отслеживанию код и модель с MLflow
6. Резюме

Вы можете получить доступ к коду статьи в следующем репозитории GitHub:

https://github.com/ghernantes/Training.MLOps.MLFlow/tree/main/2_MLFlow_Backend_and_Artifact_Storage_Scenarioslog_param(), log_metric() and log_artifacts()2_and_3

1. Части: клиентская и серверная; Магазины Backend и Artifact.

MLflow реализован с помощью пары клиент-сервер MLflow. Эта архитектура предназначена для предоставления масштабируемого и эффективного способа управления рабочими процессами машинного обучения. сервер предоставляет централизованное место для хранения и управления экспериментальными данными, артефактами модели и другими ресурсами, в то время как клиент > предоставляет интерфейс командной строки (CLI) и API для взаимодействия с сервером. Такое разделение обязанностей позволяет нескольким пользователям и командам сотрудничать над проектами машинного обучения, обеспечивая при этом безопасное управление и доступность всех данных и ресурсов. Кроме того, архитектура клиент-сервер обеспечивает гибкую основу для интеграции Mlflow с другими инструментами и службами, позволяя пользователям создавать сквозные конвейеры машинного обучения, включающие несколько этапов. разработки, тестирования и развертывания модели.

В частности, в Часть 1 этой серии статей мы уже использовали:

  • Клиент MLflow реализует log_param(), log_metric() and log_artifacts() вызовы функций, которые мы видели . Эти функции являются частью API, известного как API отслеживания MLflow.
  • Затем клиент MLflow может необязательно взаимодействовать с сервером MLflow, в зависимости от того, как переменная env MLFLOW_TRACKING_URL настроена для клиента.

MLflow также предлагает два компонента хранилища: базовое хранилище и хранилище артефактов. Во внутреннем хранилище сохраняются сущности MLflow, такие как запуски, параметры, метрики и метаданные, а в хранилище артефактов хранятся такие артефакты, как файлы, модели, изображения и объекты в памяти. AbstractStore и ArtifactRepository — это соответствующие абстрактные классы, которые определяют, как работать с этими хранилищами. FileStore, RestStore и SQLAlchemyStore являются примерами конкретных реализаций класса AbstractStore, а LocalArtifactRepository, AzureBlobArtifactRepository и S3ArtifactRepository являются конкретными реализациями класса ArtifactRepository.

В зависимости от того, как вы настроите хранилище экземпляров клиента и/или сервера MLflow, у вас будет несколько сценариев. В этой статье/лаборатории вы можете попрактиковаться в трех основных сценариях. Для этого создайте свою папку project/poc и cd в нее. Я рекомендую вам сделать копию папки репозитория 2_MLFlow_Backend_and_Artifact_Storage_Scenarioslog_param(), log_metric() and log_artifacts()2_and_3 и выполнить практические упражнения из статьи. Для краткости я буду называть скопированную папку lab2.

Откройте три разных терминала под lab2: Терминал 1 для проверки содержимого папки, Терминал 2: для запуска серверов MLflow и Терминал 3: для проведения экспериментов.

Давайте осмотрим папку lab2. На терминале 1 под lab2 запустите tree .:

$ tree .
.
├── .secrets
│   ├── env-secrets
│   ├── mysql-mlflowuser-password.txt
│   └── mysql-root-password.txt
├── examples
│   ├── quickstart
│   │   ├── img
│   │   │   ├── ...
│   │   └── mlflow_tracking.py
│   └── palmer_pinguins
│       ├── data
│       │   └── penguins_classification.csv
│       ├── img
│       │   ├── ...
│       └── notebooks
│           └── 1_Run_and_track_experiments.ipynb
├── mlflow
│   ├── .dockerignore
│   ├── conda.yml
│   ├── Dockerfile
│   ├── Dockerfile-conda
│   ├── entrypoint-conda-dev.sh
│   ├── entrypoint-pip-dev.sh
│   ├── entrypoint.sh
│   └── requirements.txt
├── .env
├── .gitignore
├── docker-compose.yml
├── README.md
├── show_all.sh
├── stack_deploy.sh
└── stack_remove.sh

У нас есть два примера:

  • Быстрый старт: очень простой модульный пример машинного обучения.
  • Palmer Pinguins: пример блокнота машинного обучения.

Давайте сначала запустим пример Quickstar в этих трех основных сценариях:

  • Сценарий 1: отслеживание клиентов в папках: с MLFLOW_TRACKING_URI="./mlruns" (без сервера отслеживания HTTP)
  • Сценарий 2: отслеживание клиентов в базе данных, например SQLite: с MLFLOW_TRACKING_URI="sqlite:///mlruns.db" (без сервера отслеживания HTTP)
  • Сценарий 3: отслеживание сервера в папках/базе данных: с `MLFLOW_TRACKING_URI="http://localhost:5000'')

2. Сценарий 1: Клиент MLflow отслеживает папки. Нет HTTP-сервера отслеживания.

В этом сценарии:

  • Клиент MLflow напрямую взаимодействует с экземпляром FileStore и LocalArtifactRepository.
  • И базовое хранилище, и хранилище артефактов имеют общий каталог в (локальной) файловой системе: ./mlruns

2.1. Установите «Внутреннее хранилище» и «Хранилище артефактов» клиента MLflow

Чтобы установить серверную часть и хранилища артефактов локально, используйте:

  • относительные пути, такие как: mlflow.set_tracking_uri("./mlruns)
  • вообще можно использовать: mlflow.set_tracking_uri("file:///tmp/my_tracking"), например: mlflow.set_tracking_uri("file://$PWD/mlruns")
import os
from random import random, randint
from mlflow import set_tracking_uri, get_tracking_uri, log_metric, log_param, log_artifacts

if __name__ == "__main__":
    set_tracking_uri("./mlruns")                  # You specify a file store backend as './path_to_store' relative path or 'file:///path_to_store' full path
                                                  # Default is './mlruns'. Used as backend store and artifacts store. You can use 'file://$PWD/mlruns' too.
...

2.2. Запустите сервер пользовательского интерфейса MLflow

Мы можем запустить локально сервер пользовательского интерфейса MLflow с помощью:

$ mlflow ui --port 5001

Это запускает 'сервер пользовательского интерфейса MLflow' по адресу http://127.0.0.1:5001 со следующей конфигурацией серверной части и хранилища артефактов по умолчанию:

mlflow ui --backend-store-uri ./mlruns --default-artifact-root ./mlruns--host 0.0.0.0 --port 5001

Перейдите в терминал 2, перейдите в папку lab2/mlflow и введите:

$ conda activate mlflow
(mlflow)$
(mlflow)$ cd mlflow
(mlflow)$ mlflow ui --port 5001
[1648126] [INFO] Starting gunicorn 20.1.0
[1648126] [INFO] Listening at: http://127.0.0.1:5001 (1648126)
[1648126] [INFO] Using worker: sync
[1648164] [INFO] Booting worker with pid: 1648164
[1648165] [INFO] Booting worker with pid: 1648165
[1648166] [INFO] Booting worker with pid: 1648166
[1648167] [INFO] Booting worker with pid: 1648167

Откройте наш первоначальный терминал 1 под lab2 и запустите tree .:

$ tree .
.
├── README.md
├── docker-compose.yml
├── examples
│   ├── palmer_pinguins
│   │   ├── data
│   │   │   └── penguins_classification.csv
│   │   ├── img
│   │   │   ├── ...
│   │   └── notebooks
│   │       └── 1_Run_and_track_experiments.ipynb
│   └── quickstart
│       ├── img
│       │   ├── ...
│       └── mlflow_tracking.py
├── mlflow
│   ├── Dockerfile
│   ├── Dockerfile-conda
│   ├── conda.yml
│   ├── entrypoint-conda-dev.sh
│   ├── entrypoint-pip-dev.sh
│   ├── entrypoint.sh
│   ├── mlruns                <- This folder is created
│   │   ├── 0
│   │   │   └── meta.yaml
│   │   └── models
│   └── requirements.txt
├── show_all.sh
├── stack_deploy.sh
└── stack_remove.sh

11 directories, 53 files

Обратите внимание, как создается папка mlruns под mlflow.

Под mlruns у нас есть эксперимент "По умолчанию" (папка 0) и нет запусков.

$ tree mlflow
mlflow
├── ..
├── examples
│   └── quickstart
└── requirements.txt

Эта папка mlruns теперь контролируется нашим работающим 'сервером пользовательского интерфейса MLflow', работающим на терминале 2, и публикуется на http://localhost:5001.

2.3 Пример быстрого старта в Сценарии 1

Перейдите к терминалу 3, активируйте mlflow conda env, перейдите в папку lab2/mlflow и запустите mlflow_tracking.py:

$ conda activate mlflow
(mlflow)$
(mlflow)$ export MLFLOW_TRACKING_URI="./mlruns"
(mlflow)$ python ../examples/quickstart/mlflow_tracking.py
Current tracking uri: ./mlruns
INFO mlflow.tracking.fluent: Experiment with name 'quickstar' does not exist. Creating a new experiment.
Current working directory: /home/gustavo/training/GitHub/Training.MLOps.MLFlow/2_MLFlow_Backend_and_Artifact_Storage_Scenarioslog_param(), log_metric() and log_artifacts()2_and_3/mlflow
Temporal directory 'examples/quickstart/outputs' created
Artifacts in 'examples/quickstart/outputs' tracked!
Temporal directory 'examples/quickstart/outputs' has been removed successfully

В этом простом сценарии клиент MLflow использует следующие интерфейсы для записи сущностей и артефактов MLflow:

  • Экземпляр FileStore (для сохранения объектов MLflow)
  • Экземпляр LocalArtifactRepository (для хранения артефактов)

Теперь у нашего lab2/mlflow/mlruns есть новый эксперимент 395173098808783198 и новый запуск d918463610894225b2c5d3856ba06870.

Перейдите к терминалу 1 под lab2 и на этот раз запустите tree mlflow:

$ tree mlflow

mlflow
├── ...
└── mlruns
    ├── 0
    │   └── meta.yaml
    ├── 395173098808783198
    │   ├── d918463610894225b2c5d3856ba06870
    │   │   ├── artifacts
    │   │   │   └── test.txt
    │   │   ├── meta.yaml
    │   │   ├── metrics
    │   │   │   └── foo
    │   │   ├── params
    │   │   │   └── param1
    │   │   └── tags
    │   │       ├── mlflow.runName
    │   │       ├── mlflow.source.git.commit
    │   │       ├── mlflow.source.name
    │   │       ├── mlflow.source.type
    │   │       └── mlflow.user
    │   └── meta.yaml
    └── models

Взгляните на 'сервер пользовательского интерфейса MLflow', чтобы узнать, как это работает!

Как видите, отслеживаемые параметры и метрики легко проверить. Артефакты также можно просматривать и загружать. Вся информация организована вокруг понятного и удобного интерфейса, сгруппированного по экспериментам и запускам.

3. Сценарий 2: отслеживание клиента MLflow в SQLite. Нет HTTP-сервера отслеживания.

В этом случае клиент MLflow напрямую взаимодействует с:

  • экземпляр SQLAlchemyStore: у нас есть внутреннее хранилище, где объекты MLflow вставляются в (локальный) файл базы данных SQLite mlflow.db
  • экземпляр LocalArtifactRepository: у нас есть хранилище артефактов, где артефакты хранятся в (локальном) каталоге ./mlruns

3.1 Установите «Внутреннее хранилище» клиента MLflow в локальной базе данных SQLite и «Хранилище артефактов» в локальной папке

Чтобы настроить серверную часть и хранилища артефактов:

  • Инструментируйте свой тренировочный код, используя: mlflow.set_tracking_uri("sqlite:///mlflow.db")
import os
from random import random, randint
from mlflow import set_tracking_uri, get_tracking_uri, log_metric, log_param, log_artifacts

if __name__ == "__main__":
    set_tracking_uri("sqlite:///mflow.db")    # backend store: SQLite database local file ./mflow.db
                                              # artifacts store: artifacts are stored under the local ./mlruns directory
...
  • В качестве альтернативы установите и экспортируйте переменную среды: MLFLOW_TRACKING_URI="sqlite:///mlflow.db", где выполняется обучающий код.

Вы указываете хранилище, поддерживаемое базой данных, как URI базы данных SQLAlchemy. База данных SQLAlchemy URI обычно имеет следующий формат:

<dialect>+<driver>://<username>:<password>@<host>:<port>/<database>
  • диалект: MLflow поддерживает диалекты базы данных mysql, mssql, sqlite и postgresql.
  • драйвер: не является обязательным. Если вы не укажете драйвер, SQLAlchemy использует драйвер диалекта по умолчанию.

Дополнительная информация: https://mlflow.org/docs/latest/tracking.html#scenario-2-mlflow-on-localhost-with-sqlite

3.2. Запуск сервера пользовательского интерфейса mlflow

Мы можем запустить локально сервер пользовательского интерфейса mlflow с помощью:

$ mlflow ui --backend-store-uri sqlite:///mflow.db --port 5002

Это запускает 'сервер пользовательского интерфейса MLflow' по адресу http://127.0.0.1:5002 со следующей конфигурацией внутреннего хранилища и хранилища артефактов:

$ mlflow ui --backend-store-uri sqlite:///mflow.db --default-artifact-root ./mlruns --host 0.0.0.0 --port 5002

Откройте терминал 2 и проверьте, не запущен ли другой процесс mlflow ui под lab2/mlflow. Остановите эту службу (Ctrl+c) и запустите:

$ mlflow ui --backend-store-uri sqlite:///mflow.db --port 5002
INFO mlflow.store.db.utils: Creating initial MLflow database tables...
INFO mlflow.store.db.utils: Updating database tables
INFO  [alembic.runtime.migration] Context impl SQLiteImpl.
INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
INFO  [alembic.runtime.migration] Running upgrade  -> 451aebb31d03, add metric step
INFO  [alembic.runtime.migration] Running upgrade 451aebb31d03 -> 90e64c465722, migrate user column to tags
INFO  [alembic.runtime.migration] Running upgrade 90e64c465722 -> 181f10493468, allow nulls for metric values
INFO  [alembic.runtime.migration] Running upgrade 181f10493468 -> df50e92ffc5e, Add Experiment Tags Table
INFO  [alembic.runtime.migration] Running upgrade df50e92ffc5e -> 7ac759974ad8, Update run tags with larger limit
INFO  [alembic.runtime.migration] Running upgrade 7ac759974ad8 -> 89d4b8295536, create latest metrics table
INFO  [89d4b8295536_create_latest_metrics_table_py] Migration complete!
INFO  [alembic.runtime.migration] Running upgrade 89d4b8295536 -> 2b4d017a5e9b, add model registry tables to db
INFO  [2b4d017a5e9b_add_model_registry_tables_to_db_py] Adding registered_models and model_versions tables to database.
INFO  [2b4d017a5e9b_add_model_registry_tables_to_db_py] Migration complete!
INFO  [alembic.runtime.migration] Running upgrade 2b4d017a5e9b -> cfd24bdc0731, Update run status constraint with killed
INFO  [alembic.runtime.migration] Running upgrade cfd24bdc0731 -> 0a8213491aaa, drop_duplicate_killed_constraint
INFO  [alembic.runtime.migration] Running upgrade 0a8213491aaa -> 728d730b5ebd, add registered model tags table
INFO  [alembic.runtime.migration] Running upgrade 728d730b5ebd -> 27a6a02d2cf1, add model version tags table
INFO  [alembic.runtime.migration] Running upgrade 27a6a02d2cf1 -> 84291f40a231, add run_link to model_version
INFO  [alembic.runtime.migration] Running upgrade 84291f40a231 -> a8c4a736bde6, allow nulls for run_id
INFO  [alembic.runtime.migration] Running upgrade a8c4a736bde6 -> 39d1c3be5f05, add_is_nan_constraint_for_metrics_tables_if_necessary
INFO  [alembic.runtime.migration] Running upgrade 39d1c3be5f05 -> c48cb773bb87, reset_default_value_for_is_nan_in_metrics_table_for_mysql
INFO  [alembic.runtime.migration] Running upgrade c48cb773bb87 -> bd07f7e963c5, create index on run_uuid
INFO  [alembic.runtime.migration] Running upgrade bd07f7e963c5 -> 0c779009ac13, add deleted_time field to runs table
INFO  [alembic.runtime.migration] Running upgrade 0c779009ac13 -> cc1f77228345, change param value length to 500
INFO  [alembic.runtime.migration] Running upgrade cc1f77228345 -> 97727af70f4d, Add creation_time and last_update_time to experiments table
INFO  [alembic.runtime.migration] Context impl SQLiteImpl.
INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
[1698376] [INFO] Starting gunicorn 20.1.0
[1698376] [INFO] Listening at: http://0.0.0.0:5002 (1698376)
[1698376] [INFO] Using worker: sync
[1698377] [INFO] Booting worker with pid: 1698377
[1698378] [INFO] Booting worker with pid: 1698378
[1698379] [INFO] Booting worker with pid: 1698379
[1698380] [INFO] Booting worker with pid: 1698380

Создается файл базы данных mlflow.db и применяются все миграции для создания его внутренней структуры. Откройте наш исходный терминал 1 под лабораторией 2 и запустите tree mkflow:

$ tree mkflow

mlflow
├── ...
├── mlruns
│   ├── 0
│   │   └── meta.yaml
│   ├── 395173098808783198
│   │   ├── d918463610894225b2c5d3856ba06870
│   │   │   ├── artifacts
│   │   │   │   └── test.txt
│   │   │   ├── meta.yaml
│   │   │   ├── metrics
│   │   │   │   └── foo
│   │   │   ├── params
│   │   │   │   └── param1
│   │   │   └── tags
│   │   │       ├── mlflow.runName
│   │   │       ├── mlflow.source.git.commit
│   │   │       ├── mlflow.source.name
│   │   │       ├── mlflow.source.type
│   │   │       └── mlflow.user
│   │   └── meta.yaml
│   └── models
└── mlflow.db   <-- This SQLite database file is created.

Обратите внимание, как файл базы данных mflow.db SQLite был создан в папке mlflow. В этом Сценарии 2 эта база данных используется непосредственно клиентом MLflow через интерфейс SQLAlchemyStore.

3.3 Пример быстрого старта в Сценарии 2

Перейдите к терминалу 3. Оболочка conda mlflow должна быть по-прежнему активирована, а рабочий каталог должен быть lab2/mlflow.

В этой папке снова запустите mlflow_tracking.py, но на этот раз измените MLFLOW_TRACKING_URI as в следующем коде:

$ conda activate mlflow
(mlflow)$
(mlflow)$ export MLFLOW_TRACKING_URI="sqlite:///mflow.db"
(mlflow)$
(mlflow)$ python ../examples/quickstart/mlflow_tracking.py
Current tracking uri: sqlite:///mflow.db
INFO mlflow.tracking.fluent: Experiment with name 'quickstar' does not exist. Creating a new experiment.
Current working directory: /home/gustavo/training/GitHub/Training.MLOps.MLFlow/lab2/mlflow
Temporal directory 'examples/quickstart/outputs' created
Artifacts in 'examples/quickstart/outputs' tracked!
Temporal directory 'examples/quickstart/outputs' has been removed successfully

В этом простом сценарии клиент MLflow использует следующие интерфейсы для записи сущностей и артефактов MLflow:

  • Экземпляр SQLAlchemyStore (для сохранения объектов MLflow)
  • Экземпляр LocalArtifactRepository (для хранения артефактов)

Теперь в нашей папке lab2/mlflow/mlruns есть новый эксперимент 1 и новый запуск 73b821edb9f54f82a72ec44fac9ff171, содержащий зарегистрированные артефакты для этого запуска.

Кроме того, файл базы данных lab2/mlflow/mlflow.db SQLite использовался для отслеживания сущностей MLflow, включая параметры и показатели этого запуска 73b821edb9f54f82a72ec44fac9ff171.

Перейдите к терминалу 1 и снова запустите tree mlflow:

$ tree mlflow

mlflow
├── ...
├── mlruns
│   ├── 0
│   │   └── meta.yaml
│   ├── 1
│   │   └── 73b821edb9f54f82a72ec44fac9ff171   <-- Artifacts of this last run
│   │       └── artifacts
│   │           └── test.txt
│   ├── 395173098808783198
│   │   ├── d918463610894225b2c5d3856ba06870
│   │   │   ├── artifacts
│   │   │   │   └── test.txt
│   │   │   ├── meta.yaml
│   │   │   ├── metrics
│   │   │   │   └── foo
│   │   │   ├── params
│   │   │   │   └── param1
│   │   │   └── tags
│   │   │       ├── mlflow.runName
│   │   │       ├── mlflow.source.git.commit
│   │   │       ├── mlflow.source.name
│   │   │       ├── mlflow.source.type
│   │   │       └── mlflow.user
│   │   └── meta.yaml
│   └── models
└── mlflow.db

Взгляните на 'сервер пользовательского интерфейса MLflow', чтобы узнать, как это работает!

Примечание.

Поскольку Клиент MLflow теперь использует интерфейс SQLAlchemyStore и SQLite в качестве внутреннего хранилища, все запуски, выполненные с FileStore в Сценарии 1, недоступны в нашем интерфейсе MLflow. Чтобы восстановить эти запуски, просто снова запустите службу пользовательского интерфейса на терминале 2 с помощью:

mlflow ui #or
mlflow ui --backend-store-uri mlruns/ --default-artifact-root mlruns/ --host 0.0.0.0 --port 5001 

4. Сценарий 3: клиент MLflow + сервер отслеживания HTTP

В этом сценарии:

Клиент MLflow напрямую взаимодействует с:

  • экземпляр LocalArtifactRepository. Artifact Store находится в папке ./mlruns/), и
  • экземпляр RestStore для доступа к серверу отслеживания MLflow.

Сервер отслеживания MLflow взаимодействует с (в зависимости от указанной конфигурации):

  • экземпляр FileStore: Backend Store находится в папке ./mlruns/ (сценарий 3a), или
  • экземпляр SQLAlchemyStore: Backend Store находится в mlflow.db файле базы данных SQLite (сценарий 3b)

и обслуживание артефактов отключено (используя опцию --no-serve-artifacts)

4.1 Локально задайте «Внутреннее хранилище» сервера отслеживания HTTP и «Хранилище артефактов» клиента MLflow

Чтобы настроить серверную часть и хранилища артефактов, сначала сообщите клиенту MLflow, который будет работать вместе с сервером отслеживания HTTP MLflow:

  • Инструментирование обучающего кода с помощью: mlflow.set_tracking_uri("http://my-tracking-server:5003"):
import os
from random import random, randint
from mlflow import set_tracking_uri, get_tracking_uri, log_metric, log_param, log_artifacts

if __name__ == "__main__":
  set_tracking_uri("http://localhost:5003")            # Scenario 3
...
  • Или установка и экспорт переменной окружения: MLFLOW_TRACKING_URI="http://localhost:5003", где выполняется обучающий код:
$ export MLFLOW_TRACKING_URI="http://localhost:5003"

Затем запустите сервер отслеживания HTTP MLflow.

  • реализация сценария 3a с:
mlflow server \                               # Scenario 3a:
--backend-store-uri ./mlruns \                # backend store: local folder under ./mlruns (see flow: 1a --> 1b)
--default-artifact-root ./mlruns \            # artifacts store: artifacts are stored under the same local ./mlruns directory
--no-serve-artifacts \                        # the server doesn't manage the artifact store: log_artifact() http requests are sent to the client
--host 0.0.0.0 --port 5003                    #                                               (see flow: 2a --> 2b --> 2c)
  • или с помощью следующей команды оболочки для реализации сценария 3b:
mlflow server \                               # Scenario 3b:
--backend-store-uri sqlite:///mlflow.db \     # backend store: SQLite database local file ./mlflow.db
--default-artifact-root ./mlruns \            # artifacts store: artifacts are stored under the local ./mlruns directory
--no-serve-artifacts \
--host 0.0.0.0 --port 5003

Примечания:

  • --default-artifact-root требуется, когда серверное хранилище не основано на локальном файле, а обслуживание артефактов отключено.
  • В последнем случае (сценарий 3б) для нас создается файл БД SQLite.

Дополнительная информация: https://mlflow.org/docs/latest/tracking.html#scenario-3-mlflow-on-localhost-with-tracking-server

4.2. Запустите новый локальный сервер отслеживания MLflow (сценарий 3b)

Откройте терминал 2 и остановите все службы (Ctrl+c), работающие под lab2/mlflow. Теперь запустите:

$ mlflow server --backend-store-uri sqlite:///mflow.db \
                --default-artifact-root ./mlruns \
                --no-serve-artifacts --host 0.0.0.0 --port 5003

[1849352] [INFO] Starting gunicorn 20.1.0
[1849352] [INFO] Listening at: http://0.0.0.0:5003 (1849352)
[1849352] [INFO] Using worker: sync
[1849353] [INFO] Booting worker with pid: 1849353
[1849354] [INFO] Booting worker with pid: 1849354
[1849355] [INFO] Booting worker with pid: 1849355
[1849356] [INFO] Booting worker with pid: 1849356

ПРИМЕЧАНИЕ. Если mflow.db все еще существует, он будет использован повторно. Если нет, процесс создания файла базы данных и миграции содержимого базы данных выполняется снова.

4.3 Пример быстрого старта в сценарии 3b

Перейдите к терминалу 3. Оболочка mlflow conda должна быть все еще активирована, а рабочий каталог должен быть lab2/mlflow.

В этой папке снова запустите mlflow_tracking.py, но на этот раз измените MLFLOW_TRACKING_URI, как в следующем коде:

$ conda activate mlflow
(mlflow)$
(mlflow)$ export MLFLOW_TRACKING_URI="http://localhost:5003"
(mlflow)$
(mlflow)$ python ../examples/quickstart/mlflow_tracking.py
Current tracking uri: http://localhost:5003
Current working directory: /home/gustavo/training/GitHub/Training.MLOps.MLFlow/lab2/mlflow
Temporal directory 'examples/quickstart/outputs' created
Artifacts in 'examples/quickstart/outputs' tracked!
Temporal directory 'examples/quickstart/outputs' has been removed successfully

Взгляните на сервер пользовательского интерфейса MLflow, чтобы увидеть, как это работает!

В очередной раз удалось отследить параметры, метрики и фиктивный артефакт test.txt.

5. Выполните пример «Пингвины Палмера» по Сценарию 3b.

В этом случае мы проиллюстрируем, как отслеживать реальный обучающий пример, включающий классификацию трех типов пингвинов: Адели, Генту и Антарктического ремешка. Решаемая проблема требует использования функций, основанных на измерении стебля этих пингвинов:

Данные были собраны и предоставлены доктором Кристен Горман и станцией Палмера, Антарктида, LTER, членом Сети долгосрочных экологических исследований. Он предоставляет отличный набор данных для исследования и визуализации данных в качестве альтернативы набору данных радужной оболочки глаза.

Ноутбук 5.1 1_Run_and_track_experiments.ipynb

Откройте и запустите все ячейки в следующей записной книжке:

1_Run_and_track_experiments.ipynb

Вы можете найти этот блокнот в репозитории статей. Инструментальный обучающий код, использованный для последнего запуска в этой записной книжке, выглядит следующим образом:

mlflow.set_experiment(exp_name)                                                                    # <-- Set the experiment we want to track to

with mlflow.start_run() as run:                                                                    # <-- Start a run of the experiment
    print(f"Started run {run.info.run_id}")
    # Load dataset
    print("Load dataset...")
    culmen_columns = ["Culmen Length (mm)", "Culmen Depth (mm)"]
    target_column = "Species"

    data_path = "../data/penguins_classification.csv"
    data = pd.read_csv(data_path)
    mlflow.log_param("num_samples", data.shape[0])                                                 # <-- Track the number of samples in the dataset

    # Prepare a train-test-split
    print("Prepare a train-test-split...")
    data, target = data[culmen_columns], data[target_column]
    data_train, data_test, target_train, target_test = train_test_split(
        data, target, random_state=0)

    # Initialize and fit a classifier
    max_depth = 3
    max_leaf_nodes = 4
    print(f"Initialize and fit a DecisionTreeClassifier with max_depth={max_depth}, max_leaf_nodes{max_leaf_nodes}")
    
    mlflow.log_params(                                                                             # <-- Track parameters
        {"max_depth": max_depth, 
         "max_leaf_nodes": max_leaf_nodes}
    )
    tree = DecisionTreeClassifier(
        max_depth=max_depth,
        max_leaf_nodes=max_leaf_nodes
    )
    tree.fit(data_train, target_train)

    # Calculate test scores
    test_score = tree.score(data_test, target_test)
    mlflow.log_metric("test_accuracy", test_score)                                                 # <-- Track metrics
    print(f"Result: Accuracy of the DecisionTreeClassifier: {test_score:.1%}")
    
    # Track artifacts 
    os.chdir("../../../mlflow")                                                                    # Change the current working directory to the same path the tracking server was executed:
    print(f"Current working directory temporaly moved to: {os.getcwd()}")

    mlflow.log_artifact("../examples/palmer_pinguins/notebooks/1_Run_and_track_experiments.ipynb") # <-- Track the source code of the notebook
    print(f"Notebook '1_Run_and_track_experiments.ipynb' stored in: {run.info.artifact_uri}")

    # Log the model
    mlflow.sklearn.log_model(tree, "model")                                                        # <-- Log the model
    print(f"Model stored in: {run.info.artifact_uri}/model")

    os.chdir("../examples/palmer_pinguins/notebooks")                                              # Change the current working directory to its original position         
    print(f"Current working directory: {os.getcwd()}")

5.2 Отслеживание обучающего кода и модели с помощью MLflow

После полного выполнения перейдите к терминалу 1 типа tree mlflow. У вас будет следующая структура папок:

$ tree mlflow
mlflow
├── ...
├── examples
│   └── quickstart
├── mflow.db
├── mlruns
│   ├── 1
│   │   └── 001d3acc26f64968ab1901578f65cfeb
│   │       └── artifacts
│   │           └── test.txt
│   └── 2
│       ├── 1720bf243bfe45e09d006afc1d4659d3
│       │   └── artifacts
│       │       └── 1_Run_and_track_experiments.ipynb
│       └── 8b52015be19d42cebf8b609b8ccb1042
│           └── artifacts
│               ├── 1_Run_and_track_experiments.ipynb
│               └── model
│                   ├── MLmodel
│                   ├── conda.yaml
│                   ├── model.pkl
│                   ├── python_env.yaml
│                   └── requirements.txt
└── requirements.txt

В блокноте мы выполнили три прогона. Только два последних произведенных артефакта, которые были зарегистрированы в папке .\mlflow\mlruns\2\.

Взгляните на пользовательский интерфейс отслеживания, чтобы увидеть, как это работает!

Обратите внимание, как в этом последнем примере мы отслеживали не только параметры и метрики, но и сам блокнот, создавший отслеживаемую метрику, а также обученную модель, созданную в результате прогона.

6. Резюме

В статье представлено пошаговое руководство по настройке MLflow в трех разных сценариях.

В Сценарии 1 в руководстве объясняется, как настроить по умолчанию "внутреннее хранилище" и "хранилище артефактов" клиента MLflow, а также запустить Сервер пользовательского интерфейса MLflow. Кроме того, в руководстве представлен пример «быстрого запуска» в этом сценарии.

Переходя к Сценарию 2, руководство демонстрирует, как настроить «Внутреннее хранилище» клиента MLflow в локальной базе данных SQLite и « Артефакты хранятся в локальной папке. Как и в сценарии 1, запускается сервер пользовательского интерфейса MLflow, а также включен пример «быстрого запуска».

Сценарий 3 охватывает настройку пары клиент MLflow и отслеживание сервера отслеживание. И «Внутреннее хранилище», и «Хранилище артефактов» настраиваются локально, и запускается новый локальный сервер отслеживания MLFlow. В сценарии 3b в руководстве снова приводится пример «быстрого старта».

Наконец, мы покажем, как выполнить пример «Пингвины Палмера» в Сценарии 3b, используя «Notebook 1_Run_and_track_experiments.ipynb». В этом последнем примере мы отслеживали не только параметры и метрики, но и сам блокнот, создавший отслеживаемую метрику, а также обученную модель, созданную при последнем запуске.

В следующем выпуске мы объясним, как докеризировать сервер отслеживания, который мы использовали для сценария 3b.