Задача Incomplete Utterance Restoration

Генеративная модель на основе sberbank-ai/rugpt3large_based_on_gpt2 для восстановления полного текста реплик в диалоге из контекста.

Допустим, последние 2 строки диалога имеют вид:

- Как тебя зовут?
- Джульетта Мао

Модель позволяет получить полный текст последней реплики, с раскрытыми анафорами, эллипсисами и т.д.:

Меня зовут Джульетта Мао

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

Подробнее о том, какие ситуации и как обрабатываются моделью, смотрите в конце страницы и в этом документе.

Пример использования

Данная модель работает в прототипе диалоговой системы. Она не требует для работы никакой "обвязки", пре- или постпроцессинга, помимо стандартных для моделей семейства GPT, поэтому использовать ее очень просто:

import torch
from transformers import AutoTokenizer, AutoModelForCausalLM


device = "cuda" if torch.cuda.is_available() else "cpu"
model_name = "inkoziev/rugpt_interpreter"
tokenizer = AutoTokenizer.from_pretrained(model_name)
tokenizer.add_special_tokens({'bos_token': '<s>', 'eos_token': '</s>', 'pad_token': '<pad>'})
model = AutoModelForCausalLM.from_pretrained(model_name)
model.to(device)
model.eval()

# На вход модели подаем последние 2-3 реплики диалога. Каждая реплика на отдельной строке, начинается с символа "-"
# В конце добавляем символ "#"
input_text = """<s>- Как тебя зовут?
- Джульетта Мао #"""
#input_text = """<s>- Что Предтечи забрали у Предшественников?
#- Они узурпировали у них Мантию — защиту всего живого в галактике #"""

encoded_prompt = tokenizer.encode(input_text, add_special_tokens=False, return_tensors="pt").to(device)

output_sequences = model.generate(input_ids=encoded_prompt, max_length=100, num_return_sequences=1, pad_token_id=tokenizer.pad_token_id)

text = tokenizer.decode(output_sequences[0].tolist(), clean_up_tokenization_spaces=True)[len(input_text)+1:]
text = text[: text.find('</s>')]
print(text)

Формат входных данных

На вход модели подается результат токенизации для текста, составленного из 2 или 3 последних реплик диалога. Первым токеном должен быть <s>. Каждая реплика должна начинаться префиксом "- ". Реплики разделяются символом перевода строки. К последней реплике, которая будет раскрываться, добавляется подстрока " #".

<s>- Как тебя зовут?
- Джульетта Мао #

Обрабатываемые ситуации

Модель разрабатывается с прицелом на использование в чатботе. Она поддерживает некоторые типичные ситуации в читчате, которые перечислены далее.

В примерах после символа ⇒ идет эталонная раскрытая реплика, которую должна сгенерировать модель.

Эллипсисы:

- Как же тебя зовут, а?
- Меня – Стас, а тебя?  ⇒ Меня зовут Стас. Как тебя зовут?

В редких случаях и главное слово в словосочетании может опускаться, модель попытается его восстановить:

- Мама, купи мне собаку.
- А ты будешь за ней ухаживать?
- А ты мне здоровую купи.  ⇒ купи мне здоровую собаку

Анафора:

- Ты собак любишь?
- Не люблю я их  ⇒ я не люблю собак

Иногда для раскрытия полной реплики требуется привлечение здравого смысла, модель для этого будет опираться на статистику претрейна:

- Мне на голову упала коробка.
- А что в ней было?  ⇒ что было в коробке|голове?

Гэппинг:

- Ты кошек любишь?
- Их – нет  ⇒  я не люблю кошек

Сложный гэппинг:

- В 25 лет вы получаете пенсию?
- Не я - отец.  ⇒  Я не получаю пенсию. Отец получает пенсию

Восстановление необязательного местоименного подлежащего (см. pro drop):

- Согласна?
- Да  ⇒ я согласна

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

- Ты разве ещё не ел?
- Тебя ждал  ⇒  я еще не ел. я ждал тебя.

Отрицания в диалоге:

- Я не прав?
- Нет. (Да.) ⇒ ты не прав

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

- Как прошли выходные?
- В Простоквашино ездила...  ⇒  я на выходных ездила в Простоквашино

Все вышесказанное может быть в разных сочетаниях одновременно:

- Где твой кот?
- Жена к ветеринару повезла.  ⇒ жена повезла моего кота к ветеринару
- Заболел?  ⇒  твой кот заболел?

