![Датасаентисты обучают модель в естественной среде обитания Датасаентисты обучают модель в естественной среде обитания](https://habrastorage.org/getpro/habr/upload_files/9e8/cfd/28b/9e8cfd28b9c6c033f6d7d8a18f69cafb.jpeg)
Что мы делаем?
В Контуре много продуктов, а значит и большой простор для применения машинного обучения: например, в Толке нужен CV, в Фокусе – работа с табличными данными, в Нормативе – умный поиск. В ответ на такое разнообразие задач в Центре ИИ Контура есть как продуктовые, так и исследовательские команды. К одной из исследовательских команд (мы их также называем лабораториями) принадлежу и я, Саша Панкратов. В этой статье я расскажу, что и зачем делает Speech&NLP лаборатория Центра ИИ, какие технологии мы используем и какие проблемы с их помощью решаем.
Основная задача Speech&NLP лаборатории – держать нос по ветру и при появлении новых исследований и технологий проверять, можем ли мы адаптировать их и принести измеримую выгоду командам разработки и пользователям продуктов Контура. Иными словами, наша цель – быть мостиком между современным состоянием рисёрча в области и запросами от других команд. Результат этой деятельности – технология/модель, обёрнутая в веб-сервис, так что пользователи могут закрывать свои сценарии, не погружаясь глубоко в предметную область и специфику ML.
Вот какие решения мы уже успешно внедрили:
Транскрибация речи. Мы создали и поддерживаем внутренний сервис, который решает задачу преобразования речи в текст. Он используется в упомянутом выше Толке и во внутренних сервисах для анализа звонков. В обоих случаях он приносит понятную пользу: экономию времени, трудозатрат и душевных сил сотрудников, ведь извлечь информацию из текста можно в разы быстрее, чем из аудио или видео.
Постобработка транскрипций. От текста немного толку, если его никто не прочтёт. Текст без знаков препинания, больших букв и разделения реплик по говорящим – читать почти невозможно. Значит, нам нужно обработать результаты транскрибации, перед тем как отдавать их пользователям. При этом нужно следить за тем, чтобы текст становился как можно более читаемым, но не терял своей специфики. И дьявол, как обычно, в деталях. Слово, которого нет в словаре русского языка, может быть опечаткой, а может быть специфичным термином. В первом случае его лучше бы починить, а во втором не ломать. А заглавные буквы есть не только в начале предложения, но и в именах собственных, аббревиатурах и так далее. Кстати, наша модель для расстановки знаков препинания и больших букв есть в открытом доступе.
Поиск сущностей в тексте. Например, автоматическое извлечение адресов или ФИО, написание которых не формализовано.
А это то, над чем ведется активная работа, близкая к выходу в прод:
Языковая модель как сервис. Часто ДС-командам нужно что-нибудь обучить поверх векторного представления слов или текстов. Чтобы не решать каждую такую задачу силами лаборатории, мы делаем векторизацию-как-сервис. Такой подход позволит продуктовым командам получать векторное представление своих данных и самостоятельно решать свою задачу при появлении новых сценариев.
Синтез речи по тексту. Иногда проще и удобнее, если робот может говорить.
Зачем мы это делаем
Можно заметить, что ни одно из описанных решений не является чем-то необычным в 2023 году. Резонный вопрос тут может звучать так:
![](https://habrastorage.org/getpro/habr/upload_files/4b8/025/05b/4b802505b508727f3c341b1d012956f1.jpeg)
Или, чуть более подробно: “Погодите, всё ведь уже есть. Распознавание речи доступно как API, технологии открыты, смотрите, даже для русского языка современные модели доступны. Зачем нужна отдельная команда, да ещё и лаборатория?”
Вопрос валидный, и самый короткий ответ таков: “Всё так, но есть нюансы”.
Внешнее API – это дорого. Очень дорого. На примере перевода речи в текст, математика такая: стоимость хостинга наших сервисов с учётом стоимости железа и электричества в десятки раз ниже, чем транскрибация наших объёмов через какой бы то ни было готовый сервис распознавания. А ещё есть данные (примерно все, на самом деле), которые страшно или незаконно отдавать вовне, тем более, что прецедентов утечек очевидно конфиденциальных данных множество.
Открытые модели – это прекрасно. Те люди, что причастны к их созданию и попаданию в общий доступ, заслуживают всяческой благодарности. Однако, каждый, кто проводил эксперименты с предобученными моделями на своих специфичных данных, знает, в чём тут подвох: если ваши данные сильно отличаются от того, на чём модель училась, результат будет в лучшем случае на уровне “ну, сойдёт”. Если хочется получить качество, приемлемое для продукта, нужно сделать много нетривиальной работы по адаптации технологии под свои реалии. Опять же, на примере распознавания речи: часть сервисов телефонии хранит данные в 8кГц MP3, и изменение этого – масштабная инженерная задача. Почти все современные открытые модели учились на данных в 16кГц и без артефактов сжатия MP3, а значит, качество на наших данных драматически падает относительно цифр в статьях. Немая сцена, занавес.
Как мы это делаем
Основа нашей деятельности – эксперимент! Общая постановка выглядит так: есть проблема, которую можно решить с помощью имя_технологии. Давайте применим технологию и сделаем что-то, чтобы она работала как надо. Нельзя заранее знать наверняка, что именно нужно сделать с предобученной моделью, чтобы добиться хорошего результата. Так же не выйдет предсказать, что именно пойдёт не так при попытке обучить модель на своих данных и железе.
![](https://habrastorage.org/getpro/habr/upload_files/c38/c1f/5af/c38c1f5af1d53367bf5ddfb804e54a40.jpeg)
Но можно сформулировать гипотезы, отсортировать их по отношению потенциальной выгоды к трудозатратам и проверить по порядку. Именно вокруг эффективности проверки гипотез и выстроен наш процесс, и именно этой цели служат используемые технологии.
Наши эксперименты должны обладать такими свойствами:
⏩ Быстрый сетап. Нельзя терять время на долгой настройке и запуске эксперимента: это выльется в замедление вообще всех исследований.
? Воспроизводимость. Если результаты нельзя перепроверить, то через полгода в них нет уверенности и от них нет пользы. Значит, нужно иметь возможность заново провести любой эксперимент в тех же самых условиях и быть уверенным, что разные технические нюансы или человеческий фактор не исказят результат.
? Документируемость. Знание, которым никто не обладает, бесполезно. Значит нужно сделать так, чтобы всегда можно было быстро и удобно обратиться к полученным ранее результатам, сравнить их с чем-то, освежить в памяти сделанные выводы.
☑️ Готовность к продакшену. Наша итоговая цель – докатить ценность в виде сервиса до пользователей. Соответственно, нельзя проводить исследования “в вакууме”, без оглядки на то, что нам это предстоит запустить под нагрузкой и на ресурсах, которые стоят денег и конечны.
Каждый из этих пунктов обеспечивается применением одной или нескольких технологий.
Speechbrain
⏩ Быстрый сетап
? Воспроизводимость
? Документируемость
В идеале хочется, чтобы эксперимент как можно более полно описывался конфигурационным файлом. Если сетап состоит не в изменении кода, а в редактировании человекочитаемого конфига, то процесс сильно упрощается: исследователь указывает что он хочет проверить, а не занимается реализацией высокоуровневых концепций в коде для каждой гипотезы. Нам в этом помогает фреймворк SpeechBrain. Это обёртка над PyTorch, которая делает ровно то, что нам нужно, то есть переводит нас с уровня конкретных действий над тензорами на уровень взаимодействия с процессом обучения. В SpeechBrain есть:
Удобная система хуков для гибкой настройки процесса обучения. Весьма удобный гибкий и расширяемый train loop.
Гибкий язык для описания конфигураций – HyperPyYAML.
Лирическое отступление про HyperPyYAML
Автору этих строк кажется, что yaml, в который можно засунуть код на питоне, который исполняется в момент парсинга файла – это, в целом, ужасная идея. Однако, прожив с этими конфигами бок о бок долгое время, вынужден признать, что для сценариев конфигурирования обучения это работает и помогает. Что не отменяет возможности изрешетить себе нижние конечности, если не держать в голове этот риск. Тут нам сколько-то помогла практика ревью конфиг-файлов перед запуском обучения: это отнимает минут десять времени человека, но сильно сокращает количество ошибок, вызванных неправильными конфигами.
Рецепты! То есть имплементированные модели с конфигами. Для быстрого старта исследований работает хорошо, но впечатляющих результатов “из коробки” добиться вряд ли выйдет.
Last but not least, внятные интерактивные туториалы и живое комьюнити: на ишью в гитхабе команда отвечает, и конкретно наш опыт взаимодействия вполне позитивный.
В целом, есть множество альтернатив: PyTorch Lightning, например. Но наши потребности лучше всего закрыл именно SpeechBrain.
Kubernetes
? Воспроизводимость
Эксперименты хочется запускать в известном и предсказуемом окружении и с понятными лимитами по ресурсам. Если речь идёт не об интерактивном процессе типа отладки, а о долгом (часы-дни) обучении, то на помощь приходит абстракция job, которую предоставляет Kubernetes. Наш процесс работы с Kubernetes включает в себя:
Базовый образ. Он собран и лежит в хранилище, в нём установлены все нужные зависимости и там же проходит обучение (и интерактивные эксперименты тоже). Это позволяет малой кровью решить проблему фиксации зависимостей и обеспечить одинаковое окружение для всех экспериментов. Это, однако, не идеальное решение: менеджмент системных и python-зависимостей не то чтобы должен решаться с помощью использования конкретного собранного образа. Есть специальные инструменты, например Poetry. Однако, если в контексте воспроизводимости браться за честный менеджмент зависимостей, то возникает нужда очень правильно его приготовить: зафиксировать версии в т.ч. транзитивных зависимостей, не допустить разрастания процедуры резолвинга зависимостей на десятки минут и так далее. В наших сценариях периодически обновляемый образ в сочетании с указанием версии образа в описании эксперимента работает хорошо и проблем пока не доставлял.
CI-пайплайн на основе Gitlab CI. Позволяет привязывать запуск job’ов к созданию тега в репозитории с кодовой базой. Ожидает найти конфиг по конкретному пути в корне репозитория, подхватывает его и далее делает всё самостоятельно согласно этому конфигу: создаёт под, клонирует туда нужный код, запускает указанный entrypoint. Запуск эксперимента по нажатию кнопки – это удобно. Воспроизведение эксперимента перезапуском job’ы, привязанной к тегу – очень удобно. Оверхед на CI при отладке – неудобно, но в интерактивном процессе отладки полная воспроизводимость в будущем обычно и не нужна, поэтому можно создать окружение и в обход такой машинерии.
Grafana. Как дашборд с базовыми системными метриками подов. Конкретная реализация сервиса дашбордов не особенно-то важна, главное, чтобы был прямой и известный путь, позволяющий наглядно увидеть потребление ресурсов и его историю на графиках.
![Базовые системные метрики пода в Grafana Базовые системные метрики пода в Grafana](https://habrastorage.org/getpro/habr/upload_files/c58/036/d9f/c58036d9f7d3311808a35f7c5084c9c8.png)
Ceph, CephFS и S3
⏩ Быстрый сетап
? Воспроизводимость
Нам, как и любым датасайентистам, нужно хранить много данных, и делать это нужно надёжно и безопасно. Также необходимо уметь получать доступ к данным из окружения, где ведётся эксперимент. Мы добиваемся этого с помощью своего кластера Ceph. Это open-source распределённая система для хранения данных, которая поддерживает автоматическую репликацию и различные интерфейсы доступа к данным. Мы используем CephFS, когда нужен интерфейс в виде файловой системы, и S3-API, когда удобнее HTTP-интерфейс.
ClearML
? Воспроизводимость
? Документируемость
ClearML – это MLOps-инструмент, позволяющий выстраивать трекинг экспериментов. Альтернатива W&B, neptune.ai, MLFlow и другим подобным продуктам. Позволяет из кода обучения отправлять данные, метрики и артефакты на сервер, чтобы впоследствии иметь их в доступности и в привязке к конкретному эксперименту. Кроме данных, явно отправленных через питоновский клиент, перехватывает и отправляет на сервер stdout/stderr питоновского процесса и базовые системные метрики, в т.ч. о памяти и загрузке GPU. Также есть веб-приложение, которое позволяет эти данные удобно просматривать в real-time и сравнивать разные эксперименты друг с другом. Конкретно ClearML выбрали, так как:
Есть бесплатная версия.
Open source – если понадобится, то можно явно на него влиять.
Можно использовать как self-hosted систему.
Набор функций веб-приложения “из коробки” закрывает наши потребности.
Есть интеграция с S3 в качестве хранилища, то есть совместимо с S3-api нашего кластера Ceph.
Пример сравнения экспериментов в веб-интерфейсе ClearML
В процессе эксплуатации у нас возникло несколько вопросов к фронтенду и реализации питоновского клиента, но чего-то частотного, критичного и непреодолимого мы за полгода использования не увидели. А облегчение менеджмента артефактов, хранения и сравнения экспериментов – увидели.
Помимо трекинга экспериментов, ClearML позволяет решать и другие MLOps-задачи, но мы сейчас используем его только как трекер.
Onnx
☑️ Готовность к продакшену
Onnx – это инструмент, который позволяет экспортировать модели машинного обучения в собственный формат вычислительного графа и впоследствии эффективно исполнять их в большом разнообразии окружений с помощью onnx-runtime. Исторически его использование у нас связано с интеграцией с onnx-runtime и C#. Это позволяет с одной стороны эффективно инференсить модели в продакшене (не без хитрых сюрпризов и заковыристых багов, но ничего непреодолимого при должном желании), а с другой делегировать написание и поддержку действительно высоконагруженных сервисов бэкендерам. Несколько лет назад доминирующим с огромным отрывом стеком для бэкенда в Контуре был C# и .NET, поэтому onnx существенно расширял возможности по интеграции моделей.
В 2023 году есть желание посмотреть на альтернативы для формата экспорта модели и инференса в продакшене, например, на TorchScript, особенно в контексте грядущего релиза PyTorch2.
Процесс документации экспериментов
? Воспроизводимость
? Документируемость
Как известно из бородатой шутки, исследование отличается от раздолбайства фактом ведения лабораторного журнала. Этот пункт не про конкретную технологию, а про процесс, который мы выработали для минимизации человеческих ошибок в проведении и интерпретации экспериментов. Основные идеи таковы:
Конфиги долгих (дни и более) экспериментов проходят пре-ревью перед запуском. Это отнимает пять-десять минут времени второго человека и значительно уменьшает количество ситуаций вида “блин, в LR нолик лишний, перепрогонять надо”.
Все эксперименты должны быть доступны в одном месте. Нам хватает обычного git-репозитория с папочками, соответствующими экспериментам. Как оказалось, разумных названий папок и полнотекстового поиска в любимом текстовом редакторе хватает, чтобы свободно ориентироваться в исследованиях лаборатории за несколько лет.
Каждый эксперимент должен быть задокументирован. Дока – это заполненный по шаблону markdown файлик. Наличие такого “скелета” для изложения само по себе ускорило процесс документации типичного эксперимента с 2-3 часов до 30 минут. Кроме того, markdown замечателен простотой и гибкостью оформления (картинки? latex? ссылки? пожалуйста) и не содержит исполняемого кода, т.е. нельзя случайно модифицировать данные, описывая эксперимент (привет, jupyter). Md-файлики также хорошо дружат и с инструментами ревью в gitlab/github (привет ещё раз, jupyter).
Каждая дока ревьюится.
Вместо послесловия
Комбинации описанного выше нам вполне хватило, чтобы выстроить процесс эксперимента, который выдержал испытания временем: всё, кроме gitlab-CI пайплайна в эксплуатации больше полугода, а CI пайплайн активно используется примерно три месяца к текущему моменту. Этот процесс позволил нам при встрече с непонятным и мистическим ретроспективно разбираться, а что же на самом деле происходило недели и месяцы назад.
Хочу пригласить к дискуссии в комментариях тех, у кого есть вопросы, альтернативное решение какой-то проблемы или понимание того, почему так, как написано, работать не должно ?.
А если вы хотите больше знать про то, как и что используется в Центре ИИ Контура, то подписывайтесь на наш телеграм-канал.