Разворачиваем среду для машинного обучения MLflow в облаке MAIL.RU


Обещал, что буду понемногу публиковать посты про data engineering и machine learning, и вот как раз появилась возможность поделиться результатами кейса по разворачиванию среды для машинного обучения MLflow. Мой кейс повторяет оригинальную презентацию ребят из Mail.ru, однако я оптимизировал шаги прохождения, плюс обратил внимание на некоторые нюансы, которые могут возникнуть, когда пытаешься его пройти. Оригинальные материалы к кейсу можете найти по ссылке внизу поста. Облачный провайдер Mail.ru любезно предоставил 3000 бонусных рублей на тестирование их продукта, что является отличной возможностью познакомиться с их облаком.

https://res.infoq.com/presentations/mlflow-databricks/en/slides
Source: https://res.infoq.com/presentations/mlflow-databricks/en/slides

Итак, а зачем вообще нам нужен фреймворк для ML? Фреймворк представляет удобный интерфейс к моделям и их параметрам. Ведет историю и сохраняет результаты каждого запуска модели, хранит артефакты для моделей. Легко нужно найти информацию когда, какую модель запускал, какие были результаты, как она отработала по сравнению с другими запусками с другими параметрами. Дата сайентисту периодически надо переобучать старые модели и для того, чтобы не запутаться во всем этом зоопарке различных версий, MLflow реально помогает держать все это под контролем. Еще один важный момент - фреймворк позволяет упростить публикацию модели через удобные оболочки- т.н. flawors, а также с помощью докер-образов.

Само развертывание инфраструктуры в облаке не сильно отличается от таковых в других облачных провайдерах , например в Яндекс облаке. Но может возникнуть резонный вопрос - а зачем дата-сайентисту заниматься тем, что по идее должен делать дата-инженер? Не наша эта работа. vpn настраивать! Все так. И в больших организациях инженера, аналитики и DS , как правило. делают каждый свой участок работы. В организациях поменьше, дата-аналитик может быть как с уклоном в инженерию, так и с уклоном в исследования. Частые ситуации, когда нужно проверить какую-нибудь гипотезу, быстро понять работает/не работает, стоит делать или нет. И пока админы будут согласовывать доступы и поднимать виртуалки, время может быть упущено. Поэтому современному дата-санетисту неплохо владеть азами по инженерной части, чтобы просто облегчить себе жизнь, а инженерам также неплохо понимать, что из себя представляет процесс промышленного ml и что дело не ограничивается запуском моделек в jupyter-ноутбуке. В современном мире науки о данных специалист-профессионал должен обладать широким набором технических скилов.

Регистрируемся в облаке MAIL.RU


Заходим на https://mcs.mail.ru/ и регистрируем новую учетку. 




В отличие от Яндекса, где облачная учетка обязательно должна быть на яндекс-почте, у мейла таких требований нет. Я регистрировал аккаунт с гугловой почты. Бонусные баллы для теста начисляются не сразу, а на следующий день. Мне перезвонила девушка из службы поддержки. задала несколько вопрос про сервис и сказала. что баллы сейчас должны появится на балансе.

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


Данный кейс реализован именно по такому, максимально сложному сценарию.

Вспоминаю Линукс

Хорошо, что когда-то я увлекался альтернативными операционными системами и вид bash-консоли не заставил меня хлопнуть крышкой ноутбука.

Две из четырех подсистем мы будем разворачивать на виртуальных линукс-машинах. Итак, какие основные подсистемы MLflow:


  1. Tracking server (вм Линукс) - это, что-то вроде центра, который связываем между собой все остальные подсистемы и отвечает на синхронизацию данных и логирование.
  2. Backend server - (база данных Postgres) - для хранения различных служебных сущностей (параметров запуска, метрик, тегов, заметок к экспериментам, метадаты и т.д.)
  3. S3 файловое хранилище (cloud storage). В нем хранятся артефакты - сами модели, файлы, изображения, датасеты
  4. Jupyter host (вм Линукс) джупитер оболочка, в которой собственно и будем запускать модели.

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





Практически, все что надо сделать - это задать свое название сети, чтобы потом было легко ориентироваться.




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







Второй важный шаг, который надо сделать еще до создания виртуальных машин - это создать пару ключей для доступа по SSH. Не буду подробно останавливаться на этом этапе, дам лишь ссылку на документацию, где все подробно описано. Есть даже отдельная вставка, для таких как я , кто все еще использует Windows 8.1. Вам придется установить ssh-клиент Putty и немного заморочиться с преобразованием ключей из *pem в *ppk формат. Все подробно описано в справке, у меня получилось с первого раза все настроить и подключиться, чего и вам желаю. Ну, а если уже перешли на Windows 10, то у вас уже есть встроенный ssh-клиент.

