Поскольку Colab был медленным, я обновился до Pro. Каждый лимерик стоил мне десять центов.

В марте 2022 года я исследовал использование ИИ для написания стихов с определенным размером для моей Статьи о глубоком хайку. Для этого проекта я обучил языковую модель GPT-J [1] обращать внимание на количество слогов во фразах для создания коротких стихотворений на заданную тему. Умение модели писать прозу с помощью рифм я не взял. Для этого проекта под названием Deep Limericks я провел последний месяц, исследуя и обучая модель GPT-J писать лимерики, обращая внимание на метр и рифму. Вот пример вывода по теме футбол:

Ты вратарь, это твое имя.
Ты последняя линия обороны в этой игре.
Ты лучший в своей команде.
Ты тот, кто должен кричать.
Когда остальные одиннадцать игроки целятся.
- Deep Limericks

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

В этой статье я расскажу об ограничениях использования языковых моделей для написания рифмованных стихов и обсужу некоторые предшествующие работы в этой области. Я дам обзор системы Deep Limericks с подробным описанием компонентов. Я закончу, показав некоторые результаты и обсудив возможные следующие шаги.

Не забудьте проверить приложение для получения дополнительных результатов. И вы можете создавать свои собственные лимерики с помощью Google Colab здесь.

Фон

Происхождение лимерикской формы неизвестно, но ее часто связывают с происхождением из города Лимерик, Ирландия [2][3]. Одним из первых сборников лимериков является «Анекдоты и приключения пятнадцати джентльменов» [4] английского иллюстратора и поэта Эдварда Лира, изданный в 1821 году. Вот пример из книги.

Портной, который отплыл из Квебека,
В бурю однажды поднялся на палубу,
Но морские волны,
Были так сильны, как только могли быть,
И он упал по шею.
- Эдвард Лир

Лимерик Форма

Как описывает Макси Брук в своей статье Limerick-Gimerck [3], «лимерик — это бессмысленное стихотворение из пяти… строк, из которых строки 1, 2 и 5 трехфутовые и рифмованные, а строки 3 и 4 состоят из двух футов и рифмуются». Где термин «ноги» означает ударные слоги.

Вот классическая форма лимерика:

da DA da da DA da da DA
da DA da da DA da da DA
da DA da da DA da
da DA da da DA da
da DA da da DA da da DA

Подсчитав «дас», вы можете увидеть, что количество слогов в традиционной форме лимерика составляет 8/8/5/5/8. Если вы прокрутите вверх и внимательно посмотрите на сгенерированный «футбольный» лимерик, вы увидите, что ноги не выстраиваются в линию правильно, но в лимерике «Квебек» Лира ноги идеально соответствуют классической форме.

Грязные лимерики

Исторически сложилось так, что тема лимериков часто переходит на территорию с рейтингом R. Например, писатель-фантаст Айзек Азимов написал серию книг [5], наполненных «развратными лимериками». Вот относительно чистый пример.

Однажды ночью яйцеклетка сказала сперматозоиду:
«Ты очень привлекательный молодой зародыш.
Присоединяйся ко мне, мой сладкий,
Пусть наши ядра встретятся
И через девять месяцев мы оба придем к соглашению».
— Айзек Азимов

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

Пачки лимериков смеются анатомически
В космос, который весьма экономичен.
Но хорошие я видел
Так редко бывают чистыми
А чистые так редко комичны.< br /> - Вивьян Холланд

В следующем разделе будет обсуждаться предыдущая попытка создания лимериков с использованием системы ИИ.

Предыдущая работа

В 2021 году пятеро исследователей из Университета Дьюка создали систему искусственного интеллекта, генерирующую лимерики, под названием LimGen [6]. Название статьи: «Жил-был очень плохой поэт, это было автоматизировано, но вы этого не знали». Название может показаться скромным, но, похоже, оно занижает планку результатов.

Их система основана на модели GPT-2 [7] от OpenAI с добавленным кодом для изучения рифмы, ударения и размера. Вот образец из их статьи, сгенерированный с помощью подсказки «деньги».

Был жадный человек по имени Тодд,
Который потерял все свои деньги в мошенничестве.
Когда он вернулся к работе,
Его ограбил его клерк,
И он никогда не мог купить треска.
- LimGen

Вот еще одно использование подсказки «хитрость».

Был волшебник по имени Ник,
Который обманул всю свою семью в фокусе.
Когда он вернулся, чтобы спрятаться,
Его нашла невеста,
И убил волшебным губная помада
- LimGen

