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

С момента прошлого релиза мы улучшили качество наших моделей более чем на 10%, добавили правку знаков пунктуации и регистра, провели эксперименты по сжатию и ускорению полученных решений, добавили разметку пунктуации в датасеты и новые метрики в библиотеку, а нашу статью взяли на EACL 2024 в Мальте. 

Продолжаем делиться нашими результатами и вместе с этим постом выкладываем в открытое пользование:

  1. Веса генеративных моделей для коррекции правописания и пунктуации:

    1. Sage-fredt5-large;

    2. Sage-fredt5-95m: дистиллированная версия FRED-T5-1.7B; 

  2. Модель sage-mt5-large для коррекции орфографии одновременно на русском и английском языках;

  3. Модель sage-m2m100-1.2B, дообученная на датасетах с естественными (сделанными человеком) ошибках. Эту модель мы позиционировали как наше лучшее решение и выкладывали в качестве Cloud AI Service, теперь ей можно пользоваться так же как любой моделью из HuggingFace Hub;

  4. Дополнительная разметка для наших датасетов: теперь добавили корректную пунктуацию; 

  5. В библиотеку SAGE добавили метрику, отдельно учитывающую орфографические, пунктуационные ошибки и ошибки регистра. Кроме того, библиотека теперь полностью задокументирована, документация находится здесь

Модели sage-fredt5-large и sage-mt5-large выкладываются после предобучения, а sage-fredt5-95m и sage-m2m100-1.2B после дообучения. 

Далее расскажем обо всем по порядку.

Что будет дальше

Новая процедура предобучения

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

Мы показали (Таблица 1 в статье или Таблица из главы Дообучение в посте), что этап предобучения на синтетических данных оказывает ключевое влияние на способность модели исправлять ошибки. Развивая этот результат, мы дополнили sequence-to-sequence задачу дополнительными функционалами, которые модель должна была оптимизировать вместе с исходным. 

Выбор моделей

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

Однако на текущей стадии мы практически полностью перешли на моноязычные модели энкодер-декодерного типа из семейства FRED-T5 размера large и 1.7B из соображений простоты использования, производительности и, не в последнюю очередь, показываемых результатов. 

Распознавание ошибок энкодером

Предобучение моделей вида энкодер-декодер в нашей задаче во многом основывается на генерации корректных последовательностей из зашумлённых. Последние получаются в результате применения к изначально грамотным текстам алгоритмов намеренного искажения правописания, например, SBSC (Statistic Based Spelling Corruption) или Augmentex. Каждый из алгоритмов в том или ином виде «искажает» исходный текст с помощью ряда опечаток, которые можно разделить на следующие типы: вставка, удаление, замена одного символа, перемена мест двух соседних символов и удаление и вставка разделителя (пробела). 

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

Распознавание ошибок энкодером
Распознавание ошибок энкодером

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

Благодаря тому, что и SBSC, и Augmentex запоминают позиции в тексте, куда они вставляют опечатки, мы можем получить разметку входной последовательности для энкодера:

Разметка токенов входной последовательности
Разметка токенов входной последовательности

Сложность представляет только удаление символа из слова: 

text = "Я читаю кус по теории игр" # "Я читаю [курс] по теории игр"

encodings = tokenizer.tokenize(text)
print(encodings)

# ['я', 'читаю', 'ку', '##с', 'по', 'теории', 'игр']

Не ясно, какому из токенов «ку» или «##с» присваивать класс «Deletion», поэтому далее условились присваивать «Deletion» токену слева от позиции удаления. 

Приближение векторных представлений исходного предложения и коррекции

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

Sequence-to-sequence функционал
Sequence-to-sequence функционал

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

-\dfrac{1}{|\mathbf{B}|}\sum_{i=1}^{\mathbf{B}}\sum_{j=1}^{\mathbf{B}} log\dfrac{1}{1 + e^{z_{ij}(-tx_iy_j+b)}}

гдеx_i,y_j — векторные представления, соответствующие исходному предложению и корректному, |\mathbf{B}|— размер массива подаваемых в модель текстов, а z_{ij}принимает значение 1, если i = j,  и −1 в противном случае (за подробностями можно обратиться к статье Sigmoid Loss for Language Image Pre-training). Далее по тексту мы будем упоминать этот функционал в том числе как сигмоид-ошибка (с английского «sigmoid loss» или «sigloss»).

Далее уже в декодер подаётся векторное представление текста с опечатками, полученное на последнем слое энкодера. На выходе декодера так же, как и в базовом случае, считается sequence-to-sequence ошибка, и итоговый функционал для оптимизации получается как линейная комбинация sequence-to-sequence- и сигмоид-ошибок:

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

