![](https://habrastorage.org/getpro/habr/upload_files/929/11b/cfd/92911bcfd83ea28a80606bd2fb77d5f3.png)
Привет! Недавно мы представили проект «AI да Пушкин». Благодаря нейросетям поэт генерирует четверостишия по первым словам, которые предлагает пользователь. А затем читает вслух то, что получилось. Увидеть и услышать, как это происходит, можно на сайте проекта. А мы расскажем, как решили проблему отсутствия рифмы с помощью контролируемой генерации текста и какие технологии использовали, чтобы сделать проект более эффектным.
Как устроен продукт
«AI да Пушкин» — экспериментальный проект. Мы хотели показать пользователям и рынку, как работают ИИ-технологии в Тинькофф. И заодно протестировать две новые технологии на большой аудитории. Сейчас сервис работает так: пользователь придумывает начало стихотворения, а нейропоэт выдает четверостишие с ритмом и рифмой, учитывая заданный контекст. Получившееся стихотворение «AI да Пушкин» может озвучить. При этом пользователь на всех этапах видит анимацию лица поэта.
![Так выглядит десктопная версия Так выглядит десктопная версия](https://habrastorage.org/getpro/habr/upload_files/f8b/105/bba/f8b105bba742dd25a2ffb509d9339b08.png)
Все это происходит благодаря трем технологиям Тинькофф. За создание четверостиший отвечает генеративная стихотворная модель, за их озвучивание — технология VoiceKit, а за оживление портрета поэта — технология синтеза мимики и оживления портрета Thara. Нашей главной задачей было объединить технологии NLP и Thara и получить полноценного персонажа с хорошим синтезом речи и качественной анимацией. В этом тексте мы подробно расскажем о генерации стихов. А затем немного поговорим о том, как работали VoiceKit и Thara.
Как научить модель рифмовать, если она этого не хочет. Пробуем два подхода и выбираем лучший
Технологии генеративной диалоговой модели уже знакомы пользователям мобильного приложения Тинькофф. Раньше в приложении был навык болталки, который работал на ее основе: мы тестировали необходимость такой функции. Модель хорошо генерировала ответы пользователям, но не могла — и не должна была — сочинять стихи. Нам предстояло ее дообучить.
Для этого мы собрали датасет. Чтобы у модели был большой словарный запас и она могла ориентироваться в сегодняшнем контексте, мы включили в обучающую выборку не только стихи Пушкина, но и произведения современных авторов. Получилось около 60 млн стихотворений, собранных из открытых источников.
Обучив модель на этом датасете, мы получили промежуточный результат, который нас не удовлетворил. Во-первых, мы не учли некоторые моменты, когда чистили датасет, и модель нахваталась плохого. Она генерировала четверостишия с нецензурными словами, словами на иностранных языках и странными символами. Вот примеры таких стихотворений.
мои дорогие..........
.........................................
Я не знаю, что с нами будет.
Не знаю, как сложится судьба.
Во-вторых, на самом деле это нельзя было назвать стихотворениями. Мы научили модель учитывать ритм и рифму по набору правил, а не только по ударным гласным. Но в первой итерации она не научилась рифмовать. Вот пример стихотворения без рифмы:
я сяду в кабриолет и улечу.
Куда? Не знаю. Знаю одно:
Что буду там, где меня никто не ждет.
И это место называется раем.
Первую проблему мы легко решили чисткой датасета, удалив оттуда около 10 млн непригодных стихотворений. Решить проблему отсутствия рифмы оказалось сложнее. Дело в том, что мы никак не штрафовали модель за игнорирование рифм, поэтому у нее не было стимула создавать стихи. Мы провели рисерч, изучили статьи и существующие методы и выработали два собственных подхода. Сейчас подробно расскажем об обоих.
Подход первый. Подробнее о подходе можно узнать из статьи Recipes for building an open-domain chatbot. Его придумали, чтобы улучшить качество разговорных ботов. Изначально подход использовали, чтобы научить бота не выпадать из контекста диалога с пользователем и отвечать более информативными и полезными репликами. Мы решили модифицировать подход, чтобы наша модель поняла, что такое рифма, и создавала рифмующиеся строчки. Заранее скажем, что в обоих подходах мы использовали нейросеть GPT-2.
Мы разделили строки стихотворений на токены и начали специально показывать модели рифмы. В начале каждой строки мы вставляли в 20% случаев слово, которое стоит в конце предыдущей строки. А в 80% случаев — слово, которое рифмуется с последним. Таким образом модель выучила, что последнее слово должно рифмоваться с первым. В процессе инференса мы сами искали рифмы и тем самым помогали модели. Ниже — примеры стихотворений с подсказками.
Буря мглою небо кроет,
Вихри снежные крутя;
[Моет] То, как зверь, она завоет
Буря мглою небо кроет,
Вихри снежные крутя;
[Завоет] То, как зверь, она завоет,
Чтобы подход работал, мы написали специальный модуль поиска рифм. Прямо во время генерации стихотворения модуль подавал модели варианты. Модель могла выбрать предложенную нами рифму, а могла предложить свою на основе нашей. Этот подход какое-то время жил в виде бота в Телеграме, который сочинял стихи и нравился участникам бета-тестирования.
Подход второй. В рамках этого подхода мы с помощью GPT-2 обучили модель предсказывать следующее слово и подавали информацию о номере строки в таком формате: @LINE_11@@ буря мглою небо кроет @LINE_22@@.
![](https://habrastorage.org/getpro/habr/upload_files/b2f/f75/550/b2ff755505e48e57248c0c57e1b807ac.png)
Затем мы перешли к проблеме рифмы. Мы знали, что если генерировать только одну строку, вероятность получить рифму составит около 50%. А если сгенерировать десять строк, то вероятность, что появится рифма, стремится к 100%. Поэтому решили генерировать много строк и выбирать из них лучшую — ту, в которой рифма есть.
Поначалу мы думали написать отдельный классификатор для выбора лучшего варианта. Но когда посмотрели на работу модели, поняли, что в этом нет необходимости. Выкатка еще одной модели замедлила бы работу проекта. Сейчас все работает на эвристиках: они отлично справляются с задачей выбора лучшей строки и не тормозят пайплайн.
Сравнение подходов. Оба подхода обеспечили генерацию стихов. Если резюмировать, в первом подходе контроль происходил за счет того, что мы научили модель ориентироваться на рифму, которую ей подают в каждой строке, с помощью модуля поиска рифм. Во втором подходе контроль происходил за счет того, что мы заметили, что среди десяти вариантов генерации очень часто встречается строка с рифмой. Поэтому мы, по сути, контролируем генерацию, выбирая каждый раз нужную строку самостоятельно. Чтобы выбрать оптимальный подход, мы отдали результаты генерации на Толоку. Показывали людям два четверостишия и просили выбрать лучшее. Вот как выглядело задание на Толоке.
![](https://habrastorage.org/getpro/habr/upload_files/43c/6c0/958/43c6c09582c1159a21198d0016a630e7.png)
В итоге выиграл второй подход: на Толоке большинству пользователей понравились полученные с его помощью результаты.
VoiceKit и Thara: откуда у нашего нейропоэта голос и «живой» портрет
Большую часть этой статьи мы посвятили контролируемой генерации стихов, но создание «AI да Пушкин» как продукта было бы невозможным без синтеза речи и анимации портрета поэта.
Команда VoiceKit подарила нейропоэту голос. VoiceKit — это технологии распознавания и синтеза речи Тинькофф. Подробнее о них можно узнать на сайте. Мы прошли такой же путь, как и любой внешний клиент: выбрали голос, который, как нам показалось, подходит поэту, а затем начали отдавать на платформу тексты. Для «AI да Пушкин» мы использовали готовые решения, поэтому не будем подробно описывать принципы их работы в этой статье. О том, как работают технологии синтеза речи в Тинькофф, можно узнать из этого видео. Если у вас останутся вопросы, поделитесь ими в комментариях, и мы постараемся ответить на них в следующих статьях.
Thara — технология, благодаря которой «ожила» внешность поэта. Это относительно молодая технология для Тинькофф. Ее создала одноименная команда экспериментальных продуктов, поэтому о технологиях «под капотом» мы пока рассказать не можем. Но примерный процесс создания анимации опишем.
Thara может работать с любой внешностью, поэтому мы начали с создания портрета Пушкина. Иллюстратор получил подробное ТЗ, которое мы составили с учетом всех технических особенностей будущего продукта. Более того, мы дали художнику доступ к технологии, чтобы он во время работы мог проверять, как работает анимация. Портрет рисовали долго: хотелось, чтобы наш Пушкин был узнаваемым и современным. При этом он обязан был соответствовать ожиданиям пользователей о том, как должен выглядеть нейропоэт. В итоге получилось несколько версий портрета. Собрав мнения пользователей и проголосовав внутри команды, мы выбрали итоговый вариант.
Затем в дело вступила Thara. Технологию можно разложить на два компонента: кодирование аудио и декодирование его в картинку. На рынке есть похожие решения, но большинство из них заточены под конкретных персонажей. Кроме того, они не позволяют делать синтез быстро и при этом качественно. У многих решений проблемы с движениями: при поворотах головы появляются артефакты, анимация начинает выглядеть неестественно и иногда пугающе. В Thara мы путем доработки технологии смогли этого избежать. Модель хорошо достраивает уши, челюсть и даже волосы в динамике.
Отдельной задачей стала выразительная мимика губ. Для нас было важно, чтобы поэт говорил именно то, что сгенерировала стихотворная модель. Так мы добивались максимальной синхронизации всех составляющих проекта: это был отличный продуктовый вызов для команд. Мы использовали модель, которая решает задачу LipSync, а именно доработанную версию сети wav2lip, функционирующую быстрее обычной. Нам нужно было, чтобы она работала с минимумом артефактов в области губ и зубов: без искажения формы, цвета губ и текстуры кожи. Для этого мы провели большую работу по правильной отрисовке губ и зубов на портрете Пушкина, который подаем модели на вход. Теперь процесс выглядит так: сначала мы снимаем с реального человека движения головы и глаз и перекладываем на портрет нашего Пушкина с помощью модели First Order Motion Model. Затем с модифицированной версией wav2lip накладываем на видео анимированные под проговариваемую речь губы, а сверху дорабатываем текстуру и общий стиль видео с модифицированной версией модели GPEN.
Кроме того, мы обучили «AI да Пушкин» эмоциям. Для этого команда Thara записала несколько видео с нужными эмоциями, например закатыванием глаз или улыбкой. А модель смогла считать их и подстроить под мимику нейропоэта.
![Одна из эмоций Одна из эмоций](https://habrastorage.org/getpro/habr/upload_files/a91/3cb/fe5/a913cbfe5bef6ce79535c3a10dbcefcf.gif)
Все это происходит быстро, скорость анимации — 20—25 FPS (frames per second, кадров в секунду). Сейчас «AI да Пушкин» работает в HD-разрешении, не занимая при этом много места на GPU.
Заключение
В итоге у нас получился технологически интересный продукт, над которым работали около 30 человек из разных команд. С помощью «AI да Пушкин» сочинили стихотворения сотни тысяч пользователей: в среднем каждый из них сгенерировал 3,7 стихотворения. А всего получилось более 800 тысяч стихотворений. Что интересно, пользователи предпочитали вводить собственный текст в качестве начала стихотворения, а не использовать наши подсказки. Сгенерировав стихотворение, они присылали друзьям ссылку на проект и скриншоты с результатами. Это стало главным каналом привлечения новых пользователей. Из этого мы сделали вывод, что проект понравился аудитории.
Сейчас мы готовимся внедрять технологии, примененные при создании «AI да Пушкин», в другие сервисы и продукты Тинькофф. Например, контролируемая генерация, о которой мы подробно рассказали в этой статье, поможет улучшить качество ответов финансового ассистента Олега. А о применении остальных технологий и их устройстве мы постараемся подробнее рассказать в блоге в будущем.
Комментарии (13)
kichrot
25.04.2022 16:28+1Класс!!!
За 10 минут сваяла:
АНТИПОЗИТИВИЗМ
Наука с философий начинается!
Она, как свет в кромешной темноте.
В ней человек и мир преображается,
Путь к совершенству открывая красоте.Наука философией заканчивается -
В ней нет ни смысла, ни идей.
И в жизни ничего не значится
Без философии людей.Наука без философии мертва?!
Вселенная - всего лишь пустота?
И что же есть, по сути, человек?
Зачем живет он на Земле свой век?Наука без философии мертва!
Без философий не рождаются слова!
Без философских мыслей нет стихов,
Без философских мыслей - нет основ!
averkij
25.04.2022 16:37Сейчас все работает на эвристиках: они отлично справляются с задачей выбора лучшей строки
А какого рода эвристики?fursov Автор
25.04.2022 18:06+1По сути, просто ищем строчку с рифмой (определяем ударную гласную, смотрим ее фонему и позицию в слове). И плюс проверяем, что слово не входит в список "запретных" слов
Whatson
25.04.2022 18:04+1И вот стремлюсь я в сис-админы?!
Не надо, друг мой, не старайся!
Я не хочу такой картины!
Уйди с дороги, не пытайся!
T968
25.04.2022 18:04Что то не так
С дуба падают листья ясеня -
Это осень, мой друг, пришла
И в багряные краски красит
Все, что лето с собой унесла.
Whatson
25.04.2022 18:10Бэк энд пилю я тихой сапой -
Я сам с собой наедине.
Вокруг меня сплошная лапа,
А в лапе ножик на ремне.
shadrap
26.04.2022 16:20очень не плохо! Эвристики ориентирутся только на рифму ? точно? мне показалось что как минимум еще на схожий к праймеру контент, потому что меняя праймер в рифму машина выдавала близкий результат еще и по смыслу.
Такая Поэзия наоборот..) не от смысла а от содержания!)
Rustacean