Рано или поздно перед любой компанией, которая хочет внедрить системы машинного обучения в свою инфрастуктуру, встает вопрос разметки данных. Чистые данные в достаточно большом количестве - залог хорошей модели, все мы прекрасно знаем правило "Garbage in - garbage out". Такой вопрос недавно встал и передо мной. В этом посте я поделюсь своим опытом поиска инструментов для разметки текста и звука под in-house разметчиков, постараюсь описать их плюсы и минусы, а в конце расскажу на чем мы в итоге остановились и что из этого вышло. Задачи на данном этапе относительно стандартные для NLP: классификация, NER, потенциально также может понадобиться entity-linking и разметка аудио под задачи ASR, но это пока менее приоритетно. Инструмент в идеале нужен open-source, но если будет приемлимый ценник за какие-то нужные фичи - мы готовы заплатить. Заранее скажу, что этот пост никем не спонсировался, а все написанное ниже является сугубым ИМХО. Также имейте ввиду, что впечатления об использовании различных инструментов были составлены на момент написания статьи - осень-зима 2021-го года. Если вы смотрите на эти инструменты сильно позднее - возможно, информация будет уже не актуальной. Ну а теперь, поехали! Я решил начать с инструмента, который долгое время был у меня на слуху, но до которого никак не доходили руки - Label Studio (v. 1.3). Начнем с его плюсов: Легко поднять и настроить. Ну то есть буквально две строчки в командной строке. Весь интерфейс достаточно интуитивный. Есть поддержка мультилейбла, иерархической классификации, relation extraction и прочих достаточно "экзотических" в NLP штук. Можно задавать свои шаблоны (templates) разметки если знаешь html. Можно запиливать свои модели, чтобы учились в режиме онлайн и делали pre-annotation + интеграции с различными БД. Кроме текста можно размечать и аудио. Есть open-source версия. Минусы: Несмотря на интуитивность, в UI достаточно большое количество багов. Часть функционала отсутствует в бесплатной версии (об этом ниже). Достаточно дорогая платная версия. В целом произвел впечатление добротного проекта на стадии поздней беты (в основном из-за интерфейса). Но при этом даже open-source версия поддерживает кучу полезных штук: пре-аннотации с моделями ML, интеграции с различными БД, кучу различных шаблонов и типов данных. Ну и сам факт, что ее можно быстро завести и настроить, уже говорит о многом. Менеджмент проектов однако остается открытым вопросом - на мой взгляд, в бесплатной версии это сделано не очень удобно: ты создаешь проект и загружаешь туда диалоги, каждая реплика - отдельная задача (аннотация). В итоге придется под каждого разметчика (и под каждый пак данных!) создавать свой проект - это все будет разрастаться очень быстро и за этим придется активно следить. Менеджерить это все будет при небольшой команде (10 человек, +/-), наверное, не очень сложно, но если будете расти - придется думать, что с этим делать. Не совсем понятно, насколько лучше ситуация в платной версии: не факт, что разделение админ/разметчик даст более прозрачную структуру проектов. Впрочем, у меня сложилось впечатление, что если эту самую структуру хорошо огранизовать и пару вечеров плотно покурить документацию с API - можно и на open-source версии жить очень долгое время. Более подробно об отличиях платной и open-source версии можно почитать здесь. Основное отличие заключается в том, что у вас просто больше контроля над разметчиками: можно заводить задания под конкретных людей, иметь разделения на администратора/разметчика, подробные логи активности с аналитикой, автоматически производить кросс-валидацию и хостить сам сервис на серверах labelstudio. Цены: Open-source - бесплатно. 300$ / пользователь / месяц (до 10 людей) за "team edition" которая лучше, чем open-source, но все равно имеет кучу ограничений, самое важное - нет разделения на разметчика/админа + нельзя заводить задания на конкретного пользователя. Какой-то сомнительный middle-ground, который, кажется, не стоит своих денег. Цена за enterprise не оглашается, но при большой команде это наверное единственный вариант, который, вероятнее всего, обойдется в копеечку. По этому инструменту совсем немного информации на официальном сайте.Он платный, доступ только по API, разбираться не стал (хочется все-таки найти опенсорс или что-то, что можно протестировать без проблем), но нашел человека, который им пользовался, вот его комментарий: Ситуация такая. Он неплохой, есть автодополнение (модель online тренируется). Из минусов - замечали небольшие глюки. Невозможно делать "nested" разметку. Плюс ценник для корпоратива конский. Сейчас на 7 разметчиков - $2600 счет пришел. Список фичей в платной версиии вполне достойный, хоть и не самый впечатляющий (ничего такого, что я не нашел бы в labelstudio). Цены: Индивидуальный план - 50$ / месяц. 1 Annotator. 500 Annotations / Month. Span Annotations Classifications & Relationships. API Access. LightTag AI Suggestions. Командный пакет - 100$ / месяц. Unlimited Annotators. 500 Annotations /Month. Span Annotations Classifications & Relationships. API Access. LightTag AI Suggestions. Bring Your Own Pre-Annotations On premise - ценник не оглашается. LDAP/SSO. Role Based Access Controls. Audit Logs. Customization and Training. Смущает, что после 500 аннотаций (на разметчика? или всего?) - приходится платить за каждую сверху, аннотация - это, судя по всему, одна реплика. Т.е каждая реплика 2 цента после первого же дня, если не брать on premise версию. Простая математика: разметчик в среднем может делать 1к реплик в день - это еще +20$ / день за разметчика. Непонятно, указана ли стоимость в месяц за разметчика, или же весь сервис вне зависимости от числа разметчиков. Плюс доступ по API, если у вас есть персональные данные - могут возникнуть сложности. Такая базовая вещь, как логи - только в самой дорогой версии. Из плюсов - есть возможность получить бесплатный доступ, если вы делаете исследования в некоммерческих целях. В целом - остались довольно смешанные впечатления, выглядит очень спорно и дорого за функционал, который они предоставляют. Следующий инструмент из списка - tagtog. Из плюсов: Выглядит достаточно готовым продуктом, занимаются именно NLP (что, кстати, одновременно и минус, потому что в labelstudio, например, можно и аудио размечать, а нам это потенциально может быть очень кстати). Есть relation extraction и всякие другие полезные шаблоны. Есть open-source версия. Платная версия не очень дорогая. Можно впиливать свои модели, обученные на уже размеченных данных для пре-аннотаций того, что еще не разметили. Из минусов: Загрузка файлов только через CLI, в интерфейсе такой возможности просто нет. Менеджмент проектов как в labelstudio, только с лишней головной болью насчет загрузки. Особенно печально если менеджерить это будет человек далекий от IT. UI на троечку (субъективно). Работа по API, опять вопросы персональных данных, да и мне лично не очень комфортно когда ты чужой веб-сайт для таких вещей используешь, а не у себя что-то поднимаешь - просто гораздо меньше контроля над происходящим.В целом выглядит так, что если вам не понравится open-source версия labelstudio - это второе, на что можно обратить внимание, если вы решите вопросы персональных данных. С ценами можно ознакомиться здесь. Я бы не брал ничего ниже team pro (99$ / usr / month) т.к. пре-аннотации и разделение на разметчика / администратора - очень важные штуки, которые могут сэкономить вам в дальнейшем кучу времени и нервов. Плюсы: Недорогие (500$ / год). Есть демо версия (просто разметка) которую можно пощупать на сайте. Минусы: Абсолютно упоротый CLI, который при достаточно большом шаблоне становится ну совсем неподъемным. Например, список лейблов нужно прописывать в консоли при создании проекта. На моей прошлой работе в шаблоне было более 100 лейблов - как с этим работать - непонятно. Нет опенсорс версии чтобы пощупать, что к чему. Впиливать модели для пре-аннотаций можно только из SpaCy. Документация на троечку и не отвечает на многие вопросы. UI на троечку (опять же, очень субъективно). Про менеджмент проектов всего пару слов и выглядит так, как будто он не очень хорошо продуман. В принципе, достаточно сказано. Выглядит, как очень узкоспециализированный инструмент для тех, кто плотно работает со SpaCy. Если это про вас, то больше информации можно найти на официальном сайте. Здесь делают разметку "под ключ". Это в принципе не наш юз-кейс, но все же можно про них кое-что рассказать.  С ребятами из этой команды я сталкивался когда они находились еще на стадии альфы, но тогда их функционала не хватало под наши задачи, поэтому пришлось от них отказаться. Сайт красивый, но абсолютно не информативный, нет документации, пара красивых картинок и две кнопки заказать (разумеется, без ценников). Можно было бы хотя бы внушающий список компаний с которыми уже работаете написать, чтобы как-то посолиднее выглядело, что ли. Кажется, что если вы работаете в компании уровня сбера - то, возможно, сможете позволить себе там что-то разметить, хотя в таком случае непонятно как это интегрировать с уже имеющимися у вас системами, да и проще наверное в таком случае свой инструмент сделать - с дивана кажется, что хорошая команда фронтендеров под узкий пул задач такие вещи сделает за 2-3 месяца. Из плюсов разве что наличие своих разметчиков, включая узконаправленных специалистов, вроде юристов - можно использовать как единоразовую акцию, ибо на поток ставить такую громадину кажется будет очень сложно. Это, наверное, единственный юзкейс, который мне пришел в голову, потому что, как я уже писал, это совсем не под наши задачи. Идем дальше. Хотя формально толока не является инструментом для in-house разметки (как и tagme) - я решил внести ее в список. Толока - это скорее платформа, которую можно использовать для crowd-source разметки.К сожалению, я имею достаточно ограниченный опыт работы с этой платформой. Виной всему - персональные данные, с которыми приходится работать. И хотя формально данные которые вы заливаете на платформу являются конфиденциальными: Для исполнителей данные заказчика позиционируются как конфиденциальные — это прописано в соглашении с исполнителем Ничего не мешает недобросовестному разметчику куда-нибудь их слить.Тем не менее, у нас был небольшой опыт работы с платформой: мы размечали данные под задачу ASR на английском языке. Сразу же мы столкнулись с несколькими проблемами: Данные требуется обезличить. И это не так легко, особенно когда речь идет об аудиозаписях. Требуется предобученная модель для транскрибации, модель NER для выделения имен/номеров/геолокаций и еще какой-нибудь кастомный классификатор, например для имен компаний. Составить ТЗ - тоже работа, притом очень важная: от нее будет зависеть качество разметки. Нужно учесть все краевые случаи (например, как правильно размечать аббревиатуры вроде UK, что делать если говорящий повторяет слово несколько раз или оно обрывается, что делать если говорящий заикается и т.д.) - все это должно быть в тестовом, которое должно показать все нюансы, но при этом быть достаточно коротким. Никто не захочет решать тестовое со 100 примерами, прежде чем приступить к разметке, имея вероятность его провалить и просто так потратить свое время. Нужно разбираться в нюансах самой платформы: какие метрики выставить для прохождения тестового, как отобрать достаточно квалифицированных людей под задачу и прочее, прочее. Если вы сталкиваетесь с этим в первый раз - вам вероятнее всего придется искать кого-то более опытного, или учиться на своих ошибках. Собственно, последнее и самое важное - качество разметки. Это самая большая проблема подобных платформ - не имея собственных разметчиков вы не можете контролировать качество разметки и обучать людей тому, как размечать правильно (да, это не так просто, как кажется!). Для задачи ASR используется метрика WER (word error rate), так вот на наших данных разметка с толоки имела WER порядка 20. Для понимания - наши уже предобученные модели на тех же данных выдавали WER порядка 15, поэтому подобная разметка только ухудшила бы модель. Последнее пожалуй является самым большим и критичным минусом (вместе с персональными данными). Это особенно чувствуется, если вы обучаете что-то сложное вроде диалогового агента, где вам встречается несколько десятков сущностей и интентов, для понимания которых нужно быть специалистом в вашей сфере (например, банковской или технической) - в таких случаях crowd-source просто не вывозит. Стоит отметить и плюсы. Толока отличное место, если вам требуется разметка как единоразовая акция - например, для скоринга уже предобученной модели или для понимания нужен ли вам вообще ML. Скорость разметки. 5 часов аудио у нас размечали более ста человек и сделали они это буквально в течение часа-двух. Относительно небольшая стоимость. 1000 заданий транскрибации стоят 18 долларов, остальные цены можно узнать на сайте  Несмотря на все написанное выше, на толоке все-таки можно получить достаточно высокое качество разметки (особенно если домен не слишком специфичный). Для этого требуется сделать достаточно длинное и сложное тестовое задание, покрывающее все краевые кейсы, порог прохождения в районе 95% правильных примеров из тестового и после этого - контролировать разметчиков, подмешивая в "боевые" данные уже заранее размеченные примеры - таким образом вы сможете смотреть, что все правила, выученные в тестовом задании соблюдаются. Кроме этого - можно настроить кросс-валидацию и умную агрерацию размеченных примеров. Это достаточно много работы (и денег), но по рассказу коллег - это действительно очень сильно улучшает качество разметки, хотя и заметно уменьшает ее скорость - ибо браться за такие задания хотят гораздо меньше людей. Последнее, впрочем, не должно быть большой проблемой - средний ежедневный онлайн толоки - порядка 20 тысяч человек и, вероятнее всего, вы без проблем сможете найти людей под свои задачи, просто не так молниеносно, как это было бы с более низким порогом вхождения. Помимо всех инструментов выше, я так же проверил еще несколько: https://webanno.github.io/webanno/ https://inception-project.github.io/ https://brat.nlplab.org/introduction.html Однако, везде беглый просмотр документации выявлял, что: Не хватает каких-то фичей (пре-аннотации / интеграции). Непонятный менеджмент проектов. Сама документация выглядит сомнительно и не отвечает на вопросы, что уже само по себе первый тревожный звоночек. В сравнении с тем же labelstudio они очень сильно проигрывают почти по всем параметрам. Проект банально выглядит заброшенным. Отдельным пунктом стоит выделить https://github.com/doccano/doccano, с которым я столкнулся уже после того, как мы приняли решение о том, какой инструмент будем использовать.  Об этом инструменте я слышал достаточно много хороших отзывов, вдобавок он имеет лицензию MIT vs Apache 2.0 у конкурентов, что может быть критично для некоторых проектов. Этот инструмент я оставлю читателю на самостоятельный разбор. Хорошенько все обдумав и посмотрев еще раз на все инструменты выше, я пришел к следующему выводу: надо заводить labelstudio и настраивать open-source версию под наше небольшое количество разметчиков. Выстраивание процесса разметки - дело нелегкое. Требуется выяснить: Как удалять уже размеченные проекты, делая бэкап данных, чтобы они не копилиcь. Как интегрировать ее с какой-либо БД. Как сделать pre-annotations и active-learning. Как автоматизировать выгрузку уже размеченных данных и п. 1, 3. Подумать над названиями проектов, чтобы было понятно: кому размечать, что размечать, и какие модели для пре-аннотаций туда закидывать. Ну и дату разметки еще неплохо иметь. За счет этого можно будет потом и статистики по разметчикам считать. Открытый вопрос насчет кросс-валидации: даже в open-source версии можно ее самим сделать, и не факт что выйдет хуже, чем в платной версии. Еще один открытый вопрос: насколько критично, что нет разделения администратор/разметчик - надо будет следить, что бы разметчики не сломали что-нибудь. По-крайней мере на часть этих вопросов я попытаюсь ответить ниже. В целом, как я уже писал, сам проект произвел достаточно хорошее впечатление. В списке их пользователей Intel, Nvidia, IBM и другие гиганты индустрии - что уже, в общем-то, о многом говорит. Помимо всего прочего у них активное community в Slack, где можно достаточно оперативно (обычно) получить ответ на возникший вопрос. Ну и плюс это open-source, если что, можно что-то самим допилить или все-таки разориться на платную версию. Сам сервис поднимается очень просто: pip install label-studio label-studio start Есть варианты поднятия через docker, heroku и еще куча разных вариантов под ваши нужды. При старте можно прописать порт, на котором сервис будет крутиться, дефолтный - 8080. После этого - просто заходите в браузере по IP тачки на которой этот сервис крутится (если у вас есть доступ по ssh, разумеется) - и вы можете начать пользоваться Labelstudio. Могу только добавить, что ставить лучше не с pip, а клонировать мастер ветку репозитория - несколько моих проблем решилось именно таким нехитрым приемом. Обновления на pip , видимо, подливают с большим запозданием. После создания пользователя можно начать тестировать работу с файлами. Через UI загрузка и выгрузка работает отлично - ты кидаешь .txt или .csv/.tsv файл - и на каждую строчку создается отдельная задача внутри проекта. Это прямо то, что нужно. А вот на моменте с интеграциями начала происходить какая-то дичь. Те же .txt/.csv/,tsv файлы которые отлично грузятся через UI - напрочь отказываются грузиться с хранилища (в моем случае - просто локальная папка). LS говорит, нужен json в специальном формате. Читаем документацию, где написано, что можно кидать несколько заданий в одном json-файле. Копируем формат, вставляем - получаем ошибку. Ты мне, говорит, мол, список пихаешь, а должен быть словарь. Я пытался в словаре кормить ссылки на файлы с данными - это тоже не работает. Мне кажется я вообще перепробовал все форматы из документации и еще несколько своих придумал. Спустя 3 часа непонимания, гугления и чтения документации я все-таки наткнулся на issue, которую должны поправить в следующем релизе. По факту, на каждую задачу (читай - реплику) придется создавать отдельный json. Т.е. если у меня 5 проектов по 1000 реплик каждый - это 5000 json-файлов в день, которые придется таскать туда-сюда. Очень надеюсь, что скоро поправят, ибо при хоть сколько-нибудь большом проекте это будет вызывать проблемы. Удивительно, что с этим столкнулись только на столь поздней версии, ведь это едва ли не первое с чем сталкиваешься при использовании. Есть еще вариант с созданием проектов и задач через API без интеграции с хранилищем - но там полетели такие дикие ошибки (которые тоже, к сожалению, висят без ответа в слаке) - что я просто забил. Общался с парнем, который как и я использовал LS - он тоже не смог разобраться с API и загружал данные ручками через UI, просто делая большие проекты, чтобы не приходилось этим заниматься каждый день.А, ну и еще: можно в json'e кормить ссылки на файлы, если ты... Поднимешь отдельный http сервер который будет кормить url-ы на локальные файлы. Настолько извращаться я не стал и решил подождать фикса issue выше.То есть как бы куча вариантов того, как можно просто залить файлы но не один из них толком не решает проблемы, которая встает при первом же использовании тулзы - хочется просто залить несколько заданий из одного файла. Интересно то, что ведь можно просто скопировать функционал, который уже реализован через UI - но по каким-то причинам это не было сделано. С выгрузкой таких проблем не возникло и там все работает отлично. К слову о слаке: он является ограниченно полезным. Не стоит возлагать на него слишком много надежд. Мне несколько раз помогали решить проблему (большинство решалось пуллом последней версии master main ветки), однако очень много вопросов остаются без ответа. Например, пост с вопросом о memory leak внутри одного из js-фреймворков который используется проектом висит без ответа с августа. Не знаю, действительно ли там текла память, но проблемы с аудио у меня тоже были. Возможно, ответят тебе или нет сильно зависит от загруженности ребят и тупости вопроса, но сам факт наличия слака в любом случае радует, ибо помочь могут не только создатели LS, но и его пользователи. В целом API сделана достаточно удобно с точки зрения функционала (очень много всего, что можно сделать - от создания проектов и привязки хранилища до синхронизации и почти любой хотелки), но очень печально с точки зрения примеров с юз-кейсами и юзабилити в целом. Простой пример - я создал проект и хочу привязать к нему хранилище. Казалось бы, напиши имя проекта и создай, но... Хранилище привязывается к проекту по ID проекта. ID можно узнать только после создания. Хорошо, что при создании этот ID приходит обратно, и не надо парсить весь список проектов чтобы узнать этот ID (что я делал сперва), иначе вообще печаль была бы. Хотелось бы, например, иметь возможность прицепить хранилище сразу при создании проекта, ну да это уже хотелки, которые не столь важны. Другая проблема - очень много вещей, которые не описаны в доке: valueType в шаблонах, file_upload при заливке данных (который вообще int - я так и не понял, что это) и список можно очень долго продолжать. Несмотря на какие-то досадные мелочи (которые, как мне кажется, от отсутствия хорошей документации или просто ее неактуальности) - работать с этим очень даже можно. Его я особо не трогал, но в целом дефолтный бэкенд для классификации текста у меня завелся без проблем. Есть вызовы API fit/predict, кастомный бэкенд пишется как наследование от базового класса с реализацией нужных методов и, несмотря на то, что я его не писал - из документации все выглядит на удивление понятным и не вызывает вопросов. Для разных моделей придется поднимать несколько бэкендов на разных портах. Однако, тут встает проблема того, что если вдруг у них изменится API, или они переедут на какую-то новую версию pytorch, например, - скорее всего все придется переписывать, что не есть очень хорошо. Вам стоит дважды подумать, стоит ли это впиливать, потому что пре-аннотации можно делать при загрузке: уже готовой моделью размечать и загружать данные с предсказаниями (для которых есть отдельное поле, чтобы при выгрузке эти данные не считались размеченными), не впиливая саму модель в инфраструктуру LS, что очень круто. Я думаю пока остановиться на этом варианте Бэкапы делаются легко. При старте сервиса прописывается путь, в котором лежит БД и медиа-файлы со всеми шаблонами, данными, проектами, пользователями и прочим-прочим. Достаточно скопировать эту папку - и бэкап сделан. В документации написано, что по дефолту в качестве БД используется SQLite, которая, вроде как, не production ready. Я пока не тестировал нагрузку, однако, по словам человека который LS уже использовал - при 20 разметчиках и нескольких проектах на сотни тысяч заданий - проблем не возникало, что радует.В целом, несмотря на некоторые описанные выше косяки, у меня в голове уже выстроилась схема того, как это все можно оформить в скрипты, которые автоматизируют почти все этапы: от загрузки сырых данных, до выгрузки уже готовых. Инструмент, на самом деле, очень сильный в плане функционала, ребятам просто надо немного поработать над usability и документацией. ETL пайплайн, который у меня выстроился в голове (и который можно автоматизировать при помощи LS), выглядит примерно так: Получаем сырые данные. Предобработка (если нужно), разделение данных по N реплик на K разметчиков (например на день/неделю). Доработка шаблона: новые классификаторы и классы + автоматическое создание xml шаблона из которого будет собираться UI для инструмента. Тут могут возникнуть определенные проблемы, если у вас будет несколько классификаторов или иерархическая классификация - но они решаются созданием новых скриптов для генерации шаблона, ну или его можно просто ручками сделать через GUI и скопировать, если лень парсить xml. Создание K проектов под каждого разметчика в формате username_currentdate, чтобы было удобнее менеджерить и собирать статистику. Интеграция каждого проекта с отдельным хранилищем для каждого разметчика (с дивана кажется, что локальное хранилище менеджерить будет проще чем, например, S3, а доступ на тачку все равно есть только у тех, у кого ssh ключи, хотя LS пишут что local storage - это небезопасно). Пре-аннотация скриптами (если вы не будете писать свой ML-backend). Заливка данных в это хранилище, синхронизация и создание тасок. Ежедневная выгрузка уже размеченных данных, удаление размеченных данных, заливка новых. Постобработка, дообучение модели. Сбор статистики по разметчикам. Бэкап. Следующая итерация. Все это делается через API, что-то я уже трогал и тестировал, что-то показалось понятным и простым из документации - с этим можно будет разобраться чуть позже, если мы все-таки решим настолько заморачиваться с разметкой. Как afterthought могу сказать, что вне зависимости от того, какой инструмент вы выберете (если это не разметка под ключ) - работы тут немало: сделать фундамент можно за ~4 недели, а вот на поддержку потом лучше брать отдельного человека (сильный Junior MLE/DE по ощущениям должен справиться), ибо вам придется: Постоянно переделывать шаблоны под бизнес-хотелки. Заливать фиксы новых версий LS (или вашего фреймворка) и каждый раз смотреть, что сломалось. Плотно работать с разметчиками на тему инструкций и отвечать на вопросы по разметке. Интегрировать новые модели для пре-аннотаций. И еще куча всяких неожиданностей, которые обязательно всплывут на стадии эксплуатации. Можно в теории самому заниматься этим "парт-тайм" в перерывах между нашими любимыми fit/predict, но мне этот вариант не особо по душе, я уже пробовал. На этом в общем-то все, спасибо за внимание! Если у вас возникли какие-то вопросы по статье - можете написать мне в telegram: @overclocked1827или в комментариях - я постараюсь на них ответить. Удачи! Machine Learning Engineer