Обучить модель RoBERTa расстановке запятых на балконе для продакшена

в 14:16, , рубрики: python, pytorch, roberta, запятая, знаки препинания, искусственный интеллект, машинное обучение, нейросеть, обработка текста, пунктуация
Обучить модель RoBERTa расстановке запятых на балконе для продакшена - 1

RoBERTa — улучшенная версия модели BERT, разработанная Facebook AI. Она показывает отличные результаты в задачах обработки естественного языка, таких как классификация текстов и генерация ответов.

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

  • расставить запятые – 290 000 запросов/месяц

  • расставить точки – 15 000 запросов/месяц

По статистике, 95% запросов посвящены запятым, уделим им особое внимание. Добавим мультиязычность, чтобы получать больше трафика.

Для знакомства с нейронными сетями прочитал книгу Масахиро Араки «Занимательная манга. Машинное обучение» и другие.

Идея

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

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

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

Технология

У языка Python много библиотек и уроков по работе с нейронными сетями. Попробовал для машинного обучения библиотеку Keras, но при создании простой нейронной сети качество исправления пунктуации оказалось нулевым.

Нашел в открытом доступе GitHub проекты, написанные с помощью библиотеки PyTorch:

Напишу свою реализацию обучения нейронной сети, основанную на коде из этих репозиториев.

Архитектура

Трансформеры – общедоступные нейросети, которые хорошо работают с текстом и выделяют важные связи между словами. Можно скачивать их модели на Hugging Face.

Слои разрабатываемой нейронной сети:

  1. Трансформер

  2. Двунаправленный LSTM

  3. Linear

Датасет

Нашел для русского языка датасеты:

  1. Gazeta dataset

  2. Lenta.ru news dataset

  3. mc4 clean dataset

  4. MLSUM dataset

  5. MuSeRC dataset

  6. WikiLingua dataset

В скаченных текстах могут встречаться различные проблемы:

  • нет заглавных букв

  • намешаны разные языки

  • неверно расставлена пунктуация

  • вставлены смайлики и спецсимволы

  • вставлены куски кода

Очищу тексты для улучшения машинного обучения. Получился обработанный русский датасет весом 9 ГБ.

Воплощение логики машин

Улучшение текстового датасета выполнялось по шагам:

  1. Удалить HTML-теги и спецсимволы

  2. Заменить все числа на цифру 1,  чтобы сеть не подумала, что расстановка пунктуации зависит от конкретных чисел

  3. Заменить все email-адреса на цифру 2

  4. Заменить все ссылки на цифру 3

  5. Удалить предложения с символами переноса строк rn

  6. Удалить перед знаками препинания пробелы

  7. Удалить лишние символы и смайлики

  8. Заменить символы '-‑−–—―_'  на общий символ тире, чтобы сеть не отвлекалась на разные виды одного символа

  9. Заменить символы '.!…' на общий символ точки

  10. Заменить символы '„”“"’`' на общий символ кавычки

  11. Заменить символы '({[«<' на общий символ открывающей скобки. Аналогично для закрывающих скобок

  12. Удалить повторяющиеся подряд знаки препинания

  13. Удалить скобки, которые являются пустыми или содержат одно слово

  14. Удалить повторяющиеся подряд пробелы

  15. Удалить предложения, состоящие из более 45 слов, так как они являются набором слов, кодом, текстом без пунктуации

  16. Удалить почти все предложения, в которых нет запятых, чтобы сеть не думала, что запятые слишком редки и их надежнее не ставить лишний раз

Написание кода

Выбираем язык, с которым будет работать нейронная сеть. Указываем путь до директории с датасетами:

language = RU
dataset_dir = join(DATASET_DIR, language)

Парсим скаченные из интернета датасеты и сохраняем тексты в файлы с расширением txt в той же директории:

parse_datasets(dataset_dir)

Обрабатываем распаршенные датасеты и сохраняем в файлы с расширением normalized в той же директории:

normalize_datasets(dataset_dir)

Любой один обработанный датасет переименовываем в summary_validation.dataset. Все остальные файлы *.normalized объединяем в общий summary_train.dataset:

merge_train_datasets(dataset_dir, language)

Тренируем расстановку точек(DOT) или запятых(COMMA):

fit(language, PUNCTUATION_TYPES['COMMA'])

Тестируем натренированную модель:

predict = inference(language, 'Привет как дела учитель', PUNCTUATION_TYPES['COMMA'])
print('Результат: ' + predict[0])

Входные данные

Перед началом машинного обучения прогоню датасет через общедоступную нейронную сеть библиотеки Spacy. То есть использую Named Entity Recognition, чтобы заменить все имена и названия в текстах на соответствующие теги:

  • PER  – имя человека

  • ORG – организация

  • LOC  – географический объект

Это делается, чтобы реализуемая нейронная сеть не подумала, что расстановка пунктуации зависит от конкретных имен людей, названий городов или организаций. У библиотеки Spacy имеются модели для русского языка и множества других.

Каждое слово датасета перепишу в отдельную строку. Если после слова есть знак препинания, который нужно научиться расставлять, то он записывается через табуляцию.

Он
приезжает
к
мистеру
</perb/>    ,
своему
бывшему
школьному
тренеру     ,
и
тот
пускает
его
переночевать.

Имя Сатоши заменено на тег </perb/>. Можно переименовать этот тег на любое другое слово, главное, передать его используемому трансформеру, чтобы создался соответствующий токен. Этот токен всегда будет находиться на месте имен и нейронная сеть сообразит, что, видимо, в этом есть смысл.

Используемые параметры тренировки:

BATCH_SIZE = 4
LEARNING_RATE = 5e-6
FREEZED_PRETRAINED_MODEL = False

Значение FREEZED_PRETRAINED_MODEL, равное False, приводит к дообучению и улучшению под нашу задачу трансформера, который является первым слоем нейронной сети.

Вычислительные мощности

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

Использовал компьютер:

  • GTX 3090 Ti 24 ГБ

  • Ryzen 9 5950X 16 ядер

  • DDR4 3200 МГц 128 ГБ

  • SSD 1 ТБ

  • Блок питания 1000 Вт

Чтобы получать удаленный доступ к компьютеру без монитора, понадобился HDMI эмулятор монитора.

При обработке датасетов на гигабайты приходилось хранить и перекладывать огромные тексты между переменными. Обработка производилась параллельно на половине ядер процессора, при этом использовалось до 100 ГБ ОЗУ.

Пропустить 9 ГБ текста через Named Entity Recognition библиотеки Spacy занимало 3 дня. Пришлось распределить процесс на 4 ядра и занять 110 ГБ ОЗУ. Время выполнения уменьшилось до 1 дня.

Во время машинного обучения расходовалось до 100 ГБ оперативной памяти.

Переобучение

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

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

Перед обучением пропускаю подготовленный текст датасета через токенизатор трансформера и получаю массив токенов. Заставлю нейронную сеть учиться устойчивым признакам, а не запоминать конкретные примеры. То есть с вероятностью 15% буду искажать значения массива токенов:

  • Удалить токен

  • Заменить текущий токен на UNKNOWN, который обозначает что-то незнакомое

  • Добавить после текущего токена дополнительный UNKNOWN

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

Тренировка зимой

Подготовил рабочий код и гигабайтный датасет только зимой. Начал тренировку нейронной сети, оставив системный блок в комнате. Быстро стало жарко, а с открытым окном холодно. Ночью мешали шум кулеров и пиканье видеокарты.

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

Подготовил обогреватель, так как жар видеокарты не справился с морозами. При температурах ниже -10 °C завершал обучение. После переноса ПК в тёплое помещение ему необходимо согреться и высохнуть в выключенном состоянии.

Морозы вынудили переставить системный блок в коридор между комнатами. Температура помещения стала комфортной, а шум кулеров и видеокарты уже не мешал через закрытые двери.

Тренировка летом

Разместил компьютер на балконе. С помощью термогигрометра отслеживал, чтобы влажность окружающей среды не превышала 60%. Накрыл системный блок листом фанеры, чтобы дождь из окна не мог навредить технике.