Мне эти лимерики кажутся второстепенными. Рифмы хорошие, но ударение и метр немного не те. Проза тоже немного не то, а изюминки плоские. Они скорее странные, чем забавные.

Авторы статьи признают как положительные, так и отрицательные стороны своей системы. Они попросили экспертов сравнить лимерики, созданные людьми и LimGen, и они оценили их по пяти критериям по шкале от 1 до 5 (чем больше, тем лучше).

… хотя экспертная оценка подтверждает, что человеческие поэты превосходят LimGen, она все же показывает, что LimGen работает достойно по нескольким показателям: LimGen имеет достойную грамматику и может хорошо рассказать историю своими стихами. Кажется, что грамматика и рассказывание историй — самые простые поэтические атрибуты для освоения. … Эмоциям и рассудительности научиться труднее. Но что действительно отличает поэтов-людей и LimGen, так это способность поэтов постоянно шутить.
— Jianyou Wang, et al.

Далее я расскажу об основных компонентах Deep Limericks и подробно расскажу о реализации.

Системные компоненты

Вот основные компоненты системы Deep Limericks.

Я начал с набора данных из более чем 60 тысяч лимериков на zenodo.org [8]. Он называется Набор лимериков для вычислительной поэтики и выпущен под лицензией Creative Commons Attribution.

Я подготовил набор данных для многозадачного обучения, сначала извлекая тему из одного или двух слов для каждого лимерика с помощью KeyBERT [9]. Затем я преобразовал лимерики и темы в фонемы, используя Phonemizer [10], чтобы помочь системе обучить размер и рифму. Я отфильтровал лимерики до 55 тысяч, удалив те, которые либо не рифмовались должным образом, либо имели разное количество слогов в строках.

Затем я создал записи для многозадачного обучения, используя темы, лимерики и последние слова в каждой строке, также известные как наборы рифм. Обучающий набор включает как текстовую, так и фонемную версии данных. Я дорабатывал 8-битную модель GPT-J-6B [1] в течение пяти дней с помощью Google Colab Pro+.

Я разработал интерактивную систему генерации лимериков. Вы начинаете с того, что вводите тему, например «футбол», и она производит до 10 наборов рифм, например «игра / имя / команда / крик / цель». После выбора набора рифм система сгенерирует несколько кандидатов на первую строку лимерика, каждый из которых заканчивается словом «игра». Вы выбираете свою любимую строчку и повторяете процесс еще четыре раза, пока пятистрочный лимерик не закончится.

Детали компонентов и процессов обсуждаются в следующих разделах.

Сведения о системе

Набор данных Лимерикс

Я обучил систему на примерах из набора лимериков для вычислительной поэтики (DOLFCP) Алмаса Абдибайе и др. Они выпустили набор данных под лицензией Creative Commons Attribution с открытым исходным кодом. Это коллекция из 65 881 лимерика разной степени качества. Вот пример из набора данных.

Чтобы звуковая волна двигалась, знайте,
что нужна среда, как воздух.
В вакууме нет звука
Можно услышать; они обнаружили
Его проводимость равна нулю. (Ничего там нет.)
- DOLFCP #22519

Вот еще один пример.

"Позвольте мне сходить на блошиный рынок, пожалуйста?
Я никогда не видела таких мест."
Она совершила
грубую ошибку новичка,
вернувшись с большой пакетик с блохами.
- DOLFCP #51951

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

KeyBERT для извлечения ключевых слов

Чтобы заставить новую модель генерировать новые лимерики на основе тем, предоставленных пользователями, я извлек ключевые слова для каждого лимерика в наборе данных и использовал их в обучающих данных. Как и в предыдущих проектах, я использовал KeyBert [9] для извлечения ключевых слов. Вот код Python.

from keybert import KeyBERT
kw_model = KeyBERT()
limerick = """For a sound wave to move, be aware
That a medium’s needed, like air.
In a vacuum no sound
Can be heard; they have found
Its conduction is nil. (Nothing’s there.)"""
keywords = kw_model.extract_keywords(limerick, keyphrase_ngram_range=(1, 2), stop_words=None)
print(keywords[0][0])

Результатом является «звуковая волна» для этого лимерика и «блошиный рынок» для второго примера, показанного выше.

Использование фонемизатора для преобразования текста в фонемы

Чтобы заставить систему обращать внимание на метр и рифму, я обучил систему, используя как текст (также известные как графемы), так и фонемы. Я использовал проект Phonemizer для преобразования лимериков в фонемы в Фестивальном формате, который указывает разрывы слогов. Исходный код здесь.

