Нет ничего нового в потребности многих специалистов по данным, которые постоянно пытаются найти способ сократить разрыв между этапом разработки модели и ее дальнейшим развертыванием. Этот процесс подразумевает несколько итераций, пока команда не будет уверена в производительности модели. С появлением CD4ML разрыв становится меньше, и появляется множество вариантов решения этой проблемы. Многие платформы предоставляют способ выполнения обучения, прогнозирования и проверки в соответствии со стратегией пакетной обработки/задания. В то время как многие облачные провайдеры заботятся о таких вопросах, предлагая такие инструменты, как AWS Sagemaker или Google IA Platform, нередко можно найти компании, которые скорее поддерживают свои собственные подходы без привязки к поставщику.

Одним из вариантов является использование среды на основе контейнеров (например, K8s), которая допускает такое распределенное выполнение, что открывает возможности для масштабирования решения и создания более сложных конвейеров.

В этой статье я хотел бы рассказать об очень конкретном случае использования. Как разработать небольшой проект на Python для последующего обучения этой модели в контейнере Docker. Несмотря на то, что вся статья будет посвящена Docker, я думаю, что переход с локальной машины на более крупную среду должен быть относительно простым.

Готовиться

Довольно часто можно найти решения, которые используют сырой pip или conda внутри контейнера для установки зависимостей и последующего запуска эксперимента.
На самом деле, этот подход уже был в поле зрения MLflow. MLflow, среди прочего, предлагает концепцию Проекты MLflow.

Эти проекты MLflow — это просто путь к более структурированному репозиторию и автоматизируемому коду. Он также обрабатывает зависимости для управления разработкой и выполнением содержащегося в нем кода. Эти зависимости обрабатываются с помощью conda. Несмотря на то, что conda — отличный инструмент для работы со средами и зависимостями, я обнаружил, что накладные расходы времени довольно чрезмерны из-за создания среды conda во время выполнения, что необходимо непосредственно перед обучением/тестированием модели в контейнере.

В дополнение к вышеупомянутым инструментам есть и другие довольно интересные. Одним из самых привлекательных является Поэзия. Poetry — это менеджер пакетов. Несмотря на то, что он не такой мощный, как среда создания conda, он предоставляет очень полезный и простой интерфейс для отслеживания и установки зависимостей. Он также позволяет выполнять код с использованием точек входа, подобных найденным в проектах MLflow.
Если вас интересуют эти различия, то одно из них заключается в том, что Poetry, например, не может установить пользовательскую версию Python, в отличие от conda. Есть некоторые отличия, которые стоит знать. Чтобы более подробно ознакомиться с этой темой, обратитесь к этой другой статье.

Итак, это было слишком много назад, и мы должны начать с реального кода. Наша цель здесь проста: мы пишем код для обучения модели, обучаем ее в контейнере Docker. По пути мы узнаем, как использовать Poetry для создания проекта, управления его зависимостями, а затем выполнения нашего кода.

Краткое изложение предстоящего путешествия:
1. Создание нашего проекта машинного обучения с помощью Poetry
2. Разработка модели на локальном уровне
3. Обучение нашей модели в контейнере

Создание нашего ML проекта с Poetry

Прежде всего, вам нужно убедиться, что в вашей среде доступен Python. После этого нужно установить Poetry. Следующая команда сделает это.

curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python -

Если вам нужно уточнить детали во время установки, я рекомендую вам посетить документы.

Чтобы начать новый проект (на этот раз мы назовем его poe_model_example), выполните следующую строку:

poetry new poe_model_example

Это создаст проект с простой, но подходящей структурой.
Наоборот, если у вас уже есть папка, просто запустите каталог, находящийся внутри него, и предоставьте запрошенную информацию:

poetry init

В обоих случаях будет создан файл pyproject.toml. Этот файл является краеугольным камнем проекта. Здесь разработчик объявит необходимые зависимости для выполнения проекта. Можно отредактировать файл вручную, чтобы добавить зависимости, но в целом более быстрый и чистый способ — это добавить их:

poetry add pandas
poetry add scikit-learn~0.24
poetry add click

Примечание: pandas 1.2, вероятно, не работает, если версия python 3.7. Эта проблема решается просто путем обеспечения того, чтобы весь диапазон разрешенных версий Python поддерживался нашей запрошенной версией pandas. В этом случае изменение версии Python на 3.7.1 просто решит конфликт.

Чтобы установить вашу среду, находясь в корневой папке вашего проекта:

poetry install

Начнется установка всех ваших пакетов. После установки появится файл с именем poetry.lock. Этот файл является одним из других важных символов здесь. Он содержит информацию о каждой версии и сведения о каждом установленном пакете. Это важно, потому что, когда вы делитесь своим проектом, другие пользователи смогут копировать точно такую ​​же среду. Другой факт, что наличие thispoetry.lock ускорит разрешение зависимостей, поскольку они уже установлены.
Как вы могли заметить, при добавлении пакета, если вы не укажете иное, допускается диапазон версии. Например, ^7.1.2 означает, что в пустой проект можно установить любой пакет из 7.1.2‹=версия‹8.0. Но как только вы сделаете poetry install, будет выбрана последняя доступная версия в этом диапазоне. Эта версия будет записана в файл poetry.lock. По этой причине важно зафиксировать и поделиться этим файлом вместе с проектом.

После установки ваших пакетов можно получить доступ к этой среде:

poetry shell

И проверьте наш путь Python:

which python bash

