MLComponent подходит для быстрых вычислений, в частности, запуска предобученной модели машинного обучения на небольшой выборке данных. Например, распознавание объекта на одном изображении, классификация таблицы текстовых данных. Если алгоритм работает за доли секунды, то он подходит для создания MLComponent.
На основе образа Docker, указанного в манифесте MLComponent, создаётся Docker-контейнер. В него устанавливается системная библиотека платформы, которая создаёт веб-сервис. При получении запроса от пользователя веб-сервис вызывает функцию inference, указанную в манифесте MLComponent, и передаёт вывод функции пользователю.
Формат самих входных данных, которые передаются в аргументе `inputs` при вызове функции, и выходных данных, возвращаемых функцией, должен быть указан в docstring-спецификации.
Для каждой переменной нужно указать следующее:
1. Информация о переменной в формате `:param inputs.NAME: DESCRIPTION`
2. Информация о типе данных в формате `:type inputs.NAME: TYPE1 or TYPE2 or TYPE3[, optional]`
Здесь,
-`inputs` - тип переменной. Для входных это `inputs`, для выходных - `outputs`.
-`NAME` - имя переменной. Должно в точности соответствовать имени, которое передаётся через API.
-`DESCRIPTION` - описание переменной. Может содержать несколько строк текста. Используется в OpenAPI спецификации и каталоге.
-`TYPE1`, `TYPE2`, `TYPE3` - типы данных и типы содержимых, которые могут быть присвоены переменной.
- Типы содержимого (content_type) указываются так же, как типы данных - `FP32 or text/csv`.
- Если указано хотя бы один `content_type`, то тип `FILE` добавляется автоматически, даже если не указан - `:type inputs.mydata: text/csv`.
- Если не указан `content_type`, предполагается, что поддерживается любой.
- Если про тип переменной не указано ничего, предполагается, что поддерживается любой тип и любое содержимое.
-`[, optional]` в конце типа переменной может быть указано `, optional` (без квадратных скобок), что означает, что переменная опциональная, вызов функции должен работать и без неё.
В этом разделе описаны особенностей реализации функции inference и рекомендации. Технически функция может быть реализована любым способом, который соответствует интерфейсу, но при возможности желательно следовать рекомендациям ниже.
За передачу модели в функцию отвечают два параметра: `model_key` и `model`.
-`model_key` - строка-ключ, позволяющая загрузить модель с диска или хранилища файлов. Обычно, это путь. Например, `/home/project/data/model_weights.pth` для загрузки файла или `/home/project/google-bert/bert-base-uncased` для загрузки модели из папки.
-`model` - уже загруженный объект модели. Этот же объект возвращается функцией в кортеже `outputs, model`.
Так как ML-компонент предназначен для быстрых вычислений, предполагается, что время выполнения одного запроса гораздо меньше времени загрузки модели или запуска контейнера. Поэтому один и тот же контейнер и один и тот же объект модели используется для множества запросов.
Если модель `model` не передана в функцию inference (например, это первый запрос к новому модулю), веса ИИ-модели загружаются с использованием ключа `model_key`. Эти загруженные веса возвращаются в конце работы функции и передаются в аргумент `model` при каждом следующем вызове.
Тип объекта `model` может быть любым, то есть это может быть и набор моделей, если это соответствует логике вычислений.
#### Пример функции
```python
def inference(
parameters: list,
inputs: list,
output_fields: list,
model_key: str,
model: Any = None,
) -> (list, Any):
"""
:param inputs.X: Матрица экземпляров для классификации;
:type inputs.X: FP64 or FP32 or FILE or text/csv
:param outputs.predict: Результат прогнозирования;
:type outputs.predict: INT32 or 'FILE' or text/csv
"""
outputs = []
if not model:
model = joblib.load(model_key)
for entry in inputs:
if entry["datatype"] == "FILE":
if entry["content_type"] == "text/csv":
input_table = load_csv(entry["data"])
else:
raise AttributeError(f'Not supported file type {entry["content_type"]}')
-`spec/env` - переменные окружения, передаваемые в контейнер. Вы можете вынести настройки контейнера в переменные окружения и задавать их в ML-компоненте, чтобы не нужно было изменять код и пересоздавать образ Docker с новыми значениями.
-`spec/mlService`
-`packageRegistryName` - название репозитория с пакетами Python, должно соответствовать "внешнему" названию из компонента приложения в пункте **7.6**. Название может быть другим, главное - соответствие названий друг другу.
-`inference/fileExchange` - соединение файловой системы контейнера (сервиса) и ящика S3 для обмена файлами.
-`fileBox` - название ящика S3 для файлов пользователей.
-`inferenceFilesPath` - путь, куда будут записываться создаваемые файлы внутри контейнера. К этому пути должны быть права доступа у пользователя контейнера. С этой папкой фреймворк взаимодействует автоматически, то есть лучше сделать уникальный путь, который нигде больше не используется.
-`inference/model` - соединение файловой системы контейнера (сервиса) и ящика S3 для подключения модели расчётов.
-`modelBox` - название ящика S3, где размещена модель.
*Здесь используется путь `users/developer/file_groups/models` как решение проблемы загрузки весов моделей и прочих данных в хранилище S3. При загрузке через файловый API от лица пользователя USER файлы загружаются по пути `users/USER/file_groups/...`. То есть в текущем примере веса можно загрузить от лица пользователя `developer` в папку `models/`, и через ML-компонент дать к ним доступ всем остальным пользователям.*