from phonemizer import phonemize
from phonemizer.separator import Separator
limerick = """For a sound wave to move, be aware
That a medium’s needed, like air.
In a vacuum no sound
Can be heard; they have found
Its conduction is nil. (Nothing’s there.)"""
phonemes = phonemize(limerick, language='en-us',  
  backend='festival',separator=Separator(phone="-", word=' ',
  syllable='|'), strip=True)

Ниже приведен пример лимерика как в графемном, так и в фестивальном фонемном формате.

Чтобы звуковая волна двигалась, знайте,
f-ao-r ax s-aw-n-d w-ey-v t-ax m-uw-v b-iy ax|w-eh-r

Что среда нужна, как воздух.
dh-ae-t ax m-iy|d-iy|ax-m-z n-iy|d-ax-d l-ay-k eh-r

В вакууме нет звука
ih-n ax v-ae|k-y-uw-m n-ow s-aw-n-d

можно услышать; они нашли
dk-ae-n b-iy hh-er-d dh-ey hh-ae-v f-aw-n-d

Его проводимость нулевая. (Ничего там нет.)
ih-t-s k-ax-n|d-ah-k|sh-ax-n ih-z n-ih-l n-ah|th-ax-ng-z dh- э-р

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

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

awесть / воздух / звук / найдено / здесь
топор|w-eh-r / а-р / s-aw-n-d / f-aw-n-d / dh-а-р

Обратите внимание, как по-разному пишутся последние части слогов в графемах в строках 1, 2 и 5. Где фонетическое написание идеально совпадает. Это указание на рифмы.

Я использовал фонетическую форму лимериков, чтобы просеять наборы данных, чтобы включить только записи, которые следуют схеме рифмовки AABBA и строго придерживаются схемы 8/8/5/5/8 для слогов. Результирующий набор данных содержит 55 000 записей вместо 62 000.

Модель генерации языка GPT-J

GPT-J — это модель большого языка с открытым исходным кодом, основанная на коммерческой модели GPT-3 от OpenAI [11]. Он был обучен с использованием The Pile [12], коллекции из 825 гигабайт текста.

Вот список отличий от авторов GPT-J.

Дизайн нашей модели и выбор гиперпараметров очень похожи на 6.7B GPT-3 с некоторыми отличиями. Примечательно,

- Модель обучалась на токенах 400B из датасета The Pile с текстом 800GB.

- Эффективное внимание (линейное, локальное/скользящее окно и т. д.) не использовалось для простоты, так как оно не могло значительно повысить пропускную способность в таком масштабе.

- Размерность каждой головки внимания установлена ​​равной 256, что в два раза больше, чем у ГПТ-3 сопоставимого размера. Это заметно улучшило пропускную способность с минимальным снижением производительности.

- Бен Ван и Адам Комацудзаки [1]

Обратите внимание, что модель GPT-J работает аналогично модели Кюри OpenAI GPT-3, которая является шагом вниз по сравнению с их большой моделью Давинчи. Вы можете бесплатно поэкспериментировать с GPT-J здесь.

Предубеждения и ограничения

Как и большинство больших языковых моделей, GPT-J имеет врожденные предубеждения и ограничения, извлеченные из обучающих данных в The Pile. Об этом пишут авторы модели GPT-J в своей карточке модели.

GPT-J обучался на Pile, наборе данных, который, как известно, содержит ненормативную лексику, непристойные и другие грубые выражения. В зависимости от варианта использования GPT-J может создавать социально неприемлемый текст. …

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

ОК, верно подмечено.

Использование GPT-J для создания лимериков

Сначала я спросил GPT-J, что такое лимерик, и после нескольких попыток он хорошо ответил.

Что такое лимерик?
Лимерик – это стихотворение на английском языке, состоящее из пяти строк и использующее схему рифмовки AABBA. Лимерики обычно пишутся от третьего лица, рассказывают историю и обычно изображают юмористическую ситуацию.

Итак, он знает, что такое лимерик. Но когда я побудил его написать на тему «кофе» без всяких доработок, вот что у меня получилось:

Напишите забавный лимерик на эту тему из пяти строк.
ТЕМА: Кофе
ЛИМЕРИК:
1.
Мужчина пил кофе в кафе
2. Когда бариста увидел его, он
3. Спросил , «Что это?»
4. Мужчина ответил: «Это
5. Смесь из трех бобов»

Это интересное начало истории, но это явно не лимерик. Пришлось дорабатывать модель, чтобы она работала.

Многозадачное обучение

Подобно технике, которую я использовал в своем проекте Deep Haiku, я также использовал многозадачное обучение, чтобы научить GTP-J сочинять лимерики.