Если вы попытаетесь импортировать pandas без предварительного вызова оболочки поэзии, вам будет предложено ввести ModuleNotFoundError: No module named ‘pandas‘.

Другой способ запуска скриптов в среде поэзии — использование poetry run. Пример:

poetry run which python

Если все прошло правильно, вы должны увидеть тот же путь, что и раньше, при вызове оболочки поэзии. Сила «бега» выходит за рамки этого. Поэзия поддерживает создание точек входа. Эти точки входа объявлены в pyproject.toml, и они являются «ярлыками» для быстрого выполнения вашего кода.
Давайте напишем небольшой пример. В poe_model_example создайте файл с именем main.py и добавьте следующий код:

Этот код проанализирует параметр (name) и передаст привет. Легко!
Это может быть следующим образом:

poetry run python poe_model_example/main.py -n Edgar

Но есть более компактный способ вызова этой функции. Как мы уже говорили, точки входа — это своего рода ярлыки для выполнения функций в файлах.
Это приведет к очень аккуратному способу выполнения различных частей вашего решения. Чтобы определить точку входа, вам нужно открыть файл pyproject.toml. Вы увидите что-то вроде:

[tool.poetry]
name = “poe_model_example”
version = “0.1.0”
description = “”
authors = [“Your Name <you-mail>”]
[tool.poetry.dependencies]
python = “3.7.1”
pandas = “1.2.1”
scikit-learn = “0.24.1”
click = “7.1.2”
[tool.poetry.dev-dependencies]
pytest = “5.2”
[build-system]
requires = [“poetry-core>=1.0.0”]
build-backend = “poetry.core.masonry.api”

Внизу добавьте:

[tool.poetry.scripts]
main = “poe_model_example.main:hello”

Синтаксис module.submodule:function.
Теперь мы можем переписать предыдущую строку так:

poetry run main -n Edgar

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

Разработка модели в местном

Создайте файл с именем train.py на том же уровне, что и main.py. Давайте определим некоторые импорты и глобальные переменные:

Модели будут сохранены в model_folder, а данные будут загружены из data_folder..

После обучения нашей модели нам понадобится эта пара функций, чтобы оценить ее производительность.

А теперь наша функция поезда.

После добавления предыдущего скрипта нам нужно изменить pyproject.toml. Добавлять:

train = “poe_model_example.train:train”

В центре внимания всей нашей разработки находится выполнение контейнерного исполнения.
Следовательно, было бы действительно интересно загрузить данные из корзины в какое-нибудь облако или базу данных.
Для простоты мы создадим фиктивный набор данных.
Чтобы создать набор данных , просто используйте следующий фрагмент:

Попробуйте свою модель на местном уровне:

poetry run train -n 10

В заключение зафиксируйте и отправьте свою работу в репозиторий. Неважно, публичный или приватный.
Этот код можно найти на моем GitHub.

Обучение нашей модели в контейнере Docker

На данный момент мы почти касаемся конца. Эта часть будет короче.
Для выполнения кода в контейнере есть несколько доступных контейнеров, готовых к использованию в DockerHub.

Прежде чем начать, если ваш репозиторий частный, вам нужно будет создать пару SSH-ключей (не забудьте зарегистрировать публичный), а затем:

SSH_NAME=’<your-ssh-key>’
GIT_REPO=’[email protected]:<user/your-repo>.git’
docker run -it \
--rm \
-v $HOME/.ssh/$SSH_NAME:/home/poe/.ssh/ssh-key \
-v $HOME/.ssh/$SSH_NAME.pub:/home/poe/.ssh/ssh-key.pub \
-v $HOME/models/:/home/poe/models/ \
-v $HOME/data/:/home/poe/data/ \
mgvalverde/batch-poetry:1.1.4-py37 \
$GIT_REPO train -n 10

Если ваш репозиторий является общедоступным, вы можете игнорировать часть SSH и использовать ссылку git в формате HTTPS.

После выполнения вы должны получить что-то вроде:

Если вы пропустили предыдущие шаги и просто хотите увидеть, как это работает на самом деле, попробуйте следующее:

docker run -it \
--rm \
mgvalverde/batch-poetry:1.1.4-py37 \
https://github.com/mgvalverde/poe_model_example.git main -n <your-name>

Что касается семантики тега контейнера, то первые три поля указывают на версию Poetry. Последние символы сообщают о версии Python.
Можно вызвать py37, py38 и py39.

Контейнер CDM получит имя репозитория, точку входа Poetry и, возможно, список необходимых параметров. Его можно использовать с репозиториями, размещенными в GitHub, Bitbucket и GitLab.

Если вам нужно изменить образ, он доступен на GitHub.

Следующие шаги

Так что это! Мы разработали модель и выполняем ее в докере. Следующие шаги, которые выходят за рамки этой статьи, заключаются в переносе этого выполнения в более масштабируемую среду, такую ​​как кластер K8s.
Несмотря на это, я дам несколько советов на случай, если вам понадобится перенести его на K8s.
SSH можно заменить на secrets, которые можно аналогичным образом смонтировать в вашем модуле. В нашей статье мы решили свести все к минимуму, чтобы не переусердствовать, но ничто не мешает вам загружать и сохранять данные с помощью корзины или базы данных. Точно так же есть несколько довольно удобных инструментов, таких как MLflow (и облачное хранилище), которые можно использовать для отслеживания (и сохранения) моделей.

Если вы добрались до здесь, спасибо!
Пожалуйста, не стесняйтесь комментировать ниже все, что вам нравится.
До следующего раза!