Бэкенд, машинное обучение и serverless — самое интересное с июльской конференции Хабра

Конференция Хабра — история не дебютная. Раньше мы проводили довольно крупные мероприятия Тостер на 300–400 человек, а сейчас решили, что актуальными будут небольшие тематические встречи, направление которых можете задавать и вы — например, в комментариях. Первая конференция такого формата прошла в июле и была посвящена бэкенд-разработке. Участники слушали доклады об особенностях перехода из бэкенда в ML и об устройстве сервиса «Квадрюпель» на портале «Госуслуги», а также приняли участие в круглом столе, посвященном Serverless. Тем, кто не смог посетить мероприятие лично, в этом посте мы рассказываем самое интересное.

9bd04a8ab9b6a12c0d985c7d2a13bc3e.jpg

Из бэкенд-разработки в машинное обучение


Чем занимаются дата-инженеры в ML? Чем сходны и чем отличаются задачи бэкенд-разработчика и ML-инженера? Какой путь нужно пройти, чтобы сменить первую профессию на вторую? Об этом рассказал Александр Паринов, который ушел в машинное обучение после 10 лет бэкенда.

71d4b7e2307b78cefd6f1868a33b983d.jpg
Александр Паринов

Сегодня Александр работает архитектором систем компьютерного зрения в X5 Retail Group и контрибьютит в Open Source проекты, связанные с компьютерным зрением и глубоким обучением (github.com/creafz). Его скилы подтверждает участие в топ-100 мирового рейтинга Kaggle Master (kaggle.com/creafz) — самой популярной платформы, проводящей соревнования по машинному обучению.

Зачем переходить на машинное обучение


Полтора года назад Джефф Дин, главы Google Brain — проекта Google по исследованию искусственного интеллекта на основе глубокого обучения — рассказал, как полмиллиона строк кода в Google Translate заменили нейронной сетью на Tensor Flow, состоящей всего из 500 строк. После обучения сети качество данных выросло, а инфраструктура упростилась. Казалось бы, вот наше светлое будущее: больше не придется писать код, достаточно делать нейронки и закидывать их данными. Но на практике все гораздо сложнее.
6e1ef3f8d1dc8a5c0b9997d067fd42e0.pngML-инфраструктура в Google
 
Нейронные сети — это лишь небольшая часть инфраструктуры (маленький черный квадратик на картинке выше). Требуется еще много вспомогательных систем, чтобы получать данные, обрабатывать их, хранить, проверять качество и т. д., нужна инфраструктура для обучения, развертывания кода машинного обучения в продакшене, тестирования этого кода. Все эти задачи как раз похожи на то, чем занимаются бэкенд-разработчики.
a4021b9083599fca9590b8e4e86f264e.pngПроцесс машинного обучения

Чем отличается ML от бэкенда


В классическом программировании мы пишем код, и это диктует поведение программы. В ML у нас есть небольшой код модели и много данных, которыми мы закидываем модель. Данные в ML очень важны: одна и та же модель, обученная разными данными, может показывать совершенно разные результаты. Проблема заключается в том, что почти всегда данные разрозненны и лежат в разных системах (реляционные базы данных, NoSQL-базы, логи, файлы).
337654f0fe47cacf9bc67106a4220f27.pngВерсионирование данных

ML требует версионирования не только кода, как в классической разработке, но и данных: необходимо четко понимать, на чем обучалась модель. Для этого можно пользоваться популярной библиотекой Data Science Version Control (dvc.org).
 
8c672ec94474cfe5514c2cd63ef7e19d.png
Разметка данных

Следующая задача — разметка данных. Например, отметить все предметы на картинке или сказать, к какому классу она принадлежит. Этим занимаются специальные сервисы наподобие «Яндекс.Толоки», работу с которыми сильно упрощает наличие API. Сложности возникают из-за «человеческого фактора»: повысить качество данных и свести ошибки к минимуму можно, поручая одно и то же задание нескольким исполнителям.
 
1065a6eadbc73ed0b75a57c7b5f81a4b.pngВизуализация в Tensor Board

Логирование экспериментов необходимо для сравнения результатов, выбора лучшей по каким-то метрикам модели. Для визуализации есть большой набор средств — например, Tensor Board. Но для хранения экспериментов каких-то идеальных способов нет. В маленьких компаниях зачастую обходятся excel-табличкой, в крупных используют специальные платформы для хранения результатов в БД.
 
