Сходил я сегодня на NLP митап от Хуавея. Были доклады в основном по бертоведению. Попробовал записать их на лету; получилось примерно так.
Рассказывает Dr. Qun Liu, Chief Research Scientist @ Huawei Noah's Ark.
Первая задача: переводя с китайского на английский, вставлять местоимения, пропущенные в Китайском.
Решение: взять параллельный корпус, применить выравнивание слов, вставить в китайский текст местоимения на место пропущенных английских, выкинуть предложения с плохим скором по языковой модели, и на полученном корпусе (китайский текст) выучить, куда вставлять какие местоимения. Переводить на английский уже после вставки. Ну или можно одновременно переводить и предсказывать, куда вставлять китайские местоимения.
Вторая задача: переводить относительно большие тексты. Например, диалоги. Ребята предлагают строить общий контекст для всего документа. Он строится иерархически (LSTM на уровне предложений, а потом на них LSTM для текста), и его саммари используется как фича в модели перевода. Этим саммари можно:
- Инициализировать и энкодер, и декодер
- Вставлять как фичу, на которую может смотреть атеншн (наряду с обычными словами) на каждом шаге декодинга. Смотреть может и энкодер, и декодер-до-энкодера, и декодер-после-энкодера. Предварительно можно фильтровать каким-то гейтинговым механизмом, с величиной гейта, зависящей от текущего места в тексте. То есть как бы дополнительный множитель в атеншне для этого слагаемого.
Впрочем, эта моделька работает хуже, чем аналог, который кэширует билингвальные кусочки текста (я не понял, как именно) в каком-то key-value хранилище.
Ещё одна фишка: претренировывать модели на sentence-level параллельных корпусах, тюнить на более редких document-level корпусах. На втором шаге тренируются только те кусочки атеншенов, которые смотрят на общедокументный контекст (и сам извлекатель этого общего контекста); остальные параметры зафиксированы.
Рассказывает Михаил Архипов (@DeepPavlov) - Multilingualism of BERT
Кусочек истории: когда-то тренировали эмбеддинги слов для разных языков, а потом учили матрицу проекции из одного в другой. Удивительно, но если потребовать, чтобы эта матрица была ортогональной, качество растёт.
Ещё один старый подход многоязычных эмбеддингов без учителя: потюнить GAN, чтобы одна модель угадывала язык по эмбеддингам, а другая строила эмбеддинги, такие, чтобы первая не угадала.
Потом фейсбук предложил LASER на biLSTM без атеншна (это важно) поверх BPE: сделаем мультиязычный энкодер и одноязычный декодер, и переводить с 50 языков на английский и испанский. У энкодера получились вполне пригодные эмбеддинги, универсальные для всех языков. Тестили на датасете XNLI, получился zero-shot transfer для NLI с английского на другие языки, почти без потери перформанса по сравнению с английским. Магия!
Более новая статья (cross lingual language model pretraining) - уже на транформерах. На входе эмбеддинги токенов, позиции и предложений, слова рандомно дропаются, и модель предсказывает их, глядя на два предложения на разных языках - так она автоматически учится выравнивать слова, и получается круто.
Многоязычный берт учился так же, как англоязычный, на нормальный бертовый лосс, без всяких параллельных корписов - и получилсоь норм по качеству, но модель получается тяжеловатой. Потом получается нормальный zero-shot transfer для NER, для POS-тегов, для перевода методом ближайших соседей по среднему эмбеддингу токена (статья How multilingual is multilingual BERT). Кстати, для задач типа сентимента пулинг по токенам работает сильно хуже CLS-токена, по опыту диппавлов.
Ачивка DeepPavlov: потюнили multilingual-BERT на NER на огромном OntoNotes, перенесли на NER, получили для PER отличное качество, а LOC и ORG сильно хуже.
Ещё ачивка: zero-shot cross-lingual QA. Просто потыкайте: https://demo.ipavlov.ai/#/mu/textqa
У многоязычного берта только 20% токенов встречаются в русском, это неэкономно. Как его пожать до моноязычной модели? Можно собрать новый BPE словарь для только русского, инициализировать его мультиязычно, и дотюнить (все веса). Инициализировать новые токены можно суммой многоязычных эмбеддингов их старых токенов. Кстати, проблема BERT - в том, что сложно учить позиционные эмбеддинги для длинных последовательностей (приходится маленькие батчи делать, чтобы в память всё влезло). Но iPavlov смог, и получился RuBERT, который взял несколько русских SOTA (а также болгарский, чешский и пользский).
Рассказывает Никита Сметанин из Реплики - BERT для диалогов на проде
Реплика в общих чертах устроена примерно так. Ответы могут поступать из трёх источников:
- Редакторские ответы
- Retrieval моделька и реранкер ответов
- Генеративная моделька
Кроме этого, есть модель, оценивающая сессию (насколько юзер доволен диалогом) - пока что не особо влияет на ответы.
Ретривал моделька скорит, насколько каждое предложение из отмодерированной обучающей выборки (100К) подходит для текущего контекста. Их бейзлайн - две башни w2v+BiLSTM + self-attention, и cosine distance между ними, обученная на triplet margin loss. Примерно как в Алисе. Вместо w2v+lstm можно взять два предобученных берта и зафайнтюнить их. В качестве предобученной модели ребята взяли гугловский берт, слегка пожали его в длину и глубину, неделю тренировали на своих текстах, и получили нечно работающее. Но работающее хуже, чем бейзлайн, хоть и вдвое тяжелее (100М против 50М параметров), увы.
Вторая модель - реранкер. Ретривал даёт 20 кандидатов, эвристики отбират из них 5, и реранкер выбирает из них одну - с максимальной вероятностью лайка от пользователя. Датасет был 15М пар контекст-ответ-лайк/дизлайк. Бейзлайн конкатенировал эмбеддинги контекста и ответа, пропускал их через 4 полносвязных слоя, и предсказывал вероятность лайка. В берт загрузили контекст и ответ (с разными сегментными эмбеддингами), и получили весьма крупный рост продуктовых метрик. Моя гипотеза, почему это работает: во-первых, теперь контекст и ответ аттендятся друг на друга (а не только на себя), во-вторых, оригинальный берт училя именно тна такую задачу. После введения реранкера качество (залайканность) нейронных ответов выросла до уровня редакторских.
Третья модель - оценка сессии. Модель предсказывала, как юзер оценит сессию (-1/0/+1) по сконкатенированному диалогу. Бейзлайна тут не было, но в итоге что-то получилось и работает. Немного выводов.
Как тренировать берт?
- Включить mixed-precision (нужно помасштабировать loss)
- Включить XLA, чтобы учиться быстрее.
- Укоротить предложения с 128 до 80 (качество не упало
- Можно срезать число слоёв с 12 до 8-10
- Тренироваться horovod'ом на куче GPU
- Заране токенизировать обучающую выборку
Как использовать берт:
- Батчифицировать запросы (по 32)
- Mixed-precision -> x2 speedup
- XLA (ещё +20%)
Всё это позволяет добиться скорости выполнения, пригодной для продакшна. Ура!