Add mldev doc
This commit is contained in:
parent
4e7ca3030e
commit
b606038efe
2 changed files with 261 additions and 0 deletions
|
@ -10,3 +10,4 @@
|
|||
- [Компонент MLComponent](./pages/mlcmp.md)
|
||||
- [Компонент ExperimentPipeline](./pages/pipeline.md)
|
||||
- [Терминология](./pages/terminology.md)
|
||||
- [Пайплайны MLDev](./pages/complex-pipeline.md)
|
||||
|
|
260
pages/complex-pipeline.md
Normal file
260
pages/complex-pipeline.md
Normal file
|
@ -0,0 +1,260 @@
|
|||
# Сложный пайплайн (mldev)
|
||||
|
||||
[MLDev](https://gitlab.com/mlrep/mldev) - программное обеспечение, упрощающее запуск воспроизводимых вычислительных экспериментов.
|
||||
|
||||
С помощью MLDev можно создавать более сложные вычислительные эксперименты (пайплайны) для использования на фреймворке, а также более удобно работать с обычными пайплайнами.
|
||||
|
||||
Принцип работы с фреймворком при помощи MLDev:
|
||||
|
||||
1. Разработчик создаёт манифест эксперимента, аналогичный манифесту пайплайна.
|
||||
2. На основе манифеста эксперимента с помощью mldev автоматически генерируется манифест пайплайна и собираются docker-образы.
|
||||
3. Разработчик добавляет сгенерированный манифест пайплайна и docker-образы к модулю как при обычном создании пайплайна.
|
||||
|
||||
## Подготовка элементов mldev
|
||||
|
||||
В примере далее рассматривается следующая структура файлов, относящихся к MLDev.
|
||||
|
||||
```
|
||||
experiments
|
||||
├── .mldev
|
||||
│ ├── config.yaml
|
||||
│ └── stages.py
|
||||
├── experiment-unip-pipeline.yaml
|
||||
└── unip-pipeline.yaml
|
||||
```
|
||||
|
||||
- `config.yaml` - настройки MLDev, такие как параметры запуска, уровень логирования и шаблон названия docker-образов.
|
||||
- `stages.py` - загрузка используемых компонентов MLDev с помощью выражения `import`.
|
||||
- `experiment-unip-pipeline.yaml` - mldev-пайплайн сборки эксперимента, запускаемый разработчиком.
|
||||
- `unip-pipeline.yaml` - основной пайплайн, используется пайплайном сборки для построения вычислительного эксперимента.
|
||||
|
||||
## config.yaml
|
||||
|
||||
Пример содержимого `config.yaml`:
|
||||
|
||||
```yaml
|
||||
logger:
|
||||
level: DEBUG
|
||||
extras:
|
||||
base: mldev.experiment_objects
|
||||
containers: mldev_containers.containers
|
||||
environ:
|
||||
IMAGE_TAG_TEMPLATE: 'platform-reg.stratpro.hse.ru/myproject/${name}:${revision}'
|
||||
UNIP_MLDEV_PIPELINE_OUTPUT: ./build/pipelines
|
||||
EXPERIMENT_FILE: ./experiments/unip-pipeline.yaml
|
||||
FORCE_RUN: True
|
||||
```
|
||||
|
||||
- `logger.level` - уровень логирования, `DEBUG`, `INFO` или `ERROR`.
|
||||
- `extras` - дополнительные модули MLDev, необходимые для взаимодействия с фреймворком.
|
||||
- `environ` - переменные окружения
|
||||
- `IMAGE_TAG_TEMPLATE` - шаблон названия образа Docker. `${name}` будет автоматически заменено на название этапа из файла эксперимента, а `${revision}` - на короткий хэш последнего коммита в репозитории проекта
|
||||
- `UNIP_MLDEV_PIPELINE_OUTPUT` - путь, куда будет сохранён сгенерированный манифест пайплайна для фреймворка
|
||||
- `EXPERIMENT_FILE` - файл с вычислительным экспериментом
|
||||
- `FORCE_RUN` - параметр, заставляющий MLDev собирать эксперимент заново, даже если не найдено изменений с прошлой сборки
|
||||
|
||||
|
||||
## stages.py
|
||||
|
||||
Пример файла `stages.py`:
|
||||
|
||||
```python
|
||||
from mldev_containers import ContainerStage, StageCode, StageVar
|
||||
from unip.mldev_pipeline.unip_pipeline import UnipPipeline
|
||||
from unip.mldev_pipeline.dataloader import StageSrc
|
||||
```
|
||||
|
||||
- `UnipPipeline`, `StageCode`, `StageVar`, `ContainerStage` - классы компонентов, необходимых для работы с пайплайнами
|
||||
- `StageSrc` - класс подключения модуля данных
|
||||
|
||||
Аналогично модулю данных в примере, для подключения других специализированных этапов, таких как подключение к суперкомпьютеру cHARISMa и автоматическая генерация отчёта об эксперименте, необходимо добавлять соответствующие классы в `stages.py`.
|
||||
|
||||
|
||||
## experiment-unip-pipeline.yaml
|
||||
|
||||
В этом файле определяется небольшой вычислительный эксперимент MLDev, в результате которого должен быть собран полноценный эксперимент из файла `unip-pipeline.yaml`.
|
||||
|
||||
Здесь определяются параметры запуска и переменные окружения полноценного эксперимента, а также добавляются вспомогательные команды.
|
||||
|
||||
Пример файла `experiment-unip-pipeline.yaml`
|
||||
|
||||
```yaml
|
||||
pipeline: !GenericPipeline
|
||||
runs:
|
||||
- !BasicStage
|
||||
name: experiment
|
||||
env:
|
||||
PYTHONPATH: './experiments/.mldev'
|
||||
MLDEV_CONFIG_PATH: './experiments/.mldev/config.yaml'
|
||||
PIP_EXTRA_INDEX_URL: '${env.PIP_EXTRA_INDEX_URL}'
|
||||
script:
|
||||
- mkdir -p ./build/containers
|
||||
- mkdir -p ./build/pipelines
|
||||
- rm -rf ./build/containers/*
|
||||
- rm -rf ./build/pipelines/*
|
||||
- mldev run pipeline -f ./experiments/unip-pipeline.yaml
|
||||
|
||||
```
|
||||
|
||||
- `pipeline: !GenericPipeline` - указывает, что это объект класса `GenericPipeline` - стандартный пайплайн библиотеки MLDev, не относящийся к фреймворку.
|
||||
- `runs` - список этапов, которые будут выполнены в ходе выполнения пайплайна GenericPipeline
|
||||
- `!BasicStage` - указывает, что текущий этап - это объект класса `BasicStage`, стандартного класса этапа пайплайна в MLDev.
|
||||
- `name: experiment` - имя этапа. Не используется далее
|
||||
- `env:` - переменные окружения, с которыми запускается этап сборки полноценного пайплайна,
|
||||
- `PYTHONPATH` - чтобы модули MLDev, импортированные в файле `stages.py` были загружены, нужно указать в PYTHONPATH путь к папке с этим файлом. В данном примере, `./experiments/.mldev`
|
||||
- `MLDEV_CONFIG_PATH` - путь к используемому в полноценном эксперименте файлу настроек MLDev.
|
||||
- `PIP_EXTRA_INDEX_URL` - дополнительные индексы для установки пакетов Python. Используются для установки пакетов фреймворка, которые не размещены в индексе PyPI. Значение `'${env.PIP_EXTRA_INDEX_URL}'` означает, что переменная окружения `PIP_EXTRA_INDEX_URL` копирует содержимое такой же переменной из среды, которая запускает эксперимент.
|
||||
- `script` = команды, которые выполяются в текущем этапе `experiment`. В данном примере это создание папок `./build/containers` и `./build/pipelines`, удаление их содержимого и запуск сборки полноценного пайплайна.
|
||||
|
||||
|
||||
Подробнее про переменную окружения `PIP_EXTRA_INDEX_URL` и запуск сборки.
|
||||
|
||||
Дополнительные индексы пакетов Python указываются в формате
|
||||
|
||||
```sh
|
||||
export PIP_EXTRA_INDEX_URL="https://my_username:mypassword_or_token_abcdef1234@platform-forgejo.stratpro.hse.ru/api/packages/my_org/pypi/simple https://my_username:mypassword_or_token_abcdef1234@platform-forgejo.stratpro.hse.ru/api/packages/another_org/pypi/simple"
|
||||
```
|
||||
|
||||
Чтобы не сохранять реквизиты доступа в сам репозиторий, используется подход с копированием их из внешней среды. Общий набор команд для сборки эксперимента mldev может быть примерно такой:
|
||||
|
||||
```sh
|
||||
cd /home/my_username/MLOPS/my_project/
|
||||
export PIP_EXTRA_INDEX_URL="https://my_username:mypassword_or_token_abcdef1234@platform-forgejo.stratpro.hse.ru/api/packages/my_org/pypi/simple https://my_username:mypassword_or_token_abcdef1234@platform-forgejo.stratpro.hse.ru/api/packages/another_org/pypi/simple"
|
||||
source venv/bin/activate
|
||||
mldev run -f experiments/experiment-unip-pipeline-paper.yaml
|
||||
```
|
||||
|
||||
## unip-pipeline.yaml
|
||||
|
||||
Этот файл полностью описывает вычислительный эксперимент, аналогично компоненту `ExperimentPipeline`.
|
||||
|
||||
### UnipPipeline
|
||||
|
||||
Основной объект вычислительного эксперимента, который должен быть определён в файле `unip-pipeline.yaml` - это объект `pipeline:!UnipPipeline` со следующей структурой:
|
||||
|
||||
```yaml
|
||||
pipeline: !UnipPipeline
|
||||
name: my-project
|
||||
namespace: pu-username-pa-appname
|
||||
variables:
|
||||
- name: preparation_data
|
||||
- name: internal_state
|
||||
- name: user_report
|
||||
runs:
|
||||
- *container_stage_prepare
|
||||
- *container_stage_complete
|
||||
connected_boxes:
|
||||
- name: user-box
|
||||
path: /userdata/
|
||||
default: true
|
||||
mount_s3_box:
|
||||
s3_box_name: users
|
||||
```
|
||||
|
||||
- `name: my-project` - имя, которое будет использовано далее при генерации имени компонента `ExperimentPipeline`.
|
||||
- `namespace` - пространство имён приложения, аналогично с остальными манифестами компонентов.
|
||||
- `variables` - список переменных, которые используются во всех этапах, вместе взятых. Аналогично `ExperimentPipeline`. Для каждой переменной помимо поля `name` можно указать поля `path` (точка монтирования в контейнере) и `mountFrom` (DataBox и точка монтирования в хранилище S3).
|
||||
- `runs` - список этапов пайплайна. В примере - ссылки на отдельно определённые компоненты.
|
||||
- `connected_boxes` - раздел, полностью аналогичный такому же разделу в `ExperimentPipeline` - определение связанных компонентов `DataBox`, указание пути монтирования по умолчанию и внутреннего имени DataBox, которое используется в этом файле далее. В отличие от `ExperimentPipeline`, где используется camelCase, здесь используется snake_case.
|
||||
|
||||
### ContainerStage
|
||||
|
||||
Отдельный этап пайплайна `UnipPipeline` - это `ContainerStage`. Такой этап соответствует этапу `ExperimentPipeline`.
|
||||
|
||||
|
||||
```yaml
|
||||
container_stage_prepare: !ContainerStage &container_stage_prepare
|
||||
name: my-prepare
|
||||
base_image: platform-reg.stratpro.hse.ru/my_org/myproject-prepare:718e2b0
|
||||
stage: *stage_prepare
|
||||
build:
|
||||
<<: *build
|
||||
code: *code
|
||||
env:
|
||||
MY_CUSTOM_FLAG: "True"
|
||||
resource_limits:
|
||||
cpu: "1"
|
||||
memory: 500M
|
||||
```
|
||||
|
||||
- `container_stage_prepare: !ContainerStage &container_stage_prepare`:
|
||||
- `container_stage_prepare:` - корень объекта этапа
|
||||
- `!ContainerStage` - класс, на основе которого будет создан этап
|
||||
- `&container_stage_prepare` - имя, по которому на этот этап можно ссылаться. Это имя используется в `UnipPipeline`
|
||||
- `my-prepare` - название этапа. Используется как название этапа в `ExperimentPipeline` и в названии Docker-образа
|
||||
- `base_image` - образ Docker, на основе которого будет создан этап. Это может быть как стандартный образ вида `python:3.11.10-slim-bullseye`, так и образ, загруженный в реестр фреймворка вида `platform-reg.stratpro.hse.ru/my_org/myproject-prepare:718e2b0`.
|
||||
- `stage: *stage_prepare` - объект вида `BasicStage`, в котором определяются входные, выходные данные и точка входа, запускающая вычисления.
|
||||
- `build` - параметры сборки Docker-образа, здесь определяются отдельным объектом.
|
||||
- `code` - объект типа `StageCode`, который определяет устанавливаемые через `requirements.txt` зависимости, а также файл с исходным кодом проекта, добавляемые в контейнер.
|
||||
- `env` - набор произвольных переменных окружения, которые будут установлены при запуске контейнера.
|
||||
- `resource_limits` - лимиты ресурсов в терминах Kubernetes, аналогично `ExperimentPipeline`.
|
||||
|
||||
#### build
|
||||
|
||||
В данном определении используется несколько ссылок на внешние объекты. Объект `build` имеет структуру
|
||||
|
||||
```yaml
|
||||
build_params: &build
|
||||
root: .
|
||||
output: build/containers
|
||||
```
|
||||
|
||||
Это означает, что корнем сборки Docker-контейнера выступает корень репозитория, а сгенерированные скрипты сборки и Dockerfile-ы появятся в папке `build/containers` в репозитории.
|
||||
|
||||
#### code
|
||||
|
||||
Объект `code` имеет структуру
|
||||
|
||||
```yaml
|
||||
code: !StageCode &code
|
||||
requirements: ./requirements.txt
|
||||
src:
|
||||
- ./myproject/
|
||||
- ./my_static_config.json
|
||||
- ./.mldev/
|
||||
- ./experiments/unip-pipeline-paper.yaml
|
||||
```
|
||||
|
||||
- Это объект типа `StageCode`, на который далее можно ссылаться по имени `code`.
|
||||
- `requirements` - файл с зависимостями, который будет скопировать в контейнер и использован для установки зависимостей
|
||||
- `src` - список файлов или папок, которые будут скопированы в рабочую директорию контейнера. По умолчанию это `/unip`.
|
||||
|
||||
Объект `StageCode` предполагает единый проект, даже если в его рамках запускаются разные файлы. Если несколько контейнеров объединяются в один пайплайн с разными `StageCode`, то в результате сгенерируется несколько объектов `ExperimentPipeline`, составляющих цепочку запуска.
|
||||
|
||||
#### BasicStage
|
||||
|
||||
Объект `BasicStage` определяет входные, выходные данные этапа пайплайна, а также точку входа.
|
||||
|
||||
```yaml
|
||||
stage_prepare: !BasicStage &stage_prepare
|
||||
name: stage_prepare
|
||||
inputs:
|
||||
- !StageVar
|
||||
name: preparation_data
|
||||
path: ./data/preparation
|
||||
outputs:
|
||||
- !StageVar
|
||||
name: internal_state
|
||||
script:
|
||||
- python src/prepare.py
|
||||
```
|
||||
|
||||
- `stage_prepare: !BasicStage &stage_prepare` - аналогично предыдущим компонентам, объект `stage_prepare` класса `BasicStage`, на который можно ссылаться как `stage_prepare`.
|
||||
- `name` - название этапа
|
||||
- `inputs` - список входных переменных
|
||||
- `!StageVar` - переменная типа `StageVar`. Это обычный тип переменных по умолчанию, аналогичный переменным `ExperimentPipeline`.
|
||||
- `name` - название переменной, используется далее в пайплайне и в контейнере.
|
||||
- `path` - путь монтирования переменной внутри контейнера. Если передан относительный путь, он рассчитывается от рабочей директории контейнера - `/unip`.
|
||||
- `outputs` - аналогично `inputs`
|
||||
- `script` - точка входа в этап эксперимента.
|
||||
- При этом точкой входа в контейнер будет команда MLDev `mldev run stage_prepare -f /unip/experiments/unip-pipeline.yaml`, а уже запущенный ей процесс выполнит команду из поля `script`.
|
||||
|
||||
## MLOps-модули
|
||||
|
||||
MLOps-модули фреймворка и некоторые другие дополнительные возможности работают за счёт замены стандартных классов `ContainerStage`, `BasicStage` и `StageVar` на свои варианты.
|
||||
|
||||
Например:
|
||||
|
||||
- `CharismaStage` вместо `ContainerStage` позволяет отправить вычислительную задачу на суперкомпьютер cHARISMa.
|
||||
- `StageSrc` вместо `StageVar` позволяет использовать данные из модуля данных.
|
||||
- `Report` вместо `BasicStage` позволяет сгенерировать отчёт о проведённом вычислительном эксперименте.
|
Loading…
Reference in a new issue