Как я тестирую крупные системы, которые невозможно протестить на статичных данных. DevOps.. DevOps. ml.. DevOps. ml. mlops.. DevOps. ml. mlops. qa.. DevOps. ml. mlops. qa. архитектура систем.. DevOps. ml. mlops. qa. архитектура систем. имитационное моделирование.. DevOps. ml. mlops. qa. архитектура систем. имитационное моделирование. тестирование.

Например, в управлении транспортом статичные данные (например, сет за «типичный вторник») не дают протестировать систему в условиях праздника, крупной аварии, сессии у студентов, скидки 99% на Лабубу в крупном супермаркете и так далее. 

Что мы сделали:

— Стали брать реальные данные с прода, которые выбиваются за стандартные представления.

— Обезличивать их.

— Использовать ML-модель для генерации сценариев, где эти данные увязываются с остальными в системе. Это типа генерации новых данных с усилением трендов и их пересечением.

То есть фактически по модели швейцарского сыра — мы имеем один статичный срез, а затем начинаем ходить в прод и искать новые дырки. Потом соединяем несколько дырок в новом слое и накладываем слои друг на друга, чтобы посмотреть, не будет ли сквозного отверстия. 

Цель — не просто нагрузить систему, а протестировать жизнеспособность архитектуры в похожих на реальные условиях. 

Тепловая карта заполненности транспорта

Тепловая карта заполненности транспорта

Очень упрощая, наши наборы тестов учатся нестандартным ситуациям с прода и включают их и в тестовые выборки данных, и в юнит-тесты, и такие ситуации не только покрываются как частные случаи, но и включаются в сложные сценарии, где 3 малозначимых отказа могут привести к аварии.  

Я думаю, что это будущее тестирования сложных систем, и мы с командой уже затащили это в автоматический пайплайн. 

Безопасники напомнили, что я не могу называть прямо особенности конкретных проектов, но это диспетчеризация городского транспорта, финансовые хайлоады и разного рода задачи, похожие по профилю на антифрод. Но поверьте, вы этим пользуетесь каждый день, если живёте в Москве, а если не в Москве — вероятно, тоже участвуете или как набор данных, или как пользователь, но пореже. 

Почему старые подходы перестали работать

Всё началось с классической ситуации: к нам пришёл заказчик и сказал: «Это работает медленно, это работает плохо и непонятно, как будет работать дальше». Система — классический enterprise-хаос: многомодульная, микросервисная, омниканальная, где контекст пользователя передавался «какой-то непонятной штукой» в новый сервис, разработанный другим подрядчиком. 

Никто до конца не понимал, что происходит.

Мы начали с азов: внедрили профилирование, поковырялись в базе данных, посмотрели на запросы. Нашли очевидное: где-то не было индексов, где-то использовались слишком длинные query, которые вешали систему. Но это было лечение симптомов. Заказчик спросил: «Окей, а как нам заложить в архитектуру стандарт, чтобы этого не повторялось? Как нам спрогнозировать, что будет, когда данных станет в 10 раз больше?»

Вот тут мы и упёрлись. Наши статичные моки — это был, условно, вторник 1924 года. Мы могли удвоить нагрузку, но это был тот же самый вторник, просто в двойном объёме. Заказчик смотрел на наши отчёты и говорил: «Ребята, ну это какая-то усреднённая вещь, средняя температура по больнице. А жизнь — она другая». 

И он был прав.

Имитационное моделирование 

На производствах с кучей переменных используется не тестирование, а имитационное моделирование. Там в систему загоняются все данные и делается WHAT IF-анализ. Чаще, правда, это WTF-анализ, особенно когда это реально крупное производство. 

Наш случай с транспортом отлично это иллюстрирует. Продолжая аналогию, сначала задача была простой: считать, сколько людей вошло в автобус и вышло. Потом её усложнили: нужно было из толпы выделять женщин, мужчин, студентов, чтобы понять, почему в 8 утра пиковая нагрузка — может, рядом институт. Затем система разрослась на новые районы города, и данные оттуда в тот же самый вторник приходили совершенно другие. Эта дифференциация данных была для нас ключевой. Нам нужно было не просто фиксировать разницу, а анализировать её, чтобы строить тепловые карты и планировать новые оптимальные маршруты. Это уже не тестирование, это почти эмуляция управления полётами, где маршрут может поменяться за секунды из-за внештатной ситуации.

Дашборд по количеству пассажиров на маршруте в разрезе временных слотов и вместимостью

Дашборд по количеству пассажиров на маршруте в разрезе временных слотов и вместимостью
Таблица анализа временного слота по маршруту

Таблица анализа временного слота по маршруту

В смысле, да, мы строим расписание и знаем, куда сколько автобусов отправить, чтобы маршрутная сеть не сложилась. И мы помогаем принимать решения по тому, где какой нужен «запас прочности» на разные случаи. Так что если вы проклинаете кого-то, стоя в холод на остановке уже ПЯТУЮ МИНУТУ, — это либо наш кривой алгоритм, либо ресурсное ограничение. Просто знайте, что всего лет 20 назад без нашего софта вы, возможно, в такой же ситуации пошли бы пешком. 

Вот для того, чтобы прогнать хитрые комбинации факторов, мы сделали ML-систему, которая генерирует реалистичные данные для тестов.

Как это работает

Несколько источников данных. Мы не полагаемся на что-то одно. Сейчас наша модель питается из трёх потоков:

