Что под капотом «ответов на вопросы» Маруси?
Привет, это команда ответов на вопросы Маруси.
Этот материал состоит из двух частей. Это вторая часть (первая часть). В ней мы чуть глубже копнём технический аспект того, как устроены ответы на вопросы голосового помощника Маруся.
В первой части мы поверхностно рассмотрели механизм, позволяющий нашему голосовому помощнику понимать вопросы и реагировать на них. Теперь поговорим о том, как мы некоторое время назад создавали систему ответов на вопросы, и с помощью каких решений достигался результат, соответствующий как требованиям пользователей, так и техническим ограничениям.
Материал может быть интересен тем, кто только начинает свой путь в NLP или разрабатывает аналогичные решения, но не обладает несколькими стойками c DGX.
Recap. Какую задачу мы решаем?
В систему ответов на вопросы попадают в основном запросы с информационной потребностью, такие как: «Работает ли библиотека имени Ленина в 3 часа ночи» или «Как сделать лук в майнкрафте». За выделение этого среза из общего потока отвечает система матчинга запросов в отдельные навыки Маруси (об этой системе мы вкратце упоминали в первой части статьи).
Как устроен поток информационных запросов?
Хорошими мы назовём вопросы, на которые при должном старании и использовании правильных информационных ресурсов мы, в теории, можем ответить.
Плохими будем называть вопросы, которые, являясь по внешнему виду вопросительным обращением с целью получения информации, не содержат достаточно данных, чтобы понять, что именно хотел пользователь.
Примеры плохих вопросов:
Кто его знает где?
А почему скажи почему получается что (возможно, объект обсуждения где-то в предыдущем контексте).
Как как правильно выйти (возможно, речь про Vim, но мы этого не услышали).
Кто такой Алексей Иванов (какой именно?!).
Также возможно, что из-за специфики уровня речи пользователя и неидеального распознавания реплика превращается в невообразимое нечто:
Расскажи об агнии левны барто (скорее всего, Агния Барто).
Таблетку анороферон расчесывать или пить (расчесывать ~ рассасывать).
Стоп для лечения кашляев со трудненого рождения в мокроты при невони и бронхити можно быстро принять.
Какой командир проявил свой военный денег битве при туре в восьмом веке нашей эры.
Ещё одной формой «плохих вопросов» являются запросы, которые связаны с точной информацией, к которой у ассистента априори нет доступа:
Что я сейчас показываю руками?
Что я сказал минуту назад?
Как зовут моего брата?
Какие задания будут на ЕГЭ в этом году?
Кто победит на матче Динамо-Спартак?
При плохом вопросе логично переспросить и уточнить у пользователя о его истинных намерениях, либо констатировать невозможность ответить на него.
Отделением плохих вопросов и ошибок матчинга от всего потока информационных запросов занимается отдельный классификатор, обученный на разметке, примеры из которой вы видели выше.
Теперь давайте поговорим о том, как можно отвечать на хорошие вопросы. Сначала вопрос предварительно обрабатывается:
Удаляем слова вроде «расскажи» или «объясни».
В контексте беседы ищем недостающую информацию, если вопрос связан, с предыдущими репликами.
Выделяем ключевые объекты и свойства для работы с графом знаний.
После препроцессинга у нас есть хороший запрос, в котором нет ничего лишнего. Что можно сделать?
Мы можем попытаться сгенерировать ответ с помощью генеративной модели (GPT/T5), но есть вероятность, что она ответит неточно или даже дезинформирует. Вероятность ошибки тем выше, чем больше вопрос имеет отношение к конкретным местам, событиям, объектам и датам. Но при этом генеративная модель может показывать неплохой результат на запросах, требующих мнение по открытой и нечувствительной теме, например: «К чему снится как кот ест кота?» или «Как удивить гостей?». К несчастью, это не очень большое множество вопросов.
Небольшое отступление про ChatGPT
Так уж получилось, что материал выходит в дни, когда в широких интернетах активно хайпится ChatGPT (обзор). Результат OpenAI производит потрясающее впечатление сейчас, и, можно не сомневаться, задаст тренд на ближайшие несколько лет.
Нельзя избежать сравнения методов, используемых в ChatGPT, и методов, представленных в этой статье. Прямо сейчас всем (включая нас самих) намного интереснее обсуждать большие генеративные модели, обученные в RLHF пайплайнах. Но при этом у нас остаются и насущные задачи, которые уже как‑то решаются. Одно дело — искать в текущих решениях зону роста с помощью модной темы, другое — безапелляционно утверждать, что ChatGPT — лучшее решение всех проблем на свете.
Если вы не только видели скриншоты из интерфейса ChatGPT, но и непосредственно взаимодействовали с ним, то, скорее всего, понимаете, какие могут быть проблемы при использовании такой системы в существующих интерфейсах голосовых ассистентов.
Первое и главное: ChatGPT достаточно долго отвечает; на момент публикации такая длительность ответа даже для сверхточного ответа воспринимается пользователями колонки как слишком долгая и создаёт ощущение «туповатого ассистента».
Второе. Взаимодействие c ChatGPT происходит через GUI. И то, что лаконично выглядит в виде текста, не всегда хорошо воспринимается на слух.
Это не означает, что ChatGPT, по нашему мнению, плох и не годится для решения наших задач. Как раз наоборот. Вокруг полно сценариев, в которых потенциал диалоговых систем размаха ChatGPT будет востребован и актуален как ничто иное. Но в начале 2023 года это не сценарий коротких и точных ответов на информационные запросы пользователей в умной колонке.
И конечно же всё выше написанное не значит, что голосовой ассистент Маруся никогда не будет использовать внутри себя такие системы. Маруся живёт не только в колонке, но ещё и в мобильных приложениях и веб-версии. Следите за анонсами, чтобы не пропустить важные обновления ;)
В результате оптимальным по соотношению надежность/качество является поиск ответов на вопросы в открытом интернете. Чтобы такое решение работало, Марусе необходим собственный поиск по вебу. Высокоуровнево процесс выглядит так:
Используем исходный вопрос для получения выдачи. На деле всё сложнее, с запросом проводится много различных манипуляций препроцессинга, но для простоты опустим.
В полученной поисковой выдаче рассматриваем топ-N документов, в которых мы будем искать текст, содержащий ответ. Для простоты будем считать, что речь идёт про топ-10.
Обрабатываем найденный текст для придания ему наиболее уместной формы. В колонке это может быть одна форма ответа, в приложениях на разных платформах — другая.
Разумеется, мы ранжируем выдачу и ищем ответ с помощью моделей машинного обучения. Рассказ про них прибережём на потом, а сейчас давайте поговорим о том, как, имея в руках 10-20 страниц поисковой выдачи, можно достаточно быстро найти в них короткий текст, являющийся ответом на вопрос.
SQuAD (Stanford Question Answering Dataset)
Описанная выше постановка задачи, возможно, вам что-то сильно напоминает. Это классический Question Answering в постановке machine reading comprehension, где на вход подаётся запрос и текст, а на выход — позиции начала и конца ответа в предлагаемом тексте. На данный момент эта задача неплохо решена на популярных наборах данных:
Squad2.0
SberQuad
TyDI
xQuad
Более того, в репозитории huggingface есть объекты и утилиты предварительной обработки данных для такой задачи. В топе Squad2.0 можно обнаружить достаточно развесистые решения, на не менее развесистых трансформерах размером large и выше (то есть скрытое состояние 1024+, количество слоёв 24+). Такие модели требуют достаточно ёмких GPU. В домашних условиях на карточках уровня 2080TI такое не то что учить, а даже инферить затруднительно.
Какие здесь ещё есть нюансы?
Во-первых, большинство публичных наборов данных не русскоязычные. Эту проблему как-то пытаются закрывать коллеги из Сбера. Но, в целом, количество данных на других языках значительно больше.
Мультиязычность датасета для решения целевой задачи не только вредна, но и полезна, если вы используете мультиязычные претрейны, такие как XLM-RoBERTa или MT5. Результаты экспериментов с русскоязычными текстами при использовании комбинации мультиязычной pretrain-модели и мультиязычного обучающего набора значительно превосходят результаты работы с обучающими наборами исключительно из русских текстов.
Но есть и весьма острая проблема: распределение тем, объектов и свойств в реальном приложении сильно отличается от открытых наборов данных. Об этом можно почитать в статье “What do models learn from question answering datasets?”. Наши эксперименты соотносятся с этими результатами. Если коротко, то для того, чтобы качественно отвечать на вопросы из предметной области или приложения, вам нужны размеченные данные из той же предметной области или приложения.
Вторая проблема чисто вычислительная.
Для поиска ответа в большом тексте требуется весь этот текст передавать в модель вместе с вопросом. С одной стороны, архитектура трансформера несколько ограничивает количество текста, которое единовременно мы можем показать модели (впрочем, ничего лучше сейчас нет). На деле текст перед подачей в модель нарезают на фрагменты — пассажи (их делают с перекрытием, на случай, если настоящий ответ окажется на границе фрагментов). С другой стороны, для инференса всех пассажей требуется достаточно много вычислений, а ответ нужно получить достаточно быстро. Это можно решать тремя способами:
Залить проблему железом: поставить больше производительных GPU, которые параллельно будут обсчитывать пакеты с длинными пассажами. Удовольствие для богатых.
Можно уменьшать размер модели, но — сюрприз! — будет падать качество финального решения. На практике это значит, что модель будет периодически выделять не самый лучший ответ, а какие-то куски текста, похожие на правильный ответ, который при этом достаточно часто находится в топе решений, но модель не присваивает ему необходимый скор, чтобы он стал лучшим вариантом.
Можно уменьшать размер пассажа. Модели, обученные на наборах вроде SQuAD, даже из достаточно больших текстов извлекают относительно короткие подстроки. Уменьшение размера пассажа на качество влияет не так сильно, как уменьшение модели.
В целом, такую модель можно было бы использовать для поиска ответов на вопросы, если бы не одно чисто продуктовое обстоятельство. Мы делаем ответы для голосового ассистента, живущего в колонке. А это задаёт нам несколько продуктовых ограничений, и первое из них: ответ должен быть кратким, но не слишком!
Пример:
— Сколько живут хомяки?
— Два-три года. [Информация, в целом, верна, но ответ слишком короткий]
— Средняя продолжительность жизни хомяка составляет два-три года. [Более подходящий ответ для ассистента в колонке]
Поскольку иногда ассистент даёт неправильные ответы на задаваемые вопросы, пользователи не сильно доверяют полученной от него информации. В более экзотических случаях, особенно когда ответ не очевиден, слишком короткие ответы могут вызывать недоверие.
Пример:
— Правда ли, что медведи зимой выходят из спячки, чтобы нормально поспать?
— Да, правда. [Нет уверенности, что вопрос был понят — нет уверенности, что ответ верный]
Ответ должен быть кратким, но при этом из него должно быть понятно, что ассистент верно понял вопрос. Другими словами, ответом на вопрос пользователя должно быть минимум одно предложение. Получить приемлемое предложение из короткого ответа несложно, достаточно выдать всё предложение из текста, которое содержит найденный короткий ответ.
Второе ограничение: ответ должен быть развёрнутым и полным. На некоторые вопросы, как, например, вышеописанные, ответа одним предложением будет достаточно. Но есть вопросы, ответы на которые требуют больше двух предложений.
— Кто такой Дональд Трамп?
— Почему мы всегда видим одну и ту же сторону Луны?
— Почему зимой холодно, а летом жарко?
— В чём разница между фанатиком и верующим?
— Когда это всё закончится?
Хорошие ответы на такие вопросы выходят за пределы объяснений «из-за приливного захвата» или фраз в духе «потому что».
Спановая нейронка склонна выделять разные ответы вокруг наиболее вероятного. Если же в надежде получить развёрнутый ответ мы продолжим чтение текста, в котором нашли короткий ответ, то рискуем озвучить нерелевантную информацию, потому что тема всего текста запросто может не совпадать с темой вопроса.
Итак:
Спановая нейронка может найти короткий ответ в пассаже, но для озвучивания ответа мы всё равно расширяем его минимум до одного предложения.
Спановая нейронка не позволяет эффективно собирать ответ, состоящий из нескольких предложений, отвечающих на исходный вопрос.
Для улучшения качества ответов нужно улучшать разметку данных. Разметка для такой нейронки требует не банального интерфейса, а хорошей системы проверки результатов.
Спановая нейронка либо медленно работает, либо требует достаточно большого количества дорого железа.
Проще значит лучше
Всё вышеописанное выглядит так, что использование спановой нейронки, обученной на открытых данных, не может дать решения, соответствующего продуктовым задачам. Какие есть альтернативы?
Если нам, в итоге, нужно выдать пользователю целое предложение, то давайте не искать в тексте позиции начала и конца, а классифицировать отдельные предложения по признаку, являются ли они ответом на вопрос или нет?
Преимущества:
Лёгкость обучения.
Лёгкость разметки (на первый взгляд).
Понятность задачи для оценки качества.
Итак, у нас есть тексты, полученные из поиска (для простоты можно представлять себе топ-10 документов, найденных по вопросу). Где-то на этих 10 страницах есть утверждения, которые сильнее других годятся в качестве правильного короткого ответа (либо их там совсем нет из-за неидеальной работы поиска на достаточно экзотических запросах). На один документ приходится от 200 до 1000 предложений.
С помощью обученной на первом шаге нейросети мы можем локализовывать ответ в тексте и получать для каждого предложения confidence наличия ответа (степень уверенности, что ответ именно в этом предложении).
Из таких данных мы можем собрать первую версию датасета. Фактически «перелить» спановую нейронку в классификатор пар. После обучения на таком датасете мы получим классификатор, принимающий на вход «исходный вопрос» и «текст потенциального ответа», и возвращающий вероятность того, что этот текст действительно является ответом.
Для эффективного повышения качества неплохо бы размечать результаты работы модели на живом потоке и добавлять их в обучающий набор. Неправильные ответы при таком подходе являются хорошими hard-negative примерами.
Про активное обучение
Здесь хотелось бы упомянуть об использовании практик активного обучения (Active Learning), которые привели к «неожиданному» результату. С помощью поиска несложно найти потенциальные ответы, лежащие в зоне неуверенности модели. «Неожиданность» заключается в том, что примеры, сложные для большого трансформера, также сложны и для человека, оценивающего предложение по формальному признаку, содержит ли оно ответ на вопрос. В результате мы усложнили инструкцию и начали размечать более тонкие аспекты фактовых ответов, сильнее учитывающие форму ответа.
Примеры неудач при активном обучении (Active Learning):
— Кто такой Локи?
— В игре Cultures 3 Локи является одним из основных героев, сначала он помогал Бьярни, потом его предал.
— А что такое Солнце?
— Звезда такой массы, как Солнце, должна существовать на главной последовательности в общей сложности примерно 10 млрд лет.
— Кто первый президент Российской Федерации?
— Наличие большого количества проблем значительно понизило рейтинг Ельцина.
— Что такое АЭС?
— Атомные электростанции России.
Как видите, вопрос был услышан и понят; более того, формально ответы содержат информацию, являющуюся ответом. Но учить модель признавать тексты такого типа правильными было бы опрометчиво.
В качестве pretrain-модели используется RoBERTa-large. Даже не смотря на то, что модель теперь «смотрит» на достаточно ограниченный по длине участок текста, она, по меркам диалоговой системы, работает по прежнему слишком долго, а нам нужно достаточно быстро обрабатывать порядка 600 предложений в каждом из 10+ документов.
Обратите внимание, что при этом конечным результатом является относительно короткий ответ. То есть большая часть времени тратится на оценку предложений, которые радикально плохи в качестве финального ответа. Решение осознаётся достаточно быстро: для того, чтобы отсеять радикально нерелевантные примеры, можно использовать модели попроще (поменьше). Значительно проще!
Пропустим этап поиска оптимальной конфигурации, уточним только, что качество финального результата относительно использования одной большой модели почти не проседает. Первая версия ответов на вопросы из поиска выглядела так:
На первом уровне все предложения оцениваются полносвязной нейронкой на мешке эмбедингов. После токенизации эмбединг каждого токен прогоняется через полносвязные слои, а затем по всей последовательности берётся max-pooling. Получившиеся представления передаются в полносвязную сеть, которая выучивает целевой таргет для обоих входов. Эта модель оставляла 512 предложений-кандидатов.
Совершенно не обязательно решать все задачи Sota-решениями. Банальные задачи можно предоставить банальных архитектурам. На втором уровне мы используем свою собственную маленькую RoBERTa, состоящую из четырёх трансформерных блоков с размерностью скрытого состояния 256. Это наш маленький трансформер, полученный в результате предобучения на наших задачах (см. соответствующий раздел). Результатом работы этой модели-классификатора были 32 лучших предложения.
Бытует мнение, что хороший трансформер раскрывает всё преимущество архитектуры только при наличии большого количества параметров. Однако даже при таких маленьких размерах трансформер на голову выше любых других архитектур. Хорошее предобучение – залог успеха. Финальная модель создана на основе RoBERTa-large, она классифицирует предложения и выбирает из них лучшее в качестве ответа, при условии, что оно проходит порог классификации в «хорошие» ответы.
Большая модель больше всего похожа на то, что представляют в DS-сообществе, когда слышат про BERT'ы и трансформеры.
Все более мелкие версии являются результатом дистилляции (knowledge distillation) большой модели.
Отчего возникает сухость во рту? Топ ответов: |
Сухость во рту возникает при сильном обезвоживании организма, к примеру, в жаркую погоду или после интенсивных физических нагрузок. |
Временное состояние, возникающее ночью или по утрам, может быть вызвано: проблемами с дыханием, возникающими вследствие храпа или насморка, когда из-за этого высушивается слизистая полости рта. |
Постоянно сушит во рту, основные причины — полная дисфункция слюнных желез. |
Сухость во рту (или гипосаливация) возникает в результате таких заболеваний, как сахарный диабет, анемия, патологии дыхательный системы и ЖКТ и пр. Также повышенной сухости может способствовать частое курение… |
ОРВИ, грипп, ангина и другие инфекционные заболевания, при которых наблюдается повышение температуры, потоотделение, рвота и диарея приводят к обезвоживанию организма и появлению сухости во рту. |
После оценки доли правильных ответов среди лучших найденных предложений обнаружилось, что для разных типов вопросов качество может сильно отличаться. Так, на вопросы про «определения» вида «что такое?» и «кто такой» модели демонстрировали достаточно хорошее качество (более 80 % уже в самых первых версиях). С другой стороны, для вопросов, на которые достаточно сложно ответить точно (например, вопросы вида «как лучше сделать что-то» или «почему»), исчерпывающий ответ редко укладывался в одно лучшее предложение и соответствующие значения метрик были значительно хуже. Дабы избежать «нераскрытости темы» мы можем отвечать не только лучшим кандидатом в ответы, а несколькими из попавших в топ-3. Это значительно увеличивает качество ответа, в том числе в категориях, где качество ответа одним предложением уже достаточно высокое. И модели, и поиск не идеальны, поэтому периодически лучшим предложением становится не предложение с ответом, а предложение, обозначающее тему и повествующее о ключевом объекте вопроса; в этом случае топ-2- или даже топ-3-предложение, склеенное с такой вводной, формирует хороший ответ.
Однако при таком подходе возникает риск отправить в финальный ответ два одинаковых по смыслу предложения или, что ещё хуже, взаимоисключающие утверждения. Решением этой проблемы занимается отдельная модель, которая по тексту вопроса предсказывает оптимальную стратегию формирования ответа.
Примеры вопросов для разных стратегий (формулировки пользовательские):
Топ-1 кем была построена пизанская башня кто построил зимний дворец как стирать носки кто придумал штаны кто открой америку кто придумал систему координат кто такой рентген где изобрели антибиотик когда создали интернет | Склейка (топ-1 — топ-3) что ну какая нужна канцелярия для девятого класса нужно наше время куда пойти где развлечься какие квартиры сдают в аренду в барселоне какие картинки можно нарисовать стилусом какие нововведения есть вконтакте какие бывают виды фоновых салатов в общем разносят какие то подарки и какие и какие то для взрослых какие бывают борщи супов а сейчас какие строят диваны |
Предобучение моделей
Все QA-модели, упомянутые в статье, предобучались. Такой вот примерно путь предобучения усредненный, потому что вариантов масса (c).
Сначала все модели учатся на common crawl-данных на базовые задачи: MLM и NLU.
Модели предобучаются на задачи ранжирования на размеченных датасетах поиска — предсказывают релевантность пар «запрос из поиска» + «текст из заголовка или тела страницы».
Модели предобучаются на наборах данных типа SQuAD для выделения спана в тексте.
Модели окончательно учатся классифицировать тексты на разметках качества ответов, либо на hard/soft-метках большой модели.
Эволюция пайплайна
Выше вкратце обрисована одна из ранних версий системы ответов на вопросы. Разумеется, будучи однажды отправленной в production она не остановилась в развитии. Регулярная разметка данных позволяет собирать датасеты для улучшения поиска и моделей ответов. Более быстрые рантаймы и более быстрые карточки снижают требования к скорости, а также позволяют расширить зону поиска ответа с 10 до большего количества документов на 1 запрос.
Однако важно не упускать из виду возможности по наращиванию качества, не связанного с production-инфраструктурой и бо̒льшим количеством обучающих данных.
Какие есть проблемы у описанной выше схемы? Маленькие модели ограничены по ёмкости и не могут в рамках фиксированной задачи расти по качеству так же эффективно, как растёт большая модель, если ей дать больше хорошо размеченных данных. Что можно сделать:
Увеличить качество маленьких моделей при фиксированном качестве большой модели.
Увеличить скорость работы моделей в пайплайне, чтобы впихнуть в runtime модель побольше.
Увеличить качество большой модели при постоянном качестве разметок.
Ансамбль вместо исходной большой нейронки
С последним пунктом всё относительно ясно. Можно пойти путём воина и изобретать новый класс моделей. А можно взять более эффективную pretrain-модель для оффлайн-модели, она будет либо больше, либо эффективнее при тех же «размерах». Например, различные T5, GPT, DeBERTa и AlBERTa архитектуры размером XL и XXL.
Во-вторых, обучив каждую из вышеперечисленных pretrain-моделей можно выходные предсказания моделей накрыть градиентным бустингом, и тем самым взять всё самое лучше от всех моделей (см. staking/blending). Получившуюся конструкцию дистиллировать в модели, которые могут быть внедрены на конкретном виде железа.
Переход к ранжированию
Можно заметить, что первые модели, участвующие в отборе кандидатов, не решают, нужно ли показывать ответ. Их задача — поднимать в топ хорошие ответы и отправлять на дно плохие, то есть ранжировать. А значит, можно уйти от классификационной постановки и перейти напрямую к решению задачи ранжирования. Это позволяет повысить качество работы нижних моделей.
Шаринг Query-эмбединга
Если присмотреться к работе самой слабой модели «на мешке эмбедингов», то можно заметить, что изначально представление запроса считается несколько раз. Давайте считать его один раз. Но если это делать исключительно в маленькой модели, то мы не получим значительного роста производительности и никак не повлияем на качество.
Как можно повлиять на качество в самой маленькой модели? Если в ней используется одно и то же представление запроса для самых разных потенциальных ответов, то можно попробовать сделать его максимально качественным. Для этого возьмём самую большую из доступных моделей и научим её решать задачу ранжирования пар вопрос-ответ, но не в режиме cross-encoder’а (классический трансформер, в котором два текста соединяются через токен-разделитель), а dual-encoder’ом (сиамская сеть, dssm: запрос и ответ подаются отдельно, а мерой релевантности является скалярное произведение представлений текстов). Тогда представление запроса из такой модели можно посчитать один раз и подавать его во все интересующие нас модели.
На практике получилось, что средняя сеть в режиме dual-encoder’а вместе с эмбедингом запроса из большой модели работала лучше, чем средняя модель в режиме cross-encoder’а. А время, потраченное на многократное вычисление эмбеддинга запроса в первых двух моделях, покрывает временны̒е издержки от использования большого query-эмбеддера.
С течением времени росло количество данных для обучения всех моделей, и их качество плавно росло. В какой то момент самая маленькая модель начала оставлять после фильтрации те же примеры, что и средняя модель. А это значит, что в этот момент средняя модель перестала быть нужной и её можно удалить из пайплайна. Со временем мы и вовсе отказались от использования средней модели, потому что качество маленькой модели с большим эмбедингом запроса удовлетворяло нашим требованиям
В настоящий момент пайплайн выглядит следующим образом:
В начальной точке у нас есть запрос вместе с топом поисковой выдачи, разбитой на отдельные предложения.
Запрос векторизуется большой моделью. Это представление будет использоваться далее для фильтрации совсем нерелевантных предложений. Эта же самая модель дополнительно классифицирует запрос, определяя оптимальное количество предложений в ответе.
Рассчитанное на предыдущем шаге представление используется в простенькой нейронке, представления предложений в которой получены в результате MaxPool’инга по эмбедингам отдельных токенов. Эта нейронка оставляет до 64 предложений, похожих на ответ на исходный вопрос. Нейронка не принимает решение о том, является ли предложение хорошим ответом, она сортирует их по степени «хорошести в качестве ответа».
Финально модель размера roberta-large, обученная как cross-encoder, классифицирует каждую пару вопрос-ответ.
Из трёх лучших предложений и их окружений в тексте формируется ответ, который увидит пользователь.
Итоги
Система ответов на вопросы по вебу за относительно короткое время прошла путь от ответов готовыми поисковыми сниппетами до поиска и формирования собственных ответов, наиболее удовлетворяющих ожиданиям пользователей. Для этого пришлось преодолеть некоторое количество вызовов, применить техники выжимания максимального перфоманса из ML-моделей, рантаймов и железа.