0c2bf374fc82ea80c96757253e2575b1.pngПлатформ для машинного обучения множество, но ни одна из них не закрывает и 70% потребностей
 
Первая проблема, с которой приходится сталкиваться при выводе обученной модели в продакшн, связана с любимым инструментом дата-сайентистов — Jupyter Notebook. В нем нет модулярности, то есть на выходе получается такая «портянка» кода, не разбитого на логические куски — модули. Все перемешано: классы, функции, конфигурации и т. д. Этот код трудно версионировать и тестировать.
 
Как с этим бороться? Можно смириться, как Netflix, и создать свою платформу, позволяющую прямо в продакшене запускать эти ноутбуки, передавать им на вход данные и получать результат. Можно заставить разработчиков, которые катят модель в продакшн, переписать код нормально, разбить на модули. Но при таком подходе легко ошибиться, и модель будет работать не так, как задумывалось. Поэтому идеальный вариант — запретить использовать Jupyter Notebook для кода моделей. Если, разумеется, дата-сайентисты на это согласятся.fee0716bf440a4cf5a28b405c0a4f775.pngМодель как черный ящик

Самый простой способ вывести модель в продакшн — использовать ее как черный ящик. У вас есть какой-то класс модели, вам передали веса модели (параметры нейронов обученной сети), и если вы этот класс инициализируете (вызовите метод predict, подадите на него картинку), то на выходе получите некое предсказание. Что происходит внутри — не имеет значения.

7ed1dc5a3f28c94339439c1625a2263d.png
Отдельный процесс-сервер с моделью

