Итоговый проект в рамках курса "Программирование и лингвистические данные", ФиКЛ, НИУ ВШЭ.
Могут ли роботы заменить живых преподавателей? Сложный вопрос... А давайте проверим!
Во ВКонтакте есть большое количество пабликов с цитатами преподавателей разных ВУЗов, школ и даже отдельных ОП / предметов. Я собрал цитаты из этих пабликов (чуть больше 40000 для маленькой модели и чуть больше 54000 - для большой) и обучил на них модель rugpt3small_based_on_gpt2 от Сбера так, чтобы она генерировала что-то похожее. Затем я создал группу во ВКонтакте и бота для него же, чтобы все могли насладиться творчеством нейропреподавателей.
В ручном режиме было отобрано несколько десятков сообществ, в которых публикуются цитаты преподавателей. Из выборки исключались такие цитатники, которые активно совмещались с "Подслушано", то есть те, где, кроме цитат, студенты задавали различные вопросы, делились мнение и (активнее всего другого) искали вторую половинку. К сожалению, фильтровать такой контент в автоматическом режиме нет почти никакой возможности. Цитаты собирались с помощью VK_API.
Некоторая фильтрация и очистка текстов, всё же, проводилась. Во-первых, в корпус не попадали записи, содержащие эмодзи и адреса URL. Из выборки, разумеется, исключались посты, официально помеченные ВКонтакте как рекламные, а также репосты. После долгого раздумья я также принял решение исключать все посты с вложениями, даже с фотографиями - таким образом было пропущено незначительное количество полноценных цитат, однако большинство такого контента - реклама, объявления или мемы (последние - хороши, но для нас абсолютно бесполезны).
Из текстов убирались хэштеги и упоминания, а также была сделана попытка убрать подписи (фамилии и имена преподавателей). Кажется, что в автоматическом режиме без машинного обучения хорошо это сделать невозможно, но многие распространённые шаблоны удалось поймать.
В процессе обучения выяснилось, что модель, обученная на однострочных цитатах без диалоговых составляющих, генерирует более удачные тексты - а потому сборщик цитат работает в двух режимах: в первом собираются все цитаты (после очистки мусора), во втором - только однострочные. В абсолютном большинстве случаев это фразы преподавателей без участия студентов или дополнительного пояснения контекста, что лучше всего обрабатывается моделью.
Сборщик цитат - grabber.py
. В файле можно задать параметр make_small
, чтобы определить режим его работы. Результат работы сборщика - база данных SQLite3 с таблицами quotes
и garbage
: в первой лежат цитаты, на которых в дальнейшем мы будем учить модель, во второй - то, что было посчитано мусором. Перед запуском сборщика нужно установить зависимости с помощью pip3 install -r requirements.txt
, а также указать сервисный токен standalone-приложения VK в config.py
. В этом же файле можно найти список групп, из которых выкачивались данные.
За основу была взята модель rugpt3small_based_on_gpt2 - самая маленькая модель семейства RUGPT3. К сожалению, ресурсы бесплатного Google Colab, где производилось обучение, не рассчитаны на модели большего размера. Обучение проводилось с помощью библиотеки 🤗 Transformers
, которая предоставляет набор удобных методов для работа с такого рода моделями.
К каждой цитате я добавил затравку: "Преподаватель говорит: ". Это позволяет генерировать случайные цитаты без привязки к конкретному инпуту, а также полезно для разграничения сэмплов. В конец каждой цитаты также был добавлен спецтокен <|endoftext|>
, идентифицирующий конец примера (это хорошее решение при условии, что сами сэмплы очень маленькие).
Я токенизировал данные с помощью предобученного токенизатора из RUGPT3Small, соединил все тексты и разбил их на равные блоки длиной 512 токена (максимум, который влезал в оперативную память Colab).
Наконец, модель была обучена и протестирована на валидационной выборке. Показатель perplexity для модели, которая была обучена на малом наборе данных, составил чуть больше 18, на большом - чуть больше 19, что в наших условиях очень неплохо. Обученные модели (и большая, и малая) были выгружены на 🤗 (Hugging Face), откуда можно генерировать текст прямо через API, не загружая модель локально.
Тетрадка с кодом файн-тьюнинга - training.ipynb
. Можно запускать в Google Colab с ускорителем GPU или на любом компьютере с достаточной оперативной памятью и наличием GPU.
Я создал паблик ВКонтакте и бота для него (работает в сообщениях группы). В боте пользователи могут генерировать цитаты: либо случайные, либо с пользовательским началом. Каждую присланную цитату пользователи могут оценивать положительно или отрицательно. Любая положительно оценённая цитата попадает в очередь публикаций на странице. Каждый час случайным образом выбирается одна цитата из списка понравившихся пользователю, которая публикуется на стене.
Бот использует VKBottle
- асинхронную библиотеку для работы с API ВКонтакте, а также Aiosqlite
- библиотеку для асинхронной работы с SQLite3. Модель вызывается с помощью API от 🤗 с помощью AIOHTTP
, то есть для запуска бота не требуется иметь модель или набор данных. Таким образом, бот является асинхронным, что минимизирует риски его зависания и вылета. Возможна работа нескольких пользователей одновременно.
Кодовая база бота никак не связана с кодом сборщика и обучения модели, он может быть запущен независимо. Список зависимостей и краткая инструкция по запуску лежит в папке bot
.