Как перенести код машинного обучения и его зависимости в производственную среду.

Джейн работает инженером по машинному обучению (ML) в успешном стартапе. Они собираются выпустить первую версию своего продукта, который в значительной степени зависит от производительности алгоритма машинного обучения, над которым она работает. После нескольких итераций модель, которую она обучила, показала достаточно хорошие результаты на отложенном наборе тестов, и она готова сделать следующий шаг.

Во-первых, она быстро разрабатывает прототип с помощью Gradio и размещает его на пространствах Hugging Face. Теперь у нее есть работающее приложение на основе машинного обучения с простым пользовательским интерфейсом, которым она может поделиться с доверенными друзьями и коллегами. Джейн использует это для получения отзывов и проверки производительности модели в реальных сценариях.



Теперь она готова приступить к следующему этапу процесса разработки; построить правильный сервер логического вывода. Убежденная, что подход «Модель как услуга» (MaaS) — это путь вперед, она добавляет несколько новых пунктов в свой список задач:

  • Упакуйте модель
  • Создайте REST API
  • Оптимизировать работу сервиса
  • Займитесь масштабированием
  • Оптимизация развертывания версий


Сегодня понедельник. Она берет первый пункт в своем списке: упаковать модель. В этой истории мы исследуем две ее альтернативы и почему наиболее часто используемая дорога — хотя и каменистая — является наилучшей.

Learning Rate — информационный бюллетень для тех, кому интересен мир ИИ и MLOps. В первую субботу каждого месяца вы будете получать от меня новости и мысли о последних новостях и статьях об искусственном интеллекте. Подписывайтесь здесь!

Упаковка моделей и управление зависимостями

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

Предсказания модели зависят от написанного ею кода, его зависимостей и весов модели. Все эти артефакты должны присутствовать на сервере логических выводов. К сожалению, это непростая задача. Вы можете подумать, что Джейн достаточно раскрутить виртуальную машину, подключиться к ней по ssh, установить все зависимости, скопировать код и веса модели, запустить приложение flask и назвать его сервером вывода. Это не; так в чем проблема?

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

Код вашей модели может зависеть от десятков или сотен других библиотек (например, pytorch, torchvision, torchmetrics, numpy, scipy и т. д.). Ваш сервер приложений также имеет свои собственные зависимости (например, flaks, gunicorn и т. д.). Уследить за всем и поддерживать различные среды, как известно, сложно. Джейн необходимо синхронизировать свои среды разработки, тестирования, промежуточной и производственной среды. Это кошмар.

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

Ограничение зависимостей модели

Один из вариантов Джейн — ограничить зависимости ее модели. Сегодня основным способом сделать это является использование библиотеки под названием ONNX (Open Neural Network Exchange).

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

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

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

Упаковка кода вывода в контейнеры

Когда мы говорим о контейнерах, девять из десяти раз мы имеем в виду контейнеры Docker. Хотя Docker требует некоторого обучения, начать работу с ним не так сложно, и это лучший вариант для Джейн.

Джейн должна написать Dockerfile, создать образ и отправить его в реестр образов, например DockerHub. На более позднем этапе это можно автоматизировать с помощью конвейера CI/CD, поэтому вложение времени в это может занять много времени. Джейн теперь может перенести этот образ на любой компьютер, на котором работает среда выполнения контейнера, и выполнить его без каких-либо головных болей.

Контейнеры и Docker произвели революцию в том, как мы упаковываем приложения. Они настолько вездесущи, что даже если вы не хотите углубляться в детали, некоторые сервисы могут помочь вам упаковать ваш код машинного обучения в стандартные, готовые к работе контейнеры. Cog, BentoML и Truss — это проекты, которые обеспечивают более быстрый способ доставки ваших моделей.

Однако я считаю, что, поскольку вы в любом случае собираетесь писать файл YAML, лучше изучить синтаксис Docker и Kubernetes. Это знание, которое вы можете перенести и в другие домены, помогая вам получить общее представление о многих шагах, которые входят в процесс развертывания.

Заключение

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

Когда вы будете готовы упаковать его и создать сервер вывода, у вас будет два варианта: ограничить его зависимости или упаковать его в контейнер.

В этой истории мы увидели, что, несмотря на амбициозность таких инструментов, как ONNX, упаковать код вашей модели и его зависимости в контейнер — это еще не все. В дальнейшем мы увидим, как это сделать с помощью Docker, KServe и Kubernetes.

об авторе

Меня зовут Димитрис Пулопулос, я инженер по машинному обучению, работаю в компании Аррикто. Я разработал и внедрил ИИ и программные решения для крупных клиентов, таких как Европейская комиссия, Евростат, МВФ, Европейский центральный банк, ОЭСР и IKEA.

Если вы хотите прочитать больше сообщений о машинном обучении, глубоком обучении, науке о данных и DataOps, подпишитесь на меня в Medium, LinkedIn или @james2pl в Twitter.

Высказанные мнения являются исключительно моими собственными и не отражают точку зрения или мнение моего работодателя.