Быстрый старт
Для деплоя модели от разработчика требуется обернуть код с моделью специальным образом. Подход будет знаком, если вы уже работали с такими фреймворками как flask, connexion, fastapi. Если нет - ничего страшного, это простые концепции
mmf-meta
Для начала работы вам необходимо установить библиотеку mmf-meta:
mmf
Импортируем библиотеку mmf_meta
, для простоты присвоим ей более короткое название - mmf
import mmf_meta as mmf
import pandas as pd
import pickle
with open('model', 'br') as f:
model = pickle.load(f) # (1)
- Модель может загружаться как угодно, в этом примере используется pickle
artifact
Чтобы сообщить mmf, что файл model
- это артефакт, его нужно отметить специальным образом.
В таком случае в MMF появится возможность управления артефактами: загрузка, хранение, контроль версий.
Есть два способа работы с артефактами:
Если артефакт относительно небольшой, его можно разместить "рядом" с исходным кодом. Под небольшим мы понимаем файл размером до 10мб. Большие размеры будут замедлять загрузку информации о модели, поэтому нужно использовать второй способ.
- Помечаем файл 'model' как артефакт
Альтернативный способ (на одну строку меньше, смысл не меняется)
with mmf.artifact
полностью заменяетwith open
без потери функционала.
Если артефакт существенных размеров, мы оборачиваем его загрузку в специальную функцию - таким образом во время первой загрузки модели артефакт может еще не существовать на сервере и может храниться отдельно от исходного кода в S3-хранилище.
@mmf.artifact('model') # (1)
def model(): # (2)
with open('model', 'br') as f:
return pickle.load(f) # (3)
- Декоратор, помечающий функцию как загрузчик модели
- Функция, которая отвечает за загрузку модели
- Важно, модель теперь не записывается в переменную, а возвращается как результат работы функции model()
Внимание!
mmf.artifact
проверит размер файла и если он превысит установленный лимит (10мб), поднимется ошибка
и модель не будет загружена. В таком случае нужно использовать второй вариант - хранение артефакта в хранилище.
target
Далее нам предстоит оформить "target" - это функция, которую мы хотим предоставить внешним пользователям.
MMF поддерживает работу с табличными данными. Автоматически преобразует поддерживаемые типы в DataFrame.
@mmf.target(returns=mmf.DataFrame(format=mmf.XLSX)) # (1)
def score(
data = mmf.DataFrame(description='Данные для модели') # (2)
):
return model.predict(data) # (3)
- Декоратор, помечающий функцию как target. Если функция возвращает какой-то результат, тип результата нужно пометить с помощью параметра returns, в данном примере модель возвращает DataFrame, при этом MMF преобразует его в формат .XLSX перед отправкой пользователю.
- Дескриптор, помогающий MMF понять, какие данные ожидаются от пользователя. Подробнее про дескрипторы
- Вызов модели. Независимо от того, как был оформлен артефакт
model
, для таргета - это всегда один и тот же объект, те в нашем примере - результат работыpickle.load
Работа с данными в формате объектов (python dict). MMF может принимать от пользователя json, xml, protobuf и автоматически преобразовывать их в dict.
@mmf.target(returns=mmf.Dict(format=mmf.JSON)) # (1)
def score(
data = mmf.Dict(description='Данные для модели в формате JSON') # (2)
):
return model.predict(data)
- В данном случае мы сообщаем MMF, что модель возвращает данные как dict и просим MMF по-умолчанию конвертировать его в JSON.
- Дескриптор, указывающий на использование данных в формате dict. MMF автоматически распакует json-совместимый объект, полученный от клиента. Для распаковки используется высокопроизводительная библиотека orjson
MMF способен работать с любыми данными, в том числе смешивать разные типы. На примере работы с изображением:
@mmf.target(returns=mmf.String()) # (1)
def score(
img = mmf.Img( # (2)
format='rgb',
description='Файл изображения, совместимый с opencv'
),
model_id = mmf.String( # (3)
description='ID модели, которую нужно использовать для классификации'
),
):
return model[model_id].predict(data) # (4)
- Сообщаем, что модель возвращает строку
- На вход ожидаем изображение. При этом MMF автоматически преобразует его в numpy-массив, в данном случае в формате rgb.
- Дополнительный параметр - id модели, в этом вымышленном сценарии у нас есть несколько моделей, которые могут классифицировать изображение
- Модель возвращает рассчитанный класс как текст.
Модель может содержать любое кол-во таргетов, входные/выходные параметры можно комбинировать как угодно, в любом порядке/количестве и с любыми поддерживаемыми типами
Внимание!
Все аргументы таргета в обязательном порядке должны содержать дескрипторы, в противном случае модель не будет
загружена с ошибкой DescriptorError
результат
В результате мы получим примерно такой файл с описанием модели, назовем его main.py
:
import mmf_meta as mmf
import pandas as pd
import pickle
with mmf.artifact('model', 'br') as f:
model = pickle.load(f)
@mmf.target(returns=mmf.DataFrame(format=mmf.XLSX))
def score(
data = mmf.DataFrame(description='Данные для модели')
):
return model.predict(data)
requirements.txt
Для указания зависимостей проекта используется pip-совместимый файл requirements. Общая рекомендация к этому файлу - указание списка основных зависимостей со строгим указанием версий. Рекомендуется фиксировать все установленные во время разработки зависимости, чтобы поведение модели воспроизводилось гарантированно без ошибок и отклонений.
poetry - современенный, набирающий популярность, инструмент для управления зависимостями python. Основное "удобство" от использования poetry - это фиксация версий основных зависимостей и так же связанных ними непосредственно в моменте установки.
C poetry привычная установка pip install pandas
заменяется на poetry add pandas
, что в последствии дает
строгую фиксацию всех зависимостей в файле poetry.lock
Для конвертации в requirements.txt в poetry есть встроенный функционал:
Если вы пользуетесь pip для установки пакетов, pip-tools может помочь зафиксировать все установленные версии зависимостей.
Для этого нужно сначала заполнить файл requirements.in без указания версий
И далее запустить встроенную функцию для компиляции в requirements.txt:test
Перед деплоем рекомендуется протестировать проект, чтобы убедиться, что все сделано правильно. Для этого можно воспользоваться встроенным скриптом:
main.py
- файл, в котором описан проект
Указанный скрипт создаст виртуальное окружение, установит в него mmf-meta, и все зависимости, указанные
в requirements.txt и запустит команду mmfmeta get-meta main
, которая создаст файл mmf.json с подробным описанием
проекта. После чего виртуальное окружение будет удалено.
deploy
И теперь настало время развернуть модель в MMF. Для этого вам нужно сначала разместить исходный код в любой привычной git-системе, например на github. Если этот процесс вызывает какие-то трудности, есть так же опция - упаковать все в архив.
Далее перейти в интерфейс вашего кластера MMF, либо на демо-кластер. Нажать кнопку новый проект и следовать дальнейшим инструкциям.