̶с̶а̶м̶̶о̶изолента мёбиуса
2.48K subscribers
14 photos
2 videos
1 file
194 links
Костыли и технологии для обработки естественных языков. Обзоры статей и личный опыт. by @cointegrated
Download Telegram
Пара статей про мультиязычные модельки.

LaBSE: language-agnostic BERT sentence embeddings (2020)
Чего хотят авторы: добыть мультиязычные эмбеддинги предложений, как Laser или mUSE, только лучше: чтоб и хорошо перформили на редких языках, и не теряли качество на самых частотных.
Что сделали: предобучили BERT на задачах masked language modeling + translation language modeling (см.ниже) для 109 языков, потом пофайнтюнили на задаче translation ranking. Translation ranking - значит, в батч подаются много пар предложений на языках А и Б, и надо правильно выбрать, какие являются переводами каких. Сходство предложений изменяется как косинусная близость между [CLS] эмбеддингами, и у правильной пары она должна быть хотя бы на margin больше, чем у всех неправильных пар. Замечу ещё, что в модели конский wordpiece словарь - 500к токенов, против 30К у BERT-multilingual, так что редкие языки они должны покрывать куда полнее.
Оценивают это также на задачах подбора правильных переводов на корпусах BUCC, Tatoeba, UN. Для топ 14 языков качество выходит чуть выше чем у mUSE и сравнимо с Laser, на большее редких языках - сильно лучше, чем Laser. На англоязычных задачах semantic text similarity перформанс, впрочем, ниже, чем у mUSE или SentenceBERT - но это они на моноязычных датасетах с парами предложений вообще не файн-тюнились.
Модель выложена на tfhub и даже уже на huggingface, можно пользоваться. Есть основания надеяться, что с её помощью межъязычный transfer learning может получиться хорошо.

Cross-lingual Language Model Pretraining (2019)
В этой статье как раз представляют translation language modeling, на котором предобучали LaBSE. Задача - получить хорошие предобученные мультиязычные модели для NLU. Сравнивают три задачи: causal language modeling CLM, masked language modeling MLM, и MLM+TLM. TLM работает так: в BERT подаётся пара предложений с одинаковым смыслом на разных языках, причем segment embeddings обозначают язык, а position embeddings в обоих предложениях идут с нуля, и к такому инпуту применяется обычное MLM. Поскольку два предложения могут _внимать_ друг другу, модель выучивается сопоставлять слова из разных языков.
Модель, обученную на MLM+TLM, тестировали на датасете XNLI, и выбили SOTA с большим отрывом в двух сетингах: 0-shot (когда модель учится NLI только на англоязычных парах предложений, а потом применяется к куче языков), и translate-train (когда англоязычные обучающие примеры переводятся на все языки, и классификатор учится на многоязычном корпусе).
Модель, обученная только на MLM (без параллельных корпусов) оказалась полезной для инициализации как unsupervised, так и supervised моделей для машинного перевода - оба раза взяли новый рекорд. Языковые модели CLM для редких языков дали более низкую перплексию, чем монолингвальные (проверяли на непальском). Наконец, MLM модель дала словные эмбеддинги, лучше совпадающие для пар слов из разных языков, чем mUSE.
Модельки есть на гитхабе и называются XLM.

