{
    "version": "https:\/\/jsonfeed.org\/version\/1.1",
    "title": "Yuriy Gavrilov: posts tagged MLOps",
    "_rss_description": "Welcome to my personal place for love, peace and happiness 🤖 Yuiry Gavrilov",
    "_rss_language": "en",
    "_itunes_email": "yvgavrilov@gmail.com",
    "_itunes_categories_xml": "",
    "_itunes_image": "https:\/\/gavrilov.info\/pictures\/userpic\/userpic-square@2x.jpg?1643451008",
    "_itunes_explicit": "no",
    "home_page_url": "https:\/\/gavrilov.info\/tags\/mlops\/",
    "feed_url": "https:\/\/gavrilov.info\/tags\/mlops\/json\/",
    "icon": "https:\/\/gavrilov.info\/pictures\/userpic\/userpic@2x.jpg?1643451008",
    "authors": [
        {
            "name": "Yuriy Gavrilov - B[u]g - for charity.gavrilov.eth",
            "url": "https:\/\/gavrilov.info\/",
            "avatar": "https:\/\/gavrilov.info\/pictures\/userpic\/userpic@2x.jpg?1643451008"
        }
    ],
    "items": [
        {
            "id": "317",
            "url": "https:\/\/gavrilov.info\/all\/data-stack-2-0-zakat-lambda-arhitektury-i-voshod-fluss-s-lance\/",
            "title": "Data Stack 2.0: Закат Lambda-архитектуры и восход Fluss с Lance",
            "content_html": "<h2>Data Stack 2.0: Закат Lambda-архитектуры и восход Fluss с Lance<\/h2>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/gavrilov.info\/pictures\/Snimok-ekrana-2026-02-13-v-01.58.40.png\" width=\"1796\" height=\"340\" alt=\"\" \/>\n<\/div>\n<p>В мире инфраструктуры данных происходит “тектонический сдвиг”, описанный в отчетах <a href=\"https:\/\/a16z.com\/emerging-architectures-for-modern-data-infrastructure\/\">a16z.com<\/a>. Индустрия отходит от сложной Lambda-архитектуры (где batch и streaming живут отдельно) к унифицированным решениям, которые называют <b>Streamhouse<\/b>.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/gavrilov.info\/pictures\/Snimok-ekrana-2026-02-13-v-01.59.13.png\" width=\"1476\" height=\"412\" alt=\"\" \/>\n<\/div>\n<p>Два ключевых игрока, меняющих правила игры в этом переходе:<\/p>\n<ol start=\"1\">\n<li><b>Apache Fluss<\/b> — управляемое хранилище для потоковой обработки (Streaming Storage).<\/li>\n<li><b>Lance<\/b> — формат данных нового поколения для AI и Data Lake.<\/li>\n<\/ol>\n<h3>1. Проблема: Почему одной Kafka больше недостаточно?<\/h3>\n<p>Долгое время Apache Kafka была стандартом де-факто для передачи данных. Однако, как отмечают эксперты Ververica в статье <a href=\"https:\/\/www.ververica.com\/blog\/a-world-without-kafka\">Мир без Kafka<\/a>, Kafka была спроектирована как *распределенный лог*, а не как база данных.<\/p>\n<p>Перевод есть тут, у меня: <a href=\"https:\/\/gavrilov.info\/all\/mir-bez-kafka-pochemu-kafka-ne-podhodit-dlya-analitiki-realnogo\/\">https:\/\/gavrilov.info\/all\/mir-bez-kafka-pochemu-kafka-ne-podhodit-dlya-analitiki-realnogo\/<\/a><\/p>\n<p><b>Фундаментальные ограничения брокеров сообщений (Kafka\/Pulsar) для аналитики:<\/b><\/p>\n<ul>\n<li><b>Слабая работа с обновлениями (Updates):<\/b> Kafka — это `append-only` система. Реализация `UPDATE` или `DELETE` требует использования *Compact Topics*, что не дает гарантий мгновенной консистентности и сложно в эксплуатации.<\/li>\n<li><b>Медленное чтение истории:<\/b> Чтобы найти запись годичной давности, вам часто нужно прочитать весь лог последовательно (Scan). Сложность операции — $O(N)$.<\/li>\n<li><b>Row-based природа:<\/b> Данные хранятся строками (Message bytes). Для аналитики (OLAP), где нам нужен средний чек по столбцу `price`, системе приходится распаковывать и читать *все* поля сообщения, что неэффективно.<\/li>\n<\/ul>\n<h3>2. Apache Fluss: Недостающее звено для Flink<\/h3>\n<p><a href=\"https:\/\/fluss.apache.org\">Apache Fluss<\/a> создан, чтобы решить проблему “разделения” между потоком и таблицей. Это нативное хранилище для Apache Flink, которое поддерживает <a href=\"https:\/\/www.ververica.com\/blog\/introducing-fluss\">концепцию Fluss<\/a>.<\/p>\n<h4>Архитектурные прорывы:<\/h4>\n<ol start=\"1\">\n<li><b>Гибридная модель чтения (Stream-Table Duality):<\/b> Fluss позволяет читать данные и как бесконечный поток (Log), и как изменяемую таблицу с первичными ключами (Primary Key Table). Это делает реализацию <b>CDC (Change Data Capture)<\/b> тривиальной: обновления перезаписывают старые значения по ключу.<\/li>\n<li><b>Колоночная проекция (Columnar Projection):<\/b> В отличие от Kafka, Fluss может отдавать аналитическому движку (Flink) только нужные колонки. Это снижает нагрузку на сеть (`I\/O`) в разы.<\/li>\n<li><b>Real-Time Lookups:<\/b> Fluss поддерживает точечные запросы (Point Lookup) по первичному ключу с задержкой порядка миллисекунд.  <br \/>\n$$Latency_{Fluss} \\ll Latency_{Kafka Scan}$$  <br \/>\nЭто позволяет использовать его как *Serverless State* для приложений, избавляясь от необходимости ставить рядом Redis или RocksDB.<\/li>\n<li><b>Tiered Storage в Data Lake:<\/b> Fluss работает в паре с <b>Apache Paimon<\/b> (ранее Flink Table Store). Горячие данные живут в Fluss (на быстрых дисках\/RAM), а по мере устаревания автоматически конвертируются в формат Lakehouse (Paimon\/Parquet\/ ну или Iceberg) и уходят в S3.<\/li>\n<\/ol>\n<h3>3. Lance: Новый стандарт для AI в Data Lake<\/h3>\n<p>Если Fluss отвечает за доставку и горячее состояние, то <b>Lance<\/b> меняет подход к хранению холодных данных для задач машинного обучения (ML).<\/p>\n<p>Традиционный формат <b>Parquet<\/b> великолепен для аналитики (сканирование больших диапазонов), но ужасен для AI, где требуется <b>случайный доступ (Random Access)<\/b> для формирования батчей обучения.<\/p>\n<p><a href=\"https:\/\/lance.org\">Lance<\/a> решает эти проблемы:<\/p>\n<ul>\n<li>Случайный доступ:** Lance позволяет извлекать строки по индексу в ~100 раз быстрее Parquet.<\/li>\n<li>Векторный поиск:** Это формат со встроенным векторным индексом (IVF-PQ). Вы можете хранить эмбеддинги прямо в файлах на S3 и выполнять поиск ближайших соседей (ANN) без отдельной VectorDB (вроде Pinecone или Milvus).<\/li>\n<li>Zero-Copy версионирование:** Эффективное управление версиями датасетов без дублирования данных.<\/li>\n<\/ul>\n<h3>4. Сборка пазла: Как это работает вместе<\/h3>\n<p>Современный <b>Streamhouse<\/b> (см. <a href=\"https:\/\/bigdataschool.ru\/blog\/news\/flink\/fluss-for-flink\/\">примеры архитектуры]<\/a><\/p>\n<p>выглядит как-то так:<\/p>\n<p>Схема потока данных (Workflow):<\/p>\n<ol start=\"1\">\n<li><b>Ingestion:<\/b>  <br \/>\nПриложения (на Go, Java, Python) пишут данные.<\/li>\n\n<ul>\n  <li>Важно:* Поскольку Fluss совместим с протоколом Kafka, можно использовать существующие <b>Kafka-клиенты<\/b> в Go-сервисах для записи в Fluss, не дожидаясь нативных библиотек. Но это пока только теория. Сходу я не нашел примеров быстро, но можно использовать GO и Arrow Flight SQL.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<ol start=\"2\">\n<li><b>Streaming Storage (Fluss):<\/b>  <br \/>\nFluss принимает данные, индексирует первичные ключи и хранит “горячее” окно (например, 24 часа).<\/li>\n\n<ul>\n  <li>Flink* выполняет `JOIN` и агрегации прямо поверх Fluss, используя `Lookup Join` (обогащение данных без сохранения большого стейта внутри Flink).<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<ol start=\"3\">\n<li><b>Archiving & AI (Paimon\/Lance):<\/b>  <br \/>\nИсторические данные сбрасываются в S3.<\/li>\n\n<ul>\n  <li>Для классической BI-аналитики используется формат <b>Apache Paimon<\/b> или Iceberg.<\/li>\n  <li>Для ML-задач данные конвертируются или хранятся в <b>Lance<\/b>.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<ol start=\"4\">\n<li><b>Unified Analytics (Trino):<\/b>  <br \/>\nДвижок <a href=\"https:\/\/lance.org\/integrations\/trino\/config\/\">Trino<\/a> позволяет делать SQL-запросы ко всем слоям одновременно. Аналитик пишет один `SELECT`, а Trino забирает свежие данные из Fluss, а исторические — из S3 (Lance\/Parquet\/iceberg).<\/li>\n<\/ol>\n<h4>Пример интеграции (концептуальный)<\/h4>\n<p>Поскольку прямого клиента Go для Fluss нет, использование в микросервисах чаще всего выглядит как работа через Kafka-протокол или HTTP-прокси, а основная логика ложится на Flink (Java\/Python\/ или еще чего):<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">\/\/ Flink SQL example: Создание таблицы, управляемой Fluss\nCREATE TABLE user_behavior (\n    user_id BIGINT,\n    item_id BIGINT,\n    action STRING,\n    ts TIMESTAMP(3),\n    PRIMARY KEY (user_id) NOT ENFORCED\n) WITH (\n    'connector' = 'fluss',\n    'bootstrap.servers' = '...:9092', \/\/ Fluss совместим с Kafka-адресацией\n    'table.log.consistency' = 'eventual' \/\/ Оптимизация под высокую пропускную способность\n);<\/code><\/pre><p>Надо пробовать и тестировать... все таки еще инкубационный и это только теория.<\/p>\n<h3>5. Выводы и рекомендации<\/h3>\n<ol start=\"1\">\n<li><b>Не используйте Kafka как базу данных.<\/b> Если вашей архитектуре требуются частые обновления (`UPSERT`) и точечные запросы (`Lookup`), <a href=\"https:\/\/fluss.apache.org\">Apache Fluss<\/a> — это более подходящий инструмент в экосистеме Flink.<\/li>\n<li><b>Lance для AI.<\/b> Если вы строите RAG (Retrieval-Augmented Generation) или RecSys, рассмотрите формат Lance вместо связки “Parquet + внешняя VectorDB”. Это упростит инфраструктуру.<\/li>\n<li><b>Следите за совместимостью.<\/b> Интеграции Lance с Trino и Fluss с не-JVM языками (например, Go, Rust или еще чего) находятся в активной разработке. Используйте проверенные пути (Kafka Protocol для Ingestion, DataFusion\/Java\/Python для Querying).<\/li>\n<\/ol>\n<h4>Полезные ресурсы для изучения:<\/h4>\n<ul>\n<li><a href=\"https:\/\/a16z.com\/emerging-architectures-for-modern-data-infrastructure\/\">Emerging Architectures for Modern Data Infrastructure (a16z<\/a>)<\/li>\n<li><a href=\"https:\/\/www.ververica.com\/blog\/introducing-fluss\">Introducing Fluss (Ververica<\/a>)<\/li>\n<li><a href=\"https:\/\/bigdataschool.ru\/blog\/news\/flink\/fluss-for-flink\/\">Fluss for Flink (BigDataSchool<\/a>)<\/li>\n<li><a href=\"https:\/\/github.com\/lance-format\/lance-trino\/issues\/29#issuecomment-3893178604\">Lance & Trino Integration Issue (GitHub<\/a><\/li>\n<\/ul>\n",
            "date_published": "2026-02-13T01:59:35+03:00",
            "date_modified": "2026-02-15T13:51:52+03:00",
            "tags": [
                "AI",
                "big data",
                "Data",
                "Data Engineer",
                "MLOps"
            ],
            "image": "https:\/\/gavrilov.info\/pictures\/Snimok-ekrana-2026-02-13-v-01.58.40.png",
            "_date_published_rfc2822": "Fri, 13 Feb 2026 01:59:35 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "317",
            "_rss_enclosures": [],
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "highlight\/highlight.js",
                    "highlight\/highlight.css"
                ],
                "og_images": [
                    "https:\/\/gavrilov.info\/pictures\/Snimok-ekrana-2026-02-13-v-01.58.40.png",
                    "https:\/\/gavrilov.info\/pictures\/Snimok-ekrana-2026-02-13-v-01.59.13.png"
                ]
            }
        },
        {
            "id": "287",
            "url": "https:\/\/gavrilov.info\/all\/postroenie-nadezhnyh-ml-sistem-i-tehnicheskiy-dolg\/",
            "title": "Построение надежных ML-систем и технический долг",
            "content_html": "<p>Машинное обучение (ML) превратилось из чисто исследовательской дисциплины в мощный инструмент для создания сложных и полезных продуктов. Сегодня ML-системы принимают критически важные решения в медицине, финансах и автономном транспорте <a href=\"https:\/\/medium.com\/@hybrid.minds\/building-robust-ml-systems-a-guide-to-fault-tolerant-machine-learning-f4765d23a51d\">medium.com<\/a>. Однако быстрая разработка и развертывание — лишь верхушка айсберга. Основные трудности и затраты возникают при их долгосрочной поддержке. Неожиданные сбои моделей являются одним из главных барьеров для внедрения технологий ИИ <a href=\"https:\/\/arxiv.org\/abs\/2503.00563\">arxiv.org<\/a>.<\/p>\n<p>В этой статье мы разберем полный жизненный цикл ML-проекта, проанализируем концепцию «скрытого технического долга» и объединим эти знания в единую методику для создания надежных и развиваемых систем.<\/p>\n<h3>Часть 1. Карта жизненного цикла ML-проекта<\/h3>\n<p>Любой ML-проект — это не просто обучение модели, а сложный, итеративный процесс. Рассмотрим его типичный жизненный цикл, разделив на две основные фазы: <b>Исследования<\/b> и <b>Эксплуатация<\/b>.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/gavrilov.info\/pictures\/ML.jpg\" width=\"1170\" height=\"1202\" alt=\"\" \/>\n<div class=\"e2-text-caption\">Из книги масштабируемые данные<\/div>\n<\/div>\n<h3>Фаза 1: Исследования (Research)<\/h3>\n<p>Это итеративный этап проверки гипотез. Главная цель — доказать (или опровергнуть), что с помощью ML можно решить поставленную бизнес-задачу с приемлемым качеством.<\/p>\n<ol start=\"1\">\n<li><b>Запуск проекта:<\/b>\n<ul>\n  <li>Задачи:** Четкое определение бизнес-проблемы и формулировка ML-гипотезы («Сможем ли мы предсказывать Y с помощью данных X с точностью N?»). На этом этапе важно задать фундаментальный вопрос: а нужно ли здесь вообще машинное обучение? Создается техническая инфраструктура: репозиторий в Git, проект в системе CI\/CD (например, Jenkins, GitLab CI).<\/li>\n  <li>Участники:** Бизнес-заказчики, продуктовые менеджеры, аналитики, специалисты по Data Science.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<ol start=\"2\">\n<li><b>Проектирование данных:<\/b>\n<ul>\n  <li>Задачи:** Поиск, сбор и интеграция данных из различных источников в единое хранилище («озеро данных»). Затем данные исследуются на предмет полноты, аномалий и качества, после чего происходит их очистка, трансформация и регистрация в качестве «очищенных» наборов данных.<\/li>\n  <li>Участники:** Инженеры данных (Data Engineers), команда DWH, специалисты по Data Science.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<ol start=\"3\">\n<li><b>Экспериментирование:<\/b>\n<ul>\n  <li>Задачи:** Это сердце работы Data Scientist. Здесь происходит генерация признаков (`feature engineering`), подбор архитектуры модели, ее обучение, валидация и оценка. Критически важными шагами являются версионирование данных и кода, а также фиксация всех результатов и метрик для обеспечения воспроизводимости.<\/li>\n  <li>Участники:** Специалисты по Data Science (ML\/DS).<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p>Эта фаза завершается решением: если эксперименты успешны, проект переходит в фазу эксплуатации. Если нет — он либо отправляется на новый виток исследований, либо закрывается.<\/p>\n<h3>Фаза 2: Эксплуатация (Operations \/ MLOps)<\/h3>\n<p>Цель этой фазы — превратить успешный прототип в надежный, масштабируемый и автоматически работающий продукт, а также поддерживать его работоспособность во времени.<\/p>\n<ol start=\"1\">\n<li><b>Ввод в эксплуатацию:<\/b>\n<ul>\n  <li><b>Задачи:<\/b> Код, написанный для экспериментов, часто требует серьезного рефакторинга и оптимизации для производственной среды. Строится автоматизированный конвейер (pipeline), который выполняет все шаги: от получения свежих данных до выгрузки предсказаний. Этот процесс должен быть не только автоматизированным, но и устойчивым к сбоям, что является ключевым принципом как MLOps, так и классической инженерии надежности Reliability Engineering <a href=\"https:\/\/arxiv.org\/abs\/2411.08981\">arxiv.org<\/a>.<\/li>\n  <li><b>Участники:<\/b> ML-инженеры, DevOps-инженеры, инженеры данных.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<ol start=\"2\">\n<li><b>Мониторинг:<\/b>\n<ul>\n  <li><b>Задачи:<\/b> После развертывания работа не заканчивается. Необходимо постоянно отслеживать как технические, так и качественные показатели модели: стабильность входных данных, качество предсказаний (точность, полнота), а также бизнес-метрики. Для оценки реального влияния на продукт проводятся А\/В-тесты.<\/li>\n  <li><b>Участники:<\/b> ML-инженеры, SRE (Site Reliability Engineers), аналитики, продуктовые менеджеры.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p>Этот цикл непрерывен. Данные мониторинга могут выявить деградацию модели, что повлечет за собой запуск нового витка исследований для ее улучшения.<\/p>\n<h3>Часть 2. «Скрытый технический долг в системах машинного обучения»<\/h3>\n<p>В 2015 году исследователи из Google опубликовали знаковую работу «Hidden Technical Debt in Machine Learning Systems». Они показали, что в ML-системах технический долг накапливается быстрее и опаснее, чем в традиционном ПО.<\/p>\n<p><b>Основная идея:<\/b> Легко построить прототип ML-системы, но чрезвычайно сложно и дорого поддерживать его в рабочем состоянии. Причина — множество скрытых проблем системного уровня, которые не являются багами в коде, но со временем делают систему хрупкой и непредсказуемой.<\/p>\n<h3>Ключевые источники технического долга в ML:<\/h3>\n<ol start=\"1\">\n<li><b>Эрозия границ и связанность (Entanglement):<\/b> В ML практически невозможно изолировать компоненты из-за принципа CACE («Changing Anything Changes Everything» — «Изменение чего угодно меняет всё»).\n<ul>\n  <li>Изменение одного признака влияет на важность всех остальных.<\/li>\n  <li>Добавление нового признака `x_n+1` может полностью изменить веса старых `x_1...x_n`.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<ol start=\"2\">\n<li><b>Зависимости от данных (Data Dependencies):<\/b> Эти зависимости коварнее зависимостей от кода, так как их сложнее отследить статически.\n<ul>\n  <li><b>Нестабильные данные:<\/b> Использование данных из другой ML-системы, которая может обновляться без вашего ведома — это бомба замедленного действия. «Улучшение» в той системе может сломать вашу.<\/li>\n  <li><b>Недоиспользуемые данные:<\/b> Со временем признаки могут становиться ненужными (Legacy Features), добавляться «пачкой» ради мнимого прироста метрик (Bundled Features) или дублировать друг друга (Correlated Features). Они не приносят пользы, но увеличивают сложность и уязвимость системы.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<ol start=\"3\">\n<li><b>Антипаттерны проектирования:<\/b>\n<ul>\n  <li><b>Код-клей (Glue Code):<\/b> Огромное количество кода пишется для «склеивания» данных с универсальной ML-библиотекой (например, `scikit-learn`, `TensorFlow`). Авторы утверждают, что в зрелой системе ML-код может составлять всего 5%, а остальное — «клей».<\/li>\n  <li><b>Джунгли конвейеров (Pipeline Jungles):<\/b> Системы подготовки данных часто разрастаются органически, превращаясь в запутанные «джунгли» из скриптов, которые невозможно тестировать, отлаживать и развивать.<\/li>\n  <li><b>Мертвые пути экспериментов:<\/b> В коде остаются ветки `if\/else` от прошлых экспериментов, которые усложняют тестирование и создают риск неожиданного поведения.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<ol start=\"4\">\n<li><b>Петли обратной связи (Feedback Loops):<\/b> Модель в реальном мире влияет на среду, из которой она же и получает данные для будущего обучения. Это может привести к сужению разнообразия и деградации модели, когда она начинает усиливать свои собственные прошлые решения.<\/li>\n<\/ol>\n<ol start=\"5\">\n<li><b>Долг конфигурации (Configuration Debt):<\/b> Конфигурация ML-систем (какие признаки использовать, параметры алгоритма, пороги) часто занимает больше строк, чем сам код. Ею сложно управлять, ее редко тестируют, а ошибки в ней могут приводить к катастрофическим последствиям.<\/li>\n<\/ol>\n<h3>Часть 3. Практические выводы<\/h3>\n<p>Схема жизненного цикла из Части 1 показывает, <b>ЧТО<\/b> и <b>КОГДА<\/b> нужно делать. Статья о техническом долге из Части 2 объясняет, <b>ПОЧЕМУ и КАК<\/b> это нужно делать правильно, чтобы система не развалилась через полгода.<\/p>\n<p>Взаимосвязь очевидна: почти каждый источник технического долга зарождается на <b>фазе исследований<\/b> и проявляется во всей красе на <b>фазе эксплуатации<\/b>.<\/p>\n<ul>\n<li>Блок <b>Экспериментирование<\/b> — это фабрика по производству `кода-клея` и `недоиспользуемых признаков`. Погоня за сотыми долями процента в метрике качества часто приводит к огромному усложнению системы.<\/li>\n<li>Блок <b>Ввод в эксплуатацию<\/b> без рефакторинга и целостного проектирования порождает `джунгли конвейеров`.<\/li>\n<li>Блок <b>Мониторинг<\/b> — главный инструмент для обнаружения последствий технического долга: смещения данных (Data Drift) и деградации модели (Model Drift).<\/li>\n<\/ul>\n<h5>Рекомендации по созданию надежных ML-систем<\/h5>\n<p>Чтобы построить устойчивую ML-систему, необходимо с самого начала применять инженерную дисциплину.<\/p>\n<ol start=\"1\">\n<li><b>Целостный подход к надежности.<\/b> ML-система — это не только модель. Это данные, признаки, код, конвейеры и мониторинг. Цель — не просто высокая точность, а построение надежной и заслуживающей доверия системы <a href=\"https:\/\/ieeexplore.ieee.org\/iel8\/11127213\/11127132\/11127251.pdf\">ieeexplore.ieee.org<\/a>.<\/li>\n<\/ol>\n<ol start=\"2\">\n<li><b>Версионирование всего.<\/b> Для борьбы с хаосом необходимо версионировать всё: данные, код, параметры экспериментов и итоговые модели. Это единственный способ обеспечить воспроизводимость и возможность отката.<\/li>\n<\/ol>\n<ol start=\"3\">\n<li><b>Автоматизация (MLOps).<\/b> Ручные шаги — источник ошибок. Все процессы, от сборки данных до развертывания модели, должны быть автоматизированы. Тестирование должно включать не только код, но и данные (проверки на соответствие схеме, распределению), а также качество самой модели.<\/li>\n<\/ol>\n<ol start=\"4\">\n<li><b>Проактивный мониторинг.<\/b> Настройте алерты на аномалии во входных данных (data drift), падение качества предсказаний (model drift) и нарушение ключевых бизнес-метрик. Это ваш радар для обнаружения скрытого технического долга в реальном времени.<\/li>\n<\/ol>\n<ol start=\"5\">\n<li><b>Проектирование с учетом отказоустойчивости.<\/b> Система должна быть спроектирована так, чтобы изящно справляться с частичными сбоями: например, иметь логику-запасной вариант (fallback), если источник данных недоступен, или временно отключать модель, если ее предсказания становятся неадекватными <a href=\"https:\/\/medium.com\/@hybrid.minds\/building-robust-ml-systems-a-guide-to-fault-tolerant-machine-learning-f4765d23a51d\">medium.com<\/a>.<\/li>\n<\/ol>\n<ol start=\"6\">\n<li><b>Кросс-функциональные команды и культура.<\/b> Жесткое разделение ролей «исследователь» (Data Scientist) и «инженер» (ML Engineer) — корень многих проблем. Наиболее успешные команды — это гибридные группы, где инженеры и исследователи работают вместе. Такая культура ценит не только прирост точности, но и упрощение системы, удаление лишних признаков и снижение общей сложности.<\/li>\n<\/ol>\n<h3>Заключение<\/h3>\n<p>В конечном счете, успех ML-проекта определяется не тем, как быстро была создана первая версия, а тем, как долго и эффективно она может приносить пользу, адаптируясь к меняющемуся миру. Игнорирование технического долга — это взятие кредита под высокий процент, который неизбежно придется выплачивать временем, деньгами и репутационными потерями.<\/p>\n<hr \/>\n<p>Ниже представлен перевод и краткий пересказ ключевых идей научной статьи «Скрытый технический долг в системах машинного обучения» от D. Sculley и других исследователей из Google. Пояснения к терминам и концепциям добавлены в формате `<?>`.<\/p>\n<p>Оригинал тут: <a href=\"http:\/\/a.gavrilov.info\/data\/posts\/ml-Paper.pdf\">http:\/\/a.gavrilov.info\/data\/posts\/ml-Paper.pdf<\/a><\/p>\n<hr \/>\n<h4>Скрытый технический долг в системах машинного обучения<\/h4>\n<h5>Аннотация<\/h5>\n<p>Машинное обучение (МО) предлагает мощный инструментарий для быстрого создания сложных систем прогнозирования. Однако эта статья утверждает, что опасно считать такие быстрые успехи бесплатными. Используя концепцию технического долга из инженерии программного обеспечения, мы показываем, что в реальных МО-системах часто возникают огромные постоянные затраты на их поддержку. Мы исследуем несколько специфичных для МО факторов риска, которые необходимо учитывать при проектировании: размывание границ, связанность, скрытые петли обратной связи, необъявленные потребители, зависимости от данных, проблемы конфигурации, изменения во внешнем мире и различные антипаттерны на уровне системы.<\/p>\n<h3>1. Введение<\/h3>\n<p>По мере того как сообщество машинного обучения накапливает опыт работы с реальными системами, проявляется неприятная тенденция: разработка и развертывание МО-систем выполняются относительно быстро и дёшево, но их поддержка со временем становится сложной и дорогой.<\/p>\n<p>Эту дихотомию можно понять через призму <b>технического долга<\/b> <?>. Как и в случае с финансовым долгом, иногда существуют веские стратегические причины для его накопления. Не весь долг плох, но весь долг нужно обслуживать. «Выплата» технического долга может включать рефакторинг кода, улучшение тестов, удаление мёртвого кода, сокращение зависимостей и улучшение документации. Откладывание этих выплат приводит к накоплению затрат, подобно процентам по кредиту.<\/p>\n<p><?Технический долг (technical debt) — это метафора в разработке ПО, обозначающая накопленные в системе проблемы, которые возникают из-за выбора быстрых и простых решений вместо более качественных, но долгих. Как и финансовый долг, он требует «выплаты» в будущем в виде рефакторинга и исправления архитектуры, иначе «проценты» (затраты на поддержку и внесение изменений) будут расти.?><\/p>\n<p>Мы утверждаем, что МО-системы особенно склонны к накоплению технического долга, поскольку они наследуют все проблемы поддержки традиционного кода и добавляют к ним свой набор специфичных для МО проблем. Этот долг трудно обнаружить, так как он существует на уровне системы, а не на уровне кода. Данные влияют на поведение МО-системы, что может незаметно нарушать традиционные абстракции и границы.<\/p>\n<p>На уровне системы МО-модель может незаметно размывать границы абстракций. Повторное использование входных сигналов может непреднамеренно связать в остальном изолированные системы. Пакеты МО могут рассматриваться как «чёрные ящики», что приводит к появлению большого количества «кода-клея». Изменения во внешнем мире могут непредвиденным образом повлиять на поведение системы. Даже мониторинг поведения МО-системы может оказаться сложной задачей без продуманного дизайна.<\/p>\n<h3>2. Размывание границ из-за сложности моделей<\/h3>\n<p>Сильные абстракции и модульность помогают создавать поддерживаемый код. К сожалению, в МО-системах трудно обеспечить строгие границы абстракции, поскольку желаемое поведение часто нельзя выразить в виде логики без зависимости от внешних данных.<\/p>\n<ul>\n<li><b>Связанность (Entanglement).<\/b> МО-системы смешивают сигналы, делая изоляцию улучшений невозможной. Это <b>принцип CACE (Changing Anything Changes Everything — «Изменение чего угодно меняет всё»)<\/b>. Изменение распределения одного признака (x₁) может изменить важность или веса всех остальных признаков. Добавление или удаление признаков имеет тот же эффект. Улучшение одной модели в ансамбле может ухудшить общую точность системы, если ошибки станут более коррелированными.<\/li>\n<li><b>Каскады исправлений (Correction Cascades).<\/b> Часто возникает соблазн исправить проблему A’, которая немного отличается от уже решенной проблемы A, создав новую модель `m’` поверх существующей модели `mA`. Эта новая модель `m’` учится вносить небольшую поправку. Однако это создаёт новую зависимость от `mA`, что делает будущий анализ улучшений `mA` значительно дороже. Каскады таких исправлений могут привести к тупиковой ситуации, когда улучшение любого отдельного компонента ухудшает общую производительность системы.<\/li>\n<li><b>Необъявленные потребители (Undeclared Consumers).<\/b> Часто предсказания МО-модели становятся общедоступными (например, через логи). Другие системы могут начать тайно использовать эти данные в качестве входных. В классической инженерии это называют <b>долгом видимости<\/b> <?>. Такие необъявленные потребители создают скрытую жёсткую связь. Любые изменения в исходной модели, даже улучшения, могут негативно и непредсказуемо повлиять на эти системы-потребители.<\/li>\n<\/ul>\n<p><?Долг видимости (visibility debt) — это тип технического долга, возникающий, когда зависимости между частями системы неочевидны или не задокументированы, что затрудняет анализ последствий изменений.?><\/p>\n<h3>3. Зависимости от данных стоят дороже зависимостей от кода<\/h3>\n<p>Зависимости от данных в МО-системах могут накапливать долг так же, как и зависимости кода, но их гораздо труднее обнаружить. Зависимости кода можно выявить статическим анализом, а для зависимостей от данных таких инструментов мало.<\/p>\n<ul>\n<li><b>Нестабильные зависимости от данных.<\/b> Удобно использовать в качестве признаков данные из других систем. Однако если эти входные сигналы нестабильны (например, сами являются выходом другой МО-модели, которая со временем обновляется), они могут меняться. Даже «улучшения» входного сигнала могут иметь разрушительные последствия для потребляющей его системы. Распространённая стратегия смягчения — создание версионных, «замороженных» копий таких данных.<\/li>\n<li><b>Недостаточно используемые зависимости от данных.<\/b> Это входные сигналы, которые дают очень небольшой прирост производительности, но делают систему излишне уязвимой к изменениям. Они могут появиться несколькими путями:\n<ul>\n  <li><b>Устаревшие признаки (Legacy Features):<\/b> Признак добавляется на ранней стадии, со временем новые признаки делают его избыточным, но его не удаляют.<\/li>\n  <li><b>Пакетные признаки (Bundled Features):<\/b> Группа признаков добавляется вместе, потому что «в пакете» они показали пользу, хотя некоторые из них по отдельности бесполезны.<\/li>\n  <li><b>ε-признаки <?>:<\/b> Признаки, которые добавляют ради крошечного прироста точности, но при этом значительно усложняют систему.<\/li>\n  <li><b>Коррелированные признаки (Correlated Features):<\/b> Когда два признака сильно коррелируют, модель может ошибочно отдать предпочтение не причинно-следственному, а зависимому, что делает систему хрупкой, если в будущем эта корреляция изменится.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><?Эпсилон-признаки (ε-Features) — это признаки, которые дают очень незначительное (на величину эпсилон) улучшение точности модели, но при этом могут существенно усложнять систему, увеличивая затраты на ее поддержку.?><\/p>\n<hr \/>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/gavrilov.info\/pictures\/ML-2025-10-16-v-00.42.29.png\" width=\"1038\" height=\"360\" alt=\"\" \/>\n<div class=\"e2-text-caption\"><b>Рисунок 1:<\/b> Лишь малая часть реальных МО-систем состоит из кода МО (маленький чёрный квадрат в центре).<\/div>\n<\/div>\n<p>Необходимая окружающая инфраструктура огромна и сложна.<\/p>\n<ul>\n<li>`ML Code` — Код МО<\/li>\n<li>`Configuration` — Конфигурация<\/li>\n<li>`Data Collection` — Сбор данных<\/li>\n<li>`Feature Extraction` — Извлечение признаков<\/li>\n<li>`Data Verification` — Верификация данных<\/li>\n<li>`Machine Resource Management` — Управление ресурсами<\/li>\n<li>`Analysis Tools` — Инструменты анализа<\/li>\n<li>`Process Management Tools` — Инструменты управления процессами<\/li>\n<li>`Serving Infrastructure` — Инфраструктура для развёртывания<\/li>\n<li>`Monitoring` — Мониторинг<\/li>\n<\/ul>\n<hr \/>\n<h3>4. Петли обратной связи<\/h3>\n<p>Ключевая особенность работающих МО-систем — они часто начинают влиять на собственное поведение.<\/p>\n<ul>\n<li><b>Прямые петли обратной связи.<\/b> Модель напрямую влияет на выбор данных для своего будущего обучения. Например, система рекомендаций показывает пользователю определённые товары; если пользователь кликает на них, эти клики используются для дообучения модели, что закрепляет её текущее поведение.<\/li>\n<li><b>Скрытые петли обратной связи.<\/b> Две отдельные системы косвенно влияют друг на друга через реальный мир. Пример: одна система выбирает товары для показа на веб-странице, а другая — связанные с ними отзывы. Улучшение одной системы (например, показ более релевантных товаров) приведёт к изменению поведения пользователей (больше кликов), что, в свою очередь, повлияет на вторую систему (какие отзывы показывать).<\/li>\n<\/ul>\n<h3>5. Антипаттерны МО-систем<\/h3>\n<p>Для академического сообщества может быть удивительно, что в реальных МО-системах лишь малая часть кода (см. Рисунок 1) отвечает непосредственно за обучение или предсказание. Остальное — это инфраструктурная «обвязка».<\/p>\n<ul>\n<li><b>«Код-клей» (Glue Code) <?>.<\/b> Системный дизайн, при котором пишется огромное количество вспомогательного кода для передачи данных в универсальные МО-пакеты и из них. Этот код «приклеивает» систему к особенностям конкретного пакета, делая переход на альтернативы крайне дорогим. Иногда дешевле создать чистое нативное решение, чем использовать универсальный пакет, если 95% системы — это «код-клей».<\/li>\n<\/ul>\n<p><?«Код-клей» — это код, который не реализует основную бизнес-логику, а служит только для «склеивания» различных, часто несовместимых между собой, программных компонентов или библиотек. Его большое количество — признак плохой архитектуры.?><\/p>\n<ul>\n<li><b>«Джунгли конвейеров» (Pipeline Jungles).<\/b> Особый случай «кода-клея», часто возникающий при подготовке данных. Системы превращаются в «джунгли» из скриптов для парсинга, объединения данных и сэмплирования, которыми сложно управлять и тестировать.<\/li>\n<li><b>Мёртвые ветки экспериментального кода (Dead Experimental Codepaths).<\/b> Часто для экспериментов в основной код добавляются временные условные ветки. Со временем они накапливаются, усложняя поддержку обратной совместимости и тестирование. Знаменитый пример — <a href=\"https:\/\/habr.com\/ru\/articles\/198766\/\">система Knight Capital, потерявшая $465 млн за 45 минут<\/a> из-за непредвиденного поведения устаревшего экспериментального кода.<\/li>\n<li><b>Долг абстракции (Abstraction Debt).<\/b> В МО не хватает сильных, общепринятых абстракций, подобных реляционной базе данных в мире СУБД. Это размывает границы между компонентами системы.<\/li>\n<\/ul>\n<h3>Распространённые «запахи» кода в МО <?><\/h3>\n<ul>\n<li><b>«Запах» простых типов данных (Plain-Old-Data Type Smell):<\/b> Использование обычных `float` или `int` вместо более насыщенных типов. Например, параметр модели должен «знать», является он порогом принятия решения или множителем.<\/li>\n<li><b>«Запах» многоязычности (Multiple-Language Smell):<\/b> Использование нескольких языков программирования в одной системе усложняет тестирование и передачу ответственности.<\/li>\n<li><b>«Запах» прототипа (Prototype Smell):<\/b> Постоянное использование отдельной среды для прототипирования может указывать на то, что основная система слишком неповоротлива и сложна для изменений. Существует опасность, что под давлением сроков прототип будет запущен в продакшен.<\/li>\n<\/ul>\n<p><?«Запах» кода (Code Smells) — это термин, обозначающий признак в коде, который указывает на более глубокую проблему в архитектуре или дизайне системы. Это не ошибка, но повод для рефакторинга.?><\/p>\n<h3>6. Долг конфигурации<\/h3>\n<p>Конфигурация МО-систем — ещё одна область накопления долга. Любая крупная система имеет огромное количество настраиваемых опций. В зрелой системе количество строк конфигурации может значительно превышать количество строк кода. Ошибки в конфигурации могут приводить к потере времени, вычислительных ресурсов и проблемам в продакшене.<\/p>\n<p><b>Принципы хорошей системы конфигурации:<\/b><\/p>\n<ul>\n<li>Легко задавать новую конфигурацию как небольшое изменение предыдущей.<\/li>\n<li>Трудно допустить ошибку вручную.<\/li>\n<li>Легко визуально сравнить две конфигурации.<\/li>\n<li>Легко автоматически проверять базовые факты (количество признаков, зависимости).<\/li>\n<li>Возможность обнаруживать неиспользуемые или избыточные настройки.<\/li>\n<li>Конфигурации должны проходить ревью кода и храниться в репозитории.<\/li>\n<\/ul>\n<h3>7. Работа с изменениями во внешнем мире<\/h3>\n<p>МО-системы увлекательны тем, что они напрямую взаимодействуют с внешним миром. Но внешний мир редко бывает стабилен, что создаёт постоянные затраты на поддержку.<\/p>\n<ul>\n<li><b>Фиксированные пороги в динамических системах.<\/b> Часто порог принятия решения (например, для классификации письма как спама) устанавливается вручную. Если модель обновляется на новых данных, этот старый порог может стать недействительным.<\/li>\n<li><b>Мониторинг и тестирование.<\/b> Необходимо в реальном времени отслеживать поведение системы. Ключевые метрики для мониторинга:\n<ul>\n  <li><b>Смещение предсказаний (Prediction Bias):<\/b> Распределение предсказанных меток должно соответствовать распределению реальных меток. Отклонение этого показателя часто указывает на проблемы.<\/li>\n  <li><b>Ограничения на действия (Action Limits):<\/b> В системах, которые выполняют действия в реальном мире (например, делают ставки на аукционе), полезно устанавливать «разумные» лимиты. Срабатывание такого лимита должно вызывать тревогу и требовать ручного вмешательства.<\/li>\n  <li><b>Поставщики данных (Up-Stream Producers):<\/b> Системы, поставляющие данные для МО-модели, должны тщательно отслеживаться и тестироваться. Любые сбои в них должны немедленно передаваться в МО-систему.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h3>8. Другие области долга, связанного с МО<\/h3>\n<ul>\n<li><b>Долг тестирования данных (Data Testing Debt).<\/b> Если данные заменяют код, то данные, как и код, должны тестироваться.<\/li>\n<li><b>Долг воспроизводимости (Reproducibility Debt).<\/b> Воспроизводить эксперименты в реальных системах сложно из-за рандомизации, недетерминизма параллельных вычислений и взаимодействия с внешним миром.<\/li>\n<li><b>Долг управления процессами (Process Management Debt).<\/b> В зрелых системах могут работать сотни моделей одновременно. Это порождает проблемы с массовым обновлением конфигураций, управлением ресурсами и т.д.<\/li>\n<li><b>Культурный долг (Cultural Debt).<\/b> Жёсткая граница между «исследователями МО» и «инженерами» контрпродуктивна. Важно создавать культуру, в которой удаление признаков, снижение сложности и улучшение стабильности ценятся так же высоко, как и повышение точности.<\/li>\n<\/ul>\n<h3>9. Выводы: Измерение и выплата долга<\/h3>\n<p>Технический долг — полезная метафора, но без строгой метрики. Как его измерить? Быстрое продвижение команды вперёд не является доказательством низкого долга, поскольку его полная стоимость становится очевидной только со временем.<\/p>\n<p><b>Полезные вопросы для оценки долга:<\/b><\/p>\n<ul>\n<li>Насколько легко протестировать совершенно новый алгоритмический подход в полном масштабе?<\/li>\n<li>Каково транзитивное замыкание всех зависимостей от данных?<\/li>\n<li>Насколько точно можно измерить влияние нового изменения на систему?<\/li>\n<li>Ухудшает ли улучшение одной модели или сигнала работу других?<\/li>\n<li>Как быстро новые члены команды могут войти в курс дела?<\/li>\n<\/ul>\n<p>Выплата технического долга, связанного с МО, требует осознанного решения, которое часто может быть достигнуто только через изменение культуры команды. Признание, приоритизация и вознаграждение этих усилий важны для долгосрочного здоровья и успеха МО-команд.<\/p>\n",
            "date_published": "2025-10-16T00:27:47+03:00",
            "date_modified": "2025-10-16T00:57:10+03:00",
            "tags": [
                "Data Governance",
                "Data Products",
                "MLOps"
            ],
            "image": "https:\/\/gavrilov.info\/pictures\/ML.jpg",
            "_date_published_rfc2822": "Thu, 16 Oct 2025 00:27:47 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "287",
            "_rss_enclosures": [],
            "_e2_data": {
                "is_favourite": false,
                "links_required": [],
                "og_images": [
                    "https:\/\/gavrilov.info\/pictures\/ML.jpg",
                    "https:\/\/gavrilov.info\/pictures\/ML-2025-10-16-v-00.42.29.png"
                ]
            }
        },
        {
            "id": "283",
            "url": "https:\/\/gavrilov.info\/all\/potokovaya-obrabotka-stateful-i-stateless\/",
            "title": "Потоковая обработка: Stateful и Stateless",
            "content_html": "<div class=\"e2-text-picture\">\n<img src=\"https:\/\/gavrilov.info\/pictures\/image-213.png\" width=\"1096\" height=\"731\" alt=\"\" \/>\n<div class=\"e2-text-caption\">Оригинал тут: <a href=\"https:\/\/www.arroyo.dev\/blog\/stateful-stream-processing\/\">https:\/\/www.arroyo.dev\/blog\/stateful-stream-processing\/<\/a><\/div>\n<\/div>\n<p>Современные системы обработки данных все чаще работают с непрерывными потоками событий — от отслеживания активности пользователей на сайтах до мониторинга IoT-устройств. Этот подход позволяет анализировать информацию в реальном времени. В основе таких систем лежит выбор между двумя фундаментальными парадигмами: потоковой обработкой с состоянием (stateful) и без него (stateless).<\/p>\n<p>А все эти изыски пошли от <a href=\"https:\/\/news.ycombinator.com\/item?id=43833310#43834033\">этого поста<\/a>:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">I haven't dug deep into this project, so take this with a grain of salt. \/\/ пишет про ArkFlow\nArkFlow is a &quot;stateless&quot; stream processor, like vector or benthos (now Redpanda Connect). These are great for routing data around your infrastructure while doing simple, stateless transformations on them. They tend to be easy to run and scale, and are programmed by manually constructing the graph of operations.\nArroyo (like Flink or Rising Wave) is a &quot;stateful&quot; stream processor, which means it supports operations like windowed aggregations, joins, and incremental SQL view maintenance. Arroyo is programmed declaratively via SQL, which is automatically planned into a dataflow (graph) representation. The tradeoff is that state is hard to manage, and these systems are much harder to operate and scale (although we've done a lot of work with Arroyo to mitigate this!).\nI wrote about the difference at length here: https:\/\/www.arroyo.dev\/blog\/stateful-stream-processing<\/code><\/pre><p>А про маленького Stateless зверька <a href=\"https:\/\/github.com\/arkflow-rs\/arkflow\">ArkFlow<\/a> будет потом статейка. В прочем можете уже посмотреть и раньше.<\/p>\n<p><b>Потоковая обработка с состоянием (stateful)<\/b> означает, что система способна запоминать информацию о ранее обработанных событиях. Это позволяет выполнять сложные операции, такие как агрегации, объединения (joins) и вычисления в “окнах” времени.<\/p>\n<p>В этой статье мы разберем, в чем разница между этими подходами, когда стоит выбирать тот или иной, и как современные движки, такие как Apache Flink или RisingWave, справляются со сложностями хранения состояния. Про “Восходящую волну” и делал тестик тут <a href=\"https:\/\/gavrilov.info\/all\/sozdaem-streaming-lakehouse-za-chas-rukovodstvo-po-risingwave-la\">https:\/\/gavrilov.info\/all\/sozdaem-streaming-lakehouse-za-chas-rukovodstvo-po-risingwave-la<\/a><\/p>\n<h4>Потоковая обработка без состояния (Stateless)<\/h4>\n<p>Многие системы потоковой обработки являются stateless. Это означает, что они обрабатывают каждое событие изолированно, не имея возможности “помнить” информацию о данных, которые видели ранее.<\/p>\n<p>На самом деле, наличие состояния — это источник больших сложностей. Хранение состояния делает систему в десятки раз сложнее в эксплуатации. Именно поэтому базы данных гораздо труднее обслуживать, чем типичные микросервисы, которые чаще всего проектируются как “stateless”.<\/p>\n<p>В потоковой обработке отсутствие состояния также означает, что система выполняет только простые операции преобразования или фильтрации (в SQL-терминах это `SELECT` и `WHERE`). Сложные операции, требующие группировки или объединения данных (`GROUP BY`, `JOIN`, `ORDER BY`), в таких системах невозможны.<\/p>\n<p><b>Преимущества stateless-систем:<\/b><\/p>\n<ul>\n<li><b>Простота эксплуатации:<\/b> Их легко запускать в кластерных системах вроде Kubernetes или в бессерверных средах типа AWS Lambda.<\/li>\n<li><b>Легкость масштабирования:<\/b> Достаточно просто добавить больше обработчиков (workers).<\/li>\n<li><b>Изолированные сбои:<\/b> Выход из строя одного узла не влияет на другие.<\/li>\n<li><b>Быстрое восстановление:<\/b> Не нужно восстанавливать какое-либо состояние.<\/li>\n<\/ul>\n<p>Если ваши задачи укладываются в эти ограничения (нет агрегаций, нет необходимости группировать данные), вам следует использовать stateless-обработку. Часто для таких задач даже не нужен специализированный движок потоковой обработки — достаточно сервиса, который читает события из источника (например, Apache Kafka), выполняет простую логику и записывает результат.<\/p>\n<p><b>Примеры использования:<\/b><\/p>\n<ul>\n<li>Сбор метрик с серверов, их преобразование и отправка в базу данных для мониторинга.<\/li>\n<li>Обработка логов: фильтрация, удаление конфиденциальных данных, изменение формата.<\/li>\n<\/ul>\n<p>Пример простого SQL-запроса, который может быть выполнен в stateless-системе:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">SELECT timestamp, redact(log_text) -- Выбираем время и скрываем часть текста лога\nFROM logs\nWHERE log_level = 'ERROR'; -- Только для событий с уровнем 'ERROR'<\/code><\/pre><h4>Добавление состояния (Stateful)<\/h4>\n<p>Однако большинство бизнес-задач требуют запоминания информации о прошлых событиях, то есть требуют наличия состояния <a href=\"https:\/\/www.decodable.co\/blog\/stream-processing-stateless-vs-stateful\">decodable.co<\/a>. Вместе с состоянием часто возникает необходимость в <b>перераспределении (shuffling)<\/b> данных между узлами кластера.<\/p>\n<h5>Пример: Агрегации с состоянием для обнаружения мошенничества<\/h5>\n<p>Представим, что e-commerce сайт должен обнаруживать и блокировать мошеннические операции с кредитными картами. Один из эффективных признаков мошенничества — “сколько неудачных транзакций было у этого пользователя за последние 24 часа”.<\/p>\n<p>С помощью SQL это можно выразить так:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">SELECT\n  user_id,\n  count(*) as failed_count\nFROM transactions\nWHERE\n  status = 'FAILED'\nGROUP BY\n  user_id,\n  -- hop - это функция скользящего окна в некоторых диалектах SQL\n  hop(INTERVAL '5 seconds', INTERVAL '24 hours');<\/code><\/pre><p>SQL-запрос преобразуется в граф операторов (конвейер), где каждый шаг выполняет свою часть логики.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/gavrilov.info\/pictures\/image-214.png.jpg\" width=\"2560\" height=\"347\" alt=\"\" \/>\n<div class=\"e2-text-caption\">Схема конвейера обработки запроса<\/div>\n<\/div>\n<p>Этот запрос подсчитывает количество неудачных событий для каждого `user_id`. Чтобы получить итоговое число, нам нужно, чтобы <b>все события для одного и того же пользователя (например, “bob”) попадали на один и тот же вычислительный узел<\/b>. Этот процесс перенаправления данных называется <b>перераспределением (shuffling)<\/b> и в SQL вводится оператором `GROUP BY`.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/gavrilov.info\/pictures\/image-214.png\" width=\"1542\" height=\"390\" alt=\"\" \/>\n<div class=\"e2-text-caption\">Пример перераспределения данных<\/div>\n<\/div>\n<p>Но чтобы посчитать количество событий за 24 часа, система должна <b>хранить<\/b> эти события на протяжении всего окна. Это и есть <b>состояние (state)<\/b>. Оно необходимо для любого запроса, который вычисляет агрегаты по времени.<\/p>\n<h5>Пример: Состояние в ETL-конвейерах<\/h5>\n<p>Состояние полезно даже в задачах, которые на первый взгляд кажутся простыми. Например, при загрузке событий в озерo данных ( вроде Amazon S3). Казалось бы, это stateless-операция: получил событие, преобразовал, записал.<\/p>\n<p>Такой подход будет работать при небольшом объеме данных. Но с ростом трафика он приведет к проблемам с производительностью: запись множества мелких файлов в S3 неэффективна и сильно замедляет последующее чтение данных.<\/p>\n<p><b>Решение с использованием состояния:<\/b><br \/>\nStateful-движок может перераспределять события по их типу (`event_type`), направляя каждый тип на свой узел. Затем, используя состояние, он накапливает события в буфере в памяти, пока не соберется достаточно большой пакет (например, 8-16 МБ), и только потом записывает его в S3 одним большим файлом. Это значительно повышает производительность как записи, так и чтения.<\/p>\n<h4>Как и где хранится состояние?<\/h4>\n<p>Разные движки потоковой обработки решают эту задачу по-разному <a href=\"https:\/\/www.skyzh.dev\/blog\/2023-12-28-store-of-streaming-states\">skyzh.dev<\/a>:<\/p>\n<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" class=\"e2-text-table\">\n<tr>\n<td style=\"text-align: center\">Движок\/Система<\/td>\n<td style=\"text-align: center\">Подход к хранению состояния<\/td>\n<td style=\"text-align: center\">Пояснение<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><b>Apache Flink<\/b><\/td>\n<td style=\"text-align: center\">Локально на узле (в памяти или RocksDB)<\/td>\n<td style=\"text-align: center\">RocksDB — это встраиваемая key-value база данных, основанная на LSM-деревьях. Она позволяет хранить огромные объемы состояния, но сложна в настройке и может вызывать проблемы с I\/O диска из-за операций сжатия (compaction).<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><b>ksqlDB \/ Kafka Streams<\/b><\/td>\n<td style=\"text-align: center\">Гибридное (в Kafka и локально)<\/td>\n<td style=\"text-align: center\">Часть состояния хранится в топиках Apache Kafka, а состояние для оконных функций — локально на узлах в памяти или RocksDB.<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><b>RisingWave \/ Arroyo<\/b><\/td>\n<td style=\"text-align: center\">Удаленно (в S3 или FoundationDB) с локальным кэшем<\/td>\n<td style=\"text-align: center\">Современный подход, при котором основное хранилище состояния отделено от вычислений. На вычислительных узлах находится только “горячий” кэш активных данных. Это значительно ускоряет масштабирование и восстановление после сбоев, так как не нужно перемещать терабайты данных между узлами.<\/td>\n<\/tr>\n<\/table>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/gavrilov.info\/pictures\/image-215.png\" width=\"1395\" height=\"700\" alt=\"\" \/>\n<div class=\"e2-text-caption\">Схема LSM дерева<\/div>\n<\/div>\n<h4>Согласованное сохранение состояния (Checkpointing)<\/h4>\n<p>Теперь, когда наши узлы хранят состояние, что произойдет, если они выйдут из строя? Если не принять мер, состояние будет потеряно.<\/p>\n<p>Для обеспечения отказоустойчивости stateful-системы используют механизм <b>контрольных точек (checkpointing)<\/b> — периодическое создание согласованных “снимков” состояния всего конвейера и сохранение их в надежное хранилище (например, S3).<\/p>\n<p>Ключевая задача здесь — гарантировать семантику <b>“exactly-once” (ровно один раз)<\/b>. Это означает, что даже в случае сбоев и восстановлений каждое входящее событие будет обработано и повлияет на итоговое состояние ровно один раз, без потерь и дубликатов <a href=\"https:\/\/export.arxiv.org\/pdf\/2208.09827v2.pdf\">export.arxiv.org<\/a>.<\/p>\n<p>Для этого используется элегантный алгоритм Чанди-Лэмпорта. Его суть в том, что через поток данных пропускаются специальные маркеры — <b>барьеры контрольных точек<\/b>. Когда оператор получает барьеры от всех своих входов, он делает снимок своего текущего состояния и пересылает барьер дальше.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/gavrilov.info\/pictures\/image-216.png\" width=\"1395\" height=\"700\" alt=\"\" \/>\n<div class=\"e2-text-caption\">Поток барьеров контрольных точек<\/div>\n<\/div>\n<p>Современные системы делают этот процесс максимально эффективным:<\/p>\n<ul>\n<li><b>Асинхронность:<\/b> Создание контрольной точки не блокирует обработку новых данных.<\/li>\n<li><b>Инкрементальность:<\/b> В хранилище отправляются только измененные данные, а не всё состояние целиком.<\/li>\n<\/ul>\n<p>Это позволяет создавать контрольные точки очень часто (например, каждые 10 секунд). В случае сбоя системе потребуется перечитать и обработать заново лишь данные за последние 10 секунд, что делает восстановление почти мгновенным.<\/p>\n<h4>Итог<\/h4>\n<p>Потоковая обработка без состояния (stateless) проста и эффективна для ограниченного круга задач, таких как фильтрация или простое преобразование данных.<\/p>\n<p>Однако большинство нетривиальных бизнес-задач — распознавание паттернов, аналитика в реальном времени, корреляция событий — требуют <b>обработки с состоянием (stateful)<\/b> <a href=\"https:\/\/www.e6data.com\/blog\/stateful-vs-stateless-stream-processing\">e6data.com<\/a>. Исторически это было связано с большими операционными сложностями, особенно при использовании систем раннего поколения, которые хранили всё состояние локально на вычислительных узлах.<\/p>\n<p>Современные движки, такие как RisingWave и Arroyo, решают эту проблему, отделяя хранение состояния от вычислений. Они используют удаленное хранилище с локальным кэшированием, что делает масштабирование, восстановление после сбоев и развертывание новых версий кода значительно проще и быстрее.<\/p>\n<p>Таким образом, хотя stateful-системы по своей природе сложнее, современные архитектурные решения делают их мощь доступной для широкого круга задач, открывая дорогу для по-настоящему продвинутой аналитики в реальном времени.<\/p>\n<p>А это тут пока положу, а то забуду :)<\/p>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/774870\">https:\/\/habr.com\/ru\/articles\/774870<\/a> – Землю — крестьянам, gRPC — питонистам. Она про grpc питонячий.<\/p>\n",
            "date_published": "2025-10-01T02:00:00+03:00",
            "date_modified": "2025-10-01T01:03:52+03:00",
            "tags": [
                "MLOps",
                "Programming"
            ],
            "image": "https:\/\/gavrilov.info\/pictures\/image-213.png",
            "_date_published_rfc2822": "Wed, 01 Oct 2025 02:00:00 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "283",
            "_rss_enclosures": [],
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "highlight\/highlight.js",
                    "highlight\/highlight.css"
                ],
                "og_images": [
                    "https:\/\/gavrilov.info\/pictures\/image-213.png",
                    "https:\/\/gavrilov.info\/pictures\/image-214.png.jpg",
                    "https:\/\/gavrilov.info\/pictures\/image-214.png",
                    "https:\/\/gavrilov.info\/pictures\/image-215.png",
                    "https:\/\/gavrilov.info\/pictures\/image-216.png"
                ]
            }
        },
        {
            "id": "250",
            "url": "https:\/\/gavrilov.info\/all\/evolyuciya-i-buduschee-orkestracii-ii\/",
            "title": "Эволюция и будущее оркестрации ИИ",
            "content_html": "<p>Давайте проследим историю оркестрации и выясним, почему она стала обязательной для будущего ИИ и агентов.<\/p>\n<p>Оригинал тут: <a href=\"https:\/\/unionailoop.substack.com\/p\/the-evolution-and-future-of-ai-orchestration\">https:\/\/unionailoop.substack.com\/p\/the-evolution-and-future-of-ai-orchestration<\/a><br \/>\n2 июля 2025 г. – Кетан Умаре — генеральный директор и соучредитель Union.ai. Ранее он занимал несколько руководящих должностей в Lyft, Oracle и Amazon, работая с облачными технологиями, распределенными системами хранения данных, картографией и системами машинного обучения.<\/p>\n<p>Термин “оркестрация” значительно эволюционировал за последнее десятилетие. То, что начиналось как способ упорядочивания микросервисов и задач обработки данных, превратилось в ключевой фактор для современных приложений, охватывающий системы от традиционных бэкендов до высокодинамичных, интеллектуальных рабочих нагрузок на агентах.<\/p>\n<p>Сегодня мы наблюдаем ранние дни нового вида оркестрации, которая не просто перемещает данные или вызывает сервисы, но думает, адаптируется и реагирует в реальном времени. Давайте проследим историю оркестрации и выясним, почему она стала обязательной для будущего ИИ и агентов.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/gavrilov.info\/pictures\/image-194.png\" width=\"1456\" height=\"971\" alt=\"\" \/>\n<\/div>\n<p>Настоящим узким местом являются не модели или вычисления – это мы.<\/p>\n<p>Модели переходят от “что запускается дальше” к “что думает дальше”, и это заставляет формироваться новый, мощный слой наших технологических стеков. Но чтобы понять, что неизбежно, нам нужно понять, что привело нас сюда.<\/p>\n<p><b>1. Зарождение оркестрации: ETL и микросервисы<\/b><\/p>\n<p><b>2012 – ETL<\/b><br \/>\nОркестрация впервые появилась для обеспечения ETL (извлечение, преобразование, загрузка), где планировщики, такие как Airflow, управляли приемом и преобразованием данных на больших хранилищах данных.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/gavrilov.info\/pictures\/image-195.png\" width=\"1094\" height=\"537\" alt=\"\" \/>\n<\/div>\n<p><b>Диаграмма: Процесс ETL<\/b><\/p>\n<ul>\n<li>Извлечение:** Извлекает и проверяет данные из различных источников.<\/li>\n<li>Преобразование:** Обрабатывает и организует извлеченные данные, чтобы сделать их пригодными для использования.<\/li>\n<li>Загрузка:** Перемещает преобразованные данные в репозиторий данных.<\/li>\n<\/ul>\n<p><b>2014 – Микросервисы<\/b><br \/>\nПоскольку использование постоянно растущих объемов данных стало более критичным для инноваций, возникла потребность в оркестрации микросервисов, где системы, такие как AWS Step Functions или Cadence, обеспечивали надежное выполнение вызовов сервисов и повторные попытки в транзакционных системах.<\/p>\n<p>На ранних этапах оркестрация в основном сосредоточивалась на упорядочивании или определении, когда и как вызывать функцию, запускать скрипт или запускать контейнер. Трудоёмкие вычисления перекладывались на традиционные вычислительные движки, такие как Spark, AWS Batch, GCP Cloud Run или, позже, K8s. Оркестрация не касалась вычислений, и ей это было не нужно.<\/p>\n<p><b>2. Машинное обучение: оркестрация встречается с вычислениями<\/b><\/p>\n<p><b>2017 – ML-конвейеры<\/b><br \/>\nML привнесло новые требования: дорогие вычисления и отказоустойчивость.<\/p>\n<p>В отличие от микросервисов или пакетного ETL, рабочие процессы ML представляют собой долгосрочные процессы, тесно связанные с инфраструктурой. Графические процессоры, на которые сейчас в большей степени полагаются, особенно для нужд обучения ML, являются более дорогими, чем центральные процессоры. Обучение моделей, их оценка, настройка гиперпараметров — все это требует динамического распределения ресурсов GPU или CPU. А поскольку эти процессы занимают гораздо больше времени, отказоустойчивое восстановление после сбоев стало гораздо важнее.<\/p>\n<p>Эти потребности породили оркестраторы ML-конвейеров, такие как Flyte, которые до сих пор являются открытыми решениями для оркестрации, на которые полагается большинство команд.<\/p>\n<p><b>2021 – Управляемая оркестрация ML<\/b><br \/>\nПо мере того как оркестрация ML становилась более сложной, она ложилась более тяжелым бременем на команды ML, данных и платформ, которым нужно было поддерживать инфраструктуру. Им нужны были системы оркестрации, которые определяли DAG (ориентированный ациклический граф), выделяли ресурсы, управляли жизненным циклом задач и чисто масштабировались до нуля.<\/p>\n<p>Платформы оркестрации, такие как Union.ai, Prefect и Airflow, появились для снятия инфраструктурной нагрузки с оркестрации. С появлением эпохи ИИ они стали гораздо популярнее для команд, создающих рабочие процессы ИИ\/ML, как критически важную часть своей работы.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/gavrilov.info\/pictures\/image-196.png\" width=\"1456\" height=\"817\" alt=\"\" \/>\n<\/div>\n<p><b>3. Агентные системы: оркестрация в эпоху ИИ<\/b><\/p>\n<p><b>2025 – ИИ и агентная оркестрация<\/b><br \/>\nСейчас мы вступаем в новую фазу: оркестрацию интеллектуальных агентов и систем ИИ.<\/p>\n<p>Агенты — это автономные, способные сохранять состояние программы (часто управляемые большими языковыми моделями), которые могут планировать, рассуждать и действовать. И оркестрация критически важна для их успеха в масштабе. Почему?<\/p>\n<ol start=\"1\">\n<li><b>Они зависят от интеграций.<\/b> Агенты часто полагаются на внешние инструменты (API, базы данных, модели), и эти взаимодействия должны управляться.<\/li>\n<li><b>Они принимают динамические решения.<\/b> Агенты часто уточняют результаты за несколько проходов, подобно настройке гиперпараметров или рекурсивному исключению признаков в ML.<\/li>\n<li><b>Они делегируют.<\/b> Один агент может вызывать другого, который может разветвляться на новые инструменты или рабочие процессы.<\/li>\n<li><b>Они требуют вычислений.<\/b> Рассмотрим агентов, которые решают парсить веб или выполнять код. Если мы думаем об агентах как о программистах, то быстро понимаем, что оркестрация без доступа к вычислениям ограничивает их автономию.<\/li>\n<\/ol>\n<p>Современные платформы разработки ИИ должны быть способны оркестрировать эти стохастические системы от начала до конца и динамически, а не статически. В противном случае мы лишаем агентов свободы действий.<\/p>\n<p>Это отражает идеи Anthropic: создание эффективных агентов означает управление инструментами, адаптацию стратегий и надежное оркестрирование долгосрочных фоновых задач. Оркестрация здесь — это не статический DAG. Это динамический цикл.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/gavrilov.info\/pictures\/image-197.png\" width=\"914\" height=\"1193\" alt=\"\" \/>\n<\/div>\n<p><b>Будущая инфраструктура разработки ИИ<\/b><\/p>\n<p>“По некоторым оценкам, более 80% проектов ИИ терпят неудачу – это вдвое превышает процент неудач проектов в области информационных технологий, которые не связаны с ИИ”. – RAND<\/p>\n<p>По мере созревания ML и агентных систем в 2025 году и далее, команды, создающие их, обнаруживают, что общие потребности в разработке ИИ выходят на первый план. Это не гипотетические проблемы. Мы видели их вживую у реальных клиентов и в продуктах, которые они создают.<\/p>\n<ul>\n<li>Динамические рабочие процессы:** в отличие от статических DAG, динамические рабочие процессы позволяют агентам и системам ИИ принимать решения на лету во время выполнения.<\/li>\n<li>Гибкая интеграция инфраструктуры:** оркестрация должна происходить по облакам и кластерам, в некоторых случаях динамически переключаясь на источник наиболее доступных вычислений.<\/li>\n<li>Кросс-командное выполнение:** эти платформы должны объединять отдельных лиц, команды и агентов в единой среде разработки совместно, безопасно и надежно.<\/li>\n<li>Наблюдаемость, надежность и управление:** агенты и рабочие процессы могут работать автономно в черном ящике. Платформы разработки ИИ должны обеспечивать прозрачность для рассуждений, сбоев, происхождения данных и использования ресурсов.<\/li>\n<li>Масштаб:** большие данные становятся больше. Вычислительная мощность востребована как никогда. Платформы должны надежно справляться с требованиями к масштабированию, присущими этим системам.<\/li>\n<\/ul>\n<p><b>Заключение:<\/b><\/p>\n<p><b>Слой инфраструктуры разработки ИИ<\/b><\/p>\n<p>Мы вступаем в мир, где оркестрация — это не просто “что запускается дальше”, но “что думает дальше”.<\/p>\n<p>Эволюция от статических ETL-конвейеров к динамическим ML-рабочим процессам теперь совпала с ростом автономных агентов, и это сближение раскрывает фундаментальную истину.<\/p>\n<p><b>Агенты и современные ML-системы требуют нового слоя в наших технологических стеках: инфраструктуры разработки ИИ.<\/b><\/p>\n<p>Агенты и ML-системы по своей природе стохастичны, принимают решения во время выполнения на основе обрабатываемых данных, требуют динамического выделения вычислений и включают итеративное уточнение. Что наиболее важно, оба требуют оркестрации, которая может адаптироваться к изменяющимся условиям, а не просто выполнять предопределенные, линейные шаги.<\/p>\n<p>Это схождение указывает на единую, унифицированную абстракцию оркестрации, которая может обеспечить то, что так отчаянно необходимо обеим областям: надежность для долгосрочных процессов, которые не могут себе позволить терять состояние, динамическое обеспечение вычислений, масштабирующихся в соответствии со спросом, и отказоустойчивость, которая изящно обрабатывает неизбежные сбои в сложных, распределенных системах.<\/p>\n<p>Будущее оркестрации обеспечивает основу для слоя инфраструктуры разработки ИИ, будучи:<\/p>\n<ul>\n<li>Динамичной** – адаптирующей структуру рабочего процесса на основе условий выполнения.<\/li>\n<li>Эфемерной** – запускающей и останавливающей ресурсы по мере необходимости в рабочих процессах.<\/li>\n<li>Мультиагентной и мультичеловеческой** – оркеструющей сотрудничество между автономными системами и командами.<\/li>\n<li>Надежной и наблюдаемой** – обеспечивающей видимость и восстановление для систем, которые работают автономно.<\/li>\n<li>Безопасной** – управляющей доступом и выполнением в различных распределенных рабочих нагрузках.<\/li>\n<\/ul>\n<p>Оркестрация становится центральной нервной системой систем ИИ, питая этот новый слой инфраструктуры разработки ИИ в наших технологических стеках.<\/p>\n<p>Вопрос больше не “как запустить этот конвейер?”, а “как позволить системам решать, что запускать, когда запускать и как делать это надежно в масштабе?”<\/p>\n",
            "date_published": "2025-07-03T00:53:08+03:00",
            "date_modified": "2025-07-03T00:52:16+03:00",
            "tags": [
                "AI",
                "MLOps"
            ],
            "image": "https:\/\/gavrilov.info\/pictures\/image-194.png",
            "_date_published_rfc2822": "Thu, 03 Jul 2025 00:53:08 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "250",
            "_rss_enclosures": [],
            "_e2_data": {
                "is_favourite": false,
                "links_required": [],
                "og_images": [
                    "https:\/\/gavrilov.info\/pictures\/image-194.png",
                    "https:\/\/gavrilov.info\/pictures\/image-195.png",
                    "https:\/\/gavrilov.info\/pictures\/image-196.png",
                    "https:\/\/gavrilov.info\/pictures\/image-197.png"
                ]
            }
        },
        {
            "id": "248",
            "url": "https:\/\/gavrilov.info\/all\/crisp-ml-q-standartizirovannaya-metodologiya-razrabotki-mashinno\/",
            "title": "CRISP-ML(Q)+MLOps and Platform: Стандартизированная методология разработки машинного обучения с гарантией качества",
            "content_html": "<div class=\"e2-text-picture\">\n<img src=\"https:\/\/gavrilov.info\/pictures\/image-194.png.jpg\" width=\"2560\" height=\"1421\" alt=\"\" \/>\n<\/div>\n<p>CRISP-ML(Q) (<b>C<\/b>ross-<b>I<\/b>ndustry <b>S<\/b>tandard <b>P<\/b>rocess for <b>M<\/b>achine <b>L<\/b>earning with <b>Q<\/b>uality Assurance) — это современная процессная модель для управления жизненным циклом ML-проектов. Она была разработана как эволюция классической методологии <a href=\"https:\/\/www.datascience-pm.com\/crisp-dm-still-most-popular\/\">CRISP-DM<\/a> (Cross-Industry Standard Process for Data Mining, 1999 г.), которая остается одной из самых популярных методологий для проектов по анализу данных <a href=\"https:\/\/www.datascience-pm.com\/crisp-dm-still-most-popular\/\">datascience-pm.com<\/a>. CRISP-ML(Q) адаптирует и расширяет CRISP-DM, добавляя этапы, критичные для промышленного машинного обучения: <b>обеспечение качества, мониторинг и поддержку моделей в продакшене<\/b>.<\/p>\n<p>Возникновение CRISP-ML(Q) продиктовано статистикой: значительная часть ML-проектов (по некоторым оценкам, 75-85%) не достигали поставленных целей из-за отсутствия стандартизации, проблем с данными и недооценки операционных рисков. В отличие от CRISP-DM, который сосредоточен в первую очередь на процессе анализа данных <a href=\"https:\/\/medium.com\/voice-tech-podcast\/cross-industry-standard-process-for-data-mining-crisp-dm-9edc0c5e3a1\">medium.com<\/a>, CRISP-ML(Q) охватывает <b>полный жизненный цикл<\/b> — от бизнес-постановки до эксплуатации ML-систем, делая основной акцент на обеспечении качества на каждом шаге <a href=\"https:\/\/www.mdpi.com\/2076-3417\/11\/19\/8861\">mdpi.com<\/a>.<\/p>\n<p>Кстати ранее писал про The Big Book of MLOps – 2nd Edition: <a href=\"https:\/\/gavrilov.info\/all\/sintez-the-big-book-of-mlops-2nd-edition\/\">https:\/\/gavrilov.info\/all\/sintez-the-big-book-of-mlops-2nd-edition\/<\/a><\/p>\n<p>А еще тут добавлю про ZenML pdf’ку и <a href=\"https:\/\/github.com\/zenml-io\/zenml\">https:\/\/github.com\/zenml-io\/zenml<\/a><\/p>\n<h3>Ключевые фазы методологии (6 этапов)<\/h3>\n<p>CRISP-ML(Q) структурирует процесс разработки ML-решений в шесть основных взаимосвязанных и итеративных фаз:<\/p>\n<ol start=\"1\">\n<li><b>Понимание бизнеса и данных (Business Understanding & Data Understanding)<\/b>  <br \/>\nНа этом начальном этапе определяются и понимаются бизнес-цели проекта (например, снижение времени обработки заявки на 20%), а также ключевые показатели эффективности (KPI). Эти бизнес-цели затем переводятся в конкретные задачи машинного обучения. Одновременно проводится глубокий анализ данных: исследуется их доступность, качество, потенциальные проблемы (пропуски, аномалии) и нормативные ограничения (например, GDPR), а также оцениваются необходимые ресурсы. На этом этапе могут использоваться инструменты типа ML Canvas для оценки осуществимости проекта.<\/li>\n<\/ol>\n<ol start=\"2\">\n<li><b>Инженерия данных (Data Engineering)<\/b>  <br \/>\nЭта фаза включает всестороннюю подготовку данных для моделирования. Это очистка данных (обработка пропущенных значений, удаление или корректировка выбросов), их трансформация (нормализация, стандартизация), балансировка классов (методы oversampling\/undersampling), а также генерация новых, более информативных признаков (feature engineering). Важным нововведением здесь является внедрение <b>Data Unit Tests<\/b> для предотвращения ошибок и поддержания качества данных до их использования в моделях.<\/li>\n<\/ol>\n<ol start=\"3\">\n<li><b>Моделирование машинного обучения (Machine Learning Modeling)<\/b>  <br \/>\nНа этом этапе команда выбирает подходящие алгоритмы машинного обучения, учитывая такие ограничения, как интерпретируемость модели, вычислительные ресурсы и требования к времени отклика. Происходит обучение моделей, настройка гиперпараметров и оценка их производительности на валидационных наборах данных. Для обеспечения воспроизводимости и отслеживаемости всех экспериментов фиксируются метаданные: используемые гиперпараметры, версии датасетов, окружение выполнения. Применяются такие инструменты, как MLflow и Kubeflow.<\/li>\n<\/ol>\n<ol start=\"4\">\n<li><b>Оценка качества ML-моделей (Quality Assurance)<\/b>  <br \/>\nЭто одна из ключевых отличительных фаз CRISP-ML(Q), выделенная в отдельный этап. Здесь проводится всестороннее тестирование модели: оценка ее устойчивости к зашумленным данным, проверка ключевых метрик (accuracy, F1-score, ROC-AUC) и глубокий анализ справедливости (fairness) для выявления и устранения потенциальных смещений в предсказаниях. Решение о переходе к развертыванию принимается только после того, как модель достигнет заданных пороговых значений качества (например, precision > 0.9). Эта фаза может включать проверку надежности, стабильности и объяснимости модели <a href=\"https:\/\/www.mdpi.com\/2076-3417\/11\/19\/8861\">mdpi.com<\/a>.<\/li>\n<\/ol>\n<ol start=\"5\">\n<li><b>Развертывание (Deployment)<\/b>  <br \/>\nНа этом этапе обученная и проверенная модель интегрируется в производственную среду. Развертывание может осуществляться различными способами: как REST-API, микросервис или встроенный плагин. Используются стратегии безопасного развертывания, такие как A\/B-тестирование, канареечные релизы или сине-зеленое развертывание. Обязательной частью этой фазы является наличие четкого плана отката на предыдущую версию в случае возникновения сбоев или неожиданной деградации производительности.<\/li>\n<\/ol>\n<ol start=\"6\">\n<li><b>Мониторинг и поддержка (Monitoring & Maintenance)<\/b>  <br \/>\nПосле развертывания модели начинается фаза непрерывного мониторинга её производительности в реальных условиях. Это критически важно, так как модели машинного обучения могут терять свою эффективность со временем из-за дрейфа данных (concept drift или data drift). Мониторинг включает отслеживание метрик производительности модели, выявление аномалий и автоматическое переобучение при падении метрик или существенном изменении распределения входных данных. Также на этом этапе происходит сбор новых данных, которые могут быть использованы для последующего ретренинга моделей, замыкая цикл улучшения <a href=\"https:\/\/www.mdpi.com\/2076-3417\/11\/19\/8861\">mdpi.com<\/a>.<\/li>\n<\/ol>\n<h3>Таблица 1: Сравнение CRISP-DM и CRISP-ML(Q)<\/h3>\n<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" class=\"e2-text-table\">\n<tr>\n<td><b>Аспект<\/b><\/td>\n<td><b>CRISP-DM<\/b><\/td>\n<td><b>CRISP-ML(Q)<\/b><\/td>\n<\/tr>\n<tr>\n<td><b>Фазы<\/b><\/td>\n<td>6 этапов<\/td>\n<td>6 этапов + углубление в QA<\/td>\n<\/tr>\n<tr>\n<td><b>Фокус<\/b><\/td>\n<td>Data Mining, анализ данных<\/td>\n<td>End-to-end ML-приложения, производство<\/td>\n<\/tr>\n<tr>\n<td><b>Мониторинг<\/b><\/td>\n<td>Не включен как отдельный этап<\/td>\n<td>Обязательная фаза №6<\/td>\n<\/tr>\n<tr>\n<td><b>Воспроизводимость<\/b><\/td>\n<td>Частичная, не стандартизирована<\/td>\n<td>Документирование метаданных, версионирование<\/td>\n<\/tr>\n<tr>\n<td><b>Риск-менеджмент<\/b><\/td>\n<td>Не явно выражен<\/td>\n<td>Встроен в каждый этап, риск-ориентированный подход<\/td>\n<\/tr>\n<tr>\n<td><b>Обеспечение качества<\/b><\/td>\n<td>В основном, оценка модели<\/td>\n<td>Системный QA на всех этапах жизненного цикла<\/td>\n<\/tr>\n<\/table>\n<h3>Таблица 2: Детализация Задач по Фазам CRISP-ML(Q)<\/h3>\n<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" class=\"e2-text-table\">\n<tr>\n<td><b>Фаза<\/b><\/td>\n<td><b>Задачи<\/b><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><b>1. Понимание Бизнеса и Данных<\/b><\/td>\n<td>– Определение бизнес-целей проекта.<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><\/td>\n<td>– Перевод бизнес-целей в цели машинного обучения (ML-цели).<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><\/td>\n<td>– Выявление и сбор доступных данных.<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><\/td>\n<td>– Верификация и первичный анализ данных.<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><\/td>\n<td>– Оценка осуществимости проекта (техническая, ресурсная, экономическая).<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><\/td>\n<td>– Создание концепции\/доказательства концепции (POC – Proof of Concept), если необходимо.<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><\/td>\n<td>– Определение нормативных и этических ограничений.<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: right\"><b>2. Инженерия Данных<\/b><\/td>\n<td>– Отбор признаков (feature selection).<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><\/td>\n<td>– Отбор данных (data selection), создание выборок.<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><\/td>\n<td>– Балансировка классов (методы oversampling\/undersampling).<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><\/td>\n<td>– Очистка данных (снижение шума, обработка пропущенных значений, удаление\/коррекция выбросов).<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><\/td>\n<td>– Инженерия признаков (feature engineering), создание новых признаков.<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><\/td>\n<td>– Аугментация данных (data augmentation) для увеличения объема обучающих данных.<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><\/td>\n<td>– Стандартизация\/нормализация данных.<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><\/td>\n<td>– Реализация <b>Data Unit Tests<\/b> для контроля качества входных данных.<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><b>3. Инженерия ML-модели<\/b><\/td>\n<td style=\"text-align: left\">– Определение метрик качества модели (например, точность, F1-score, ROC AUC).<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><\/td>\n<td>– Выбор алгоритма машинного обучения (включая выбор базового\/эталонного решения – baseline).<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><\/td>\n<td>– Добавление специфических знаний предметной области для специализации модели.<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><\/td>\n<td>– Обучение модели.<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><\/td>\n<td>– Опционально: применение трансферного обучения (Transfer Learning) с использованием предобученных моделей.<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><\/td>\n<td>– Опционально: сжатие модели (Model Compression) для оптимизации ресурсов.<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><\/td>\n<td>– Опционально: использование ансамблевого обучения (Ensemble Learning).<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><\/td>\n<td>– Тщательное документирование ML-модели и проведенных экспериментов (метаданные, гиперпараметры, версии).<\/td>\n<\/tr>\n<tr>\n<td><b>4. Оценка Качества ML-модели<\/b><\/td>\n<td>– Валидация производительности модели на тестовых данных.<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><\/td>\n<td>– Определение робастности (устойчивости) модели к изменениям во входных данных.<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><\/td>\n<td>– Повышение объяснимости (Explainability) модели (например, с использованием SHAP, LIME).<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><\/td>\n<td>– Оценка справедливости (Fairness) модели для предотвращения смещений.<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><\/td>\n<td>– Принятие решения о развертывании модели (Deploy\/No Deploy) на основе установленных порогов качества.<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><\/td>\n<td>– Документирование фазы оценки и принятых решений.<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><\/td>\n<td>– Проведение аудита модели.<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><b>5. Развертывание Модели<\/b><\/td>\n<td>– Оценка модели в производственных условиях (производительность, стабильность, потребление ресурсов).<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><\/td>\n<td>– Обеспечение приемлемости для пользователя и удобства использования системы.<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><\/td>\n<td>– Управление моделью (Model Governance): контроль версий, политики доступа.<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><\/td>\n<td>– Развертывание согласно выбранной стратегии (A\/B-тестирование, многорукие бандиты, канареечные релизы, сине-зеленое развертывание).<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><\/td>\n<td>– Разработка плана отката (rollback plan) на случай проблем.<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><b>6. Мониторинг и Поддержка Модели<\/b><\/td>\n<td>– Мониторинг эффективности и результативности предсказаний модели в продакшене.<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><\/td>\n<td>– Сравнение данных производительности модели с ранее заданными критериями успеха и порогами (например, деградация метрик).<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><\/td>\n<td>– Выявление дрейфа данных (data drift) и концептуального дрейфа (concept drift).<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><\/td>\n<td>– Принятие решения о необходимости переобучения модели.<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><\/td>\n<td>– Сбор новых данных из продакшена.<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><\/td>\n<td>– Выполнение разметки новых точек данных для обновления обучающей выборки.<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><\/td>\n<td>– Повторение задач из фаз “Инженерия модели” и “Оценка модели” при переобучении.<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center\"><\/td>\n<td>– Непрерывная интеграция (CI), непрерывное обучение (CT) и непрерывное развертывание (CD) модели в рамках MLOps пайплайна.<\/td>\n<\/tr>\n<\/table>\n<h3>Принципы обеспечения качества (QA)<\/h3>\n<p>CRISP-ML(Q) интегрирует принципы обеспечения качества на каждом этапе цикла разработки ML:<\/p>\n<ul>\n<li><b>Риск-ориентированный подход<\/b>: Для каждой фазы идентифицируются потенциальные риски (например, смещение данных, переобучение, дрейф модели), и разрабатываются методы их минимизации. Примеры включают использование кросс-валидации, объяснимых моделей (таких как SHAP для интерпретации предсказаний) и тщательное логирование экспериментов.<\/li>\n<li><b>Документирование<\/b>: Поддерживается строгая документация требований, версий данных, используемых метрик оценки и любых изменений в пайплайне. Инструменты типа Model Cards Toolkit могут использоваться для создания прозрачных отчетов о моделях.<\/li>\n<li><b>Автоматизация пайплайнов<\/b>: Для обеспечения воспроизводимости и эффективности процессов активно используются автоматизированные конвейеры (data pipelines, ML pipelines).<\/li>\n<\/ul>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/gavrilov.info\/pictures\/image-194.png-1.jpg\" width=\"2560\" height=\"1919\" alt=\"\" \/>\n<div class=\"e2-text-caption\">pic. Этапы оценки рисков<\/div>\n<\/div>\n<h3>MLOps: Концепция, Инструменты и Сравнение с Apache Airflow<\/h3>\n<p>MLOps — это, по сути, <b>инженерная дисциплина<\/b>, сосредоточенная на автоматизации и масштабировании жизненного цикла ML-систем, включая CI\/CD (непрерывная интеграция\/непрерывная поставка) для моделей, автоматизированное тестирование и мониторинг в продакшене <a href=\"https:\/\/www.mdpi.com\/2076-3417\/11\/19\/8861\">mdpi.com<\/a>.<br \/>\nCRISP-ML(Q), напротив, является <b>процессной моделью<\/b>, которая задает последовательность шагов и необходимых активностей для успешного выполнения ML-проекта.<\/p>\n<p>Таким образом, они дополняют друг друга:<\/p>\n<ul>\n<li>CRISP-ML(Q) определяет <b>“что делать”<\/b> и “когда делать” на каждом этапе жизненного цикла ML-проекта, фокусируясь на методологии и целях.<\/li>\n<li>MLOps предоставляет <b>инструменты и практики<\/b> для реализации этих “что делать”, отвечая на вопрос “как делать”.<\/li>\n<\/ul>\n<h4>Apache SeaTunnel и Apache DolphinScheduler в контексте MLOps<\/h4>\n<p>На этапе <b>инженерии данных<\/b> и <b>мониторинга<\/b> в рамках MLOps-пайплайна часто требуются мощные инструменты для интеграции, обработки и оркестрации данных. Здесь на помощь приходят такие открытые фреймворки и платформы, как <b>Apache SeaTunnel<\/b> и <b>Apache DolphinScheduler<\/b>.<\/p>\n<ul>\n<li><b>Apache SeaTunnel<\/b>: Этот фреймворк является высокопроизводительным, распределенным решением для интеграции и синхронизации больших объемов данных <a href=\"https:\/\/news.apache.org\/foundation\/entry\/asf-project-spotlight-apache-seatunnel\">news.apache.org<\/a>. Он позволяет быстро и эффективно перемещать данные между различными источниками (например, базы данных, облачные хранилища, Kafka) и потребителями данных.  <br \/>\n> В контексте MLOps, SeaTunnel играет ключевую роль в:  <br \/>\n> –   <b>Подготовке данных<\/b>: Автоматизация сбора, очистки и трансформации данных для обучения и переобучения моделей. Это включает потоковую ETL\/ELT обработку, что обеспечивает актуальность и качество обучающих данных.  <br \/>\n> –   <b>Получении данных для мониторинга<\/b>: Сбор метрик производительности модели и данных о её входящих запросах из различных систем для последующего анализа дрейфа данных или деградации производительности.  <br \/>\n> –   <b>Интеграции с ML-платформами<\/b>: SeaTunnel может выступать в качестве универсального коннектора для передачи данных в хранилища признаков (feature stores) или напрямую в тренировочные пайплайны.  <br \/>\n> Фактически, SeaTunnel унифицирует процесс синхронизации и интеграции данных, поддерживая разнообразные источники и цели, необходимые для обработки больших объёмов данных в ML-системах. <a href=\"https:\/\/blog.devgenius.io\/the-evolution-of-apache-seatunnels-technical-architecture-and-its-applications-in-the-ai-field-24706d6e66e8\">blog.devgenius.io<\/a>. Например, его можно использовать для эффективного сбора данных для поиска сходства между книгами с помощью больших языковых моделей <a href=\"https:\/\/apacheseatunnel.medium.com\/breakthrough-in-the-book-search-field-c7d4ef927c69\">apacheseatunnel.medium.com<\/a>.<\/li>\n<\/ul>\n<ul>\n<li><b>Apache DolphinScheduler<\/b>: Это распределенная платформа для оркестрации рабочих процессов (workflow orchestration) с возможностью визуализации и мониторинга <a href=\"https:\/\/gavrilov.info\/all\/dolphinscheduler-and-seatunnel-vs-airflow-and-nifi\">dolphinscheduler and seatunnel vs airflow and nifi<\/a>. Если Apache SeaTunnel занимается *движением данных*, то DolphinScheduler отвечает за *управление последовательностью задач*.  <br \/>\n> В MLOps DolphinScheduler может использоваться для:  <br \/>\n> –   <b>Оркестрации ML-пайплайнов<\/b>: Автоматизация запуска задач по подготовке данных (с помощью SeaTunnel), обучению моделей, их оценке, развертыванию и мониторингу. Он позволяет определять зависимости между задачами, управлять их выполнением по расписанию или по событию, а также обрабатывать ошибки.  <br \/>\n> –   <b>Управление ресурсами<\/b>: Эффективное распределение вычислительных ресурсов для различных этапов ML-рабочих процессов.  <br \/>\n> –   <b>Мониторинг рабочих процессов<\/b>: Предоставление наглядных дашбордов для отслеживания статуса пайплайнов, выявления узких мест и оперативного реагирования на сбои. <a href=\"https:\/\/blog.devgenius.io\/workflow-as-code-sagemaker-new-gameplay-with-dolphinschedulers-machine-learning-stock-selection-ad0422e8aae5\">blog.devgenius.io<\/a>.<\/li>\n<\/ul>\n<h4>SeaTunnel и DolphinScheduler против Apache Airflow<\/h4>\n<p>Обычно для оркестрации рабочих процессов в MLOps применяется <b>Apache Airflow<\/b>. Однако, в определенных сценариях, комбинация <b>Apache DolphinScheduler и Apache SeaTunnel<\/b> может предложить преимущества:<\/p>\n<ul>\n<li><b>Apache Airflow<\/b>: Широко используется для создания, планирования и мониторинга программно определенных рабочих процессов (DAGs – Directed Acyclic Graphs) <a href=\"https:\/\/risingwave.com\/blog\/which-one-wins-apache-airflow-or-spark-showdown\/\">risingwave.com<\/a>. Он обладает высокой гибкостью и огромным комьюнити.<\/li>\n<li><b>Преимущества DolphinScheduler + SeaTunnel в MLOps<\/b>:\n<ul>\n  <li><b>Специализация<\/b>: SeaTunnel <b>специализируется на высокопроизводительной передаче данных<\/b>, что делает его более эффективным для задач, связанных с перемещением и синхронизацией больших объемов данных, часто возникающих в ML. Airflow, с другой стороны, является более общим оркестратором.<\/li>\n  <li><b>Визуализация и удобство<\/b>: DolphinScheduler часто отмечается за его более интуитивный графический интерфейс и drag-and-drop функциональность, что может упростить создание и управление ML-пайплайнами для пользователей с меньшим опытом программирования, чем в Airflow, который требует написания кода на Python для DAGs. <a href=\"https:\/\/dev.to\/seatunnel\/dolphinscheduler-and-seatunnel-vs-airflow-and-nifi-2jg0\">dev.to<\/a>. DolphinScheduler поддерживает модель “Workflow as Code”, но дополняется более удобной визуализацией.<\/li>\n  <li><b>Распределенная архитектура<\/b>: DolphinScheduler изначально разрабатывался как распределенная система, что может быть преимуществом для очень больших и сложных рабочих процессов, эффективно распределяя нагрузку.<\/li>\n  <li><b>Комплексное решение для данных<\/b>: Сочетание DolphinScheduler с SeaTunnel предоставляет более цельное решение для управления <b>как потоками данных, так и рабочими процессами<\/b>, тогда как Airflow требует интеграции с отдельными инструментами для обработки данных.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>В итоге, выбор между Airflow и связкой DolphinScheduler + SeaTunnel зависит от конкретных потребностей проекта, в частности от объема и сложности задач по интеграции данных, а также от предпочтений команды в отношении визуализации и кодирования пайплайнов.<\/p>\n<h4>Примеры MLOps-платформ: Databricks и ZenML<\/h4>\n<p>На рынке существуют как открытые, так и коммерческие MLOps-платформы, которые объединяют различные инструменты для реализации полного цикла ML-разработки:<\/p>\n<ul>\n<li><b>Databricks<\/b>: Эта компания является одним из лидеров в области озер данных (Data Lakehouse) и MLOps. Их платформа предоставляет интегрированную среду для полной цепочки MLOps: от подготовки данных с использованием Apache Spark (ядра платформы Databricks <a href=\"https:\/\/risingwave.com\/blog\/which-one-wins-apache-airflow-or-spark-showdown\/\">risingwave.com<\/a>), обучения моделей, управления экспериментами (MLflow, разработанный Databricks) до развертывания и мониторинга. “The big book of MLOps от Databricks” — это всеобъемлющее руководство, которое детализирует их подход к построению MLOps-систем, подчеркивая важность воспроизводимости, автоматизации и совместной работы.<\/li>\n<li><b>ZenML<\/b>: Это Extensible MLOps фреймворк, ориентированный на Developer Experience. ZenML позволяет создавать портативные, воспроизводимые и масштабируемые MLOps-пайплайны, абстрагируя пользователей от сложности базовой инфраструктуры. Он поддерживает множество интеграций с другими популярными ML-библиотеками и платформами (например, TensorFlow Extended, PyTorch, Kubeflow, MLflow), позволяя командам выбирать лучшие инструменты для своих задач, сохраняя при этом единую MLOps-структуру. ZenML фокусируется на “workflow-as-code” и модульности, что делает его гибким решением для различных MLOps-сценариев.<\/li>\n<\/ul>\n<p>Из россияйских есть Neoflex Dognauts она обеспечивает полный цикл разработки и эксплуатации<br \/>\nML-моделей для решения задач бизнеса. Это единая платформа корпоративного MLOps позволяет управлять всем жизненным циклом DS\/ML от постановки бизнес-задач до управления внедренными моделями <a href=\"https:\/\/neoflex.dognauts.ru\/#about\">Neoflex Dognauts<\/a><\/p>\n<h4>Коммерческая реализация WhaleOps<\/h4>\n<p>На рынке существуют и коммерческие реализации платформ, основанные на технологиях Apache и тесно интегрированные с принципами CRISP-ML(Q) и MLOps. Одним из ярких примеров является компания <b>WhaleOps Technology<\/b>. <a href=\"https:\/\/www.linkedin.com\/company\/whaleops\">linkedin.com<\/a> Основанная в августе 2021 года ключевыми участниками проектов Apache DolphinScheduler и Apache SeaTunnel, WhaleOps специализируется на создании решений для DataOps и MLOps. <a href=\"https:\/\/github.com\/WhaleOps\">github.com<\/a> Платформа WhaleOps предлагает комплексный набор инструментов, который помогает компаниям внедрять и управлять ML-моделями в продакшене, используя открытые стандарты и обеспечивая высокий уровень автоматизации и контроля качества на всех этапах жизненного цикла модели. <a href=\"https:\/\/cn.linkedin.com\/company\/whaleops\">cn.linkedin.com<\/a> Такая интеграция open-source фреймворков и коммерческих платформ позволяет организациям строить масштабируемые и надежные ML-системы, полностью соответствующие лучшим практикам, описанным в CRISP-ML(Q).<\/p>\n<h3>Практические кейсы применения<\/h3>\n<p>CRISP-ML(Q) применяется в различных отраслях для создания надежных и управляемых ML-решений:<\/p>\n<ul>\n<li><b>Предиктивное обслуживание в Mercedes-Benz<\/b>: Использование CRISP-ML(Q) для прогнозирования поломок автомобилей. На фазе мониторинга был выявлен дрейф данных, вызванный изменением условий эксплуатации, что потребовало своевременного переобучения моделей для поддержания их точности.<\/li>\n<li><b>Кредитный скоринг в банках<\/b>: На фазе оценки качества (QA) методики CRISP-ML(Q) помогли обнаружить смещение модели против клиентов старше 60 лет. Это позволило скорректировать модель перед её развертыванием, обеспечив справедливость и соответствие этическим нормам.<\/li>\n<\/ul>\n<h3>Критика и ограничения<\/h3>\n<p>Несмотря на свои преимущества, CRISP-ML(Q) имеет и некоторые ограничения:<\/p>\n<ul>\n<li><b>Сложность внедрения<\/b>: Для небольших проектов или стартапов, возможно, будет избыточным следование всем детальным процедурам CRISP-ML(Q) из-за требований к документации и ресурсам.<\/li>\n<li><b>Нехватка инструментов<\/b>: Хотя MLOps предоставляет множество инструментов, некоторые аспекты QA, такие как автоматизированная проверка этики или полностью автоматизированное управление дрейфом данных, все еще требуют активного участия человека и не всегда полностью автоматизированы.<\/li>\n<\/ul>\n<h3>Заключение<\/h3>\n<p>CRISP-ML(Q) — это наиболее полная и зрелая методология для управления промышленными ML-проектами. Она успешно закрывает пробелы CRISP-DM за счет:<\/p>\n<ol start=\"1\">\n<li><b>Системного обеспечения качества (QA)<\/b> на всех этапах жизненного цикла.<\/li>\n<li><b>Эффективного эксплуатационного мониторинга<\/b> развернутых моделей.<\/li>\n<li><b>Пристального внимания к воспроизводимости<\/b> всех экспериментов и моделей.<\/li>\n<\/ol>\n<p>Для достижения максимального успеха в ML-проектах рекомендуется комбинировать методологические рамки CRISP-ML(Q) с инженерными практиками MLOps. Интеграция мощных open-source фреймворков, таких как Apache SeaTunnel и Apache DolphinScheduler, а также использование комплексных MLOps-платформ, как Databricks или ZenML, и коммерческих решений вроде WhaleOps, позволяет автоматизировать и масштабировать эти процессы. Дальнейшее развитие методологии, вероятно, будет направлено на стандартизацию этических аудитов и дальнейшую автоматизацию процессов обработки дрейфа данных, делая ML-системы ещё более надёжными и управляемыми.<\/p>\n<h3>Источники<\/h3>\n<ul>\n<li>Оригинальная статья CRISP-DM: <a href=\"https:\/\/medium.com\/voice-tech-podcast\/cross-industry-standard-process-for-data-mining-crisp-dm-9edc0c5e3a1\">https:\/\/medium.com\/voice-tech-podcast\/cross-industry-standard-process-for-data-mining-crisp-dm-9edc0c5e3a1<\/a><\/li>\n<li>CRISP-DM и его популярность: <a href=\"https:\/\/www.datascience-pm.com\/crisp-dm-still-most-popular\/\">https:\/\/www.datascience-pm.com\/crisp-dm-still-most-popular\/<\/a><\/li>\n<li>CRISP-ML(Q) и MLOps: <a href=\"https:\/\/www.mdpi.com\/2076-3417\/11\/19\/8861\">https:\/\/www.mdpi.com\/2076-3417\/11\/19\/8861<\/a><\/li>\n<li>Руководство по выбору алгоритма: <a href=\"https:\/\/www.kdnuggets.com\/2020\/05\/guide-choose-right-machine-learning-algorithm.html\">https:\/\/www.kdnuggets.com\/2020\/05\/guide-choose-right-machine-learning-algorithm.html<\/a><br \/>\n<i>image-194.png.jpg<\/i><\/li>\n<li>Подробное описание CRISP-ML(Q) на Medium: <a href=\"https:\/\/medium.com\/@desmondonam\/understanding-the-crisp-ml-q-1e8c5bbfb8cb\">https:\/\/medium.com\/@desmondonam\/understanding-the-crisp-ml-q-1e8c5bbfb8cb<\/a><\/li>\n<li>Apache SeaTunnel (официальный проект): <a href=\"https:\/\/news.apache.org\/foundation\/entry\/asf-project-spotlight-apache-seatunnel\">news.apache.org<\/a><\/li>\n<li>SeaTunnel – эволюция архитектуры: <a href=\"https:\/\/blog.devgenius.io\/the-evolution-of-apache-seatunnels-technical-architecture-and-its-applications-in-the-ai-field-24706d6e66e8\">blog.devgenius.io<\/a><\/li>\n<li>SeaTunnel для поиска (пример): <a href=\"https:\/\/apacheseatunnel.medium.com\/breakthrough-in-the-book-search-field-c7d4ef927c69\">apacheseatunnel.medium.com<\/a><\/li>\n<li>DolphinScheduler и SeaTunnel vs Airflow и NiFi: <a href=\"https:\/\/dev.to\/seatunnel\/dolphinscheduler-and-seatunnel-vs-airflow-and-nifi-2jg0\">dev.to<\/a><\/li>\n<li>DolphinScheduler – Workflow as Code + SageMaker: <a href=\"https:\/\/blog.devgenius.io\/workflow-as-code-sagemaker-new-gameplay-with-dolphinschedulers-machine-learning-stock-selection-ad0422e8aae5\">blog.devgenius.io<\/a><\/li>\n<li>Apache Airflow vs Spark: <a href=\"https:\/\/risingwave.com\/blog\/which-one-wins-apache-airflow-or-spark-showdown\/\">risingwave.com<\/a><\/li>\n<li>WhaleOps Technology (LinkedIn): <a href=\"https:\/\/www.linkedin.com\/company\/whaleops\">linkedin.com<\/a><\/li>\n<li>WhaleOps Technology (GitHub): <a href=\"https:\/\/github.com\/WhaleOps\">github.com<\/a><\/li>\n<li>WhaleOps Technology (LinkedIn CN): <a href=\"https:\/\/cn.linkedin.com\/company\/whaleops\">cn.linkedin.com<\/a><\/li>\n<li>Databricks: (“The big book of MLOps от Databricks” – ссылка на книгу, если доступна, или на соответствующий раздел сайта Databricks. Например: <a href=\"https:\/\/www.databricks.com\/solutions\/accelerators\/mlops\">databricks.com<\/a>)<\/li>\n<li>ZenML: <a href=\"https:\/\/zenml.io\/\">zenml.io\/<\/a><\/li>\n<\/ul>\n",
            "date_published": "2025-07-03T00:32:17+03:00",
            "date_modified": "2025-07-03T00:34:26+03:00",
            "tags": [
                "CRISP-ML(Q)",
                "MLOps"
            ],
            "image": "https:\/\/gavrilov.info\/pictures\/image-194.png.jpg",
            "_date_published_rfc2822": "Thu, 03 Jul 2025 00:32:17 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "248",
            "_rss_enclosures": [],
            "_e2_data": {
                "is_favourite": false,
                "links_required": [],
                "og_images": [
                    "https:\/\/gavrilov.info\/pictures\/image-194.png.jpg",
                    "https:\/\/gavrilov.info\/pictures\/image-194.png-1.jpg"
                ]
            }
        },
        {
            "id": "206",
            "url": "https:\/\/gavrilov.info\/all\/sintez-the-big-book-of-mlops-2nd-edition\/",
            "title": "Синтез – The Big Book of MLOps – 2nd Edition",
            "content_html": "<h4>Синтез “The Big Book of MLOps – 2nd Edition”:<\/h4>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/gavrilov.info\/pictures\/Snimok-ekrana-2025-03-20-v-21.46.42.png\" width=\"2092\" height=\"988\" alt=\"\" \/>\n<\/div>\n<p><a href=\"http:\/\/a.gavrilov.info\/data\/posts\/2023-10-eb-big-book-of-mlops-2nd-edition-v2-final.pdf\">2023-10-eb-big-book-of-mlops-2nd-edition-v2-final.pdf<\/a><\/p>\n<ol start=\"1\">\n<li><b>Основы MLOps<\/b>  <br \/>\nMLOps объединяет DataOps, DevOps и ModelOps для управления жизненным циклом ML-моделей. Ключевые принципы:<\/li>\n\n<ul>\n  <li>Разделение сред (разработка, тестирование, продакшн).<\/li>\n  <li>Автоматизация CI\/CD для ускорения вывода моделей в продакшн.<\/li>\n  <li>Управление данными, кодом и моделями через единую платформу (Databricks Lakehouse).<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<ol start=\"2\">\n<li><b>Ключевые обновления в версии 2<\/b>\n<ul>\n  <li><b>Unity Catalog<\/b>: Централизованное управление данными и моделями с трекингом происхождения, безопасностью и доступом.<\/li>\n  <li><b>Model Serving<\/b>: Серверное решение для развертывания моделей в реальном времени с интеграцией MLflow и автоскейлингом.<\/li>\n  <li><b>Lakehouse Monitoring<\/b>: Мониторинг данных и моделей с автоматической записью метрик в Delta-таблицы.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<ol start=\"3\">\n<li><b>Рекомендации по проектированию<\/b>\n<ul>\n  <li>Организация данных и моделей в Unity Catalog через каталоги (`dev`, `staging`, `prod`), схемы (`bronze`, `silver`, `gold`) и алиасы моделей (например, “Champion” и “Challenger”).<\/li>\n  <li>Тестирование инфраструктуры перед деплоем (нагрузочное тестирование, проверки задержки).<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<ol start=\"4\">\n<li><b>Эталонная архитектура<\/b>\n<ul>\n  <li>Разработка: EDA, обучение моделей, валидация.<\/li>\n  <li>Тестирование: Интеграционные тесты в staging-среде.<\/li>\n  <li>Продакшн: Автоматизированные пайплайны обучения, валидации, деплоя и мониторинга.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<ol start=\"5\">\n<li><b>LLMOps<\/b>\n<ul>\n  <li><b>Prompt Engineering<\/b>: Оптимизация текстовых запросов для улучшения ответов LLM.<\/li>\n  <li><b>RAG (Retrieval-Augmented Generation)<\/b>: Комбинация LLM с векторными базами данных для доступа к актуальным данным.<\/li>\n  <li><b>Тонкая настройка (Fine-tuning)<\/b>: Адаптация LLM под специфические задачи с использованием параметрически эффективных методов (LoRA).<\/li>\n  <li><b>Оценка и мониторинг<\/b>: Использование LLM как оценщиков, интеграция человеческой обратной связи.<\/li>\n  <li><b>Управление затратами<\/b>: Оптимизация размера моделей, квантование, распределенные вычисления.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<ol start=\"6\">\n<li><b>Заключение<\/b>  <br \/>\nMLOps и LLMOps требуют модульности, автоматизации и ориентации на данные. Databricks предоставляет единую платформу для управления данными, моделями и мониторингом, что ускоряет внедрение AI-решений.<\/li>\n<\/ol>\n<p>---<\/p>\n<p><b>Обработано страниц<\/b>: 78 (с 1 по 78, включая оглавление, главы и иллюстрации). DeepSeek<\/p>\n<h4>Будущие компоненты и архитектура MLOps на основе документа<\/h4>\n<p>Архитектура строится на принципах <b>data-centric AI<\/b>, <b>автоматизации<\/b> и <b>унифицированного управления<\/b> данными, моделями и кодом.<br \/>\nНиже представлены ключевые компоненты и их взаимодействие:<\/p>\n<p>---<\/p>\n<h5><b>1. Управление данными и моделями (Data & Model Governance)<\/b><\/h5>\n<ul>\n<li><b>Unity Catalog<\/b>:\n<ul>\n  <li>Централизованный каталог для данных, моделей, функций и объемов.<\/li>\n  <li><b>Структура<\/b>:\n<ul>\n    <li>Каталоги по средам (`dev`, `staging`, `prod`).<\/li>\n    <li>Схемы: `bronze` (сырые данные), `silver` (очищенные), `gold` (обогащенные), `use_case` (фичи\/модели).<\/li>\n  <\/ul>\n<\/li>\n  <li><b>Функции<\/b>:\n<ul>\n    <li>Трекинг происхождения (lineage) между данными и моделями.<\/li>\n    <li>Управление доступом (RBAC) и версионирование моделей через MLflow.<\/li>\n    <li>Алиасы моделей (например, `Champion` для продакшна).<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>---<\/p>\n<h5><b>2. Разработка и обучение моделей (Model Development)<\/b><\/h5>\n<ul>\n<li><b>Среда разработки<\/b>:\n<ul>\n  <li>Интерактивные notebooks (EDA, прототипирование).<\/li>\n  <li>AutoML для генерации базовых моделей и анализа данных.<\/li>\n  <li>Интеграция с <b>MLflow Tracking<\/b> для записи экспериментов.<\/li>\n<\/ul>\n<\/li>\n<li><b>Обучение моделей<\/b>:\n<ul>\n  <li>Пайплайны обучения с использованием Databricks Workflows.<\/li>\n  <li>Параметризация гиперпараметров и данных (из `gold` или `prod` каталогов).<\/li>\n  <li>Логирование артефактов, метрик и зависимостей в MLflow.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>---<\/p>\n<h5><b>3. Тестирование и CI\/CD (Continuous Integration\/Deployment)<\/b><\/h5>\n<ul>\n<li><b>Среда тестирования (staging)<\/b>:\n<ul>\n  <li>Интеграционные тесты (проверка совместимости компонентов).<\/li>\n  <li>Нагрузочное тестирование Model Serving:\n<ul>\n    <li>Проверка задержки (latency), пропускной способности (QPS).<\/li>\n  <\/ul>\n<\/li>\n  <li>Тестирование инфраструктуры (например, обновление алиасов моделей).<\/li>\n<\/ul>\n<\/li>\n<li><b>CI\/CD<\/b>:\n<ul>\n  <li>Автоматизация через Git (ветки `dev` → `main` → `release`).<\/li>\n  <li>Unit-тесты на CI-раннерах, интеграционные тесты в staging.<\/li>\n  <li>Развертывание через Databricks Asset Bundles.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>---<\/p>\n<h5><b>4. Продакшн-развертывание (Model Deployment)<\/b><\/h5>\n<ul>\n<li><b>Batch\/Streaming Inference<\/b>:\n<ul>\n  <li>Пакетная обработка через Spark, публикация в Delta-таблицы или key-value хранилища.<\/li>\n<\/ul>\n<\/li>\n<li><b>Real-time Inference<\/b>:\n<ul>\n  <li><b>Model Serving<\/b>:\n<ul>\n    <li>REST API для онлайн-предсказаний.<\/li>\n    <li>Поддержка A\/B-тестов, канареечных развертываний и shadow-режима.<\/li>\n    <li>Автоматическое логирование запросов\/ответов в `inference tables`.<\/li>\n<\/ul>\n<\/li>\n<li><b>Обновление моделей<\/b>:\n<ul>\n  <li>Сравнение `Champion` (текущая) vs. `Challenger` (новая) моделей.<\/li>\n  <li>Алгоритмы постепенного переноса трафика (gradual rollout).<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>---<\/p>\n<h5><b>5. Мониторинг и управление (Monitoring & Maintenance)<\/b><\/h5>\n<ul>\n<li><b>Lakehouse Monitoring<\/b>:\n<ul>\n  <li>Автоматический сбор метрик (дрейф данных, точность моделей).<\/li>\n  <li>Интеграция с Databricks SQL для дашбордов и алертов.<\/li>\n<\/ul>\n<\/li>\n<li><b>Ретрейнинг<\/b>:\n<ul>\n  <li>Триггеры на основе мониторинга (например, дрейф данных).<\/li>\n  <li>Периодическое обновление моделей по расписанию.<\/li>\n<\/ul>\n<\/li>\n<li><b>Управление затратами<\/b>:\n<ul>\n  <li>Оптимизация ресурсов (автоскейлинг Model Serving).<\/li>\n  <li>Квантование моделей, использование PEFT для LLM.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>---<\/p>\n<h5><b>6. LLMOps (специфика для больших языковых моделей)<\/b><\/h5>\n<ul>\n<li><b>Компоненты<\/b>:\n<ul>\n  <li><b>Векторные базы данных<\/b> (Chroma, Milvus) для RAG.<\/li>\n  <li><b>Prompt Engineering<\/b>:\n<ul>\n    <li>Шаблоны запросов, версионирование через MLflow.<\/li>\n    <li>Интеграция с LangChain для сложных цепочек.<\/li>\n  <\/ul>\n<\/li>\n  <li><b>Fine-tuning<\/b>:\n<ul>\n    <li>Использование PEFT (LoRA) для эффективной настройки.<\/li>\n    <li>Инструменты: Hugging Face Transformers, MosaicML.<\/li>\n  <\/ul>\n<\/li>\n  <li><b>Оценка LLM<\/b>:\n<ul>\n    <li>Автоматическая оценка через LLM-судьи (например, GPT-4).<\/li>\n    <li>Сбор человеческой обратной связи через UI.<\/li>\n<\/ul>\n<\/li>\n<li><b>Архитектурные изменения<\/b>:\n<ul>\n  <li>Модель Serving с поддержкой GPU для самохостатых LLM.<\/li>\n  <li>Интеграция с MLflow AI Gateway для управления сторонними API (OpenAI, Anthropic).<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>---<\/p>\n<h4>Ключевые инновации будущего<\/h4>\n<ol start=\"1\">\n<li><b>Полная автоматизация жизненного цикла<\/b> с AI-driven триггерами (например, авторетрайнинг при дрейфе).<\/li>\n<li><b>Гибридные пайплайны<\/b> для совместной работы классических ML и LLM.<\/li>\n<li><b>Унифицированная аналитика<\/b> данных и моделей через Lakehouse.<\/li>\n<li><b>Безопасность и compliance<\/b>:\n<ul>\n  <li>Шифрование данных\/моделей.<\/li>\n  <li>Аудит через Unity Catalog.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p>---<\/p>\n<p>Архитектура обеспечивает <b>масштабируемость<\/b>, <b>воспроизводимость<\/b> и <b>управляемость<\/b> ML-решений, адаптируясь как к классическим задачам, так и к вызовам Generative AI. DeepSeek<\/p>\n",
            "date_published": "2025-03-20T21:41:53+03:00",
            "date_modified": "2025-03-20T21:48:47+03:00",
            "tags": [
                "AI",
                "big data",
                "Data",
                "MLOps"
            ],
            "image": "https:\/\/gavrilov.info\/pictures\/Snimok-ekrana-2025-03-20-v-21.46.42.png",
            "_date_published_rfc2822": "Thu, 20 Mar 2025 21:41:53 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "206",
            "_rss_enclosures": [],
            "_e2_data": {
                "is_favourite": false,
                "links_required": [],
                "og_images": [
                    "https:\/\/gavrilov.info\/pictures\/Snimok-ekrana-2025-03-20-v-21.46.42.png"
                ]
            }
        }
    ],
    "_e2_version": 4171,
    "_e2_ua_string": "Aegea 11.4 (v4171e)"
}