Можно также поднять некий отдельный процесс и засылать его через очередь RPC (с картинками или другими исходными данными. На выходе мы будем получать предикты.

Пример использования модели во Flask:

@app.route("/predict", methods=["POST"])
def predict():
image = flask.request.files["image"].read()
image = preprocess_image(image)
predictions = model.predict(image)
return jsonify_prediction(predictions)

 
Проблема такого подхода — ограничение производительности. Допустим, у нас есть код на Phyton, написанный дата-сайентистами, который тормозит, а мы хотим выжать максимальную производительность. Для этого можно использовать инструменты, которые преобразовывают код в нативный или конвертируют его в другой фреймворк, заточенный под продакшн. Такие инструменты есть для каждого фреймворка, но идеальных не существует, придется допиливать самостоятельно.
 
Инфраструктура в ML такая же, как в обычном бэкенде. Есть Docker и Kubernetes, только для Docker нужно поставить рантайм от NVIDIA, который позволяет процессам внутри контейнера получить доступ к видеокартам в хосте. Для Kubernetes нужен плагин, чтобы он мог менеджить серверы с видеокартами.
5e2d3609d69dc2930e63945ab2dcb97d.png
В отличие от классического программирования, в случае с ML в инфраструктуре появляется много разных подвижных элементов, которые нужно проверять и тестировать — например, код обработки данных, пайплайн обучения модели и продакшн (см. схему выше). Важно протестировать код, связывающий разные куски пайплайнов: кусков много, и проблемы очень часто возникают на границах модулей.
 
c81f259b4781c850a896b5dbeb6d0302.png
Как работает AutoML

Сервисы AutoML обещают подобрать оптимальную для ваших целей модель и обучить ее. Но нужно понимать: в ML очень важны данные, результат зависит от их подготовки. Разметкой занимаются люди, что чревато ошибками. Без жесткого контроля может получиться мусор, а автоматизировать процесс пока не выходит, нужна проверка со стороны специалистов — дата-сайентистов. Вот на этом месте и «ломается» AutoML. Но он может быть полезен для подбора архитектуры — когда вы уже подготовили данные и хотите провести серию экспериментов для поиска лучшей модели.

Как попасть в машинное обучение


Попасть в ML проще всего, если вы разрабатываете на Python, который используется во всех фреймворках для глубокого обучения (и обычных фреймворках). Этот язык практически обязателен для данной сферы деятельности. С++ применяется для некоторых задач с компьютерным зрением — например, в системах управления беспилотными автомобилями. JavaScript и Shell — для визуализации и таких странных вещей, как запуск нейронки в браузере. Java и Scala используется при работе с Big Data и для машинного обучения. R и Julia любят люди, которые занимаются матстатистикой.
 
Получать практический опыт для начала удобнее всего на Kaggle, участие в одном из конкурсов платформы дает больше, чем год изучения теории. На этой платформе вы можете взять чей-то выложенный и прокомментированный код и попытаться его улучшить, оптимизировать под свои цели. Бонус — ранг на Kaggle влияет на вашу зарплату.
 
Другой вариант — пойти бэкенд-разработчиком в ML-команду. Сейчас много стартапов, занимающихся машинным обучением, в которых вы наберетесь опыта, помогая коллегам в решении их задач. Наконец, можно вступить в одно из сообществ дата-сайентистов — Open Data Science (ods.ai) и другие.
 
Дополнительную информацию по теме докладчик разместил по ссылке https://bit.ly/backend-to-ml

«Квадрюпель» — сервис таргетированных уведомлений портала «Госуслуги»


a44cf20548a8c0798c440c878570afff.jpgЕвгений Смирнов

Следующим выступал начальник отдела разработки инфраструктуры электронного правительства Евгений Смирнов, который рассказал о «Квадрюпеле». Это сервис таргетированных уведомлений портала «Госуслуги» (gosuslugi.ru) — самого посещаемого государственного ресурса Рунета. Дневная аудитория составляет 2,6 млн, всего же на сайте зарегистрировано 90 млн пользователей, из них 60 млн — подтвержденные. Нагрузка на API портала — 30 тыс. RPS.
 
3b8e5ae05d254b59de3b67093a7b0a47.pngТехнологии, которые используются в бэкенде «Госуслуг»
 
«Квадрюпель» — сервис адресного оповещения, с помощью которого пользователь получает предложение об услуге в наиболее подходящий для него момент путем настройки специальных правил информирования. Основными требованиями при разработке сервиса были гибкие настройки и адекватное время на рассылки.

Как работает Квадрюпель


4a3d78484bbe63c0ef0f1f439125b816.png

На схеме выше показано одно из правил работы «Квадрюпеля» на примере ситуации с необходимостью замены водительских прав. Сначала сервис ищет пользователей, у которых срок годности кончается через месяц. Им выставляется баннер с предложением получить соответствующую услугу и отправляется сообщение на электронную почту. Для тех пользователей, у которых срок уже истек, баннер и email меняются. После успешного обмена прав пользователь получает другие уведомления — с предложением обновить данные в удостоверении.

С технической точки зрения это groovy-скрипты, в которых написан код. На входе — данные, на выходе — true/false, совпало/не совпало. Всего более 50 правил — от определения дня рождения пользователя (текущая дата равна дате рождения пользователя) до сложных ситуаций. Ежедневно по этим правилам определяется около миллиона совпадений — людей, которых нужно оповестить.
 
018480a990a48fb2d6af080d4e16d20c.pngКаналы уведомлений «Квадрюпеля»
 
Под капотом «Квадрюпеля» находится БД, в которой хранятся данные пользователей, и три приложения:  

  • Worker предназначен для обновления данных.
  • Rest API забирает и отдает на портал и на мобильное приложение сами баннеры.
  • Scheduler запускает работы по пересчету баннеров или массовой рассылки.


fe6b6457f25777215b56879621a2a0f9.png

Для обновления данных бэкенд событийно ориентирован. Два интерфейса — рест или JMS. Событий много, перед сохранением и обработкой они агрегируются, чтобы не делать лишних запросов. Сама БД, табличка, в которой хранятся данные, выглядит как key value хранилище — ключ пользователя и само значение: флажки, обозначающие наличие или отсутствие соответствующих документов, их срок действия, агрегированная статистика по заказу услуг этим пользователем и прочее.
 
5ee0d689be5f4dd6a2deb353b3523316.png

После сохранения данных ставится задача в JMS, чтобы немедленно пересчитались баннеры — это нужно сразу отображать на вебе. Система запускается по ночам: в JMS накидываются задачи с интервалами пользователей, по которым надо пересчитать правила. Это подхватывают обработчики, занятые пересчетом. Далее результаты обработки попадают в следующую очередь, которая либо сохраняет баннеры в БД, либо отправляет в сервис задачи на нотификацию пользователя. Процесс занимает 5–7 часов, он легко масштабируется за счет того, что можно всегда либо докинуть обработчиков, либо поднять инстансы с новыми обработчиками.
 
ca94916852f26beb07515670f718219e.png

Сервис работает достаточно хорошо. Но объем данных растет, поскольку пользователей становится больше. Это приводит к увеличению нагрузки на базу — даже с учетом того, что Rest API смотрит в реплику. Второй момент — JMS, который, как выяснилось, не очень подходит из-за большого потребления памяти. Высок риск переполнения очереди с падением JMS и остановкой обработки. Поднять JMS после этого без очистки логов невозможно.
 
114bb1ad6e5870eb3ea7d0fb2228233a.png

Решать проблемы планируется при помощи шардирования, что позволит балансировать нагрузку на базу. Также в планах сменить схему хранения данных, а JMS поменять на Kafka — более отказоустойчивое решение, которое урегулирует проблемы с памятью.
 

Backend-as-a-Service Vs. Serverless


e7198c48dcf015593d8753bbb53b9164.jpg
Слева направо: Александр Боргарт, Андрей Томиленко, Николай Марков, Ара Исраелян

Бэкенд как сервис или Serverless-решение? В обсуждении этого актуального вопроса на круглом столе участвовали:

  • Ара Исраелян, технический директор CTO и основатель Scorocode.
  • Николай Марков, Senior Data Engineer в компании Aligned Research Group.
  • Андрей Томиленко, руководитель отдела разработки RUVDS. 


Модератором беседы стал старший разработчик Александр Боргарт. Мы приводим дебаты, в которых участвовали и слушатели, в сокращенном варианте.

— Что такое Serverless в вашем понимании?

Андрей: Это модель вычислений — Lambda-функция, которая должна обрабатывать данные так, чтобы результат зависел только от данных. Термин пошел то ли от Гугла, то ли от Амазона и его сервиса AWS Lambda. Провайдеру проще обрабатывать такую функцию, выделив под это пул мощностей. Разные пользователи могут независимо считаться на одних и тех же серверах.
Николай: Если просто — мы переносим какую-то часть своей IT-инфраструктуры, бизнес-логики в облако, на аутсорс.
Ара: Со стороны разработчиков — неплохая попытка сэкономить ресурсы, со стороны маркетологов — заработать побольше денег.

— Serverless — то же, что и микросервисы?

Николай: Нет, Serverless — это больше организация архитектуры. Микросервис — атомарная единица некоей логики. Serverless — подход, а не «отдельная сущность».
Ара: Функцию Serverless можно упаковать в микросервис, но от этого она перестанет быть Serverless, перестанет быть Lambda-функцией. В Serverless работа функции начинается только в тот момент, когда ее запрашивают.
Андрей: Они отличаются временем жизни. Lambda-функцию мы запустили и забыли. Она отработала пару секунд, и следующий клиент может обработать свой запрос на другой физической машине.

— Что лучше масштабируется?

Ара: При горизонтальном масштабировании Lambda-функции ведут себя абсолютно так же, как микросервисы.
Николай: Какое задашь количество реплик — столько их и будет, нет никаких проблем с масштабированием у Serverless. В Kubernetes сделал реплика-сет, запустил 20 инстансов «где-нибудь», и тебе вернулось 20 обезличенных ссылок. Вперед!

— Можно ли писать бэкенд на Serverless?

Андрей: Теоретически, но смысла в этом нет. Lambda-функции будут упираться в единое хранилище — нам же нужно обеспечить гарантированность. Например, если пользователь провел некую транзакцию, то при следующем обращении он должен увидеть: транзакция проведена, средства зачислены. Все Lambda-функции будут блокироваться на этом вызове. По факту куча Serverless-функций превратится в единый сервис с одной узкой точкой обращения к базе данных.

— В каких ситуациях есть смысл применения бессерверной архитектуры?

Андрей: Задачи, в которых не требуется общее хранилище — тот же майнинг, блокчейн. Там, где нужно много считать. Если у вас куча вычислительных мощностей, то вы можете определить функцию типа «посчитай хэш чего-то там…» Но вы можете решить проблему с хранением данных, взяв, например, от Амазона и Lambda-функции, и их распределенное хранилище. И получится, что вы пишете обычный сервис. Lambda-функции будут обращаться к хранилищу и выдавать какой-то ответ пользователю.
Николай: Контейнерчики, которые запускаются в Serverless, крайне ограничены по ресурсам. Там мало памяти и всего остального. Но если у вас вся инфраструктура развернута полностью на каком-то облаке — Гугл, Амазон — и у вас с ними постоянный контракт, есть бюджет на все это, тогда для каких-то задач можно использовать Serverless-контейнеры. Необходимо находиться именно внутри этой инфраструктуры, потому что все заточено под использование в конкретном окружении. То есть если вы готовы завязать все на инфраструктуру облака — можете поэкспериментировать. Плюс в том, что не придется менеджить эту инфраструктуру.
Ара: Что Serverless не требует от вас менеджить Kubernetes, Docker, ставить Kafka и так далее — это самообман. Те же Амазон и Гугл это менеджат и ставят. Другое дело, что у вас есть SLA. С тем же успехом можно отдать все на аутсорсинг, а не программировать самостоятельно.
Андрей: Сам Serverless недорогой, но приходится много платить за остальные амазоновские сервисы — например, базу данных. С ними народ уже судился, за то, что они драли бешеные деньги за API gate.
Ара: Если говорить о деньгах, то нужно учитывать такой момент: вам придется развернуть на 180 градусов всю методологию разработки в компании, чтобы перевести весь код на Serverless. На это уйдет много времени и средств.

— Есть ли достойные альтернативы платным Serverless Амазона и Гугла?

Николай: В Kubernetes вы запускаете какой-то job, он отрабатывает и умирает — это вполне себе Serverless с точки зрения архитектуры. Если хочется реально интересную бизнес-логику создать с очередями, с базами, то нужно чуть больше над этим подумать. Это все решается, не выходя из Kubernetes. Тащить дополнительную реализацию я бы не стал.

— Насколько важно мониторить то, что происходит в Serverless?

Ара: Зависит от архитектуры системы и требований бизнеса. По сути, провайдер должен предоставлять отчетность, которая поможет девопсу разобраться в возможных проблемах.
Николай: В Амазоне есть CloudWatch, куда стримятся все логи, в том числе и с Lambda. Интегрируйте пересылку логов и используйте какой-то отдельный инструмент для просмотра, алертинга и так далее. В контейнеры, которые вы стартуете, можно напихать агентов.

173767b57ac15dd164ad69c428d9ae03.jpg

— Давайте подведем итог.

Андрей: Думать о Lambda-функциях полезно. Если вы создаете сервис на коленке — не микросервис, а такой, который пишет запрос, обращается к БД и присылает ответ — Lambda-функция решает целый ряд проблем: с многопоточностью, масштабируемостью и прочим. Если у вас логика построена подобным образом, то в будущем вы сможете эти Lambda перенести в микросервисы или воспользоваться сторонними сервисами наподобие Амазона. Технология полезная, идея интересная. Насколько она оправдана для бизнеса — это пока открытый вопрос.
Николай: Serverless лучше применять для operation-задач, чем для расчета некоей бизнес-логики. Я всегда воспринимаю это как event processing. Если у вас в Амазоне он есть, если вы в Kubernetes — да. Иначе вам придется довольно много усилий приложить, чтобы поднять Serverless самостоятельно. Необходимо смотреть конкретный бизнес-кейс. Например, у меня сейчас одна из задач: когда появляются файлы на диске в определенном формате — нужно их заливать в Kafka. Я это могу использовать WatchDog или Lambda. С точки зрения логики подходят оба варианта, но по реализации Serverless сложнее, и я предпочитаю более простой путь, без Lambda.
Ара: Serverless — идея интересная, применимая, очень технически красивая. Рано или поздно технологии дойдут до того, что любая функция будет подниматься меньше, чем за 100 миллисекунд. Тогда в принципе отпадет вопрос о том, критично ли для пользователя время ожидания. При этом применимость Serverless, как уже говорили коллеги, полностью зависит от бизнес-задачи.

Мы благодарим наших спонсоров, которые нам очень помогли:

  • Пространство IT- конференций «Весна» за площадку для конференции.
  • Календарь IT-мероприятий Runet-ID и издание «Интернет в цифрах»  за информационную поддержку и новости.
  • «Акронис» за подарки.
  • Avito за сотворчество.
  • «Ассоциацию электронных коммуникаций» РАЭК за вовлеченность и опыт.
  • Главного спонсора RUVDS — за все!


7d53747cc37e595ec4ec995267865c93.jpg

© Habrahabr.ru