Upd. Потестировал LaBSE для русского языка на задаче детектирования парафраз с paraphraser.ru. Оказалось на одном уровне с rubert-sentence от DeepPavlov, чуть лучше чем Laser, и сильно лучше, чем mUSE, BERT-multilingual, SBERT от Сбера, и разные более простые бейзлайны.
RuSentEval: Linguistic Source, Encoder Force!
Коллеги из НИУ ВШЭ опубликовали статью, где они препарируют предобученные трансформеры, выясняя, какими лингвистическими свойствами обладают их представления предложений при работе с русским и английским языком. Делается это так: берётся эмбеддинг предложения (как средний эмбеддинг всех токенов на выбранном слое), и поверх него обучают простенький классификатор предсказывать какое-то лингвистическое свойство предложения. Свойства разделили на три группы: поверхностные (длина предложения, вхождение определенных слов), синтаксические (тип связи между вложенными предложениями, обезличенность, глубина синтаксического дерева, наличие эллипсиса, неправильный порядок слов), и семантические (число и род субъекта и объекта, наклонение, вид и время предиката). В качестве моделей используют мультиязычные BERT, BART, LaBSE, XLM-R и MiniLM из huggingface. Довольно странно, что не стали рассматривать специализированные sentence encoders - Laser и USE.
Выяснили, что качество и свойства представления предложения моделями примерно одинаковые для русского и для английского языка - и это неожиданно. Для "поверхностных" задач более полезными оказались эмбеддинги с первых слоев, для синтаксических - с более глубоких, что весьма ожидаемо.
Датасеты и код выложены на гитхаб, так что если будете обучать свой энкодер для русского языка, можно будет сразу проверить, насколько он умеет в лингвистику.
Работая в Яндексе, я часто слышал людей, описывающих свою работу как "перекладывание jsonов". Но насколько перекладывательным на самом деле может быть перекладвание, я ощутил только сейчас, когда попробовал разработать навык Алисы для умного дома - интегрировать с ней производителя отопительного оборудования. Это довольно любопытный опыт:
- Работать с NLU и NLG не надо, это происходит полностью на стороне Яндекса.
- Необходимость сделать связку аккаунтов заставляет наконец-то разобраться, как работает OAuth.
- Вся оставшаяся работа - по сути, приведение к общему знаменателю мира Умного дома Яндекса и мира моих отопительных систем.
- Пришлось разобраться в предметной области: контроллерах, котлах, отопительных контурах, нагревании воды, теплых полах, отопительных кривых.
- Разработать навык - недорого. Сказать "Алиса, сделай в гостиной потеплее" - бесценно.
Свежая статья Self-training Improves Pre-training for Natural Language Understanding
Едва ли не основная проблема в NLU - дефицит и дороговизна релевантных размеченных данных. Произошедшая три года назад революция предобученных трансформеров частично решила эту проблему: если долго обучать нейросеть как языковую модель, то, оказывается, и задачи классификации она ухватывает с небольшим числом примеров. Есть и другие способы преодолеть маленькость обучающей выборки. Один из них - аугментация: как-то деформировать обучающие примеры, повысив их разнообразие. Это офигенно работает для картинок, ведь их можно вертеть, отражать, накладывать шум, менять палитру и масштаб, - но не так хорошо работает для текстов, ибо при деформации они обычно теряют смысл и складность. И есть ещё self-learning (или же pseudo labeling): обученной моделью разметить неразмеченные примеры, и на этой разметке её же и дообучить. Хорошо работает, если примеры релевантные, а доразметка надёжная. Так вот авторы статьи как раз этого и добились.

Что сделали: взяли кучу задач на классификацию текстов, и для каждой помайнили из миллиардного корпуса предложений (Common Crawl) дополнительные обучающие примеры. Как майнили: сначала отобрали по косинусной близости к размеченным примерам, потом разметили уже обученной RoBERTa. Косинусную близость брали из собственной модели, обученной на детекцию парафраз. Оказалось, что почти ко всем задачам такая схема докидывает пару процентов к точности (по сравнению с просто файнтюнингом RoBERTa). И особенно она хорошо докидывает при дистилляции классификаторов: для дистилляции нужно сильно больше релевантных текстов, чем для файнтюнинга.

В целом, такая схема кажется не супер полезной для типичного индустриального применения в условном Яндексе, когда релевантных неразмеченных текстов и так завались. Но если найти удобный и недорогой способ самостоятельно дёргать похожие предложения из миллиардного корпуса, то, возможно, такая аугментация таки найдёт своё прикладное применение.
TinyBERT: Distilling BERT for Natural Language Understanding
Прошлогодняя статья от исследователей из Хуавей про сжатие бертов.