Сложные предложения:

- Я сварила суп, иди ешь.
- Из чего?  ⇒  из чего ты сварила суп?

Замена подлежащего производится, если это улучшает понимание реплики:

- Как себя чувствует твой попугай?
- Бедняга умер...   ⇒   мой попугай умер

Иногда от реплики остается только наречие, модель будет восстанавливать все остальное:

- Девушка, а Вы животных любите?
- Очень!  ⇒ я очень люблю животных

Форма сказуемого иногда может меняться из соображений согласованности:

- Рабинович, как думаете, что будет делать правительство, если завтра население разом бросит курить?
- Таки, поднимут акцизы на алкоголь...  ⇒ правительно поднимет акцизы на алкоголь, если завтра население разом бросит курить

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

- У тебя брат есть?
- Да, есть
- Где он работает?  ⇒ Где работает твой брат?

В данном примере модель никак не сообщит нам, откуда она взяла подстановку “твой брат” для местоимения “он”. Это сильно упрощает ручную разметку обучающего корпуса и не особо мешает диалоговой системе.

Во многих случаях модель приводит порядок слов к более-менее каноническому. Точнее говоря, она старается выдать текст с таким порядком слов, который обычно используют носители языка в данном контексте диалога. Если русскоговорящие предпочитают OVS вместо формального SVO, то модель будет выдавать именно OVS:

- У тебя штрафы были?
- Нет, их никогда не было ⇒ у меня никогда не было штрафов

Модель обычно вставляет личные местоимения, даже если форма глагола позволяет обойтись без них:

- Жару любишь?
- Ненавижу ее  ⇒ я ненавижу жару

Сложносочиненные ответы разбиваются на отдельные клаузы, чтобы downstream pipeline мог обработать их последовательно:

- Тебя как зовут?
- Кортана, а тебя как?  ⇒  Меня зовут Кортана. Как тебя зовут?

В качестве контекста можно подавать последние 2 или 3 реплики. Более длинные отношения весьма редки, чтобы ради них усложнять датасет. Кроме того, во многих случаях достаточно применить модель рекурсивно - подать вместо исходных реплик диалога результат их раскрытия моделью:

- Где живешь?
- В Шанхае  ⇒ я живу в Шанхае
- Давно?   ⇒  ты давно живешь в Шанхае?
- Два года уже  ⇒ я уже два года живу в Шанхае
- Как там погода?  ⇒ как там погода в Шанхае?

Последнее, что хочется отметить: модель обучена только на диалоговых данных с короткими репликами (читчат). Она практически не способна раскрывать анафоры в художественных текстах, хотя это не ограничение модели, а особенность обучающего датасета.

Пример работы в чате

Первый столбец содержит реплики диалога модели читчата с собой, второй столбец - результат раскрытия реплик моделью интерпретатора:

- Добрый вечер, бро!                               |  
- Чё, будем общаться?                              |  Мы будем общаться?
- Ага, а как же                                    |  Мы будем общаться
- О чем хочешь говорить?                           |  О чем ты хочешь говорить?
- Давай о чем-нибудь хорошем                       |  Я хочу говорить о чем-нибудь хорошем
- Мне нравится обсуждать компьютерные игры         |  Мне нравится обсуждать компьютерные игры
- О, компьютерные игры меня тоже интересуют        |  Меня тоже интересуют компьютерные игры
- Ты играл в Minecraft?                            |  Ты играл в Minecraft?
- Неа, но хотел бы                                 |  Я не играл в игру Minecraft. Я хочу поиграть в игру Minecraft.

Датасет

Обучающие данные без аугментации: inkoziev/incomplete_utterance_restoration.

Контакты

Если у Вас есть какие-то вопросы по использованию этой модели, или предложения по ее улучшению - пишите мне [email protected]

Citation:

@MISC{rugpt_interpreter,
    author  = {Ilya Koziev},
    title   = {Incomplete Utterance Restoration in Russian Chit-Chat conversations},
    url     = {https://huggingface.co/inkoziev/rugpt_interpreter},
    year    = 2022
}
Downloads last month
45
Inference Examples
This model does not have enough activity to be deployed to Inference API (serverless) yet. Increase its social visibility and check back later, or deploy to Inference Endpoints (dedicated) instead.

Dataset used to train inkoziev/rugpt_interpreter