Для сравнения, однозадачный подход будет заключаться в том, чтобы обучить систему генерировать лимерики по заданной теме, все в графемной форме. Проблема в том, что система не сможет «увидеть» рифмы и размер, потому что эти функции несколько скрыты в графемах. Благодаря многозадачному обучению я смог одновременно научить систему следующим четырем вещам.

  1. Как преобразовать графемы в фонемы и обратно
  2. Как составить набор рифм на заданную тему
  3. Как написать лимерик в правильной форме, учитывая тему и набор рифм
  4. Как написать лимерик с хорошей грамматикой и юмором, учитывая тему

Я построил восемь строк для обучающих данных для каждого лимерика в отфильтрованном наборе данных. Я использую разные символы для содержания записей, чтобы помочь системе узнать, какая задача является какой. Кроме того, я использую четырехсимвольную строку для обозначения определенных преобразований, например, =T2L= означает тему в лимерик и =G2P= означает графему в фонему. Вот восемь задач.

1. <topic_g =T2L= limerick_g>
2. <topic_g =T2R= limerick_rhymes_g>
3. <limerick_rhymes_g =R2L= limerick_g>
4. (topic_p =T2L= limerick_p)
5. (topic_p =T2R= limerick_rhymes_p)
6. (limerick_rhymes_p R2L= limerick_p)
7. [limerick_g =G2P= limerick_p]
8. {limerick_p =P2G= limerick_g}

Вот пара задач, прописанных для примера лимерика.

<sound wave =T2R= aware / air / sound / found / there>
(s-aw-n-d w-ey-v =T2R= ax|w-eh-r / eh-r / s-aw-n-d / f-aw-n-d / dh-eh-r)

Всего я использовал 438 496 строк в обучающем наборе данных.

Учебный GPT-J

Как только я собрал данные для обучения, я следовал инструкциям здесь, чтобы обучить модель с использованием 8-битных весов. Вот код Python, который я использовал.

from transformers import Trainer, TrainingArguments, AutoModelForCausalLM
training_args = TrainingArguments(
    output_dir="/content/outputs",
    overwrite_output_dir=True,
    num_train_epochs=1,
    evaluation_strategy="steps",
    per_device_train_batch_size=4,
    per_device_eval_batch_size=4,
    eval_steps = 500,
    warmup_steps = 500,
    prediction_loss_only=True,
    save_strategy="no",
    weight_decay=0.01)
trainer = Trainer(
    model=gpt,
    args=training_args,
    train_dataset=lm_datasets['train'],
    eval_dataset=lm_datasets['test'],
    callbacks=[SaveCallback])

Обучение системы с использованием моей подписки Google Colab Pro+ заняло пять дней. Когда обучение было завершено, система могла выполнять все восемь задач, но для создания лимериков, тематических рифм и рифмованных лимериков требовались только две. Изучение остальных шести задач помогло системе хорошо справиться с первыми двумя задачами.

Создание лимерика

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

Набор рифм

Чтобы создать набор рифм, я попросил создать набор из пяти рифм на тему «кофе». Он вернулся со следующими результатами.

topic: coffee
rhyme sets:
------------------------------------
1: drink / think / ice / nice / blink
2: pot / got / brew / you / hot
3: night / sight / tea / me / right
4: go / slow / drink / think / no
5: agree / tea / too / do / free
6: today / okay / think / drink / away
7: brazil / ill / do / too / pill
8: cup / sup / drink / think / up

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

Первая линия

Мне понравился набор рифм номер шесть, поэтому я вернул его в модель, чтобы создать несколько начальных строк для лимерика. Вот результаты.

topic: coffee
rhyme-set: today / okay / think / drink / away
first lines:
---------------------------------------
1: "I don't drink coffee", said I today.
2: Coffee’s a drink for today
3: Coffee's just what you'll have today
4: The coffee shop's open today.

Опять же, система отфильтровывает повторяющиеся строки или те, которые не заканчиваются словом «сегодня». Из четырех оставшихся мне понравился номер два. И я повторил процесс для остальных четырех строк. Мой выбор выделен жирным шрифтом.

Вторая линия

topic: coffee
rhyme-set: today / okay / think / drink / away
first_line: Coffee's a drink for today
second lines:
----------------------------------------------
1: I'm not saying it's not okay
2: (It is caffeine, not tea). Okay,
3: Not just breakfast), but it's okay
4: And tomorrow, and all day, okay?
5: That I wouldn't be drinking okay?
6: Which I must have, I guess, okay?
7: With a splash of fresh cream, it’s okay

Третья линия