Предложенные идеи:
• При дистилляции пытаться маленькой моделью предсказать все кишки большой: не только выходные вероятности, но ещё и активации избранных промежуточных слоёв, и распределение всех атеншнов, и даже входные эмбеддинги.
• Дистиллируют дважды: сначала маленькую модель предобучают на неразмеченных данных (Википедии), потом файнтюнят на датасете для конечной задачи, оба раза имитируя модель-учителя по всем вышеуказанным слоям. Поскольку датасеты для конечной задачи обычно маленькие, их двадцатикратно аугментируют, заменяя случайно выбранные слова на похожие.

Результаты:
• Моделью в 10 раз меньше чем bert-base, получили почти 97% от его качества на GLUE.
• Показали абляцией, что и пред-дистилляция, и пост-дистилляция, и аугментация конечного датасета важны. И что дистилляция с кучи слоёв тоже нужна.

Скачать англоязычную модель размера 60mb можно тут: https://huggingface.co/huawei-noah/TinyBERT_General_4L_312D

В целом, я не удивлён, что это получилось, и сам давно ожидал, когда кто-то пожмёт BERT на порядок. Думаю, что и ещё в несколько раз его удастся ужать без потери качества, ибо для решения частных задач действительно не нужно знать весь язык. Но приятно, что авторы этой статьи опубликовали весьма логичный и удобный способ компрессии. Будем ждать ещё более маленьких моделек :)
На прошлой неделе прошла конференция Balto-Slavic NLP, на которой, в частности, презентовали несколько интересных работ по русскому языку.

Russian Paraphrasers: Paraphrase with Transformers. Авторы собрали датасет русских парафраз из субтитров, новостных заголовков и диалогов с чатботами (как набирали последние, непонятно). На таких парах дообучили GPT от Сбера и mT5 (T5 работает заметно лучше, чем GPT). При генерации разные варианты парафраз переранжируются по косинусной близости их эмбеддингов предложений. В результате получается около 60-70% хороших парафраз по оценкам авторов, и около 50% - по моим собственным. Пробовали применить парафразеры для аугментации обучающих выборок задач Russian superGLUE, но прироста качества почти не получилось. Нейросетки выложены на huggingface, а готовый пакет для перефразирования - на гитхаб. Моё мнение: результат неидеального качества, но это шаг в очень важном направлении, ибо хорошие парафразеры важны для кучи других задач NLU и NLG.

Creating an Aligned Russian Text Simplification Dataset from Language Learner Data. Авторы взяли книги для иностранцев на упрощённом русском языке и произвели выравнивание их абзацев с оригиналами книг на обычном русском. Получили параллельный корпус, где в более простой версии втрое меньше уникальных слов и вдвое короче предложения. Обучили на этом нейросетку для упрощения текстов, и вроде бы качество хорошее, но ни модель, ни корпус авторы пока не выложили, так что проверить сложно. Но если вам нужна симплификация для русского уже сейчас, берите дорожку с Диалога и модель Дани Анастасьева, занявшую первое место в этой дорожке.

Abusive Language Recognition in Russian. Авторы собрали датасет на 15К абзацев из Твиттера, субтитров к South park, и уже имеющегося датасета с Кэггла, и разметили его на предмет оскорбительности. На этом попробовали обучать разные модели, и tf-idf+SVM показал себя лучше, чем BERT. Видимо, токсичность на этом датасете сводится в основном к использованию плохих слов. Данные выложены, можно пользоваться. Впрочем, непонятно, насколько это лучше, чем данные из соревнования Одноклассников.

