11 KiB
Работа с фреймворком, обзор основных компонентов
Модули
Фреймворк разделяет три типа модулей:
- Базовый модуль - приложение, которое решает прикладную задачу.
- MLOps-модуль - библиотека или набор подпрограмм, которые модифицируют работу базового модуля.
- Модуль данных - набор данных, оформленный в соответствии с интерфейсом, который поддерживается фреймворком.
Основной тип модулей, которые развёртываются на фреймворке - базовые.
Структура базового модуля
Базовый модуль состоит из нескольких частей, которые вместе складываются в приложение.
- Git-репозиторий
- Программный код, решающий прикладную задачу
- Интерфейс взаимодействия с фреймворком
- Компоненты модуля
- MLComponent
- ExperimentPipeline
- APIComponent
- DataBox
- Программный код, решающий прикладную задачу
- Системные компоненты, подключающие модуль к фреймворку
- Secret
- Repository
- PlatformApp
- Образы Docker
Роль и связь компонентов модуля:
flowchart LR
%% External APIs
MLAPI[API ML-компонента]
PipeAPI-General[Общий API пайплайнов]
PipeAPI1[API первого пайплайна]
PipeAPI2[API второго пайплайна]
FileAPI[Файловый API]
%% S3 Infrastructure
S3Storage[(S3 Хранилище)]
FileAPI ---> S3Box-UserData[S3 Box: Данные пользователей]
FileAPI ---> S3Box-ModelWeights[S3 Box: Веса моделей]
S3Box-UserData --> S3Storage
%% ML Component Section
subgraph ML-Component["ML Component"]
direction LR
MLService[ML Service]
end
MLAPI --> ML-Component
ML-Component --> S3Box-UserData
ML-Component --> S3Box-ModelWeights
S3Box-ModelWeights --> S3Storage
%% Pipeline Sections
subgraph Pipeline1["Pipeline 1"]
direction LR
Pipeline1Service1[Pipeline 1 запуск 1]
Pipeline1Service2[Pipeline 1 запуск 2]
end
subgraph Pipeline2["Pipeline 2"]
direction LR
Pipeline2Service1[Pipeline 2 запуск 1]
end
PipeAPI1 --> Pipeline1
PipeAPI2 --> Pipeline2
PipeAPI-General --> Pipeline1
PipeAPI-General --> Pipeline2
Pipeline1 --> S3Box-UserData
Pipeline2 --> S3Box-UserData
Репозиторий
Репозиторий модуля, который развёрнут на фреймворке, содержит:
- Исходный код проекта
- Зависимости проекта, по которым можно воссоздать виртуальную среду для работы с ним
- Dockerfile
- Папку с манифестами (файлами YAML) компонентов модуля
Образ Docker
Образ Docker должен быть собран на основе файла Dockerfile из репозитория модуля.
Образ должен содержать только основную программу, включая интерфейс взаимодействия с фреймворком, и зависимости, необходимые для её запуска. Образ должен быть основан на -slim
версии базового образа Python.
В образе не должно быть лишних данных, таких как:
- папка
.git
- данные для тестов
- веса ИИ-моделей
- артефакты сборки
Необходимые для работы данные нужно подключать через файловое хранилище S3:
- Для MLComponent - через пункты манифеста
modelPath
иmodelBox
. - Для ExperimentPipeline - через входную переменную, к которой прописан явный путь в
mountFrom
.
DataBox
Компонент DataBox позволяет модулю использовать файловое хранилище S3. В одном модуле может быть несколько таких компонентов, которые отвечают за разные виды данных. Например, данные конечных пользователей модуля (загруженные для расчётов файлы) и данные разработчика модуля (веса моделей ИИ).
MLComponent
MLComponent - это компонент, который позволяет создать сервис синхронной обработки вычислительных запросов.
Основной элемент кода разработчика, к которому подключается MLComponent - функция Python с заранее определённым интерфейсом ("функция inference"). В неё передаются данные, присланные пользователем, а так же модель машинного обучения, определённая в манифесте MLComponent.
Разработчик указывает, среди прочего:
- Docker-образ, который содержит реализацию функции inference
- Путь к функции inference в Docker-контейнере
- Путь в Docker-контейнере по которому можно загрузить модель ИИ
- Настройки запуска Docker-контейнера - лимиты ресурсов, переменные окружения
- Детали подключения файлового хранилища S3 к файловой системе контейнера
- Какие компоненты DataBox используются
- Соответствие путей в файловом хранилище S3 путям в файловой системе контейнера
ExperimentPipeline
Компонент ExperimentPipeline ("пайплайн") позволяет создать сервис для асинхронной обработки запросов пользователей.
В пайплайнах основной элемент кода разработчика - это контейнер Docker. Взаимодействие контейнера с фреймворком организуется через файловую систему и переменные окружения. Входные и выходные данные монтируются в файловую систему контейнера, и локальные пути к ним передаются в контейнер как переменные окружения. Таким образом, порядок работы контейнера:
- Считать переменные окружения, получить пути к входным данным и к папкам для размещения выходных данных.
- Считать данные из полученных путей к входным данным
- Произвести вычисления
- Сохранить результаты в полученные пути для размещения выходных данных
Компонент ExperimentPipeline позволяет организовывать вычисления в несколько этапов, каждый из которых запускается со своим набором входных и выходных данных. Каждый контейнер соответствует одному этапу.
В самом манифесте ExperimentPipeline разработчик, помимо прочего, указывает:
- Docker-образ, который будет запускаться
- В том числе настройки запуска - переменные окружения, лимиты ресурсов
- Входные и выходные переменные этапов
- Могут указываться детали их подключения - путь к файловом хранилище S3, путь в файловой системе контейнера
- Детали подключения файлового хранилища S3 к файловой системе контейнера
- Какие компоненты DataBox используются
- Соответствие путей в файловом хранилище S3 путям в файловой системе контейнера по умолчанию
APIComponent
Компонент APIComponent предоставляет доступ к элементам модуля через API. Есть четыре основных вида компонентов APIComponent:
- Файловый API
- API пайплайнов в целом
- API отдельного MLComponent
- API отдельного ExperimentPipeline
Первые три вида APIComponent определяются похожим образом, и с точки зрения разработчика отличаются добавлением соответствующего поля в манифест.
APIComponent отдельного ExperimentPipeline определяет всю структуру взаимодействия с соответствующим пайплайном через API, то есть входные и выходные переменные, их типы данных и описания.
Общие элементы компонентов
Манифесты компонентов имеют следующую структуру:
apiVersion: "unified-platform.cs.hse.ru/v1"
kind: <Тип>
metadata:
name: <Название компонента>
namespace: <Название приложения>
spec:
<Содержимое компонента>
Все компоненты в репозитории являются частью одного и того же приложения, поэтому значение поля metadata.namespace
у всех компонентов в одном репозитории должно совпадать.