Почему мы решили развивать практику тестирования ML



    Прогнозные и оптимизационные сервисы на базе Machine Learning вызывают сегодня интерес у многих компаний: от крупных банков до небольших интернет-магазинов. Решая задачи различных клиентов мы столкнулись с рядом проблем, что послужило для нас почвой для рассуждений на тему особенности тестирования ML. Для тех, кому это интересно, — наш очередной пост от тест-менеджера компании «Инфосистемы Джет» Агальцова Сергея.

    Раньше пользоваться преимуществами машинного обучения могли только крупные компании, так как это было дорого и сложно, кроме того, в публичном доступе было очень мало данных. Сегодня это стало намного проще. Экспертизу ML можно запросить у интегратора, специализированной компании или на тематической площадке. Это хорошо для всех, потому что с ростом экспертизы разрабатываются новые алгоритмы, и «копилка опыта» в сфере машинного обучения постоянно обогащается.

    Единственный аспект, для которого мы не нашли готового решения — это тестирование ML-сервисов. Погуглив, можно убедиться, что в поисковой выдаче нет упоминания деятельности тестировщиков при разработке подобных сервисов. Конечно, сами data science специалисты проверяют свои модели, используя различные метрики, и согласно этим метрикам сервис может даже оказаться максимально точен, однако, реальность такова, что модель не всегда способна учитывать различные производственные нюансы и узкие места. Тогда логика машинного обучения начинает обрастать хардкодом.

    В связи с этим мы начинаем сталкиваться с рядом проблем:

    • Всегда ли наша оптимизационная модель учитывает возможные производственные ограничения?
    • Способны ли наша модель работать с «узкими местами»?
    • Умеет ли наша модель корректно реагировать на производственные изменения?

    Вот тут-то мы и решили акцентировать внимание команды тестирования.

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

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


    В классическом тестировании в любом тесте мы всегда имеем «ожидаемый результат». Мы досконально знаем, какая реакция системы должна быть на те или иные входные данные. Однако если речь идёт о ML в производственных средах, то этим самым ожидаемым результатом может быть соблюдение регламентирующих документов, таких как ГОСТы, технологические инструкции и временные технологические карты, которые ограничивают как сами производственные процессы, так и качественные критерии конечного продукта. В период их тестирования мы должны быть уверены, что все эти ограничения в действительности соблюдаются, и несмотря на их количество мы уверены, что каждое из них покрыто тест кейсами.

    На примере реального проекта оптимизации производства материалов N (кейс пока не разглашаем, поэтому будем употреблять анонимные названия) мы решили этот вопрос следующим образом:

    • Мы классифицировали все марки смесей материалов N по уровню содержания в них химических элементов. В результате чего получили некий список, который в дальнейшем планировали использовать в качестве подспорья для обеспечения достаточного тестового покрытия.
    • Убедились, что выданные моделью рекомендации по всем этим смесям были в действительности безоговорочно приняты производственными технологами и зафиксировали результат этой выдачи в CSV файле. Тем самым мы получили рекомендации системы некого «золотого стандарта».
    • Далее был написан скрипт, который от версии к версии прогонял список наших эталонных смесей через модель и сравнивал результат её выдачи с тем, что хранилось у нас в csv «золотого стандарта».
    • Если никаких изменений в поведении модели не было выявлено, значит регрессионные тесты можно было считать успешными. Если же нет, то проводился «разбор полетов».

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

    Сосредоточить внимание тестирования необходимо на «узких местах»


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

    Зачастую в таких случаях оптимизационному сервису приходится «подсказать» адекватную модель поведения и это порождает хардкод, о котором я писал ранее. Но как выявить эти самые узкие места и отладить работу сервису? Об этом я расскажу на примере разработки сервиса рекомендаций управления производством материала N (кейс пока не подлежит разглашению, поэтому далее по тексту упоминаются завуалированные наименования).

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

    Второй этап представлял из себя «Silence» тестирование. Сервис был поднят в производственной среде в фоновом режиме. Он работал, не отвлекая оператора обработки материала N от управления станком, а мы в свою очередь собирали «операторские решения», сопоставляя их с тем, что рекомендовал сервис. Благодаря этому мы нашли слепые зоны модели, которые не удалось отловить на предыдущем этапе.

    Модель должна уметь реагировать на производственные изменения


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

    В процессе разработки данного сервиса мы столкнулись с любопытной проблемой, которую не смогли предусмотреть заранее.

    На протяжении нескольких лет компания при производстве топлива работала в определенном диапазоне агрегатных оборотов и использовало при этом плюс/минус одинаковое соотношение компонентов.

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

    1. Более плотно взаимодействовать с представителя заказчика из производственной части на предмет выявление «узких мест» и потенциальных продуктовых изменений.
    2. Заранее покрывать тест кейсами подобные сценарии поведения системы.
    3. Писать автотесты на проверку соблюдения производственных ограничений и корреляции признаков.

    Буквально пару слов об инструментарии тестирования, что нам пришлось использовать:

    • багтреккинг — Jira,
    • система управления качеством — Test Rail,
    • система контроля версий — GitLab,
    • CI/CD — Jenkins,
    • автотесты — Java+Junit/TestNG,
    • скрипты для прямого взаимодействия с моделью — Python+Jupyter.

    А вы тестируете ML?


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

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

    Сергей Агальцов, тест-менеджер «Инфосистемы Джет»

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

    А вы тестируете ML?

    Инфосистемы Джет
    410,87
    Системный интегратор
    Поделиться публикацией

    Комментарии 10

      0
      автотесты — Java+Junit/TestNG,
      скрипты для прямого взаимодействия с моделью — Python+Jupyter.

      а как (и зачем) вы соединили в одном проэкте жабу и питона? Какое у вас API для МЛ?
        0

        На проектах — REST API. Касательно выбора ЯП — исторически сложилось, что автотесты в компании преимущественно написаны на Java, хотя ничто не мешает их написать на Python

        +1
        Т.е. получается, что у вас модель постоянно не тренируется? Если какая либо связь модели со «свежими» данными?
          0
          Нет, постоянного дообучения не происходит. А взаимосвязь со «свежими» данными реализована, как правило, через интеграционный слой. Вопрос в частоте получения получения этих данных и регулярности их обработки. Есть проекты в которых мы получаем подобную информацию ежесекундно и на её основе выдаём свои прогнозы.
            0
            А как происходит момент «дообучения»? Что вы используете в качестве ML пайплайна?
              0
              Спустя некоторое время собираем свежие данные у заказчика, очищаем их, обучаем модель, оцениваем её, смотрим на метрику (не ухудшилась ли она), и экспортируем её.
                0
                Посмотрите в сторону kubeflow и pachyderm. Все еще костыли, но уже заменто улучшают цикл жизни модели
          0
          А как можно ожидать от модели «правильного» поведения, когда она натренирована находить котиков на картинках, а вы ей кормите картинки слонов?
            0
            Может автор высказывал мысль, что никто и не ждёт, что модель вернёт тебе, что это котик. А то что сервис в который обернута эта модель/сама модель не сдохнет вообще, когда получит слона, проверить надо
              0
              Если возник слон, значит, датасет, на котором мы обучались, возможно, не содержал слонов вообще. И тут есть несколько путей решений.

              1) Искать в исходных данных слонов, если они были — разбираться, почему мы не можем распознать их.
              2) Убедиться в том, что слоны не были выкинуты из датасета как аномалия (выброс).
              3) Захардкодить опознавание слонов

              Слоны — это, конечно, условное обозначение :)

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

            Самое читаемое