|
--- |
|
tags: Text generation |
|
|
|
license: unlicense |
|
|
|
language: ru |
|
|
|
widget: |
|
- text: "- Как тебя зовут? - Джульетта Мао #" |
|
- text: "- А живешь где? - В поясе астероидов #" |
|
--- |
|
|
|
|
|
## Задача Incomplete Utterance Restoration |
|
|
|
Генеративная модель на основе [sberbank-ai/rugpt3large_based_on_gpt2](https://huggingface.co./sberbank-ai/rugpt3large_based_on_gpt2) для восстановления полного текста реплик в диалоге из контекста. |
|
|
|
Допустим, последние 2 строки диалога имеют вид: |
|
|
|
``` |
|
- Как тебя зовут? |
|
- Джульетта Мао |
|
``` |
|
|
|
Модель позволяет получить полный текст последней реплики, с раскрытыми анафорами, эллипсисами и т.д.: |
|
|
|
``` |
|
Меня зовут Джульетта Мао |
|
``` |
|
|
|
Раскрытая реплика позволяет использовать многие классические инструменты NLP для своей обработки, |
|
включая регулярные выражения, классификаторы интентов и т.д. |
|
|
|
Подробнее о том, какие ситуации и как обрабатываются моделью, смотрите в [конце страницы](#обрабатываемые-ситуации) и в [этом документе](https://huggingface.co./inkoziev/rugpt_interpreter/blob/main/%D0%92%D0%BE%D1%81%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5%20%D0%BF%D0%BE%D0%BB%D0%BD%D1%8B%D1%85%20%D1%80%D0%B5%D0%BF%D0%BB%D0%B8%D0%BA%20%D0%B2%20%D0%B4%D0%B8%D0%B0%D0%BB%D0%BE%D0%B3%D0%B5.pdf). |
|
|
|
## Пример использования |
|
|
|
|
|
``` |
|
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>- Как тебя зовут? |
|
- Джульетта Мао # |
|
``` |
|
|
|
|
|
## Обрабатываемые ситуации |
|
|
|
Модель разрабатывается с прицелом на использование в [чатботе](https://github.com/Koziev/chatbot). Она поддерживает некоторые |
|
типичные ситуации в читчате, которые перечислены далее. |
|
|
|
В примерах после символа ⇒ идет эталонная раскрытая реплика, которую должна сгенерировать модель. |
|
|
|
[Эллипсисы](https://ru.wikipedia.org/wiki/%D0%AD%D0%BB%D0%BB%D0%B8%D0%BF%D1%81%D0%B8%D1%81): |
|
|
|
``` |
|
- Как же тебя зовут, а? |
|
- Меня – Стас, а тебя? ⇒ Меня зовут Стас. Как тебя зовут? |
|
``` |
|
|
|
В редких случаях и главное слово в словосочетании может опускаться, модель попытается его восстановить: |
|
|
|
``` |
|
- Мама, купи мне собаку. |
|
- А ты будешь за ней ухаживать? |
|
- А ты мне здоровую купи. ⇒ купи мне здоровую собаку |
|
``` |
|
|
|
[Анафора](https://ru.wikipedia.org/wiki/%D0%90%D0%BD%D0%B0%D1%84%D0%BE%D1%80%D0%B0_(%D0%BB%D0%B8%D0%BD%D0%B3%D0%B2%D0%B8%D1%81%D1%82%D0%B8%D0%BA%D0%B0)): |
|
|
|
``` |
|
- Ты собак любишь? |
|
- Не люблю я их ⇒ я не люблю собак |
|
``` |
|
|
|
Иногда для раскрытия полной реплики требуется привлечение здравого смысла, модель для этого будет опираться |
|
на статистику претрейна: |
|
|
|
``` |
|
- Мне на голову упала коробка. |
|
- А что в ней было? ⇒ что было в коробке|голове? |
|
``` |
|
|
|
[Гэппинг](https://ru.wikipedia.org/wiki/%D0%AD%D0%BB%D0%BB%D0%B8%D0%BF%D1%81%D0%B8%D1%81#%D0%93%D1%8D%D0%BF%D0%BF%D0%B8%D0%BD%D0%B3_(en:Gapping)): |
|
|
|
``` |
|
- Ты кошек любишь? |
|
- Их – нет ⇒ я не люблю кошек |
|
``` |
|
|
|
Сложный гэппинг: |
|
|
|
``` |
|
- В 25 лет вы получаете пенсию? |
|
- Не я - отец. ⇒ Я не получаю пенсию. Отец получает пенсию |
|
``` |
|
|
|
Восстановление необязательного местоименного подлежащего (см. [pro drop](https://en.wikipedia.org/wiki/Pro-drop_language)): |
|
|
|
``` |
|
- Согласна? |
|
- Да ⇒ я согласна |
|
``` |
|
|
|
Модель пытается "читать между строк" и восстанавливать подразумеваемые части реплики: |
|
|
|
``` |
|
- Ты разве ещё не ел? |
|
- Тебя ждал ⇒ я еще не ел. я ждал тебя. |
|
``` |
|
|
|
Отрицания в диалоге: |
|
|
|
``` |
|
- Я не прав? |
|
- Нет. (Да.) ⇒ ты не прав |
|
``` |
|
|
|
Интерпретация не сводится к копированию слов из контекста, иногда модель должна добавить ассоциируемые с ситуацией слова: |
|
|
|
``` |
|
- Как прошли выходные? |
|
- В Простоквашино ездила... ⇒ я на выходных ездила в Простоквашино |
|
``` |
|
|
|
Все вышесказанное может быть в разных сочетаниях одновременно: |
|
|
|
``` |
|
- Где твой кот? |
|
- Жена к ветеринару повезла. ⇒ жена повезла моего кота к ветеринару |
|
- Заболел? ⇒ твой кот заболел? |
|
``` |
|
|
|
Сложные предложения: |
|
|
|
``` |
|
- Я сварила суп, иди ешь. |
|
- Из чего? ⇒ из чего ты сварила суп? |
|
``` |
|
|
|
Замена подлежащего производится, если это улучшает понимание реплики: |
|
|
|
``` |
|
- Как себя чувствует твой попугай? |
|
- Бедняга умер... ⇒ мой попугай умер |
|
``` |
|
|
|
Иногда от реплики остается только наречие, модель будет восстанавливать все остальное: |
|
|
|
``` |
|
- Девушка, а Вы животных любите? |
|
- Очень! ⇒ я очень люблю животных |
|
``` |
|
|
|
Форма сказуемого иногда может меняться из соображений согласованности: |
|
|
|
``` |
|
- Рабинович, как думаете, что будет делать правительство, если завтра население разом бросит курить? |
|
- Таки, поднимут акцизы на алкоголь... ⇒ правительно поднимет акцизы на алкоголь, если завтра население разом бросит курить |
|
``` |
|
|
|
Во всех случаях модель не выдает никакой информации, откуда она взяла подстановку |
|
для замены или заполнения в выходном тексте. На выходе получается просто текст реплики |
|
в том виде, как ее мог бы сказать человек, безо всяких дополнительных отсылок и маркеров: |
|
|
|
``` |
|
- У тебя брат есть? |
|
- Да, есть |
|
- Где он работает? ⇒ Где работает твой брат? |
|
``` |
|
|
|
В данном примере модель никак не сообщит нам, откуда она взяла подстановку “твой брат” для местоимения “он”. |
|
Это сильно упрощает ручную разметку обучающего корпуса и не особо мешает диалоговой системе. |
|
|
|
Во многих случаях модель приводит порядок слов к более-менее каноническому. Точнее говоря, она старается |
|
выдать текст с таким порядком слов, который обычно используют носители языка в данном контексте диалога. |
|
Если русскоговорящие предпочитают OVS вместо формального SVO, то модель будет выдавать именно OVS: |
|
|
|
``` |
|
- У тебя штрафы были? |
|
- Нет, их никогда не было ⇒ у меня никогда не было штрафов |
|
``` |
|
|
|
Модель обычно вставляет личные местоимения, даже если форма глагола позволяет обойтись без них: |
|
|
|
``` |
|
- Жару любишь? |
|
- Ненавижу ее ⇒ я ненавижу жару |
|
``` |
|
|
|
Сложносочиненные ответы разбиваются на отдельные клаузы, чтобы downstream pipeline мог обработать их последовательно: |
|
|
|
``` |
|
- Тебя как зовут? |
|
- Кортана, а тебя как? ⇒ Меня зовут Кортана. Как тебя зовут? |
|
``` |
|
|
|
В качестве контекста можно подавать последние 2 или 3 реплики. Более длинные отношения весьма редки, чтобы ради них усложнять датасет. |
|
Кроме того, во многих случаях достаточно применить модель рекурсивно - подать вместо исходных реплик диалога |
|
результат их раскрытия моделью: |
|
|
|
``` |
|
- Где живешь? |
|
- В Шанхае ⇒ я живу в Шанхае |
|
- Давно? ⇒ ты давно живешь в Шанхае? |
|
- Два года уже ⇒ я уже два года живу в Шанхае |
|
- Как там погода? ⇒ как там погода в Шанхае? |
|
``` |
|
|
|
Последнее, что хочется отметить: модель обучена **только** на диалоговых данных с короткими репликами (читчат). |
|
Она практически не способна раскрывать анафоры в художественных текстах, хотя это не ограничение модели, |
|
а особенность обучающего датасета. |
|
|
|
|
|
### 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 |
|
} |
|
``` |
|
|