diff --git a/README.md b/README.md index c4381d1..2cca306 100644 --- a/README.md +++ b/README.md @@ -4,3 +4,4 @@ - [API модулей](./pages/api-module.md) - [Компонент DataBox](./pages/databox.md) - [Компонент MLComponent](./pages/mlcmp.md) +- [Компонент ExperimentPipeline](./pages/pipeline.md) diff --git a/pages/pipeline.md b/pages/pipeline.md new file mode 100644 index 0000000..c555831 --- /dev/null +++ b/pages/pipeline.md @@ -0,0 +1,209 @@ +# ExperimentPipeline + +Компонент ExperimentPipeline позволяет создать сервис для асинхронной обработки запросов пользователей. + +ExperimentPipeline подходит для вычислительных задач, которые: + +- Требуют много вычислительных ресурсов (от нескольких секунд времени и больше, большие объёмы данных) +- Не могут быть оформлены как Python-функция +- Используют MLOps-модули + +Если хотя бы один их этих критериев выполнен, задачу скорее всего лучше оформить как ExperimentPipeline. + +При получении запроса от пользователя, на основе образов Docker, указанных в манифесте ExperimentPipeline, создаются контейнеры. Указанные входные и выходные переменные становятся переменными окружения при запуске контейнера, и соответствуют определённым путям в файловом хранилище. Запускается расчёт, в ходе которого предполагается работа с файлами и папками из переменных окружения. Результаты расчёта записываются в папки, пути к которым были переданы в контейнер. + +Для добавления ExperimentPipeline к модулю разработчику нужно: + +- Добавить в модуль манифест компонента ExperimentPipeline +- Добавить в модуль манифест компонента APIComponent для обращения к ExperimentPipeline +- Добавить в модуль манифест компонента APIComponent для работы с пайплайнами в целом (один на все пайплайны) + +Также в модуле уже должен присутствовать хотя бы один компонент DataBox и соответствующий ему APIComponent. + + + + +## Добавление пайплайна в приложение + +### Переменные + +Данные передаются на вход и выход пайплайна, а также между его отдельными этапами через *переменные*. Эти переменные используются в нескольких частях работы пайплайна: + +- Внутри контейнера эти переменные доступны как переменные окружения. +- При вызове пайплайна через API эти переменные отвечают за входные и выходные данные. +- При создании манифеста пайплайна переменные указываются в манифесте самого пайплайна и его API-компонента. + +Есть три типа переменных: + +* входные - могут быть переданы в поле `inputs` при вызове пайплайна через API. +* выходные - могут быть переданы в поле `outputs` при вызове пайплайна через API. Значением может быть только путь к папке, не к файлу. +* внутренние - не передаются через API, но могут быть указаны как входные и выходные переменные отдельных этапов пайплайна, и в таком случае данные будут автоматически переданы между этапами. + +### Взаимодействие кода модуля с фреймворком + +Для каждого контейнера, созданного во время выполнения пайплайна, будут определены переменные окружения в формате `UNIP_PIPELINE_`. Значения таких переменных - пути к файлами и папкам в локальной файловой системе контейнера, с которыми должен работать код модуля. + +Например, модуль обучает ML-модель на наборе данных "xy_train". Чтобы передать этот набор данных в этап обучения внутри пайплайна и использовать его при обучении, нужно: + +1. Добавить входной параметр `xy_train` в манифест пайплайна в пункт `spec.stages.[].input`. +2. При создании контейнера, считывать переменную окружения `UNIP_PIPELINE_XY_TRAIN` - её название автоматически создаётся добавлением префикса `UNIP_PIPELINE` и переводом названия входного параметра в верхний регистр. +3. При вызове пайплайна через API, в теле вызова передавать путь к данным `xy_train` (файлу или папке). + +Если поле называется `example_field`, то внутри контейнера будет переменная `UNIP_PIPELINE_EXAMPLE_FIELD`. + +Пример такой работы: + +```python +def main(): + model_path = os.getenv("UNIP_PIPELINE_MODEL") + model = load_model(model_path) + data_path = os.getenv("UNIP_PIPELINE_DATASET") + data = load_data(data_path) + + metrics = compute_metrics(model, data) + metrics_file_name = os.path.join(os.getenv("UNIP_PIPELINE_METRICS"), "metrics.txt") + write_metrics_to_file(metrics, metrics_file_name) +``` + +Здесь используются две входные переменные, `model` и `dataset` и одна выходная - `metrics`. + +Входные переменные могут быть файлами или папками, а выходная - только папкой, поэтому в примере добавляется путь к файлу. + + +### Манифест ExperimentPipeline + +Пример манифеста самого пайплайна. + +```yaml +apiVersion: "unified-platform.cs.hse.ru/v1" +kind: ExperimentPipeline +metadata: + name: my-pipeline + namespace: pu-username-pa-bm99 +spec: + vars: + - name: xy_train + - name: xy_test + - name: extra_parameters + - name: testing_results + - name: model + + stages: + - name: stage1 + image: + existingImageName: registry-platform-dev-cs-hse.objectoriented.ru/lab-name/bm99-somename-train:4f4621b + inputs: + - name: xy_train + - name: extra_parameters + outputs: + - name: model + env: + - name: MY_VARIABLE + value: "some_value" + - name: ANOTHER_VAR + value: "2" + + entryPoint: + cmd: + - python3 + - src/training.py + resourceLimits: + cpu: 500m + memory: 256M + + - name: stage2 + image: + existingImageName: example.com/lab-name/bm99-somename-test:4f4621b + inputs: + - name: model + - name: xy_test + - name: extra_parameters + outputs: + - name: testing_results + + entryPoint: + cmd: + - python3 + - src/testing.py + resourceLimits: + cpu: 500m + memory: 256M + connectedBoxes: + - name: data-box + path: /path/to/mountpoint + default: true + mountS3Box: + s3BoxName: mymodule-data-box +``` + +Здесь, + +- `metadata.name` - название компонента пайплайна. Это название используется в API-компоненте и при выполнении запросов к пайплайну. +- `spec.vars` - список всех переменных, используемых в пайплайне, включая входные, выходные и внутренние. +- `spec.stages` - список этапов пайплайна. Этапы вызываются последовательно при вызове пайплайна. +- `spec.stages.[0].name` - название этапа +- `spec.stages.[0].image.existingImageName` - название образа, который используется для выполнения этапа пайплайна. +- `spec.stages.[0].inputs` - список входных переменных этапа. +- `spec.stages.[0].outputs` - список выходных переменных этапа. +- `spec.stages.[0].entryPoint` - точка входа в контейнер, консольная команда. + - Отдельные элементы списка будут соединены пробелами и преобразованы в единую команду. + - Команда из примера станет `python3 src/training.py` в терминале. +- `spec.stages.[0].env` - список переменных окружения, которые будут установлены в контейнере при запуске пайплайна. + - Переменные окружения могут принимать только строковые значения. + + +- `spec/connectedBoxes` - подключенные компоненты `DataBox` (ящики) + - В примере используется только один ящик, где хранятся данные, обучаемые модели, результаты и прочее + - `name` - внутреннее имя ящика, может использоваться для явного указания, откуда монтировать данные переменной. + - `path` - путь внутри контейнера, к которому монтируется ящик. Например, `/data`. + - `mountS3Box/s3BoxName` - название компонента `DataBox` из соответствующего файла манифеста. + - `default` - если указано `true`, то данные переменные автоматически монтируются из этого ящика. + +Каждый этап работает с собственными входными и выходными данными. Переменные, определённые здесь, в пайплайне, но не определённые в API, считаются внутренними переменными. Например, в примере выше такой переменной является `model`. + + +### Манифест APIComponent отдельного пайплайна + +Пример манифеста API пайплайна + +```yaml +apiVersion: "unified-platform.cs.hse.ru/v1" +kind: APIComponent +metadata: + name: api-pipeline-train-validate + namespace: pu-username-pa-bm99 +spec: + published: true + experimentPipeline: + name: my-pipeline + restfulApi: + auth: + basic: + credentials: bm99-apis-cred + identityPassThrough: true + apiSpec: + inputs: + - name: xy_train + description: "Данные для обучения. Таблица, включающая целевую переменную." + type: + datatypes: [ "FILE" ] + contentTypes: [ "text/csv" ] + - name: xy_test + description: "Данные для тестирования. Таблица, включающая целевую переменную." + type: + datatypes: [ "FILE" ] + contentTypes: [ "text/csv" ] + - name: extra_parameters + description: "Метаданные для обучения. Словарь с параметрами, передаваемыми в аргумент 'param_grid' при инициализации sklearn.model_selection.GridSearchCV." + required: false + type: + datatypes: [ "FILE" ] + contentTypes: [ "application/json" ] + outputs: + - name: testing_results + description: "Таблица со значениями метрик качества модели на тестовых данных xy_test." + type: + contentTypes: [ "text/csv" ] + +``` +