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

от автора

rupersonaagent ― это небольшая библиотека для Python с функциями и классами для разработки русскоязычного персонифицированного диалогового агента с динамической долговременной памятью. Плюс в том, что каждый алгоритм можно переиспользовать отдельно для других задач — например, представленные в ней методы оптимизации можно применить для различных генеративных и ранжирующих моделей. Сегодня мы расскажем о нескольких новых модулях из обновления rupersonaagent и посмотрим, как их можно использовать для персонификации и повышения эмоциональности ответов диалогового агента.

Подробнее о rupersonaagent мы писали в нашей прошлой статье на Хабре. В целом библиотека предоставляет разные возможности для работы с генеративными моделями и анализа текстовых данных. Например, в ней реализованы методы предобработки и автоматического извлечения информации о персоне из диалоговых данных, что позволяет эффективно анализировать текстовые взаимодействия. Также доступны модули, специализирующиеся на выявлении особенностей письменной речи в зависимости от профессии, и реализованы персонифицированные BERT модели для более глубокого понимания контекста.

Кроме того, rupersonaagent предлагает методы дистилляции моделей и оптимизации ― это помогает улучшать производительность при использовании больших моделей. Также присутствуют лингвистические правила для извлечения информации из диалогов. Модуль для работы с информацией позволяет обучать модели, которые могут интегрировать внешние знания, а собранные датасеты по профессиям служат источником знаний для долговременной памяти.

В чем проблема

В области обработки естественного языка и исследований диалога сегодня уже удалось достичь немалого: самый яркий пример ― разработка GPT, BERT моделей и их производных, которые способны генерировать текст, анализировать и понимать содержание на высоком уровне. Эти модели были обучены на огромных объемах данных и могут выполнять различные задачи, в том числе перевод, суммирование, создание контента и даже ведение диалогов. Но несмотря на это, еще остается ряд серьезных проблем.

Среди них ― отсутствие у диалоговых агентов способности к эмоциональной эмпатии, неадекватные и неуместные ответы в эмоционально насыщенных контекстах, а также неспособность учитывать эмоциональное состояние пользователя на протяжении длительного взаимодействия. Также современные диалоговые агенты иногда генерируют бессвязные и противоречивые ответы в диалоге ― это вызвано отсутствием консистентной персоны диалогового агента.

Мы решили добавить в библиотеку методы, которые помогут решить эти проблемы. Рассказываем, что получилось:

Новые модули

В нашем последнем обновлении rupersonaagent от 30 июля 2024 года мы добавили следующие модули:

  • Модуль распознавания эмоций и тональности сообщений пользователя.

  • Модуль детекции агрессивной̆ речи пользователя.

  • Модуль интерпретации моделей̆ классификации.

  • Модуль аугментации и синтеза эмоциональных и персонифицированных диалоговых данных для русского языка.

  • Модуль модификации ответа персонифицированного диалогового агента на основе информации о его персоне.

  • Модель повышения эмоциональности ответов диалогового агента с учетом контекста диалога.

В этой статье рассмотрим подробно некоторые из них.

Модель повышения эмоциональности ответов диалогового агента с учетом контекста диалога

Данный модуль основан на модели Fusion-in-Decoder.

Fusion-in-Decoder модели могут быть обучены с помощью train_reader.py и протестированы с помощью test_reader.py.

Описание всех возможных параметров доступно в файле options.py

Обучение

train_reader.py предоставляет код для обучения.

Example:

python train_reader.py \         --train_data train_data.json \         --eval_data eval_data.json \         --base_model_path base/model/path \         --per_gpu_batch_size 1 \         --name my_experiment \         --checkpoint_dir checkpoint \ 

Тензоры разного размеры ведут к увеличению затрат памяти. Тензоры, подаваемые на вход Энкодера, имеют фиксированный размер по умолчанию, в отличие от входа Декодера. Размер тензоров на стороне Декодера может быть установлен при помощи --answer_maxlength.

Тестирование