Шаг 1. Создаем Tracking Server

Идем в Облачные вычисления, Виртуальные машины, жмем создать инстанс



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



На первом шаге задаем имя нашей виртуалки, выбираем тип (процессор+память), тип дискового накопителя. операционную систему лучше брать такую, как на моем примере - Ubuntu 18.04.202003, т.к. MLflow стабилен не на всех дистрибутивах линукса, а эта версия официально одобрена для применения.

На втором шаге выбираем сеть/подсеть и ключ виртуальной машины, которые мы заранее создали. Если вы создавали одну пару ключей, то сам ключ автоматом подтянется в настройки. Дальше идут настройки firewall. Я выбрал доступ ssh и web.

Сам web потом нужно будет отредактировать, чтобы открыть порт доступа для захода на трекинг-сервер через браузер. И так у вас должны быть выбраны: default, ssh, web. На третьем шаге идут настройки резервного копирования, которые я в тестовых целях пропустил, но если вы делаете боевое развертывание, то советую уделить бэкапингу внимание. Жмем создать инстанс и ждем примерно минут 5-7, пока виртуалка создается.
 После создания инстанса зайдем в его параметры и скопируем в блокнот значения внутреннего и внешнего IP. Затем идем в настройки фаервола, находим нужную нам группу (web/ssh+web) и открываем в протоколе TCP порт 8000.

Если этого не сделать, то не получится зайти в UI сервера через браузер.


Шаг 2. Создаем backend server

Идем в боковое меню Базы данных

выбираем PostgreSQL 12

 выбираем конфигурацию (я делал на Master/Slave)

После этого задаем конфигурацию самого инстанса. Здесь все в общем-то тоже самое. что и при создании виртуалки под трекинг-сервер. Задаем имя, тип производительности, вид дисковых накопителей, секретный ключ, настройки фаервола (можно оставить только ssh, т.к. нам не понадобиться заходить на нее через web)



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

 Создадим нового сервисного юзера mlflow под которым будет работать бекенд фреймворка.


 Также идём в параметры и копируем ip-адреса нашего бэкенд сервера.

Шаг 3. Создаем объектное хранилище

Боковое меню, Объектное хранилище, S3 объектное хранилище, создать бакет


Выбираем класс хранения Hotbox.




После этого создаем папку artifacts в корневой директории.


Затем создаем аккаунт для S3.


 
Придумываем имя и копируем в блокнот Access Key и Secret Key. Они нам понадобятся дальше.




Шаг 4. Создаем инстанс под Jupyter hub

Идем в машинное обучение, Создать среду для обучения. 



Дальше проходим шаги 1-3 выбора параметров инстанса также как делали с первой виртуалкой. Записываем внешний/внутренний ip и открываем настройки фаервола на TCP, порт 8888 (оболочка джупитера)



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


Устанавливаем софт и настраиваем креды

Для того, чтобы запустить фреймворк, нам необходимо его установить, а также необходимый под него софт.

Дальше будет много кода )

Для ВМ1:

Заходим через ssh на первую вм - которую создавали под трекинг-сервер:


ssh -i YOUR_SSH_KEY ubuntu@EXTERNAL_VM_IP

Загружаем менеджер пакетов conda и активируем оболочку bash:

curl -O https://repo.anaconda.com/archive/Anaconda3-2020.11-Linux-x86_64.sh

bash Anaconda3-2020.11-Linux-x86_64.sh

exec bash



Создаем отдельное окружение под MLflow и активируем его:

conda create -n mlflow_env

conda activate mlflow_env


Устанавливаем софт:

conda install python=3.7.0

pip install mlflow==1.14.1

pip install boto3

pip install psycopg2-binary


Я рекомендую устанавливать версию 1.14.1, т.к. в версии 1.15.0 был баг, с ошибкой при соединении с бекенд сервером на postgres 
(upd. на гитхабе проекта пишут, что этот баг пофиксили в версии 1.16.0)


Теперь можно выйти из окружения:

conda deactivate

Теперь пропишем координаты нашего S3 хранилища, чтобы трекинг-сервер знал где его искать:

sudo nano /etc/environment

копируем эти строчки в свободное место:

MLFLOW_S3_ENDPOINT_URL=https://hb.bizmrg.com

MLFLOW_TRACKING_URI=http://INTERNAL_IP_TS:8000


(вместо INTERNAL_IP_TS вставьте внутренний IP нашего трекинг-сервера, который сохранили на шаге 1)

Создаем папку и файл с реквизитами доступа к S3:

mkdir .aws

nano ~/.aws/credentials


В файл копируем эти строчки:

[default]

aws_access_key_id = YOUR_ACCESS_KEY