Detecting Inappropriate Messages on Sensitive Topics that Could Harm a Company’s Reputation - работа моих коллег по Сколтеху, в каком-то смысле дополняющая предыдущую. Задача - обезопасить диалоги с чатботом, научиться выделять в сообщениях потенциально опасные темы (от наркотиков и терроризма до боди шейминга и суицида), а также конкретные опасные предложения на эти темы. И в общем-то, это две разные задачи, поскольку не любое сообщение на опасную тему само по себе является опасным. Авторы собрали датасеты из двача и ответов mail.ru, пофильтровали эвристиками и разметили на Толоке. На этом обучили два BERTа, ими вполне можно пользоваться для фильтрации сообщений (скомбинировав их со стандартным фильтром на токсичную лексику).

Там же представили статью RuSentEval: Linguistic Source, Encoder Force! о пробинге русских бертов, про которую я уже писал недавно.
Модель T5 - одна из наилучших возможных основ для seq2seq задач (суммаризация, упрощение текста, условная генерация, перефразирование и т.п.). В каком-то смысле T5, совмещающая в себе и энкодер, и декодер, берёт лучшее из мира и BERT, и GPT. А ещё, вопреки мифам, T5 не очень большая: base англоязычная версия весит 850мб, а small - вообще 230мб. Да, по перформансу это не SOTA, зато файн-тюнятся они очень быстро даже на демократичном железе.

А есть ли T5 для русского? Есть мультиязычная от Гугла на 101 язык, и в ней, понятно, большая часть эмбеддингов относятся не к русскому. А состоит она из эмбеддингов на 85%. Но если отбросить эмбеддинги, которые редко используются в русском, модель может сильно похудеть. И если потом ещё пофайнтюнить её на типично русской задаче, можно надеяться, что качество модели ещё вырастет.

Я такую модельку создал: выкинул ненужные эмбеддинги из mt5-small и дообучил на задаче восстановления испорченного русского текста (вставить удалённые слова, исправить их порядок, исправить испорченные склонения слов). Получился rut5-small-normalizer на 250мб.

Сейчас эта моделька может превратить мне ты не понимать в Я тебя не понимаю. или вы 2 билет купить от москва до петербург - в Вы можете купить 2 билета от Москвы до Санкт-Петербурга.. В общем, пытается из заданных слов собрать связные предложения. Но вы её можете пофайнтюнить и на что-нибудь более интересное)
Обещал выложить код с объяснениями к моему посту про модель T5, в которой я оставил только русский язык.

Дано: модель mT5 на 101 язык
Найти: её уменьшенную версию для русского
Решение:
1) Токенизировал токенайзером от mt5 русский корпус, подсчитал, какие токены часто использовались.
2) Залез в кишки токенайзера, удалил редко использованные токены. Запомнил соответствие между старыми и новыми номерами токенов.
3) Заменил матрицы входных и выходных эмбеддингов в нейронке, сократив их размер и передвинув строки этих матриц по соответствию из пункта 2.
4) Изменил размер словаря в конфиге модели, чтобы он совпадал с тем, что в нейронке.

Блогпост с более подробными объяснениями и кодом: https://cointegrated.medium.com/how-to-adapt-a-multilingual-t5-model-for-a-single-language-b9f94f3d9c90
Are Pre-trained Convolutions Better than Pre-trained Transformers? Такой вопрос поставили себе исследователи из Гугла, и ответили на него в лоб. Они предобучили T5-подобный трансформер и его аналоги, использующие вместо атеншна три чуть разных типа свёрток, на одном и том же текстовом датасете C4. И потом пофайнтюнили на несколько задач класификации (токсичность, сентимент, темы новостей и типы вопросов) и одной задаче семантического парсинга. И сравнили это с обучением тех же архитектур на конечной задаче с нуля. Оказалось, что на большинстве задач классификации CNN работают сопоставимо по качеству с трансформером, и так же выигрывают от предобучения. И даже на семантическом парсинге CNN отработала весьма прилично.

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

