Дообучение ruBERT на специфическом корпусе для задачи классификации

Добрый день, DeepPavlov! Спасибо за то, что вы делаете.

Друзья, у меня небольшая проблема. В начале пути по работе с BERT моделями и столкнулся со следующей проблемой.
Моя задача - дообучить ваш “DeepPavlov/rubert-base-cased-conversational” на своем специфическом корпусе для задачи классификации текстов.

Мое решение.
Я взял вашу модель из hugging face и попытался дообучить её с использованием подхода библиотеки transformers.
Основные куски кода следующие:
tokenizer = AutoTokenizer.from_pretrained(‘DeepPavlov/rubert-base-cased-conversational’)
model = BertForPreTraining.from_pretrained(‘DeepPavlov/rubert-base-cased-conversational’)
…(далее идет формирование обучающей выборки для NSP, MLM, создание необходимого объекта Dataset, создание Dataloader)
вот прям по статье этой - https://towardsdatascience.com/how-to-train-bert-aaad00533168

model.train() # и дообучение Вашей модели на специфическом русском корпусе

Далее я сохраняю дообученную мною модель и сравниваю её с Вашей “дефолтной”

Мои результаты
Качество работы полученного ruBERT я решил сравнить при помощи LogReg. Для этого:
Я сформировал тренировочную и тестовую выборку, подгрузил сначала Вашу модель, заморозил веса и получил эмбединги.
Далее я провел аналогичные операции со своей дообученной моделью.
После чего я прогнал полученные эмбеддиниги через классификатор ЛогРега (не на одном. конечно) и получил результаты, согласно которым изначальный ruBERT работает лучше, чем дообученный на специфическом корпусе.

Ваша дефолтная модель показала результат лучше, чем моя.

Подскажите, пожалуйста:

  1. Правильно ли я пытаюсь дообучить Вашу модель? И правильно ли использовать в данном случае библиотеку transformers)
    Если неправильно, то не могли бы подсказать где мне посмотреть further pretrain ruBERT (мб есть колабы или гайды) ?

  2. Если правильно, то как считаете где именно скрывается проблема и на что мне стоит обратить внимание?

Буду благодарен за обратную связь!

Добрый день!

В моделях, которые выложены через Huggingface нет параметров для MLM головы, возможно из-за этого дообучение на вашем датасете только делает модель хуже.

Чтобы подгрузить модель с MLM головой надо брать ее со странички Pre-trained embeddings — DeepPavlov 0.17.1 documentation
Разархивировать и переименовать файл bert_config.json в config.json

from transformers import BertForMaskedLM
model = BertForMaskedLM.from_pretrained("ru_conversational_cased_L-12_H-768_A-12_pt")

Проблема с MLM головой в библиотеке huggingface известна:
issues: DeepPavlov models in HuggingFace are uploaded without MLM head · Issue #1275 · deepmipt/DeepPavlov · GitHub
в ods: Slack

Обновили модели в HuggingFace, теперь MLM и NSP параметры доступны с помощью

BertForPreTraining.from_pretrained('DeepPavlov/rubert-base-cased-conversational')

Спасибо большое.
Но результат после дообучения получается все равно хуже, чем у “дефолтного” ruBERT-conversational, в т.ч. и при сравнении базового BERT.

Видимо ошибка в коде притрейна, не знаю. Может быть существуют примеры/лекции/колабы дообучения ruBERT?

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

Модель RuBERT была обучена с помощью оригинального кода от Google GitHub - deepmipt/bert: TensorFlow code and pre-trained models for BERT. Можно воспользоваться им для дообучения модели. Веса для Tensorflow моделей есть тут: Pre-trained embeddings — DeepPavlov 0.17.1 documentation.

Под дообучить embedding слой Вы имеете ввиду провести тонкую настройку (fine-tune) под конкретную задачу классификации?

Я говорил про именно дообучение только матрицы эмбеддингов на задаче MLM на ваших данных.

Добрый день, есть вопросы по до-обучению RuBERT-a на своем корпусе данных через задачу MLM. (Не fine-tuning через softmax и тд, а именно адаптация embeddings под свой домен)

  1. Есть ли туториал или ноутбук с похожей задачей? Или какой нибудь референс?
  2. Какие и сколько, если вообще нужно, замораживать слои в моделе? (embedding, Self Attention layers etc.)
  3. Можно ли просто добавить к вашему vocabulary.txt добавить свой вокабуляр слов снизу? или есть какие-то детали?

Добрый день,
для обучения RuBERT мы использовали код и инструкции из GitHub - deepmipt/bert: TensorFlow code and pre-trained models for BERT. Можно воспользоваться ими для дообучения RuBERT на вашем корпусе, т.е. взять RuBERT как начальный чекпойнт.

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

Альтернативно можно воспользоваться Huggingface Transformers: How to train a new language model from scratch using Transformers and Tokenizers. Словарь можно расширить с помощью:

from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained('DeepPavlov/rubert-base-cased')
tokenizer.add_tokens(YOUR_TOKENS)

и матрицу эмбеддингов тоже нужно подменить у модели.