aws_secret_access_key = YOUR_SECRET_KEY

Соответственно меняем YOUR_ACCESS_KEY и YOUR_SECRET_KEY на значения пары ключей от S3 сохраненный на шаге 3.

Теперь сделаем так, чтобы сам MLflow запускался как системный сервис. Это избавит нас от необходимости быть постоянно залогиненным в консоль для запуска MLflow.

Создаем 2 папки и один файл:

mkdir ~/mlflow_logs/

mkdir ~/mlflow_errors/

sudo nano /etc/systemd/system/mlflow-tracking.service


Копируем в файл следующие строчки:

[Unit]

Description=MLflow Tracking Server

After=network.target

[Service]

Environment=MLFLOW_S3_ENDPOINT_URL=https://hb.bizmrg.com

Restart=on-failure

RestartSec=30

StandardOutput=file:/home/ubuntu/mlflow_logs/stdout.log

StandardError=file:/home/ubuntu/mlflow_errors/stderr.log

User=ubuntu

ExecStart=/bin/bash -c 'PATH=/home/ubuntu/anaconda3/envs/mlflow_env/bin/:$PATH exec mlflow server --backend-store-uri postgresql://PG_USER:PG_PASSWORD@INTERNAL_IP_BACKEND_VM/DB_NAME --default-artifact-root s3://YOUR_BUCKET_NAME/YOUR_DIRECTORY/ -h 0.0.0.0 -p 8000' 

[Install]

WantedBy=multi-user.target


Соответсвенно:

PG_USER меняете на имя пользователя базы данных, которого создали на шаге 2

INTERNAL_IP_BACKEND_VM меняете на внутренний IP базы данных Postgres , тоже шаг 2

YOUR_BUCKET_NAME меняете на имя S3 хранилища c шага 3

YOUR_DIRECTORY меняете на artifacts, если задали именно такое имя директории на шаге 3

Сохраняем, закрываем.

Теперь надо активировать сам трекинг-сервер. Набираем в консоли команды:

sudo systemctl daemon-reload

sudo systemctl enable mlflow-tracking

sudo systemctl start mlflow-tracking

sudo systemctl status mlflow-tracking



После этого открываете свой любимый браузер и пишем в адресной строке:

http://EXTERNAL_IP_TS:8000

Вместо EXTERNAL_IP_TS прописываете внешний ip трекинг-сервера. Если всё сделали правильно, увидите примерно такую картинку (ui MLflow):



Для ВМ3:

Логинимся через SSH в нашу виртуалку №3.

Создадим рабочее окружение и установим софт. Все в точности, как и на первой виртуалке:

Создаем отдельное окружение под ml-flow и активируем его:

conda create -n mlflow_env

conda activate mlflow_env


Устанавливаем софт:

conda install python=3.7.0

pip install mlflow==1.14.1

pip install boto3

pip install psycopg2-binary


Создадим отдельный python kernel для ml-flow:

conda install -c anaconda ipykernel

python -m ipykernel install --user --name ex --display-name "Python (mlflow)"

Запускаем Jupyter:

jupyter notebook

Теперь открываем браузер и переходим по такому адресу:

http://name_of_host:8888/?token=5d3d6b7a0551asdffds41sdvlgfd8sdffsd329bee345esdfmkdfs2c042c0b7dffb


Где name_of_host - внешний IP нашей третьей виртуалки, а токен будет выведен в консоли

в результате запуска джупитера (его надо скопировать). Не забудьте, что порт 8888 должен быть открыт по протоколу TCP на третьей виртуалке.


Заключение

На этом всё. Среда для машинного обучения развернута. Мы с вами научились создавать виртуальные машины и устанавливать на них софт, создали базу данных Postgres и S3-бакет, установили фреймворк для машинного обучения MLflow в максимально распределенном сценарии и сконфигурировали доступ между всеми подсистемами фрейморка. И все это мы сделали в облаке, не используя он-премис инфраструктуру.

Что дальше ? Если вам интересно машинное обучение, можете самостоятельно клонировать авторский репозиторий с демо-моделью и пройти шаги начиная с 12.


Ссылки на оригинальный материалы:

Официальная документация MLflow: https://mlflow.org/docs/latest/tracking.html

Гитхаб автора оригинального кейса: https://github.com/stockblog/webinar_mlflow

Вебинар с презентацией: https://www.youtube.com/watch?v=rfEE4Yc4gXg&t=2529s


























.


Комментарии

Популярные сообщения из этого блога

Быстрый импорт в базу данных с помощью DBeaver

Jupyter-фишки, которые облегчат жизнь аналитику

Два способа загрузить свой датасет в Python

5 приемов при работе с модулем datetime в Python

Чистка и препроцессинг данных. Готовим датасет для ML.