И всё-таки иметь готовый быстрый энкодер для длинных текстов было бы круто. Будем ждать, когда кто-нибудь выложит крутую предобученную свёрточную сетку для текстов в открытый доступ)
Поделюсь несколькими статьями про сжатие языковых моделей. Зачем их сжимать? Чтобы CPU и памяти кушали меньше, очевидно.

On the Effect of Dropping Layers of Pre-trained Transformer Models подходят к задаче просто: удаляют в трансформере половину слоёв (лучше всего - верхние) и файн-тюнят его на конечную задачу. Говорят, что для многих задач просадки в качестве нет, потому что трансформеры заведомо избыточны.

Well-Read Students Learn Better: On the Importance of Pre-training Compact Models - авторы статьи утверждают, что если маленькую языковую модель предобучить на MLM задаче, потом подистиллировать об большую модель, и потом дообучить на конечную задачу, то она будет работать лучше, чем если пропустить шаг предобучения или дистилляции. Что в целом логично: предобучение без дистилляции недостаточно информативно (модель-ученик может просто не осознать, чего от неё хотят), а дистилляция без предобучения дорогая (т.к. приходится много данных через тяжеловесную модель-учителя пропускать). Но не очевидно, почему бы не попробовать и предобучение, и дистилляцию одновременно, а не последовательно.

ALBERT: A Lite BERT for Self-supervised Learning of Language Representations - успешная попытка сократить число параметров BERT: уменьшили размер эмбеддингов токенов и объединили параметры всех трансформерных слоёв. В итоге получилось в 18 раз меньше параметров, чем в обычном берте, и ускорение обучения раза в два (впрочем, скорость инференса от этого не уменьшается). Ещё поменяли одну из двух подзадач предобучения BERT: вместо next sentence prediction (определять, идёт ли второе предложение после первого, или выбрано случайно) дают sentence order prediction (определять, какое из двух предложений идёт в тексте раньше другого). Эта более сложная задача вместе с большим вычислительным бюджетам на обучение привела к тому, что ALBERT какое-то время был SOTA на GLUE (и вскоре после этого GLUE закопали).

TinyBERT: Distilling BERT for Natural Language Understanding - успешная многослойная дистилляция BERT с 10-кратным ускорением, про неё я писал отдельно.

А вообще, если хочется узнать, как сжимают языковые модели, можно почитать обзоры, типа лаконичного поста All The Ways You Can Compress BERT или относительно свежей статьи Compression of Deep Learning Models for Text: A Survey. Из обзоров видно, что для GLUE-подобных задач ничего лучше дистилляции пока не придумали, и что дистилляцию можно применять в комплекте с квантизацией (например, LadaBERT комбинируют матричные разложения, прунинг отдельных весов и дистилляцию, и получают качество TinyBERT более дёшево).

Я сам тоже на днях попробовал таки сжать BERT для русского, получил rubert-tiny, и работает он, если честно, пока отстойно. Но он в 10 раз меньше и быстрее bert-base, и, может быть, таки пригодится для какой-нибудь задачки, где скорость сильно важнее качества.
The Winograd Schema Challenge - задача по разрешению кореференции в предложениях. По сути, надо понять, к какому слову относится местоимение.
Например: "Кубок не помещается в коричневый чемодан, потому что он слишком большой". Верно ли, что слово "он" относится к слову "чемодан"? Неверно.

Прикол WSD в том, что в тестовой выборке может содержаться похожее предложение: "Кубок не помещается в коричневый чемодан, потому что он слишком маленький". И вот в таком предложении "он" уже относится к "чемодану". И оказывается, что ML алгоритмы к такому повороту не очень готовы.

На русскоязычном лидерборде наилучшая моделька выдаёт точность 67% на таких предложениях - то есть столько же, сколько и рандомный бейзлайн. На английском SuperGLUE точность выше, но разрыв с человеческим перформансом (равным 100%) пока заметный.