Тестирование моделей происходит при помощи test_reader.py
Тестовыми метриками являются Exact Match (полное совпадение) и BLEU.

Пример:

python test_reader.py \         --base_model_path base/model/path \         --model_path checkpoint_dir/my_experiment/my_model_dir/checkpoint/best_dev \         --eval_data eval_data.json \         --per_gpu_batch_size 1 \         --name my_test \         --checkpoint_dir checkpoint \ 

FiD Agent

FiD Agent это базовый класс, позволяющий использовать обученные модели в качестве диалоговых агентов

Параметры:

model_path — путь до чекпойнта  context_length — сколько последних сообщений хранится в контексте (сообщения бота и пользователя вместе)    text_maxlength — максимальная длина текста, подаваемого на вход модели  (включает в себя последнюю реплику, один факт о персоне и историю диалога).   Если текст слишком длинный, он обрезается с правой стороны.    device — cpu или gpu 

Методы:

def set_persona(self, persona: List[str]):     # установка списка фактов о персоне  def clear_context(self):     # очистка истории диалога   def set_context_length(self, length: int):     # изменение параметра context_length и обрезка истории диалога соответственно  def chat(self, message: str) -> str:     # передача одного сообщение модели и получение ответа в виде строки 

Минимальный рабочий пример:

from rupersonaagent.fidagent import FiDAgent  #Создаем объект класса агента, передавая ему путь до обученной модели model_path = "path/to/your/model" agent = FiDAgent(model_path=model_path,context_length=7,text_maxlength=200,device="cuda:0")  #Определяем набор фактов о персоне и передаем его агенту persona = ["Я аспирант", "Мне 25 лет", "Грусть"] agent.set_persona(persona)  #Отправка и получение сообщения message = "Привет, как дела?" response = agent.chat(message) print(response) 

Данные

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

The expected data format is a list of entry examples, where each entry example is a dictionary in the following format Ожидаемый формат данных это список в формате JSON, каждый пример в котором выглядит следующим образом:

Пример данных:

{          'id': '0',          'question': 'Последняя реплика',          'target': 'Ожидаемый ответ',          'answers': ['повторяет target'],          'ctxs':          [                  {                          "title": "Факт_о_персоне_1",                          "text": "История диалога"                  },                  {                          "title": "Факт_о_персоне_2",                          "text": "История диалога”                 }         ]  } 

Так как диалог состоит из последовательных реплик, то для диалога длины N реплик необходимо создать N подобных примеров.

Обработка данных

Обработка данных для датасета rupersonachat может быть воссоздана с помощью persona_chat_preprocess.ipynb

Методы:

def merge_utts(utts: List[str]) -> List[str]:     # Сливает последовательные реплики одного пользователя в одну  def clean_dialogue(dialogue: str) => List[str]:     # Обрабатывает диалог и разбивает его на отдельные реплики    def clean_persona(persona: str) -> List[str]:     # Обрабатывает описание персоны и бьет его на отдельные факты    def preprocess(ds: DataFrame, bot_prefix: str, user_prefix: str) -> List[Dict]:     # Принимает на вход pandas DataFrame и возвращает список обработанных примеров 

Пример:

# Загрузка данных как pandas DataFrame df = pd.read_csv('./TlkPersonaChatRus/dialogues.tsv', sep='\t')  # Обработка data = preprocess(df)  # Сохранение with open('data.json', 'w') as outfile:     json.dump(data, outfile) 

Модуль модификации ответа персонифицированного диалогового агента на основе информации о его персоне

Данный модель базируется на методе RAG (Retrieval Augmented Generation).

Модель ретривера для RAG может быть обучена при помощи train_biencoder.py и протестирована с помощью test_biencoder.py

Обучение

train_biencoder.py предоставляет код для обучения.

Пример:

python src/train_biencoder.py \         --data_path data/toloka_data \         --model_name "cointegrated/rubert-tiny2" \         --max_epochs 3 \         --devices 1 \         --save_path "bi_encoder/biencoder_checkpoint.ckpt" \ 

Тестирование

Тестирование моделей происходит при помощи test_biencoder.py. Тестовыми метриками являются Recall@k и MRR.

Пример:

python src/test_biencoder.py \         --model_name \          --checkpoint_dir bi_encoder/biencoder_checkpoint.ckpt \         --data_path data/toloka_data \ 

Данные

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

Ожидаемый формат данных — два столбца: запрос и кандидат, где запрос содержит историю диалога, а кандидат — следующий ход диалога.

Пример данных:

 DatasetDict({     train: Dataset({         features: ['query', 'candidate'],         num_rows: 209297     })     val: Dataset({         features: ['query', 'candidate'],         num_rows: 1000     })     test: Dataset({         features: ['query', 'candidate'],         num_rows: 1000     }) }) 
{     'query':'dialog_history',     'candidate': 'next_turn' }  {        'query': [         '<p-2> Привет) расскажи о себе',          '<p-2> Привет) расскажи о себе <p-1> Привет) под вкусный кофеек настроение поболтать появилось',          '<p-2> Привет) расскажи о себе <p-1> Привет) под вкусный кофеек настроение поболтать появилось <p-2> Что читаешь? Мне нравится классика'         ],     'candidate': [         '<p-1> Привет) под вкусный кофеек настроение поболтать появилось',          '<p-2> Что читаешь? Мне нравится классика',         '<p-2> Я тоже люблю пообщаться'         ] } 

Для экспериментов использовался датасет Toloka Persona Chat Rus. В качестве модели для обучения использовалась rubert-tiny2. LLM model — saiga_mistral_7b_gguf

Предварительная обработка данных проводилась с помощью data_processing.ipynb

Факты о персоне

Факты о персоне были загружены в векторную базу данных FAISS при помощи data_storage.py

Пример взаимодействия с диалоговым агентом

Можно пообщаться с моделью, используя demo.py

gradio demo.py  

При запуске команды, открывается ссылка с интерфейсом для общения с агентом, для того, чтобы установить персону в demo.py можно изменить переменную persona в классе ChatWrapper()

Модуль детекции агрессивной̆ речи пользователя.

Методы

  • train_ngram_attention.py — обучение и валидация NgramAttention модели;

  • train_ddp_ngram_attention.py — обучение NgramAttention модели на gpu в распределенной установке. Рекомендуется к использованию, так как процесс обучения достаточно трудоемкий;

  • train_bert.py — обучение BERT модели;

  • fusion.py — объединение BERT с NgramAttention для лучшего качества.

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

Данные должны быть представлены в виде файла csv с двумя столбцами: «comment, label и храниться в каталоге out_data. Пример набора данных можно найти в том же каталоге.

Использование

Обучение NgramAttention модели на cpu:

python -m hate_speech.train_ngram_attention --mode train 

Обучение NgramAttention модели на gpu:

python -m hate_speech.train_ddp_ngram_attention 

Скорость обучения, размер пакета и количество эпох можно указать с помощью опций --learning_rate, --batch_size, --total_epochs. Все параметры скрипта можно найти в train_ngram_attention.py или train_ddp_ngram_attention.py в случае распределенного обучения.

Оценка NgramAttention модели:

python -m hate_speech.train_ngram_attention --mode test 

Обучение и оценка BERT модели:

python -m hate_speech.train_bert 

Обучение и оценка объединенной модели:

python -m hate_speech.fusion 

Используя новые модели библиотеки rupersonaagent, нам удалось успешно разработать персонифицированный эмоциональный диалоговый агент, интегрировав ряд модулей, направленных на распознавание и интерпретацию эмоциональной окраски письменной речи. Также реализованные в библиотеки модули позволили нашему диалоговому агенту классифицировать эмоции, адаптировать свои ответы в зависимости от эмоционального состояния пользователя и заданной эмоции. Это помогло сделать взаимодействие более глубоким и персонализированным.


ссылка на оригинал статьи https://habr.com/ru/articles/831384/