Поскольку 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 сочинять лимерики.
Для сравнения, однозадачный подход будет заключаться в том, чтобы обучить систему генерировать лимерики по заданной теме, все в графемной форме. Проблема в том, что система не сможет «увидеть» рифмы и размер, потому что эти функции несколько скрыты в графемах. Благодаря многозадачному обучению я смог одновременно научить систему следующим четырем вещам.
- Как преобразовать графемы в фонемы и обратно
- Как составить набор рифм на заданную тему
- Как написать лимерик в правильной форме, учитывая тему и набор рифм
- Как написать лимерик с хорошей грамматикой и юмором, учитывая тему
Я построил восемь строк для обучающих данных для каждого лимерика в отфильтрованном наборе данных. Я использую разные символы для содержания записей, чтобы помочь системе узнать, какая задача является какой. Кроме того, я использую четырехсимвольную строку для обозначения определенных преобразований, например, =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 долларов в месяц. Не члены могут читать только три заблокированных истории каждый месяц.