В жаркие дни балкон раскалялся до 40°C. Приходилось ставить напольный вентилятор, направленный на компьютер. Снимал боковую крышку корпуса для обветривания, но детали быстро пылились и забивались пухом.

Ливни и влажность вынудили переставить системный блок в коридор между комнатами. Снял боковую крышку корпуса и направил на него вентилятор. В июле тренировки моделей приостанавливались из-за запредельной жары.

Лучший трансформер

Пробовал использовать различные предобученные трансформеры:

Обучал сеть расстановке знаков препинания на русском тексте, используя трансформер DeepPavlov/rubert-base-cased-sentence. Думал, что высшая точность исправления пунктуации будет у специализированного на конкретном языке трансформера. В итоге лучшие результаты получились на мультиязычных трансформерах.

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

Самый качественный результат на русском оказался у мультиязычных моделей xlm-roberta-base и xlm-roberta-large, так как они мастерски обобщают свои знания со всех языков.

Изначально датасет был мало очищен, поэтому большая RoBERTa давала высший результат. Эксперименты с текстами и входными данными съедали уйму времени, ведь одна эпоха занимала до 5 дней. Обученная модель на таком трансформере весит 2,4 ГБ. Для точек и запятых на четырех языках получилось всего 8 моделей. На хостинге понадобился сервер с 32 ГБ ОЗУ.

Время исправления пунктуации нейронной сетью в продакшене меня не устраивало.  Методом перебора продолжал очищать датасет и экспериментировать с входными параметрами, используя базовую RoBERTa. Эпоха занимала до 3 дней. Итоговая обученная модель весит 1,2 ГБ, работает быстрее и точнее.

Используемые параметры языков:

RU: {
    'BASIS': 'FacebookAI/xlm-roberta-base',
    'DATASET_TRAIN': 'summary_train.dataset',
    'DATASET_VALIDATION': 'summary_validation.dataset',
    'INPUT_LENGTH': 256,
    'HIDDEN_DIM': 768,
    'PAD': 1,
    'UNK': 3,
    'CLS': 0,
    'SEP': 2,
},
…

Сразу после первой эпохи тренировки получалась наилучшая модель. На последующих эпохах наблюдалось переобучение.

Результат

Google аналитика

Google аналитика

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

Через год продакшена по Google аналитике 95% трафика приходит за русской пунктуацией. Поэтому модели других языков были удалены, а сайт перенесен на сервер с 8 ГБ ОЗУ.

Расставлять в тексте точки приходят только 5% пользователей, остальным нужны запятые. Модель, исправляющая запятые, оказалась не такой идеальной, как планировалось изначально. Постарался свести её количество ошибок на незнакомых текстах к минимуму.

 Чтобы окупать расходы на проект, пришлось думать о потребляемых ресурсах сервера и стремиться к высокой скорости работы нейронной сети.

Заключение

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

Итоговый сайт и демо: https://tool-tube.com/punctuation

GitHub: https://github.com/sergobago/punctuation-restoration

Логи сервера по времени ожидания правок пунктуации

13:42:27: SpacyNeuralNetwork use ru

13:42:27: PunctuationNeuralNetwork use ru COMMA

13:42:27: Run time: 0.2552769184112549 sec

13:42:29: SpacyNeuralNetwork use ru

13:42:29: PunctuationNeuralNetwork use ru COMMA

13:42:29: Run time: 0.22917842864990234 sec

13:42:43: SpacyNeuralNetwork use ru

13:42:43: PunctuationNeuralNetwork use ru COMMA

13:42:43: Run time: 0.6038217544555664 sec

13:42:44: SpacyNeuralNetwork use ru

13:42:44: PunctuationNeuralNetwork use ru COMMA

13:42:44: Run time: 0.25376200675964355 sec

13:42:53: SpacyNeuralNetwork use ru

13:42:53: PunctuationNeuralNetwork use ru DOT

13:42:53: Run time: 0.23792386054992676 sec

Чтобы продемонстрировать возможности, расстановка запятых в этой статье выполнена нейронной сетью.

Автор: Sergobago

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js