Используйте ONNX и среду выполнения ONNX для совместного использования единой модели для разных языков программирования и технологических стеков.

Одной из частых проблем для организаций, пытающихся внедрить модели машинного обучения в производственную среду, является несоответствие между инструментами и технологиями, используемыми специалистами по данным и разработчиками приложений. Специалисты по данным, скорее всего, будут работать на Python, используя фреймворки машинного обучения, такие как Sci-kit Learn, Tensorflow или PyTorch, для построения и обучения своих моделей, в то время как разработчики приложений часто будут использовать языки программирования, такие как Java, C # или JavaScript, для создания корпоративных приложений. использование популярных фреймворков веб-приложений, таких как Spring или ASP.NET Core.

Есть много способов восполнить этот пробел. Вот несколько наиболее распространенных подходов:

  1. Попросите специалиста по данным отправить обученные параметры модели разработчику приложений, который затем должен переписать модель, используя язык веб-приложения, в котором модель будет использоваться.
  2. Разработайте отдельный набор веб-приложений для размещения развернутых моделей с помощью веб-фреймворка Python, такого как Flask или Django.

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

В этой статье мы рассмотрим лучший способ преодолеть технологический разрыв между специалистами по данным и разработчиками приложений с использованием формата модели ONNX и среды выполнения ONNX. В частности, мы покажем, как вы можете построить и обучить модель с помощью Sci-kit Learn, а затем использовать ту же модель для выполнения вывода в реальном времени в .NET Core Web API.

Что такое ONNX?

Open Neural Network Exchange или ONNX - это открытый формат модели машинного обучения, аналогичный формату Pickle, который часто используется для сохранения и загрузки моделей Sci-kit Learn, или формату SavedModel для моделей Tensorflow. ONNX, однако, не зависит от платформы, что означает, что вы можете создавать модели формата ONNX практически из любой популярной платформы машинного обучения.

В дополнение к формату модели ONNX мы также будем использовать среду выполнения ONNX, среду выполнения с открытым исходным кодом, которая позволит нам запускать нашу модель ONNX в нашем приложении .NET Core. Мы будем использовать API C #, но среда выполнения ONNX также поддерживает API для нескольких других языков, включая Python, Java и Javascript.

Вы можете узнать больше о проекте ONNX и поддерживаемых фреймворках здесь: https://onnx.ai/

И вы можете узнать больше о том, как использовать ONNX Runtime с разными языками и платформами здесь: https://microsoft.github.io/onnxruntime/

Создайте модель ONNX

Сначала мы построим и обучим модель Sci-kit Learn с использованием набора данных California Housing. Здесь нет ничего особенного, просто GradientBoostingRegressor, обученный предсказывать цену дома с учетом нескольких точек данных о районе, таких как средний доход, среднее количество спален и так далее.

Нам потребуется установить библиотеку sklearn-onnx, которая позволит нам преобразовать модель sklearn в формат ONNX:

pip install skl2onnx

Затем мы воспользуемся методом convert_sklearn() для преобразования:

Параметр initial_types определяет размеры и типы данных входных данных модели. Эта модель принимает 8 входов типа float. None во входном измерении [None,8] указывает неизвестный размер партии.

Примечание. Существуют некоторые ограничения на преобразование моделей Scikit-learn в формат ONNX. Вы можете найти подробную информацию об этих ограничениях и библиотеке sklearn-onnx здесь: http://onnx.ai/sklearn-onnx/

Выполнение логического вывода с помощью модели ONNX

Теперь о приложении ASP.NET Core, которое будет использовать нашу модель ONNX и предоставлять ее как конечную точку REST API, обеспечивая вывод в реальном времени как службу. Мы создадим пустой веб-API ASP.NET Core с помощью dotnet инструмента командной строки:

dotnet new webapi

Затем мы установим пакет NuGet Microsoft.ML.OnnxRuntime, который позволит нам загрузить и оценить модель ONNX в приложении .NET Core:

dotnet add package Microsoft.ML.OnnxRuntime

Прежде чем мы сможем оценить модель, нам нужно запустить InferenceSession и загрузить объект модели в память. Добавьте следующую строку в метод ConfigureServices в Startup.cs:

Если вы не знакомы с ASP.NET Core или внедрением зависимостей, в приведенной выше строке просто создается одноэлементный экземпляр typeInferenceSession и добавляется его в контейнер службы приложения. Это означает, что сеанс вывода будет создан только один раз при запуске приложения, и что тот же сеанс будет повторно использоваться при последующих вызовах конечной точки API вывода, которую мы создадим в ближайшее время.

Вы можете найти более подробную информацию о сервис-контейнере, времени жизни сервисов и внедрении зависимостей в целом здесь: Внедрение зависимостей в ASP.NET Core

Обратите внимание, что в приведенном выше коде мы загружаем файл модели .onnx из локальной файловой системы. Хотя это прекрасно работает для нашего примера, в производственном приложении вам, вероятно, будет лучше загрузить объект модели из внешнего репозитория / реестра модели, такого как MLFlow, чтобы отделить управление версиями модели машинного обучения от управления версиями приложения.

Теперь, когда приложение знает, как загрузить нашу модель ONNX в память, мы можем создать класс контроллера API, который в приложениях ASP.NET Core представляет собой просто класс, определяющий конечные точки API, которые будут предоставляться нашим приложением.

Вот класс Controller для конечной точки вывода:

Несколько примечаний о вышеупомянутом классе:

  • Атрибут [Route("/score")] указывает, что мы можем делать запросы к конечным точкам этого контроллера по маршруту / score
  • Обратите внимание, что конструктор класса принимает в качестве параметра объект типа InferenceSession. Когда приложение запускается, оно создает экземпляр нашего класса контроллера, передавая одноэлементный экземпляр InferenceSession, который мы определили ранее в Startup.cs.
  • Фактическая оценка нашей модели входных данных происходит, когда мы вызываем _session.Run()
  • Классы HousingData и Prediction - это простые классы данных, используемые для представления тела запроса и ответа соответственно. Мы дадим определение обоим ниже.

Вот класс HousingData, представляющий тело JSON входящего запроса API к нашей конечной точке. В дополнение к свойствам объекта мы также определили AsTensor() метод, который преобразует HousingData объект в объект типа Tensor<float>, чтобы мы могли передать его в нашу модель ONNX:

А вот класс Prediction, который определяет структуру ответа, которым будет отвечать наша конечная точка API:

Тестирование API

И это все. Теперь мы готовы запустить наш веб-API ASP.NET Core и протестировать конечную точку вывода. Используйте команду dotnet run в корне проекта, чтобы запустить приложение. Вы должны увидеть в выходных данных такую ​​строку, указывающую, какой порт прослушивает приложение:

Now listening on: http://[::]:80

Теперь, когда приложение запущено и работает, вы можете использовать свой любимый инструмент для выполнения запросов API (мой - Postman), чтобы отправить ему такой запрос:

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

Вывод

Спасибо за чтение. В этой статье мы увидели, как использовать формат модели ONNX и среду выполнения ONNX для оптимизации процесса интеграции моделей машинного обучения в производственные приложения. Хотя показанные примеры относятся к Scikit-Learn и C #, гибкость ONNX и среды выполнения ONNX позволяет нам смешивать и сопоставлять различные платформы машинного обучения и технологические стеки (например, Scikit-learn и Javascript, Tensorflow и Java и т. Д.) .

Пример кода

Вы можете найти репозиторий, содержащий весь пример кода для обучения и вывода здесь: https://github.com/gnovack/sklearn-dotnet

использованная литература

Не стесняйтесь оставлять любые вопросы или комментарии ниже. Спасибо!