Здесь нужно оговориться, что, как видно из формулы, значения функции для сигмоид-ошибки в случае текстов, исходно составляющих пару, становятся тем меньше, чем ближе друг к другу векторные представления двух текстов. Это создаёт опасность получения идентичных представлений для обоих предложений из пары. Чтобы этого избежать, мы соответствующим образом подбирали размер подмножества текстов, подаваемых в модель, а также гиперпараметры t (температура) и b (смещение, необходимое для более устойчивой сходимости алгоритма оптимизации). 

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

Возможно, имело бы смысл запустить рыбу в прутт. 

Слово «прутт» может быть заменено (с точки зрения существующих в языке слов) на «прут» или «пруд». Корректная замена определяется разрешением омофонимии относительно контекста, информацию о котором мы как раз пытаемся передать в декодер с помощью приближения векторных представлений двух текстов из одной и той же пары.

Результаты

Для корректного сравнения с ранее полученными метриками замеры проводились по аналогичному сценарию: показатели считаются как для только лишь предобученных моделей (в таблице ниже это Pre-train (PT. / NER / CLIP), NER соответствует моделям, энкодер которых дополнительно учился распознавать ошибки, CLIP — моделям, которые приближают векторные представления исходного предложения и коррекции), так и для дообученных. Дообучение проводилось на комбинации датасетов RUSpellRU и MutlidomainGold (MDG) из коллекции датасетов (бенчмарка) для коррекции правописания spellcheck_benchmark, параметры генерации не менялись и указаны в репозитории SAGE. 

Получившиеся результаты указаны в таблице ниже.

Результаты моделей, обученных с помощь Распознавания ошибок энкодером (NER) и Приближения векторных представлений исходного предложения и коррекции (CLIP)
Результаты моделей, обученных с помощь Распознавания ошибок энкодером (NER) и Приближения векторных представлений исходного предложения и коррекции (CLIP)

Помимо нашего предыдущего лучшего решения sage-m2m100-1.2B, которое мы описывали в первом посте, и новых разработок sage-fredt5-large и sage-fredt5-1.7B мы также включили замеры, произведённые на открытых инструментах Yandex.Speller, JamSpell, Hunspell и моделях gpt-3.5-turbo-0125 и gpt-4-0125-preview, которые на момент написания поста являются актуальными версиями серий gpt-3.5 и gpt-4. 

Для запросов как в gpt-3.5-turbo-0125, так и в gpt-4-0125-preview использовалась инструкция, которую путём проб и ошибок выявили как оптимальную:

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

На текущий момент лучшим решением является вариация модели sage-fredt5-1.7B RUSpellRU+MDG (+NER). Последняя обучалась с помощью дополнительной задачи для энкодера на том же самом корпусе, что и модель sage-m2m100-1.2B (подробности формирования корпуса можно прочитать в посте), разве что зашумление текстов в этот раз было выполнено с помощью Augmentex. Дообучение модели проводилось на комбинации датасетов RUSpellRU и MultidomainGold также с помощью дополнительного функционала для энкодера. 

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

Правка знаков пунктуации и регистра

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

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

Как обычно, в рамках постановки задачи мы сразу же говорим про…

Датасеты

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

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

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

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

Обновлённые датасеты выложены в открытое пользование на HuggingFace, они объединены в коллекцию spellcheck_punctuation_benchmark, пользоваться им можно как обычно:

from datasets import load_dataset

dataset = load_dataset("ai-forever/spellcheck_punctuation_benchmark", “RUSpellRU”)

Метрика

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

В новой постановке в качестве базовой реализации мы использовали ERRANT, адаптированный для русского языка, для которого мы также добавили разделение метрик по категориям ошибок: орфография и грамматика, пунктуация, регистр и неправильная замена буквы «е» на букву «ё».

Метрика вместе с подробным описанием добавлена в репозиторий SAGE. 

Результаты

Для краткости и наибольшей репрезентативности в этой главе мы приводим метрики лучших конфигураций sage-fredt5-1.7B (наше лучшее решение), sage-fredt5-large (открытая предобученная версия) и замеры gpt-3.5-turbo-0125 и gpt-4-0125-preview. Sage-fredt5-large в таблице уже дообучена на корпусах с естественными ошибками из spellcheck_punctuation_benchmark. То есть аналогичные результаты можно получить, дообучив выложенную sage-fredt5-large на новых датасетах из бенчмарка. 

Sage-fredt5-1.7B и sage-fredt5-large предобучались с помощью дополнительного функционала для энкодера, описанного в главе Распознавание ошибок энкодером, на корпусе из 7 гигабайт параллельных текстов, предварительно зашумлённых с помощью Augmentex. Дообучение проходило на датасетах RUSpellRU и MultidomainGold с уже размеченной пунктуацией. Соответствующие корпуса находятся здесь. Мы повторяли те же самые шаги, из которых состоял алгоритм обучения наших моделей для коррекции правописания, с той лишь оговоркой, что теперь, во время стадии подготовки параллельного корпуса для предобучения, кроме намеренного искажения орфографии и грамматики, также использовались аналогичные методы для пунктуации. 

