Привет, Хабр! На связи Мурат Апишев, руководитель направления NLP R&D в Just AI. Одним из ключевых направлений компании является разработка инструментов для создания голосовых и чат-ботов. Задача создания классификатора интентов в таких проектах является краеугольным камнем, и в этой статье я бы хотел поделиться некоторыми апдейтами наших продуктов в этом направлении. Речь пойдет о внедрении моделей классификации и парафраза на основе трансформеров. Приятного чтения!
Введение
В мире NLP сейчас происходит много интересного и почти фантастического. Но простые задачи обработки текстов не теряют своей актуальности, ведь для огромного количества компаний важно, чтобы их чат-боты определяли намерения пользователей быстро, качественно и дешево.
Для рядового специалиста по анализу данных и ML не составляет особого труда собрать хороший классификатор. Даже если данные сложные, можно сделать дополнительную разметку, подобрать модели, поработать над обучением и получить нужный результат. Но в мире платформ для чат-ботов (равно как и в облачных ML-сервисах общего назначения) упор делается на быстрое обучение по кнопке с минимальным вовлечением пользователя и пусть не идеальным, но достаточно хорошим качеством результата. Когда вы располагаете необходимым набором данных и/или задачи не очень сложные с т.з. близости классов и их сбалансированности, такого результата достичь несложно.
Проблема заключается в том, что обучающие выборки некоторых представителей малого и среднего бизнеса оставляют желать лучшего по всем критериям, и именно у этой категории клиентов обычно нет инхаус-специалистов и наработанных компетенций для работы с такими данными. Поэтому в подобных случаях нам бы хотелось улучшить работу NLU-решений на своей стороне.
Работа с интентами в JAICP
В нашей платформе JAICP до недавнего времени пользователь имел несколько опций для работы с интентами: паттерны, STS, Classic ML и Deep Learning (DL):
Паттерны — расширенный аналог регулярных выражений. Их можно использовать для решения сложных кейсов, но проблемы очевидны: сложность и длительность разработки и поддержки, нулевая переиспользуемость;
STS — простой алгоритм вычисления соответствий между текстами по семантической близости слов. Уже не требует ручной работы и предоставляет понятную информацию для дебага классификации, но подходит только для небольших датасетов и нагрузок на систему. Алгоритм работает медленно из-за обработки лингвистической информации (синонимы, нормальные формы и т.д.), но при этом небольшого количества тренировочных данных недостаточно для хорошего качества классификации;
Classic ML — это линейная модель на разнообразных текстовых признаках, которая показывает себя достойно в задачах с адекватным количеством объектов, но требует предобработки текста, сбалансированности классов и относительно большого объема данных, о чём редко беспокоится среднестатистический пользователь платформы без опыта работы с ML-алгоритмами;
DL — под этим названием в платформе подразумевается модель на основе CNN с одномерными свертками над предобученными векторами, которая в целом неплохо и быстро справляется с разными задачами, если адекватно выставить гиперпараметры обучения.
Практика показала, что многие авторы ботов пишут интенты на паттернах, потому что их работа более предсказуема и контролируема. Или же они используют классификатор STS, потому что он опять же самый понятный и относительно хорошо показывает себя на небольших датасетах. Эти подходы работают, но пользователи периодически выражают недовольство качеством распознавания интентов. Собрав фидбек, мы решили вплотную заняться этой проблемой.
Анализ показал, что в реализациях сервисов присутствуют недочеты, а также неоптимальность выбора дефолтных параметров, с которыми происходит обучение «по кнопке». В первую очередь мы решили исправить эти технические проблемы, но очевидной также стала необходимость создания нового сервиса для классификации на основе более совершенных мультиязычных моделей, который бы требовал от пользователя минимальной вовлеченности и подходил бы для практически всех типов датасетов, включая маленькие, несбалансированные и те, в которых разные языки смешиваются в одной фразе. Мы сразу сконцентрировали внимание на переносе обучения (transfer learning), тем более, что в алгоритме DL такой подход тоже используется. В последние годы стандартом для переноса обучения в задачах классификации и разметки стали BERT-like модели на основе кодировщика Transformer. Приятным следствием такого подхода является возможность использования одних и тех же моделей (или набора моделей в одном сервисе со стандартным интерфейсом) не только для классификации, но и для целого ряда иных задач (QA, FAQ, суфлёр и т.д.).
Тестирование собственного классификатора
Выбрав несколько подходящих базовых моделей с HuggingFace, мы с лингвистами компании провели тесты на наших внутренних данных. Проверялась прежде всего возможность получать адекватные результаты при минимальных выборках (1-5 обучающих текстов на класс). Модели использовались в качестве векторизаторов, поверх которых помещались либо KNN-индекс (мы используем для ускоренного поиска ближайших соседей NMSLIB) с различными стратегиями определения класса по соседям, либо обучаемая линейная голова.
Качество результатов оказалось неплохим, но не существенно выше, чем у нормально обученного на тех же данных алгоритма DL. Поэтому решили дообучать базовые модели для русского языка — у нас как раз и данные внутри подходящие есть и потребность в хорошем качестве наиболее высокая для русского. Данные диалоговые, поэтому модель мы учили предсказывать близость между диалоговой репликой и предшествовавшим ей контекстом. И это зашло хорошо.
После многочисленных подходов к снаряду удалось получить обновленные модели, которые в классификаторе с линейной головой по метрикам показали себя ощутимо лучше (+2-8 пунктов F1-меры на разных датасетах) базовых векторизаторов, что для первой версии мы посчитали приемлемым.
Для валидации качества работы наших классификаторов (назовем новый Transformer) мы провели тестирование на наборе русскоязычных датасетов (как открытых, так и наших внутренних), дополнительно сравнивая качество с Dialogflow как с одной из самых известных диалоговых платформ, в которой можно достаточно свободно проводить тесты. Ниже показаны параметры 9 датасетов на русском языке и результаты для них.
В публичных датасетах HWU-20-Ru и Chatbots-ru (из статьи от Ростелекома) разбиение на train/test определено заранее для чистоты сравнения с результатами предыдущего исследования, в прочих разбили случайным образом в пропорции 60/40. Время обучения измерялось в секундах. В Dialogflow отказ от классификации засчитывался как ошибочная классификация.
Все наши алгоритмы запускаются в доработанных версиях с фиксированными дефолтными параметрами (они станут доступны всем пользователям JAICP после обновления платформы). Для честности сравнения обучение происходит как и в жизни, «по кнопке», без дополнительной настройки.
Набор данных |
Число классов |
Размер train-выборки |
Размер test-выборки |
Датасет 1 |
128 |
1154 |
770 |
Датасет 2 |
4 |
196 |
132 |
Датасет 3 |
52 |
432 |
288 |
Датасет 4 |
10 |
213 |
142 |
Датасет 5 |
20 |
411 |
275 |
Датасет 6 |
56 |
793 |
530 |
Датасет 7 |
99 |
1506 |
1004 |
Датасет 8 |
20 |
100 |
100 |
Датасет 9 |
79 |
5563 |
1388 |
Характеристики датасетов, для публичных указаны названия.
Итак, результаты замеров:
Датасет 1
Алгоритм |
F1-micro |
F1-macro |
Время обучения |
Classic ML |
0.60 |
0.54 |
44 |
DL |
0.66 |
0.59 |
59 |
DialogFlow |
0.61 |
0.56 |
13 |
Transformer |
0.72 |
0.66 |
12 |
Датасет 2
Алгоритм |
F1-micro |
F1-macro |
Время обучения |
Classic ML |
0.81 |
0.81 |
5 |
DL |
0.80 |
0.81 |
19 |
DialogFlow |
0.81 |
0.83 |
13 |
Transformer |
0.81 |
0.83 |
9 |
Датасет 3
Алгоритм |
F1-micro |
F1-macro |
Время обучения |
Classic ML |
0.74 |
0.62 |
17 |
DL |
0.70 |
0.58 |
36 |
DialogFlow |
0.79 |
0.69 |
12 |
Transformer |
0.83 |
0.73 |
11 |
Датасет 4
Алгоритм |
F1-micro |
F1-macro |
Время обучения |
Classic ML |
0.82 |
0.78 |
6 |
DL |
0.86 |
0.87 |
24 |
DialogFlow |
0.87 |
0.87 |
12 |
Transformer |
0.85 |
0.85 |
13 |
Датасет 5
Алгоритм |
F1-micro |
F1-macro |
Время обучения |
Classic ML |
0.88 |
0.83 |
7 |
DL |
0.90 |
0.86 |
40 |
DialogFlow |
0.92 |
0.91 |
13 |
Transformer |
0.92 |
0.90 |
14 |
Датасет 6
Алгоритм |
F1-micro |
F1-macro |
Время обучения |
Classic ML |
0.71 |
0.59 |
21 |
DL |
0.75 |
0.65 |
64 |
DialogFlow |
0.75 |
0.65 |
12 |
Transformer |
0.76 |
0.67 |
17 |
Датасет 7
Алгоритм |
F1-micro |
F1-macro |
Время обучения |
Classic ML |
0.77 |
0.58 |
44 |
DL |
0.79 |
0.61 |
90 |
DialogFlow |
0.80 |
0.68 |
14 |
Transformer |
0.81 |
0.68 |
26 |
Датасет 8 (HWU-20-Ru)
Алгоритм |
F1-micro |
F1-macro |
Время обучения |
Classic ML |
0.67 |
0.65 |
4 |
DL |
0.80 |
0.79 |
13 |
DialogFlow |
0.72 |
0.72 |
11 |
Transformer |
0.92 |
0.92 |
12 |
Датасет 9 (Chatbots-ru)
Алгоритм |
F1-micro |
F1-macro |
Время обучения |
Classic ML |
0.73 |
0.71 |
58 |
DL |
0.78 |
0.77 |
201 |
DialogFlow |
0.63 |
0.62 |
15 |
Transformer |
0.85 |
0.83 |
92 |
Как и ожидалось, в среднем наиболее высокий прирост по сравнению с более простыми методами получается именно на проблемных датасетах с относительно небольшим числом примеров на класс (хотя и на последнем, самом большом наборе данных, качество ощутимо выросло). Скорость работы нового классификатора на момент замеров далека от оптимальной — мы находимся в процессе внедрения оптимизаций на уровне модели и сервиса, которые позволят получить значительный прирост производительности.
Альтернатива «ручной» генерации тренировочных фраз
Как было замечено выше, создание примеров для интентов — один из вызовов, с которыми сталкиваются пользователи диалоговой платформы. Далеко не всегда в наличии есть гора диалогов, из которой можно набрать достаточно разнообразных примеров для классификатора. На деле может не быть ничего, потому что чат-бот только создается или же примеров из жизни очень мало по всем или отдельным классам. Из-за этого много времени уходит на генерацию тренировочных фраз, например: «Как 20 раз сказать «хочу оформить заказ» разными словами». Как следствие, создаваемые таким образом выборки не только малы, но и достаточно однообразны по составу слов.
Для борьбы с этим можно использовать краудсорсинг (дорого, медленно, качественно) или автоматический парафраз (проще, но зато быстро и почти бесплатно). Так как кейсы применения различны, мы хотим использовать оба подхода. Большие генеративные модели за последние годы сильно продвинулись в решении разнообразных текстовых задач. Наиболее известный их представитель, ChatGPT, способен перефразировать тексты почти на человеческом уровне (а в ряде случаев и лучше обычного краудсорсера), и масштабы его использования для подобных целей будут расти (нами в том числе). Тем не менее, на момент старта разработки мы решили обучать собственную модель, поскольку это:
1) Более контролируемо и изменяемо;
2) Дешевле и быстрее;
3) Не требует пересылки данных третьей стороне. Можно дообучить свою небольшую модель под домен клиента и поставить решение в его внутренний контур.
Есть готовые относительно небольшие модели для парафраза, но свои мы учили самостоятельно, чтобы иметь возможность добавлять в них различные элементы управления результатом. В качестве данных использовались пары фраз из открытых источников и наш собственный большой набор данных, полученный с помощью обратного перевода (back translation), в сумме больше 2М пар. После ресерча и ряда консультаций было решено использовать в качестве базовой модели полный трансформер, потому что в seq-2-seq задачах он показывает себя стабильнее декодерных моделей. Мы выбрали предобученные T5 от Сбера и Google. В первой версии обучалась обычная seq-to-seq модель с кросс-энтропийным лоссом. Для генерации используется nucleus sampling, для удобства пользователей были протестированы и подобраны четыре режима генерации, регулирующие степень разнообразия результирующего текста. Тестирование моделей производилось силами внутренних асессоров, оценивалась адекватность парафраза на наборе реплик из логов чат-ботов по различным тематикам.
Несколько примеров относительно неплохих сырых вариантов для фраз на разные темы в разных режимах:
Исходная фраза |
Новая фраза |
Парафраз — изложение текста своими словами. |
Парафразы — это осмысление текста собственными словами. |
Парафраз — изложение текста своими словами. |
Перефразируя это, мы излагаем текст собственными словами. |
Google — американская транснациональная корпорация в составе холдинга Alphabet, инвестирующая в интернет-поиск, облачные вычисления и рекламные технологии. |
Google является американской транснациональной корпорацией, входящей в холдинг Альфабет, которая инвестирует в интернет поиск, облачное вычисление и рекламу. |
За окном снег, а значит скоро новый год, ура! |
У нас за окном уже снег — это означает, что скоро Новый год! |
За окном снег, а значит скоро новый год, ура! |
За окошком снег и, следовательно, скоро Новый год! Ура! |
За окном снег, а значит скоро новый год, ура! |
Снаружи лежит снежный покров — это означает приближающийся Новый Годы Ура! |
Фараон — современное наименование правителей Древнего Египта. |
Фараон - это современное название правителей Древних египтян. |
Фараон — современное наименование правителей Древнего Египта. |
Фараона — это современное имя рулевых древнего Египта. |
Санкт-Петербург назван в честь святого Петра |
Петербург носит имя Святого Петра. |
Сейчас идет конференция на которой рассказывают про обработку естественного языка |
Конференция, посвященная обработке естественных языков, проходит сейчас. |
Впрочем, еще есть над чем поработать. Иногда модель без необходимости сбивается на транслитерацию (баги исходных данных) и английские варианты слов, обычно это свойственно более «вольным» режимам генерации:
Исходная фраза |
Новая фраза |
Парафраз — изложение текста своими словами. |
Paparafrus — это пересказ текста собственными словами. |
А иногда коверкает отдельные слова (в т.ч. сущности) и существенно изменяет даты:
Исходная фраза |
Новая фраза |
Манчестер Юнайтед был основан в 1878 году под названием «Ньютон Хит» (Ланкашир энд Йоркшир Рейлуэй), в 1902 году изменил название на «Манчестер Юнайтед». |
Манчестер Юнайтедз был основан в 1978 году под названием Newton Hot (Lankshire orkshire Relue), а в 1902г. он был переименован в Манчестер Юнайтедз. |
Как мы влияли на генерацию
Следующим шагом стало добавление возможности влиять на генерацию. В рамках парафраза полезной является возможность поощрять/запрещать появление каких-то слов и словосочетаний в результате. Запрещать модели использовать определенные токены можно чисто технически, накладывая ограничения на процесс генерации методами библиотеки transformers. Для поощрения использования определенных токенов мы добавили во вход модели дополнительный контролирующий сегмент, в котором перечисляются слова, появление которых в результате очень желательно.
Сперва для проверки гипотезы мы просто добавляли в половине выборки случайные слова и словосочетания из верных парафразов в этот сегмент на входе, т.е. никак не модифицировали лосс, и это уже заработало. Позже решили усилить эффект, добавив в слагаемые кросс-энтропии взвешивание, и для токенов из контролирующего сегмента штраф за неверную генерацию был существенно повышен. Тестирование показало, что к последней версии модели долю адекватно генерируемых вариантов парафразов в тестовой выборке с учётом требований по наличию слов удалось довести до 70%. Основные сложности связаны с сохранением имен, дат и числительных. Общая адекватность модели по первому тесту осталась на прежнем уровне.
Исходная фраза: «Хочу закрыть счет в вашем банке»:
Требования по наличию |
Требования по отсутствию |
Новая фраза |
- |
- |
Я хочу закрыть свой счет у вас в банке. |
аккаунт |
- |
Я хочу закрыть свой аккаунт у вас в банке. |
аккаунт |
хочу |
Я хотел бы закрыть свой аккаунт у вас в банке. |
Исходная фраза: «Курьер сообщил, что у него нет части заказа, я хочу вернуть деньги»:
Требования по наличию |
Требования по отсутствию |
Новая фраза |
- |
- |
Курьер сказал, что части заказа у него не было, хочу вернуть наличные. |
монеты |
- |
Курьер сказал, что части заказов у него не было, мне монеты хочется вернуть. |
новый год |
заказ, заказа |
Курьер в новый год сказал, что не имеет части ордера, хочу возврата. |
Больше возможностей управления
Поскольку хороший вариант перефразирования не всегда получается с первого раза, для контроля качества и отбора мы добавили к сервису ранжирование по семантической близости с помощью внешней модели. Отбор по топу семантической близости парафраза к исходной реплике помогает избавиться от неадекватных результатов в ряде случаев (естественно, если среди кандидатов в принципе есть адекватные). Приведем несколько примеров фильтрации:
Исходная фраза |
Ранжированный список новых фраз |
От какой суммы будет бесплатная доставка? |
С какой суммы будет осуществляться бесплатная доставка? На какую сумму будет осуществляться бесплатная доставка? На какую сумму будет производиться бесплатная доставка? Какая сумма будет свободной доставки? От какой суммы вы будете получать бесплатную доставку? С какой суммы будет БЕСПЛАТНАЯ доставка? С какой суммы будет бесплатный груз? Сколько будет бесплатной доставки? С какой суммы будет бесплатный проезд? Какова будет бесплатная доставка в течение всей этой суммы? |
Курьер сообщил, что у него нет части заказа, я хочу вернуть деньги. |
Курьер рассказал, что части заказа у него нет, хочу вернуть свои деньги. Курьер сказал, что части заказа у него нет, хочу возвратить деньги. Курьер сказал, что части заказа у него нет, хочу вернуть деньги обратно. Курьер сказал, что часть заказа у него отсутствует, хочу вернуть деньги обратно. Курьер сказала, что не имеет части заказа и что я хочу вернуть ему деньги. Курьер сказал, что он не имеет части заказа и хочет вернуть мне деньги. Курьер сказал, что не имеет части заказа и хочет вернуть деньги.. Курьер сказал, что он не имеет части заказа и хочет возвратить деньги. Курьер сказал, что он не имеет части заказа и хочет возвратить деньги. Курьер сказал, что он не имеет части заказа и хочет вернуть деньги. |
При этом такой отбор может улучшить качество в ущерб разнообразию, так что в определенных случаях ранжирование можно выключать или даже использовать в обратную сторону.
В качестве дополнительной опции мы добавили в модель возможность симплификации текстов на основе датасета RuSimpleSentEval и библиотеки для промпт-тюнинга ru-prompts от Sber AI:
Исходная фраза |
Новая фраза |
Новая фраза с симплификацией |
Общая площадь Соединённого Королевства составляет 242 500 кв.км, а численность населения в 2020 году оценивалась в более чем 67 млн человек |
Общая площадь Великобритании составляет 2424,5 тысячи квадратных метров, а население в 2020 г. оценивалось более 67 миллионов. |
Общая площадь Королевства составляла 242,5 тыс. кв. км, и в 2020 г. население составляло 67 миллионов человек. |
Пётр I Алексеевич, прозванный Великим (9 июня 1672 года - 8 февраля 1725 года) — последний царь всея Руси (с 1682 года) и первый Император Всероссийский (с 1721 года). |
Петр I Алексеевич по прозвищу Великий (9.06.2012 - 8.02.1725) был последним царем всей России (1682) и первым императором Всероссийским (1721). |
Пётр I Алексевич был последним царем Руси с 1682 и первым Императором Всея Руси с 1721. |
Пушкин один из самых авторитетных литературных деятелей первой трети XIX века. |
Пушкин — один из наиболее авторитетных литературоведов первой трети девятнадцатого века. |
Пушкин — авторитетный литературный деятель первой трети 19 века. |
В природном очаге заражение обычно происходит через укус блохи, ранее питавшейся на больном грызуне. |
В природных очагах инфекция возникает, как правило, при укусе блох, которые ранее питались больным грызуном. |
Заражение происходит из-за укуса блохи. |
На первом этапе внедрения парафраза мы просто предлагаем сгенерировать другие варианты написанной пользователем тренировочной фразы, которые он сможет сам поправить и добавить в выборку или, вдохновившись ими, написать свой собственный вариант. Пока мы даже не нагружаем пользователя выбором силы перефразирования и делаем это рандомно. А уже после этого этапа MVP и получения первого фидбека мы хотим дать пользователю возможность более гибко настраивать генерацию с помощью описанных выше настроек модели. Например, управление появлением слов может быть полезным в связке с предварительным выделением важных сущностей, появление которых в парафразе является обязательным.
Подводя итоги
Разработка новых инструментов для классификации интентов проводилась одновременно с разработкой новой версии всего внутреннего NLU-движка CAILA (проект реализуется при поддержке РФРИТ) продуктов Just AI. CAILA 2.0, а точнее app.caila.io — это платформа для встраивания, хостинга и масштабирования NLP-моделей. Именно этих возможностей нам не хватало для использования хороших тяжелых моделей в продакшене, поэтому мы много работали над созданием новой микросервисной архитектуры и над переносом в неё (в ряде случаев — с улучшением, донастройкой и оптимизацией) уже используемых в наших продуктах NLU-сервисов. Таким образом, сейчас первым клиентом CAILA 2.0 становится наша же платформа JAICP. На очереди — наши клиенты on-premise, а со временем мы планируем развивать облачную платформу ещё и как маркетплейс NLP-сервисов.
Итак, мы рассказали в общих чертах о том, как улучшаем наши продукты с помощью трансформеров и надеемся, что лучшее качество классификации из коробки позволит разработчикам ботов сосредоточиться на бизнес-логике своих решений. Мы же продолжим дальнейшую работу, будем улучшать и ускорять наши модели!