Мы в SberDevices выпустили первый продукт в серии Нейроквестов — Нейрофэнтези. Квестами мы решили заняться по разным причинам. Например, в квестах можно испытать всю генеративную мощь семейства GPT-моделей. Квест также одновременно и литературный, и игровой формат взаимодействия с пользователем. В процессе игры фактически создается новая история. Среди решений на английском языке популярным стал проект AI Dungeon, мы захотели сделать нечто похожее на русском, попытавшись при этом превзойти оригинал, а также улучшить некоторые аспекты взаимодействия с пользователем. В этом посте расскажу, как мы разбирались с ходом сюжетных поворотов и с саджестами, и даже пришли к разработке инструмента для преобразования художественных текстов в обучающие данные в формате квеста.
Квесты, фэнтези, и при чем здесь машинное обучение
Согласно Википедии, квесты — это «один из способов построения сюжета в фольклорных произведениях, путешествие персонажей к определённой цели через преодоление трудностей…» Там же упоминается, что квесты ближе всего к жанру фэнтези, в котором героям также приходится преодолевать различные трудности на пути к своей цели (как хоббиты, девочка Элли и ее друзья, маг Земноморья и другие известные герои).
Таким образом, серию Нейроквестов логично было начать именно с фэнтези (продолжить ее мы планируем сказками, детективами, вестернами и другими жанрами).
Схематично устройство квестов можно представить следующим образом:
Как мы видим, при генерации историй нам нужно научиться: а) вводить главного героя и создавать зачин истории («стартовый сеттинг»); б) делать «ход» (тут мы несколько усовершенствовали решения предыдущих разработчиков, например, мы сами предлагаем пользователю несколько вариантов ходов, при этом он может вписать и свой собственный); в) генерировать развитие ситуации, естественно следующее из предыдущей истории и выбранного (или написанного) хода. Вторая и третья часть циклически повторяются до тех пор, пока история не придет к некоторому финалу.
В качестве рабочего инструмента мы выбрали генеративную модель ruGPT-3 Large (760 млн параметров) от Сбера, обученную на 600+ Гб текстов. Кроме этого мы попробовали и продолжаем обучать для разных подзадач также Small, Medium и XL модели. Про то, как в SberDevices обучали ruGPT-3, уже было рассказано в предыдущих материалах, также мы писали о том, в каких проектах может быть полезна ruGPT-3. В NLP-команде SberDevices уже есть успешный опыт применения модели к литературному творчеству: наша команда совместно с Павлом Пепперштейном уже решала похожую задачу — модель писала вместе с известным литератором рассказы.
Что могут GPT-модели? Как авторегрессионная модель, GPT предсказывает последующие слова на основе предыдущих, т. е. порождает грамматически правильный текст на русском языке в любом необходимом количестве. Текст из GPT как нефть — фонтан бьет, но если не умеешь им пользоваться — можно только запачкаться. Вот что будет, если вбить в GPT3-XL начало Толкиеновского «Хоббита»:
Очевидно, что простой затравкой к модели (zero-shot) текст фэнтези не получить. Дополнительные проблемы связаны с тем, что «обучающее окно» в 512/1024/2048 токенов обычно составляет несколько тысяч слов. В такой фрагмент сложно уместить подробный, логически законченный сюжет, столь важный для квестов. Получается, что модель «из коробки» не может научиться писать по настоящему интересную историю.
Первые результаты
Мы начали с того, что попробовали разделить задачи между разными моделями, доверяя каждой генерировать свою часть квестов. Так мы пришли к исходной архитектуре из трех моделей:
1) Генерация стартового сеттинга;
2) Генерации саджестов на основе текущей ситуации;
3) Генерация сюжетных поворотов на основе сделанного хода и предыдущей ситуации.
Все модели обучались на одной эпохе GPT-3 Large, при увеличении количества эпох в выдаче наблюдались обучающие данные «как они есть». Мы немного «играли» температурой и другими параметрами, но существенного влияния на качество генераций это не давало. Качество оценивали и сами, и через Толоку, и посредством UX-исследований.
Вот что получалось в результате:
Как можно видеть, наши первые истории были далеки от связных интересных текстов. Основными проблемами были следующие:
1) Герои хаотически появляются и исчезают;
2) События не связаны друг с другом;
3) Более позднее событие противоречит тому, что было раньше;
4) Предлагаемые действия (саджесты) — одинаковы, просто выражены разными словами;
5) История в целом представляет собой набор отдельных ситуаций без цели и логической связи;
6) В процессе игры может происходить «размытие» жанров (начиналось фэнтези, которое перешло в жанр ужасов или детектива).
Работа над ошибками и к чему она привела
Для устранения этих проблем мы действовали по трем направлениям. Во-первых, перешли от начальной архитектуры с тремя моделями к архитектуре из двух частей; оставили отдельно модель для сеттингов, но остальной текст — и подсказки, и сами ходы — стали получать одной моделью. Во-вторых, мы доработали каждую из двух моделей так, чтобы текст стал более естественным, а сюжет — более связным. Наконец, мы добавили и улучшили обучающие датасеты.
Модель стартовых сеттингов мы придумали обучать так: задавали шаблоны одного и того же типа для разных жанров, снабжая их меткой жанра. Сами шаблоны образованы заменой частей текста соответствующими синтаксическими конструкциями, такие же замены были проведены и в обучающих данных. Это отдаленно (но лишь отдаленно!) напоминает механизм Constraints у Hugging Face. В результате, меняя лишь метки жанра, можем получить совершенно разные стартовые сеттинги.
Вот что мы получим в жанре фэнтези:
А вот что даст ровно тот же шаблон в жанре ужасов:
Тот же шаблон, но уже фантастика:
И, наконец, вариант генерации старта с привкусом вестерна:
Далее, мы решили объединить модели подсказок ходов (саджестов) и самих сюжетных поворотов, разворачивающихся после сделанного хода. Чтобы сделать более гладкими переходы от предыдущего состояния и сделанного хода к новому состоянию, нам надо было разобраться с разными проблемами, перечислим некоторые из них. Как понять, какой сюжетный поворот должен следовать за данным ходом? Как сгенерировать логичные и при этом различающиеся саджесты? Как избежать зацикливания сюжета и добиться его поступательного развития?
Чтобы добиться этого, мы проработали и внедрили такие решения:
1. Добавили оценку перплексии для выбора саджестов (чем меньше перплексия, тем логичнее предлагаемый ход);
2. Ввели сравнение косинусной меры эмбеддингов саджеста и первого предложения следующего шага – чем оно выше, тем более логичным выглядит развитие сюжета после хода;
3. Ввели некоторые эвристики, улучшающие связность переходов (например, ввели запрет на имя главного героя в саджестах, внедрили алгоритм, помогающий избегать зацикливания и т.д.).
Скажем несколько слов про работу с данными. Как учит нас Ник Уолтон, создатель AI Journey 2: «Совет, который я бы дал, особенно в при работе с текстом, заключается в том, что (в определенной степени) меньший объем данных высокого качества более ценен, чем больший объем плохих данных». Мы не гнались за огромным объемом данных, но постарались улучшить их качество и разнообразить их. Кроме этого мы выкачивали данные квестов из открытых источников; просили писать квесты профессиональных редакторов; убирали регулярно повторяющиеся части, «бутылочные горлышки» квестов. Сейчас у нас порядка 75 мбайт данных разных жанров в формате квестов на русском языке.
Кроме этого, мы разработали инструмент для преобразования художественных текстов в обучающие данные в формате квеста (text2data). Чтобы преобразовать текст в обучающие данные мы проводим следующую работу: а) пытаемся определить, кто главный герой текста; б) устанавливаем, в каких именно местах художественного текста уместны саджесты; в) пробуем генерировать варианты саджестов; г) выбираем самый подходящий для данного контекста ход. Результат выглядит примерно следующим образом:
Как мы видим, в тексте определяется главный герой и некоторые его атрибуты, и проставляются саджесты-ходы.
Мы также добавляем в игру иллюстрации и пытаемся разнообразить интерфейс большим количеством заранее сгенерированных картинок. У каждой картинки есть текстовая затравка, с которой сопоставляется порождаемый GPT текст квеста — это делает картинку уместной. В итоге получаем примерно такой результат (все ходы написаны не «из головы», а выбраны из предлагаемых моделью саджестов):
Вы — замечательная смелая наездница Карлиона. Вы давно мечтали совершить что-то необыкновенное, но пока не представлялось случая. В ходе любительских археологических раскопкок вы натыкаетесь на гробницу грозного фараона. Вы поднимаете крышку саркофага, и из-под неё вылезает жук-скарабей, который издаёт воинственный стрёкот. Вы намерены непременно его поймать и отнести придворному чародею.
Поймать жука голыми руками
Вы хватаете жука за жабры и затаскиваете его подальше в саркофаг. Теперь вам надо придумать, как его поймать.
Поймать скарабея с помощью магии
Вы решаете, что поймаете скарабея с помощью магии. Сковываете его цепью, надеваете на голову мешок и надеваете на шею скарабея кожаный ремешок, чтобы не сбежал.
Оседлать скарабея и ускакать
Вы оседлали скарабея, и он помчался по пустыне, громко крича на прощание.
Вскоре вы приезжаете в крупный город Фивы. В храме Осириса вас встречает жрец, который сообщает, что отныне вы будете главной жрицей храма.
Принять эту должность
Вы соглашаетесь и приступаете к обязанностям. С каждым днём вы всё больше понимаете, что храм — это нечто большее, чем просто святилище.
Вскоре к вам в храм приходит множество людей с просьбой провести ритуал призыва дождя. Вы чувствуете себя неловко, ведь вы никогда раньше не практиковали магию.
Провести обряд самостоятельно
Вы проводите обряд самостоятельно. В ходе него вы призываете дождь, и вдруг с неба обрушивается целое облако, которое заливает храм. Люди с криками бегут в разные стороны. Жрец, который проводил обряд, пытается вас защитить, но безуспешно.
Найти укрытие
Вы решаете сбежать из храма. Теперь вы можете отправиться на поиски других приключений. Вы покидаете храм Осириса и отправляетесь на поиски легендарного храма Хатхор в Библдисе.
Посетить храм Хатхор
Вы прибываете в храм Хатхор. На входе вы встречаете гигантскую статую кобры. Вы спрашиваете у неё, можно ли у вас купить амулет, чтобы избавиться от жука.
Попросить амулет у кобры
Вы просите у кобры амулет, и она даёт вам его. Вы собираетесь уходить, как вдруг на вас набрасывается огромный паук, который обвивает вас своими усищами. Вы пытаетесь освободиться от его объятий, но ничего не выходит.
Позвать на помощь
Вы зовёте на помощь, и к вам подбегает вооружённый воин. Вы сражаетесь с пауком до тех пор, пока он не падает замертво.
Пока в текстах еще встречаются шероховатости, но у нас есть разные идеи, как устранять их. Нейрофэнтези уже доступно пользователям мобильного приложения Салют и владельцам умных устройств Sber. Приходите и играйте, творите новые истории, креативьте вместе с GPT.
Присоединяйтесь к неформальным онлайн-встречам Salute AI Day, на которых мы познакомим с нашими командами R&D, актуальными результатами исследований и разработки SberDevices, обсудим последние новости из мира ИИ. Регистрация не требуется. Подробности в чате события.
Комментарии (4)
CatInWeb
01.12.2022 18:03+1Насколько сильно меня заинтересовал ваш нейроквест, настолько же сильно меня не интересуют приложения-ассистенты. :') Вот бы это был отдельный функционал для бота telegram или web-страницы.
Возможно скачаю ненужное (лично для меня) приложение "Салют", ради того, чтобы посмотреть одну эту интересную мне функцию, но подумаю...gra-paul Автор
01.12.2022 18:05Спасибо за интерес к нашей работе!
Попробуйте все же запустить через Салют или какое-либо из наших устройств (сбербокс, например).
WaveCut
Сам пользую rugpt3_large и нравится ваш проект, но я тот несчастный, который с айфоном. Может есть вариант поковырять квесты через ТГ бота, показанного в статье?
gra-paul Автор
Спасибо большое за проявленный интерес! Бот у нас был только для внутреннего тестирования, увы. Надеюсь, Вам удастся поиграть на каком-либо из наших устройств.