13 KiB
MLComponent
Компонент MLComponent позволяет создать сервис для синхронной обработки запросов пользователей.
MLComponent подходит для быстрых вычислений, в частности запуска предобученной модели машинного обучения на небольшой выборке данных. Например, распознавание объекта на одном изображении, классификация таблицы текстовых данных. Если алгоритм работает за доли секунды, то он подходит как основа для MLComponent.
На основе образа Docker, указанного в манифесте MLComponent, создаётся контейнер. В него устанавливается системная библиотека платформы, которая создаёт веб-сервис. При получении запроса от пользователя веб-сервис вызывает функцию inference, указанную в манифесте MLComponent, и передаёт вывод функции пользователю.
Для добавления MLComponent к модулю разработчику нужно:
- Реализовать функцию, на основе которой будет создан веб-сервис.
- Добавить в модуль манифест компонента MLComponent
- Добавить в модуль манифест компонента APIComponent для обращения к MLComponent
Также в модуле уже должен присутствовать хотя бы один компонент DataBox и соответствующий ему APIComponent.
Функция inference
Для работы MLComponent нужно реализовать функцию со следующим интерфейсом:
def inference(parameters: List[Dict[str, Any]],
inputs: List[Dict[str, Any]],
output_fields: List[Dict[str, Any]],
model_key: str,
model: Any = None) -> Tuple[List[Dict[str, Any]], Any]:
Входные параметры:
parameters
- список пар[name, value]
, произвольных параметров примитивных типов.inputs
- список входных данных, где каждый элемент - это словарь. Ключи словаря:name
- название, произвольная строка, используется в коде модуля. Например,"image"
.datatype
- тип входных данных, одна из строк"FP32", "FP64", "INT32", "FILE", "str"
.content_type
- тип содержимого файла, если тип входной переменнойdatatype
- это"FILE"
.data
- строка с путём к входному файлу или одномерный список входных данных соответствующего типа.shape
- размерность входной переменной как массива, применимо даже к файлам (не размер файла в файловой системе).
output_fields
- список выходных данных, где каждый элемент - это словарь. Ключи словаря:name
- название, произвольная строка, используется в коде модуля. Например,"prediction"
.datatype
- тип выходных данных, одна из строк"FP32", "FP64", "INT32", "FILE", "str"
.content_type
- тип содержимого файла, если тип выходной переменнойdatatype
- это"FILE"
.data
- строка с путём к выходному файлу или одномерный список выходных данных соответствующего типа.shape
- размерность выходной переменной как массива, применимо даже к файлам (не размер файла в файловой системе).
model_key
- строка, по которой можно загрузить модель (обычно путь).model
- объект модели, с помощью которого проводится инференс.
Функция выводит tuple из двух объектов:
- список выходных данных, где каждый элемент - это словарь. Ключи словаря:
name
- название, произвольная строка, используется в коде модуля. Например,"prediction"
.datatype
- тип выходных данных, одна из строк"FP32", "FP64", "INT32", "FILE", "str"
.content_type
- тип содержимого файла, если тип выходной переменнойdatatype
- это"FILE"
.data
- строка с путём к выходному файлу или одномерный список выходных данных соответствующего типа.shape
- размерность выходной переменной как массива, применимо даже к файлам (не размер файла в файловой системе).
- объект модели, который можно передать в следующий вызов функции как аргумент
model
.
Формат самих входных данных, которые передаются в аргументе inputs
при вызове функции, должен быть указан в docstring-спецификации.
def inference(parameters: List[Dict[str, Any]],
inputs: List[Dict[str, Any]],
output_fields: List[Dict[str, Any]],
model_key: str,
model: Any = None) -> Tuple[List[Dict[str, Any]], Any]:
Манифесты
Пример манифеста ML-компонента.
apiVersion: "unified-platform.cs.hse.ru/v1"
kind: MLComponent
metadata:
name: somename-mlcmp
namespace: pu-username-pa-bm99
spec:
image:
existingImageName: example.com/lab-name/bm99-module-container-name:12ab345
resourceLimits:
cpu: 500m
memory: 256M
env:
- name: CUSTOM_PARAMETER_1
value: "3.14"
- name: ANOTHER_PARAMETER
value: "some_value"
mlService:
packageRegistryName: python-package-registry
inference:
fileExchange:
fileBox: user-box
inferenceFilesPath: /home/appname/users/tmp
model:
modelBox: model-box
modelPath: /home/path/to/model.joblib
entryPoint:
pythonPath: .
pythonFunction: modulename.predict.inference
connectedBoxes:
- name: model-box
path: /home/path/to
mountS3Box:
subPath: users/developer/file_groups/models
s3BoxName: mymodule-data-box
- name: user-box
copyS3Box:
s3BoxName: users
Здесь,
metadata/name
- название ML-компонента. Оно используется в API-компоненте и может использоваться в других обращениях к компоненту через kubernetes.spec/image/existingImageName
- название образа, из которого собирается ML-компонент. Этот образ был подготовлен в пункте 5.spec/image/resourceLimits
- ограничения по ресурсам для ML-компонента.- Ресурсы процессора
cpu
измеряются в ядрах.500m
- 500 миллиядер, то есть половина ядра процессора занята развёрнутым ML-компонентом. - Ресурсы оперативной памяти
memory
могут измеряться в мегабайтах, гигабайтах и других метриках памяти - Подробнее - https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
- Ресурсы процессора
spec/env
- переменные окружения, передаваемые в контейнер. Вы можете вынести настройки контейнера в переменные окружения и задавать их в ML-компоненте, чтобы не нужно было изменять код и пересоздавать образ Docker с новыми значениями.spec/mlService
packageRegistryName
- название репозитория с пакетами Python, должно соответствовать "внешнему" названию из компонента приложения в пункте 7.6. Название может быть другим, главное - соответствие названий друг другу.inference/fileExchange
- соединение файловой системы контейнера (сервиса) и ящика S3 для обмена файлами.fileBox
- название ящика S3 для файлов пользователей.
Должно соответствовать названию из пунктаconnectedBoxes
ниже в этом файле, а не названиюmetadata/name
из компонентаDataBox
.inferenceFilesPath
- путь, куда будут записываться создаваемые файлы внутри контейнера. К этому пути должны быть права доступа у пользователя контейнера. С этой папкой фреймворк взаимодействует автоматически, то есть лучше сделать уникальный путь, который нигде больше не используется.
inference/model
- соединение файловой системы контейнера (сервиса) и ящика S3 для подключения модели расчётов.modelBox
- название ящика S3, где размещена модель.
Должно соответствовать названию из пунктаconnectedBoxes
ниже в этом файле, а не названиюmetadata/name
из компонентаDataBox
.modelPath
- путь, по которому модель будет доступна внутри контейнера.
Этот путь передаётся в функциюinference
. Может быть папкой или файлом.
inference/entryPoint
pythonPath
- относительный путь от корня репозитория к папке, которая будет добавлена вPYTHONPATH
.pythonFunction
- имя функции-адаптера, включая имена промежуточных модулей.
spec/connectedBoxes
- подключенные компонентыDataBox
(ящики)- Первый ящик в примере используется для доступа к модели.
name
- имя, по которому к ящику можно обращаться выше в пунктеspec/mlService/inference/model/modelBox
.path
- путь внутри контейнера, к которому монтируется ящик.mountS3Box/s3BoxName
- название компонентаDataBox
.mountS3Box/subPath
- путь внутри ящика, который монтируется к путиpath
.
Здесь используется путьusers/developer/file_groups/models
как решение проблемы загрузки весов моделей и прочих данных в хранилище S3. При загрузке через файловый API от лица пользователя USER файлы загружаются по путиusers/USER/file_groups/...
. То есть в текущем примере веса можно загрузить от лица пользователяdeveloper
в папкуmodels/
, и через ML-компонент дать к ним доступ всем остальным пользователям.
- Второй ящик в примере используеся для взаимодействия с пользователями
name
- имя, по которому к ящику можно обращаться выше в пунктеspec/mlService/inference/fileExchange/fileBox
.copyS3Box/s3BoxName
- назание компонентаDataBox
.
- Первый ящик в примере используется для доступа к модели.