Тестирование ML-систем: сложности, факапы и рабочие практики

Тестирование ML-систем: сложности, факапы и рабочие практики

Тестирование систем машинного обучения (ML) — сложная и малоосвещённая тема. В отличие от классического ПО, ML-системы работают на основе вероятностных моделей и данных, а не жёстких правил. Это вносит свои особенности и вызывает ряд уникальных трудностей. В этой статье — разбор типичных проблем, подходов к тестированию и реальных кейсов из практики.

Кратко о проекте

Работаем над системой автозаказа для сети супермаркетов Spar. Задача — точно рассчитывать объёмы заказов, чтобы товара хватало, но не было излишков. Система учитывает десятки факторов: сезонность, погоду, праздники, календарные события. Например, перед 1 сентября растёт спрос на цветы — модель это учитывает и корректирует поставки.

Почему тестирование ML сложнее обычного

  • Вероятностное поведение вместо детерминизма. В классическом ПО одинаковые входные данные всегда дают одинаковый результат. В ML система выдаёт прогноз с определённой вероятностью. Поэтому тестирование сводится не к проверке точного ответа, а к оценке качества прогноза и допустимых отклонений.
  • Фокус смещается с кода на данные. Даже самая продвинутая модель даст плохой результат на некачественных данных. Проверка датасетов — критически важная часть тестирования.
  • Устаревание модели (model drift). Модель обучается на прошлых данных, но реальность меняется. Появляются новые товары, меняются привычки покупателей. Если не мониторить и не дообучать модель, её точность будет падать.
  • Контекст и цена ошибки. Ошибка в 10% для жевательной резинки — не критично. Та же ошибка для дорогого товара — может обернуться серьёзными убытками. Тестирование должно учитывать бизнес-последствия.
  • Новые типы ошибок. Появляются проблемы с данными: аномалии, сбои в интеграциях, некорректные источники. Такие ошибки сложнее обнаружить, чем баги в логике кода.

Тестирование ML на этапах разработки

Анализ требований

В классическом тестировании требования чёткие: «сделай X, получи Y». В ML заказчик говорит: «улучшите прогноз». Но как измерить «улучшение»?

Мы вводим метрики:

  • Технические — насколько прогноз отличается от факта.
  • Бизнес-метрики — влияние отклонения на прибыль и продажи.

Также договариваемся о допустимых отклонениях. Например, прогноз спроса на шоколад может отличаться от реальных продаж не более чем на 10%.

Планирование тестирования

Ожидаемый результат в ML — не конкретное число, а диапазон. Например, прогноз должен попадать в ±10% от факта.

Тестируем и аномальные данные: например, когда компания скупила всё мясо для корпоратива. Такие события нужно отфильтровывать, чтобы они не искажали общий прогноз.

Настройка окружения и подготовка данных

Модели чувствительны к версиям библиотек. Даже небольшое изменение может повлиять на результат. Мы используем Docker, чтобы фиксировать окружение.

Персональные данные защищаем через хэширование: видим продажи, но не можем привязать их к покупателям.

Контролируем дрейф данных: если реальные данные начинают отличаться от обучающих, точность модели падает. Нужно вовремя замечать это и дообучать модель.

Выполнение тестов

Тестирование осложняется отсутствием точного ожидаемого результата. Опираемся на метрики и диапазоны.

Важно тестировать по категориям. Например, модель может хорошо прогнозировать спрос на хлеб, но плохо — на соусы. Поэтому проверяем не только «в среднем», но и по конкретным группам товаров.

Тестируем на выборке: наборе разнообразных магазинов. Это быстрее, чем тестировать всё, но даёт представление о качестве.

Помимо модели, проверяем:

  • Дрейф данных — когда входные данные уходят от обучающих.
  • Системные баги — например, сбой в передаче данных о продажах. Даже если модель работает, без данных прогноз не будет готов.

Регрессия

После обновления модель может улучшить одну метрику, но ухудшить другую. Важно анализировать такие случаи: критично ли падение?

Иногда новая модель перестаёт справляться с задачами, которые решала старая. Чтобы избежать этого, сохраняем тесты для ключевых сценариев и проверяем их при каждом релизе.

ML-тестирование: шеф-повар, а не повар

Тестирование обычного ПО — как следование рецепту: всё расписано, результат предсказуем. Тестировщик проверяет, что всё сделано по инструкции.

ML-тестирование больше похоже на работу шеф-повара: нет точного рецепта, результат может варьироваться, нужно «пробовать на вкус». Тестировщик оценивает качество, предлагает корректировки и решает, готова ли модель к работе.

Преимущества ML-тестирования

  • Полноценное A/B-тестирование. Новую модель можно запустить параллельно со старой и сравнить в реальных условиях.
  • Реалистичные данные. Тесты проводятся на данных, близких к продакшену, что позволяет выявить проблемы до релиза.
  • Контроль через метрики. Ухудшение качества сразу заметно — можно оперативно дообучить модель.
  • Больше данных — больше сценариев. Возможность проверить поведение модели в разных условиях.
  • Проверка устойчивости. Можно моделировать сезонность, аномалии и изменения спроса, чтобы заранее выявить слабые места.

Реальные факапы

  • Грузовик молочки. Из-за путаницы в параметрах prediction_share и predict_share система выдала завышенный прогноз по молочным продуктам. В магазины приехало избыточное количество творога, сметаны и масла. Пришлось распродавать со скидками. Проблему можно было предотвратить, если бы аномалия была замечена на этапе тестирования.
  • Недопрогноз лавашей. После обновления модель перестала учитывать выходные пики спроса на лаваш. Продажи небольшие, поэтому проблему заметили поздно. Покупатели приходили за лавашем, а его не было. Кейс показал важность детального тестирования по всем категориям, даже с низким объёмом продаж.
  • Модель не узнала 2025 год. Из-за ошибки в кодировке параметра year модель не распознала начало нового года. Прогнозы стали некорректными. Система аномалий тоже не сработала. Пришлось срочно вручную корректировать заказы. Урок: нужно тестировать модель на будущих данных и проверять работу системы обнаружения аномалий.
Читать оригинал