topic: coffee
rhyme-set: today / okay / think / drink / away
first_line:  Coffee's a drink for today
second_line: With a splash of fresh cream, it's "okay"
third lines:
----------------------------------
1: (Although many think
2: (Though I think it's not think
3: But the best I think
4: If the milk's not what you think
5: If you do, as I think,
6: To serve coffee, I think.

Четвертая линия

topic: coffee
rhyme-set: today / okay / think / drink / away
first_line : Coffee's a drink for today
second_line: With a splash of fresh cream, it's "okay"
third_line : If you do, as I think,
fourth lines:
----------------------------------
1: Add some milk, and you'll drink
2: Add sugar and drink
3: But it's coffee you drink
4: And you need a strong drink
5: It's a milky drink,
6: That is, if you drink

Пятая строка

topic: coffee
rhyme-set: today / okay / think / drink / away
first_line  : Coffee's a drink for today
second_line : With a splash of fresh cream, it's "okay"
third_line  : If you do, as I think,
fourth_line : And you need a strong drink
fifth lines:
------------------------------------------
1: (Which is why I'm leaving it away).
2: Or you're not allowed to have milk away.
3: The caffeine will blow you away.
4: That will wake you up, coffee's away!

Ух, сколько было вариантов! Вот и последний лимерик.

Напиток кофе на сегодня
Со свежими сливками можно
Если так, как я думаю,
И тебе нужен крепкий напиток
Кофеин сразит наповал .
- Глубокие лимерики

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

Обсуждение и следующие шаги

Система, кажется, работает достаточно хорошо. Результаты довольно хорошие, хотя многое зависит от человеческого участия. Система, вероятно, могла бы работать полностью автоматически, если бы использовала большую модель GPT-3 davinci, но это стоило бы тысячи долларов.

Другим способом улучшить результаты было бы использование формы фонем eSpeak в дополнение к форме Festival. Это позволило бы модели видеть ударные слоги и лучше создавать лимерики с правильным ритмом.

Исходный код и Colabs

Весь исходный код этого проекта доступен на GitHub. Я выпустил исходный код под лицензией CC BY-SA.

Благодарности

Я хочу поблагодарить Дженнифер Лим за помощь в этом проекте.

Рекомендации

[1] GPT-J, Б. Ван и А. Комацузаки, Mesh-Transformer-JAX: модельно-параллельная реализация языковой модели Transformer с помощью JAX (2021)

[2] К. Г. Лумис, Американские лимерикские традиции (1963).

[3] М. Брук, Лимерик-Гимерик, Word Ways: Volume 13, Issue 1, Article 10, (1980)

[4] Э. Лир, Анекдоты и приключения пятнадцати джентльменов (1821)

[5] И. Азимов, Развратные лимерики (1976)

[6] LimGen, Jianyou Wang и др., Жил-был очень плохой поэт, он был автоматизирован, но вы этого не знали (2021)

[7] GPT-2, А. Рэдфорд и др., Языковые модели — многозадачные учащиеся без присмотра (2019)

[8] А. Абдибаев, А. Ридделл, Ю. Игараши, Д. Рокмор, Датасет лимериков для вычислительной поэтики (2021)

[9] М. Гротендорст, KeyBERT: минимальное извлечение ключевых слов с помощью BERT (2020)

[10] М. Бернар, Фонемизатор: транскрипция текста в телефоны для нескольких языков в Python (2016)

[11] Т. Браун и др., GPT-3, Языковые модели — малоэффективные ученики (2020)

[12] Л. Гао и др., Куча: 800 ГБ данных разнообразного текста для языкового моделирования (2020)

Приложение

Следующие лимерики были сгенерированы с использованием Deep Limericks в интерактивном режиме.

Рыба
Во французском ресторане я хотел бы рыбы.
С салатом я рад пожелать
Стол, чтобы пообедать
И ждать знака.
Потому что я голоден, я буду есть то, что они готовят.

Марафон
Марафон — это длинная гонка
Я думаю, что смогу выиграть с некоторым изяществом
Если я смогу дойти до конца,
Я знаю, что мой друг
будет подбадривать меня в моем темпе.

Машинное обучение
системы могут учиться.
Некоторые будут использовать это обучение, чтобы зарабатывать
Пока это всего лишь машина
Обучение — все, вы могли бы иметь в виду —
Центральная власть, мир беспокоится .

Том Брэди
Том Брэди, имя квотербека Бука,
Он настоящее произведение искусства. Жалко
Что он никогда не догадается,
При их неуспехе
Он слишком стар, чтобы играть в эту старую игру.

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