Мне это кажется довольно удивительным. Задача разрешения кореференции для местоимений - супер важная, и кажется очень базовой. И до сих пор она решена весьма так себе.
#sotanlu
Хозяйке на заметку: если вам нужно относительно качественно перефразировать предложение, можно сделать это методом back-translation: перевести его русского на английский и назад на русский.
Чтобы не получить на выходе то же самое предложение, можно запретить модели-переводчику воспроизводить n-граммы (токенные), встречавшиеся в исходном предложении.
Кажется, получается дёшево и сердито.
import torch
from transformers import FSMTModel, FSMTTokenizer, FSMTForConditionalGeneration
tokenizer = FSMTTokenizer.from_pretrained("facebook/wmt19-en-ru")
model = FSMTForConditionalGeneration.from_pretrained("facebook/wmt19-en-ru")
inverse_tokenizer = FSMTTokenizer.from_pretrained("facebook/wmt19-ru-en")
inverse_model = FSMTForConditionalGeneration.from_pretrained("facebook/wmt19-ru-en")
model.cuda();
inverse_model.cuda();

def paraphrase(text, gram=4, num_beams=5, **kwargs):
""" Generate a paraphrase using back translation.
Parameter `gram` denotes size of token n-grams of the original sentence that cannot appear in the paraphrase.
"""
input_ids = inverse_tokenizer.encode(text, return_tensors="pt")
with torch.no_grad():
outputs = inverse_model.generate(input_ids.to(inverse_model.device), num_beams=num_beams, **kwargs)
other_lang = inverse_tokenizer.decode(outputs[0], skip_special_tokens=True)
# print(other_lang)
input_ids = input_ids[0, :-1].tolist()
bad_word_ids = [input_ids[i:(i+gram)] for i in range(len(input_ids)-gram)]
input_ids = tokenizer.encode(other_lang, return_tensors="pt")
with torch.no_grad():
outputs = model.generate(input_ids.to(model.device), num_beams=num_beams, bad_words_ids=bad_word_ids, **kwargs)
decoded = tokenizer.decode(outputs[0], skip_special_tokens=True)
return decoded

text = 'Женщина-дайвер исчезла в Черном море во время научных работ на побережье Анапы.'
print(paraphrase(text, gram=3, do_sample=False))
# Женщина-водолаз пропала в акватории Черного моря, когда выполняла исследовательские работы у берегов Анапы.
# Wall time: 699 ms
#sotanlu Ещё одна задача из SuperGLUE, RTE, (Recognizing Textual Entailment) - задача классификации, следует ли второе предложение из первого. Например, "Автор поста написал в комментарии, что прорвалась канализация." и "Автор поста написал про канализацию." - здесь второе предложение вытекает из первого.

Это - самая частая формулировка более общей задачи NLI (natural language inference). А ещё её можно рассматривать как обобщение задачи детекции парафраз, ибо если пара предложений друг друга перефразирует, то они взаимно друг из друга следуют. Ещё с помощью моделей RTE удобно оценивать качество суммаризации: саммари, если оно не врёт, должно следовать из исходного текста. А одна недавняя статья от FAIR вообще предлагает все задачи на классификацию предложений и их пар переформулировать в NLI, и утверждают, что это помогает на новые задачи дообучаться быстрее. В общем-то, и zero shot classification можно как NLI сформулировать, типа следует ли из фразы "Еда была очень вкусная, и сервис хороший" фраза "Отзыв положительный".

Для задачи RTE хорошо работает классическая архитектура для классификации пар: сконкатенировать два предложения с каким-то разделителем, прогнать через BERT-подобный энкодер, классифицировать по эмбеддингу CLS токена. На huggingface есть куча готовых моделей для NLI и zero-shot classification для английского, а вот для русского я с ходу не нашёл. Но тоже, наверное, должны быть)

