GenerativeChatBot / README_Ru.md
StKirill's picture
Update README_Ru.md
994f258 verified
# Введение
В этом репозитории методы обработки естественного языка (NLP) используются для изучения стиля речи Рейчел из сериала "Друзья", проведения мультиязыкового анализа английского языка и обучения нейронной сети общению в стиле Рейчел.
Перенос стиля очень популярен в НЛП и сейчас используется в самых разных сферах, от образования до персонализации электронных помощников. А с развитием больших моделей-трансформеров, которые демонстрируют выдающиеся способности в понимании естественного языка и имитации самых разных стилей, передача стиля вышла на новый уровень. Сегодня большие языковые модели, такие как GPT3, благодаря своим объемам и миллиардам параметров способны идеально изучить все особенности обучающей выборки (т. е. обучить распределению) и сгенерировать реалистичный текст в определенном стиле.
В этом посте я исследую возможности языковых моделей для генерации текста в стиле Рейчел из знаменитого сериала "Друзья". Для этого используется корпус английских транскриптов сериала, который был собран для поиска чатбота и обучения двуязычных моделей для общения в стиле Рейчел Грин.
Кроме того, я провела анализ стиля, изучила особенности речи Рейчел.
Таким образом, проект можно условно разделить на 3 части:
* Cбор данных
* Стилистический анализ речи персонажей
* Фреймворк для обучения моделей, которые пишут текст в стиле Рейчел.
Весь код можно найти в этом репозитории HF.
# Данные
## Выбор персонажа
Я решил продолжить использовать сериал, на котором остановился в предыдущем проекте, ситком "Друзья", который шел с 1994 по 2004 год. Несмотря на свой возраст, он остается популярным и по сей день. Этот комедийный сериал рассказывает о жизни шести друзей (Росс, Фиби, Моника, Рейчел, Джоуи и Чендлер), которые живут в Нью-Йорке и постоянно попадают в какие-то неприятности и забавные ситуации. Почему мы выбрали именно этот сериал? По трем причинам:
1. Я нашел в открытом доступе расшифровки 236 эпизодов. Это очень много данных, которые я могу использовать для обучения языковой модели.
2. В сериале есть диалоги не одного, а целых шести персонажей, что открывает мне возможности для сравнительного анализа
3. Это популярный сериал, который многие из нас смотрели и хорошо знают. Это значит, что я могу сделать предположения о данных (например, Фиби говорит более простыми словами и т. д.) и оценить реалистичность стиля сгенерированного текста, основываясь на своем опыте просмотра.
## Сбор данных
Оригинальные транскрипты, которые я взял из Интернета, были на английском языке. Затем я выполнил следующую предварительную обработку текста:
1. Во-первых, я очистил данные от мелких графемных ошибок, характерных для транскриптов. Например, если персонаж говорил что-то длинное, его слова могли содержать повторы гласных для имитации длинного звука ("nooooooooooooooooooooooooooooooooooooooooooooooooo").
2. Во-вторых, я заметил, что некоторые слова содержат повторы одного и того же слова для комичности. Я также удалял такие повторы, оставляя только одну копию повторяющегося слова.
3. В-третьих, поскольку я хотел передать стиль, присущий каждому персонажу, я отбросил общие фразы, используемые всеми 6 главными героями ("Знаете что!", "О Боже!" и т. д.).
Таким образом, я собрал корпус диалогов для 6 персонажей, включающий около 8 тысяч предложений для каждого персонажа. Подробное распределение по количеству предложений для каждого персонажа вы можете увидеть в таблице ниже:
!["Number of replicas for every character"](./images/NumberOfReplicasOverCharacter.png)
### Анализ данных
Количество реплик для всех сезонов показано ниже:
!["Number of replicas for every character"](./images/NumberOfReplicasOverSeason.png)
Как видно, среднее значение количества реплик за все сезоны составляет 6000 при стандартном отклонении около 400.
Количество реплик для всех эпизодов показано ниже:
!["Number of replicas for all seasons"](./images/NumberOfReplicasInEpisode.png)
Как видно, среднее значение количества реплик в эпизоде составляет 265. Стандартное отклонение составляет около 65 реплик.
Самые частые слова в наборе данных:
!["Number of replicas for episode"](./images/MostFrequentWords.png)
# Анализ стилей персонажей
Прежде чем обучать языковые шаблоны, я исследовал стилевые особенности Рэйчел. В частности, чтобы определить особенности речи, я сделал следующее:
* Подсчитал описательную статистику: количество слов, среднее количество слов в предложении, индекс читабельности, доля сложных слов и т. д.
* Наиболее частотные слова для персонажей;
* Доля положительных и отрицательных слов.
Исходя из приведенного сюжета, можно сделать предварительные выводы о специфике речи персонажей. Например, Росс и Рейчел самые разговорчивые, у них максимальное количество предложений.
После такого первичного анализа речи я более детально исследовала словарный запас и проанализировала его с точки зрения сложности слов, используемых персонажами. За "трудные" слова мы условно приняли длинные слова, состоящие более чем из 4 слогов. Долю сложных слов для каждого персонажа можно увидеть на графике ниже:
## Самые частые слова Рейчел
Я провел анализ наиболее частотных слов Рейчел, исключив стоп-слова из nltk.stopwords("english"). Результат этого анализа показан ниже.
!["Most frequent Rachel's words"](./images/RachelMostFrequentWords.png)
Или эти данные можно представить в виде изображения
!["Most frequent rachel's words in image"](./images/RachelWords.png)
# Подготовка данных
Итак, мы собрали фразы Рейчел и разделили их на два набора данных: реплики и фразы. Для целей моделирования мы снабдили все реплики дополнительным набором лексем и тегов:
Специальные лексемы <s> и </s>, обозначающие начало и конец примера.
Имя персонажа пишется заглавными буквами.
Специальный псевдоним NOTFRIEND, который являлся маркером реплики другого говорящего в диалоговых парах "реплика НЕФРИЕНДА - ответ ГЕРОЯ". Мы использовали такой псевдоним, чтобы отделить чужие реплики от героя, чьему стилю мы хотим подражать.
Используя данные с дополнительными лексемами, я создал два набора данных для Рейчел на английском языке. Ниже приведено краткое описание каждого из них:
1. Сырые монологи - набор данных, содержащий отдельные реплики одного из персонажей. Этот набор данных позволяет модели получить максимум информации о стиле конкретного персонажа.
!["raw monologues"](./images/phrases.png)
2. Необработанные диалоги - набор данных, содержащий пары "реплика НЕдруга - ответ ГЕРОя", разделенные символом переноса строки \n. Набор данных диалогов необходим, потому что мы хотим, чтобы наша модель могла поддерживать разговор с пользователем в стиле Friends, а не просто генерировать текст.
!["raw dialogs"](./images/replicas.png)
# Обучение
## Архитектура модели GPT2
Архитектура модели GPT-2 (Generative Pre-trained Transformer 2) основана на трансформерной архитектуре, предложенной в статье "Attention is All You Need" от Vaswani et al. (2017). Однако, GPT-2 представляет собой усовершенствование и расширение этой базовой архитектуры. Вот основные компоненты архитектуры GPT-2:
1. **Stacked Transformer Decoder Layers**: GPT-2 состоит из нескольких блоков трансформера, где каждый блок представляет собой "слой декодера". Каждый слой декодера включает в себя множество механизмов внимания и нормализацию LayerNorm.
2. **Multi-Head Self-Attention Mechanism**: Этот механизм позволяет модели сосредотачиваться на различных частях входных данных и извлекать их взаимосвязи. В GPT-2 используется множество "голов" внимания, которые позволяют модели фокусироваться на разных аспектах данных.
3. **Feed-Forward Neural Networks**: Каждый блок трансформера содержит также набор полносвязных слоев (feed-forward networks), которые применяются к выходу из слоев внимания.
4. **Positional Encoding**: Для того чтобы модель могла учитывать порядок слов в последовательности, в GPT-2 используется позиционное кодирование, которое добавляет информацию о позиции каждого слова в последовательности.
5. **Layer Normalization**: Нормализация слоев (LayerNorm) применяется после каждого слоя в трансформере для стабилизации обучения.
6. **Residual Connections**: В GPT-2 используются связи прямого распространения (residual connections), которые позволяют более эффективно передавать градиенты в глубоких нейронных сетях.
7. **Position-wise Feedforward Networks**: Полносвязные сети применяются к каждой позиции в последовательности независимо, что позволяет модели лучше захватывать локальные зависимости.
Архитектура GPT-2 представляет собой стек этих блоков, причем количество блоков и их размер могут варьироваться в зависимости от размера модели. Например, оригинальная модель GPT-2 имеет 12 слоев декодера для маленьких версий и до 48 слоев для самых крупных версий.
Для обучения модели передачи стиля Рейчел чатботу я использовал несколько моделей. Обучение моделей проходит в два этапа. На первом этапе модель пытается уловить личность Рейчел и изучает ее монологи. На втором этапе модель пытается узнать, как Рейчел ведет себя в диалогах, поэтому на этом этапе модель обучается на диалогах.
В данной работе было обучено 3 модели из четырёх: GPT-2-small, GPT-2-medium, GPT-2-large
!["gpt2-models"](https://jalammar.github.io/images/gpt2/gpt2-sizes.png)
Архитектура GPT-2 в зависимости от размера модели представленна на рисунке ниже:
!["gpt2-models"](https://jalammar.github.io/images/gpt2/gpt2-sizes-hyperparameters-3.png)
1. Первый этап - GPT2. Для наборов данных я использовал TextDataset от PyTorch и библиотеку трансформаторов от huggingface.
Результаты показаны на изображении ниже
!["gpt2-results"](./images/gpt2-results.png)
2. Вторая модель - GPT2-medium. Результаты обучения на монологах показаны ниже
!["gpt2-medium-mono-train"](./images/gpt2-medium-mono-train.png)
Обучение диалогам показано на следующем изображении
!["gpt2-medium-mono-train"](./images/gpt2-medium-replics-train.png)
Результат обучения показан ниже
!["gpt2-medium-results"](./images/gpt2-medium-results.png)
2. Последняя модель - GPT2-large. Обучение на монологах показано ниже
!["gpt2-large-mono-train"](./images/gpt2-large-mono-train.png)
Обучение диалогам показано на следующем изображении
!["gpt2-large-mono-train"](./images/gpt2-large-replics-train.png)
Результат обучения показан ниже
!["gpt2-large-results"](./images/gpt2-large-results.png)
### Генерация текста
После обучения, модель собирается в pipeline
```python
chef = pipeline('text-generation', model="./models/en_gpt2-large_rachel_replics", tokenizer=model_type)
```
Для генерации текста используется следующая команда
```python
out = model.generate(inpt.cuda(),
max_length=50,
repetition_penalty=5.0,
do_sample=True,
top_k=5,
top_p=0.95,
temperature=1)
```
,где
1. **max_length=50**: Этот параметр задает максимальную длину генерируемого вывода. В данном случае он равен 50 лексемам.
2. **repetition_penalty=5.0**: Этот параметр наказывает модель за повторение одного и того же токена в выводе. Более высокое значение увеличивает наказание за повторение лексем, что потенциально может привести к более разнообразным выводам.
3. **do_sample=True**: Этот параметр указывает, использовать ли выборку при генерации. Если `True`, модель будет делать выборку из своего выходного распределения для генерации текста, что приведет к более разнообразным результатам.
4. **top_k=5**: Этот параметр определяет количество лексем, которые будут рассматриваться для выборки на основе их вероятностей. Он ограничивает выборку k лексемами с наибольшей вероятностью.
5. **top_p=0.95**: Этот параметр, также известный как выборка по ядрам, управляет порогом кумулятивной вероятности для выборки по ядрам. Он ограничивает выборку подмножеством лексем, чья кумулятивная вероятность превышает этот порог.
6. **temperature=1**: Этот параметр масштабирует логиты перед применением softmax во время выборки. Более высокая температура приводит к большей случайности в генерируемом тексте.
Overall, this code snippet generates text using a GPT-2 model with the specified input prompt and generation parameters, producing diverse and contextually relevant outputs.
# Архитектура
- PrepareData.ipynb <- Парсер данных из Интернета, очистка, токенизация и подготовка к набору данных
- train_data <- папка datasets с монологами и диалогами
- Training_gpt2_medium.ipynb <- обучение gpt2-medium
- en_gpt2-medium_rachel_replics <- модель gpt2-medium
- Training_gpt2_large.ipynb <- тренировка gpt2-large
- en_gpt2-large_rachel_replics <- gpt2-large модель
- images <- изображения для README.md
- app.py <- основной файл
- requirements.txt <- необходимые библиотеки
# Заключение и планы на будущее
Итак, я использовал методы обработки естественного языка для изучения стиля речи Рейчел из известного сериала "Друзья", провел мультиязычный анализ для английского языка и обучил языковые модели на основе GPT говорить в стиле Рейчел.
В будущем я хочу поэкспериментировать с еще более крупными моделями. Например, с LLama, а также с методами генерации управляемого текста для них.