Для формирования запросов в gpt-3.5-turbo-0125 и gpt-4-0125-preview использовалась следующая инструкция:

Перепиши "<text>" без орфографических, пунктуационных, грамматических ошибок и опечаток, сохраняя исходный стиль текста, не раскрывая аббревиатуры, не изменяя корректный текст. Напиши только правильный ответ без дополнительных объяснений.

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

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

Каждый блок соответствует одноимённой модели. Каждая строка в блоке обозначает тип ошибок: орфография и грамматика (Spelling), пунктуация (Punctuation), регистр (Case). Категория Spelling посчитана первоначальной версией метрики, чтобы можно было сравнивать с результатами из предыдущей главы. 

Жирным шрифтом выделены лучшие показатели среди представленных инструментов по каждому набору данных, по каждой категории ошибок (Spelling, Punctuation, Case) и вдоль каждой метрики.

Дистиллированная версия

Практически каждая из наших моделей имеет достаточно существенный размер: миллиард параметров или даже чуть больше. Очевидным следствием являются повышенные требования к ресурсам, которые модель потребляет во время обучения и генерации. Чтобы сделать использование результатов нашей работы более простым с точки зрения необходимых мощностей, мы решили сделать легковесный вариант лучшего решения sage-fredt5-95m

Разработка модели

Sage-fredt5-95m получена из дообученной sage-fredt5-1.7B посредством дистилляции в 95-миллионный (речь про количество параметров) вариант FRED-T5. Весь процесс проходил в три этапа: языковое предобучение FRED-T5-95m, дистилляция на данных для предобучения sage-fredt5-1.7B и дистилляция на датасетах для дообучения. 

Чтобы получить FRED-T5-95m, мы использовали оригинальную архитектуру FRED-T5 только с восемью слоями и шестью головами для механизма внимания и полностью повторили процесс языкового предобучения, описанного в статье, подготовив таким образом модель-«ученика» для последующей дистилляции.

Дистилляция выполнялась на датасетах для предобучения и дообучения sage-fredt5-1.7B по одному и тому же сценарию: модель-«учитель» (sage-fredt5-1.7B) замораживается, то есть параметры в архитектуре далее не обновляются во время процесса обучения, — затем и в «ученика», и в «учителя» подаётся одинаковый набор данных и считается несколько функционалов: дивергенция Кульбака-Лейблера между выходами декодеров «ученика» и «учителя», sequence-to-sequence ошибка «ученика», функционал, описанный в главе Распознавание ошибок энкодером, для «ученика» и средняя квадратичная ошибка активаций между каждым слоем энкодера / декодера «ученика» и соответствующим каждым третьим слоем энкодера / декодера «учителя». Все функционалы затем используются для оптимизации sage-fredt5-95m

Описанная процедура изображена на схеме

Схема процедуры дистилляции
Схема процедуры дистилляции

Результаты

Формат замеров аналогичен предыдущей главе. В таблице представлены лучшие конфигурации sage-fredt5-1.7B (наше лучшее решение), sage-fredt5-large (открытая предобученная версия), sage-fredt5-95m и замеры gpt-3.5-turbo-0125 и gpt-4-0125-preview. Все три модели семейства sage уже дообучены на датасетах с естественными ошибками из коллекции spellcheck_punctuation_benchmark. 

Кроме этого, мы добавили сравнение с открытым Yandex.Speller, нашим предыдущим лучшим решением sage-m2m100-1.2B и моделями gpt-3.5-turbo-0125 и gpt-4-0125-preview. Для Yandex.Speller и sage-m2m100-1.2B приведены только замеры правки орфографии и грамматики, потому что Yandex.Speller пунктуацию не правит, а sage-m2m100-1.2B была предназначена только для ошибок типа Spelling. 

Для формирования запросов в gpt-3.5-turbo-0125 и gpt-4-0125-preview использовалась инструкция из предыдущей главы.

Замеры представлены в таблице:

Результаты дистиллированной версии
Результаты дистиллированной версии

Дистиллированная модель находится на одном уровне с предыдущим лучшим решением sage-m2m100-1.2B, при этом имея в 12 раз меньше параметров. Пользоваться моделью можно, как и всеми остальными открытыми решениями семейства sage, через функционал HuggingFace:

from transformers import pipeline

pipe = pipeline("text2text-generation", model="ai-forever/FRED-T5-1.7B-spell-distilled-100m")

Там же, на странице с карточкой, можно протестировать модель в разделе Inference API.

Мультиязычность