Задача в стиле RTE входит и в RussianSuperGLUE, и скор на ней (87% у ансамбля, 73% у лучшей одиночной модели) пока что сильно ниже человеческого (92%). И даже на англоязычном лидерборде кожаные мешки пока что держат оборону, хоть разрыв с лучшей моделью уже и небольшой. Потому что, хоть на первый взгляд задача RTE и кажется простой и бесполезной, чтобы решить её хорошо, тексты нужно реально понимать.
Я в этом канале регулярно что-то пишу про свои pet projects, но мало пишу про основную работу в Сколтехе. Оправдываю это тем, что мы пока что мало публикуемся.
Но вот таки одну статью по моей теме (перенос стиля) опубликовали и на Диалоге представили. Там основной вклад Дарины (кстати, рекомендую ее канал @towards_nlp), но я тоже чутка поучаствовал.
Итак, Methods for Detoxification of Texts for the Russian Language, первый заход: https://arxiv.org/abs/2105.09052
Вчера СберДевайсы выпустили русскую версию модели CLIP (пост, веса).
CLIP - это пара энкодеров, которые переводят картинки и тексты в одно и то же векторное пространство. Довольно удобная штука для zero-shot классификации картинок и для поиска по ним.
А ещё в паре с картиночным GAN'ом из неё можно сделать генератор картинок по подписям, а в паре с годным генератором текстов - генератор подписей к картинкам.
В общем, полезная в хозяйстве штука, забирайте.
Помните, недавно я постил код для перефразирования предложений переводом на английский и обратно?
Так вот, оказалось, что этот бейзлайн пока что не может обойти ни одна нейросетка, специально обученная на задачу перефразирования.
Про то, как я собирал корпус парафраз, обучал модель и придумывал метрики для её оценки - читайте на Хабре.
Привет! Я сделал обзор существующих корпусов и моделей для генерации парафраз на русском языке.
А ещё сгенерировал свой корпус на миллион парафраз (он весьма неплох) и обучил свой парафразер на основе T5 (SOTA пока не получилась).
https://habr.com/ru/post/564916
Сегодня в 17:00 по Мск буду рассказывать на созвоне DeepPavlov про свой маленький русский BERT.
Вот ссылка на запись мероприятия.
Есть не до конца решённая задача: "сгенерировать предложение, похожее на заданное". Её можно решить с помощью авторегрессионной языковой модели, попросив её продолжить текст. Но можно сделать то же самое и с помощью MLM. Для этого надо просто несколько раз пропустить предложение через BERT, заменяя некоторые токены на [mask] и генерируя новое предложение из условного распределения, выданного моделью. Получается иногда бред, иногда удачно, примерно 50/50.

def replace_with_mlm(text, model, tokenizer, n_iter=5, temperature=0.5, max_span=2, change_size=True, mask=True, verbose=False):
enc = tokenizer(text)
n = len(enc.input_ids)

for i in range(n_iter):
if mask:
left = random.randint(1, n - 2)
right = random.randint(left + 1, min(left + max_span, n-1))
if change_size:
new_size = random.randint(1, max_span)
else:
new_size = right - left
enc.input_ids[left:right] = [tokenizer.mask_token_id] * new_size
with torch.no_grad():
out = model(torch.tensor(enc.input_ids).to(model.device).unsqueeze(0))
proba = torch.softmax(out.logits / temperature, -1)[0]
enc.input_ids[1:-1] = torch.multinomial(proba, 1)[1:-1, 0]
out_text = tokenizer.decode(enc.input_ids, skip_special_tokens=True)
if verbose:
print(out_text)
return out_text

Подставим сюда bert_ru_conversational_cased от DeepPavlov и какой-то текст, и посмотрим, как он мутирует:
replace_with_mlm('Путин утвердил новую Стратегию национальной безопасности России', model, tokenizer, verbose=True)
Национа Путин утвердил новую стратегию национальнои безопасности.
Владимирльный утвердил новую стратегию национально ориентированных.
Владимир Жириновский показал новую стратегию национально ориентированных.
Владимир Жириновский показал новую стратегию национального политики.
Владимир Жириновский показал нам российского национального политика.
По-моему, забавно.

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