1. Непрерывный поток данных из реального мира. Наш пайплайн автоматически «дёргает» из продакшена свежие срезы данных и логи. Мы ищем не типичные, а как раз аномальные, экстремальные ситуации, которые выбиваются из общей картины. 

2. Умное обезличивание. Мы в силу специфики и желания путешествовать по миру очень серьёзно относимся к обезличиванию. 

Система распознавания изначально создаёт обезличенный цифровой профиль пользователя (уникальный UUID). К нему привязываются неперсональные атрибуты: возраст, пол. Даже если система видит UUID, она понимает, кто это — девочка, мальчик, бабушка — без доступа к личной информации. То же самое с банковскими картами: мы гарантируем, что одна и та же карта всегда обезличивается одинаково, сохраняя все транзакционные связи, но делая невозможной обратную идентификацию.

3. Генерация «экстремальных моков». ML-модель не просто повторяет шаблоны. Мы поняли, как обогащать данные не только вертикально (меняя значения в существующих полях), но и горизонтально — добавляя новые поля и меняя саму структуру данных. Модель комбинирует реальные аномалии с прода, наши гипотезы и даже чистый рандом. 

Что будет, если закроют станцию метро и тысячи людей одновременно вызовут такси? А если начнётся ярмарка и весь трафик пойдёт в обход? Модель комбинирует реальные аномалии с прода с полностью сгенерированными нами кейсами, даже с чистым рандомом, чтобы покрыть максимум неожиданных ситуаций.

Цель — набрутфорсить такой тренд, который покроет максимум неожиданных ситуаций.

Как работает пайплайн и изменились роли 

Отлично работает! Всё это не вручную, а в рамках общего автоматизированного и MLOps-пайплайна. 

И тут самое интересное — как изменились роли.

DevOps-инженер отвечает за инструмент, который автоматически поставляет свежие моки из прода. Но откуда он знает, как правильно их интегрировать, чтобы не сломать все?

Здесь на сцену выходит QA. В enterprise-разработке, как у нас, QA обязан участвовать в проектировании архитектуры с самого начала. Это senior-специалист, который заложил в систему правила и логику, как реагировать на разные типы данных. Фактически QA становится хранителем контекста и говорит DevOps: «Вот эти данные интегрируем так, а вот эти — вот так, потому что они влияют на такие-то модули».

И даже для нас результат каждого такого прогона — это загадка. Мы сами сидим и смотрим на тренды в реальном времени, анализируя, как система справилась с новым, сгенерированным хаосом.

Как начать такой переход?

  1. Первое, что мы сделали, — написали скрипты для проверки их качества. В ML-проектах первая линия обороны — это именно данные.

  2. Не нужно сразу строить космолёт. Мы начали с автоматизации простых процессов, например, переобучения модели по расписанию.

  3. Чтобы эффективно тестировать ML-системы, нужно понимать, как они работают: что такое обучение, валидация, дрейф модели. Надо учить всех участников процесса, то есть QA. 

  4. Пришлось освоить IaC, чтобы окружения dev, staging и prod были идентичными (мы используем Terraform и Ansible), а также разобраться в observability и reproducibility (наблюдаемость и воспроизводимость).

Многие ML-проекты проваливаются не из-за плохой модели, а из-за отсутствия инженерной культуры. Мы используем DVC для версионирования данных так же, как Git для кода. 

Ошибка считать, что модель готова после обучения. В реальности данные постоянно меняются (это и есть дрейф), и без контроля модель быстро теряет актуальность.

Вот наш основной инструментарий для контроля:

  • Great Expectations это, по сути, набор unit-тестов для данных. QA определяет правила: нужные поля на месте, значения в правильном диапазоне, нет пустых ячеек.

  • Evidently AI / NannyML наши сторожевые псы. Они следят за дрейфом данных, постоянно сравнивая новые данные с эталонными. Как только разница становится критической, они бьют тревогу. Это сигнал для QA: «Ребята, реальность изменилась, пора обновлять правила в Great Expectations». И эту задачу выполняет именно QA, а не девопсы.

Для оркестрации всего этого зоопарка используем Airflow, а для трекинга экспериментов — MLflow.

Диаграмма системы

Диаграмма системы

Кем становится QA 

Этот подход полностью меняет роль QA. Он всё больше участвует в проектировании архитектуры, закладывает модели для обеспечения качества данных и валидации. 

По сути, становится архитектором тестов, который с самого начала проектирует систему так, чтобы её можно было тестировать и поддерживать. 

Его роль смещается от тестировщика к инженеру по надёжности ML-систем. 

Качество перестаёт быть финальным этапом и становится встроенным свойством системы.

Наш модуль для генерации данных оказался настолько полезным, что мы стали использовать его и на других проектах — для проведения бенчмарков и тестирования систем на деградацию производительности.

Результат

Но самое главное — доказанная ценность. В одном из проектов наша трендовая система, основанная на комбинации реальных данных с прода, наших собственных сгенерированных кейсов и эталонных моделей, построила прогноз, который в точности совпал с реальным, непредсказуемым событием в будущем. 

То есть мы поняли, где могут совпасть 4 дырки швейцарского сыра. И мы своими тестами подтвердили это. Именно в этот момент заказчик поверил в подход и начал доверять нашей ML-модели для стратегического планирования.

Автор: MishinAlex

Источник

Rambler's Top100