Уже в самом начале нашей работы мы закладывали перспективу для развития мультиязычной проверки правописания: так, в нашей первой работе мы описывали эксперименты по исправлению орфографии и грамматики для английского языка, в результате которых решение на основе T5 приблизилось и даже немного обошло gpt-3.5-turbo-0301 и gpt-4-0314 на англоязычных датасетах. 

Мы продолжаем работу в рамках этого направления и выкладываем в открытое пользование модель sage-mt5-large, способную исправлять орфографию и грамматику одновременно как русского, так и английского языков. 

Модель разрабатывалась, следуя алгоритму, описанному в предыдущем посте и главе Распознавание ошибок энкодером: корпус для предобучения на русском языке брался точно такой же, как и в других экспериментах с русским языком, на английском языке – датасет, собранный из текстов англоязычной Википедии и заголовков новостей, очищенных от неалфавитных символов и длиной больше 40 знаков. Размеры датасетов для двух языков совпадают. В качестве тестовых наборов для английского языка использовались JFLEG и BEA60K

Для зашумления текста на обоих языках применялся Augmentex, процедура предобучения идентичная описанной в главе Распознавание ошибок энкодером. В качестве базовых моделей рассматривались модели семейства M2M100, NLLB200, mT5. По результатам ряда экспериментов и соображениям эффективности остановились на mt5-large

Итоговые результаты для русского языка выглядят следующим образом:

Результаты мультиязычной модели на датасетах для русского языка
Результаты мультиязычной модели на датасетах для русского языка

И для английского языка:

Результаты мультиязычной модели на датасетах для английского языка
Результаты мультиязычной модели на датасетах для английского языка

Показатели для русского языка представлены аналогично соответствующей таблице в главе Распознавание ошибок энкодером: метрики для моделей sage-m2m100-1.2B, sage-fredt5-large, sage-fredt5-1.7B совпадают с конфигурациями RUSpellRU+MDG (+PT.) и RUSpellRU+MDG (+NER).  Для корректного сравнения sage-mt5-large здесь также дообучена на датасетах RUSpellRU и MultidomainGold, замеры произведены первоначальным вариантом метрики, учитывающим только орфографические и грамматические ошибки. 

Для английского языка подсчёты велись той же самой метрикой, результаты sage-mt5-large получены сразу после предобучения. Кроме этого мы использовали модели gpt-3.5-turbo-0301 и gpt-4-0314 для экспериментов на английском языке с инструкцией:

Rewrite "<text>" without spelling errors, grammatical errors and typos, preserve the original text style, punctuation, do not open abbreviations and do not change the correct text. Do not provide any interpretation of your answer.

Из таблиц видно, что sage-mt5-large опережает sage-m2m100-1.2B для русского языка и находится достаточно близко к моноязычной sage-t5-large и моделям семейства gpt. 

Использовать модель можно, например, вот так:

from transformers import pipeline

pipe = pipeline("text2text-generation", model="ai-forever/mT5-large-spell-ru-en")

text = '''Перведи мне текст на аглиском: "Screw you kuys, I am goin hme (c).'''
print(pipe(text)[0]["generated_text"])

# Переведи мне текст на английском: "Screw you guys, I am going home" (c).

Вместо заключения: ближайшие планы

Основной вектор работы теперь сосредоточен вокруг применения обучения с подкреплением и дальнейшего добавления языков в SAGE. Мы открыты для коллаборации, и если у вас есть идея, на каком языке ещё стоит дообучить спеллчекер, есть данные и новые домены, а также желание с нами сотрудничать — пишите, пожалуйста, нам в ТГ-коммьюнити SaluteTechGroup и авторам статьи. 

Ссылки:

  1. Библиотека SAGE на GitHub и документация;

  2. Модели sage-m2m100-1.2B, sage-fredt5-large, sage-fredt5-95m, sage-mt5-large на Hugging Face;

  3. Хаб с датасетами для спеллчека на Hugging Face;

  4. Наши академические публикации:

    1. A Methodology for Generative Spelling Correction via Natural Spelling Errors Emulation across Multiple Domains and Languages [EACL 2024]

    2. Augmentation methods for spelling corruptions

  5. Доклад на Giga R&D Day.

#lms #языковые модели #NLP #spell-correction #проверкаорфографии #augmentation

Команда разработчиков: SberDevices, AGI NLP — идея и обучение моделей @NikitaMartynov @ulyanaisaeva @DanAsOne @Technolog796и команда SberDevices, Собеседника — создатели Augmentex @Andriljo@e0xextazy <3

Комментарии (3)


  1. belonesox
    11.04.2024 10:20

    А не могли бы вы ollama модель сразу сделать, чтобы ollama могла из коробки ее поставить (ollama pull)?


    1. DanAsOne
      11.04.2024 10:20

      Модели Llama и прочие в ollama - декодеры, все наши модели пока являются энкодер-декодерами


      1. avdosev
        11.04.2024 10:20

        Пробовали обучать декодер модель? Если нет, то почему?