- BrainTools - https://www.braintools.ru -

В задаче обучения [1] модели машинного перевода есть приятный момент: вы находите несколько миллионов пар предложений и на секунду чувствуете, что самая трудная часть уже позади. Потом открываете случайную строку. Слева — предложение, справа — фрагмент таблицы. У следующей пары совпадает тема, но не смысл. Ещё чуть дальше кто-то заботливо положил в текст остатки HTML. Датасет приехал с мебелью предыдущих жильцов.
Для малоресурсных языков к этому добавляется ограниченность параллельных данных. Поэтому здесь особенно полезно понимать, что именно модель получает на вход и какую архитектуру мы пытаемся на этом обучить.
На связи Аня Лебедева, разработчик в отделе экспериментальных технологий AI VK, и сегодня я расскажу про kazRush — систему перевода с русского на казахский и обратно. Мы собрали и очистили корпус из открытых источников, обучили модели с нуля и подобрали конфигурацию модели примерно на 197 миллионов параметров. По дороге выяснилось, что более строгая очистка иногда ухудшает результат, бо́льший словарь не обязательно полезнее, а увеличение модели до 738 миллионов параметров само по себе не решает задачу. В общем, несколько вполне разумных идей пришлось проводить обратно до двери, но итоговый результат оправдал усилия. Русско-казахская модель заняла первое место в своём треке на LoResMT 2026 — воркшопе при конференции EACL.
Русский и казахский языки используются в образовании, медиа, государственных сервисах и повседневном общении. Практических сценариев для перевода достаточно. С данными ситуация сложнее: наличие миллионов носителей языка ещё не означает наличия сопоставимого количества качественных пар «предложение — перевод».
У казахского есть и особенность, которую приходится учитывать при обучении: это агглютинативный язык. К основе последовательно присоединяются аффиксы, и получается множество словоформ. Для модели это означает больше вариантов, которые нужно связать друг с другом и научиться переводить. Когда примеров мало, часть этих вариантов встречается редко.
Крупные мультиязычные модели дают хорошую отправную точку, но нам было интересно, какого качества можно добиться у специализированной системы, если тщательно подготовить двуязычные данные и подобрать под них архитектуру.
Основным прикладным направлением был перевод с русского на казахский. Обратную модель обучили заодно: к этому моменту корпус и пайплайн уже были готовы. Токенизатор и принципы построения архитектуры у 2 направлений одинаковые, веса — собственные.
Данные взяли из всех открытых ресурсов, которые смогли найти:
|
Источник |
Пар предложений до фильтрации, приблизительно |
|---|---|
|
OPUS |
718 тысяч |
|
KazParC |
2,15 миллиона |
|
WMT19 |
5,063 миллиона |
|
Turkic Interlingua, TIL |
4,403 миллиона |
Получилось около 12,3 миллиона пар до фильтрации и отбора корпусов. Источники помогали расширять покрытие: например, данные WMT добавляли государственные, юридические, институциональные и новостные тексты, а среди ресурсов OPUS были субтитры и выступления TED.
При объединении датасетов мы сохраняли для каждой записи метку источника. Это небольшое решение потом оказалось очень удобным. Если странность повторяется в тысячах строк, полезно выяснить, какой корпус её принёс.
Очистку разделили на общую, которую проходят все данные, и отдельные правила для конкретных корпусов.
Сперва пройдёмся по тривиальным способам очистки данных. Они могут быть очевидными, но важно упомянуть, что и мы не пренебрегли ими, так как это основа качественной предобработки.
Удалили точные дубликаты
Убрали HTML-теги, другую разметку, мусорные символы
Применили Unicode-нормализацию NFKC
Убрали дублирующиеся пробелы, разделители и другую лишнюю пунктуацию
Каждое предложение в паре независимо проверяли моделью определения языка fastText [2]. Оставляли пары, в которых предсказанные языки соответствовали ожидаемому направлению перевода. Например: для направления «русский — казахский» убеждались, что source sentence детектится как текст на русском, target sentence — как текст на казахском
В качестве ещё одной проверки использовали LaBSE [3]: получали мультиязычные эмбеддинги source- и target-предложений, вычисляли их скалярное произведение и удаляли пары со значением ниже выбранного вручную порога 0,4. Логично [4] было бы адаптировать порог под каждый датасет, но подбор начал занимать много времени плюс работал всё ещё нестабильно, так что остановились на едином значении, потеряв немного хороших пар и пропустив немного плохих
Теперь перейдём к нетривиальной части. После стандартной предобработки у нас всё ещё оставалось достаточно много нестыкующихся пар. Нужно было выдумать правила, согласно которым мы сможем отыскивать и удалять такие экземпляры. Одной из идей стала проверка чисел. Мы извлекали последовательности чисел с обеих сторон и сравнивали их как сеты. Сверять упорядоченные списки не было смысла — из-за особенностей грамматики в источнике и переводе числа в предложении могут идти в разном порядке, а так учитывается и состав, и количество повторений, но одинаковый порядок не требуется.
При обнаружении несовпадения пара предложений отправлялась на ручную проверку. Автоматически удалять её было бы слишком жёстко: числа могут быть корректно записаны разными способами, например в источнике — цифрами, а в переводе — словами. Если при ручной проверке выявлялся такой случай, числа приводились к одному формату. А если проверка показывала, что тексты с несовпадением чисел не являются переводами друг друга, пару исключали.
После первой итерации обучения обнаружили, что, с какой бы буквы (заглавной или прописной) ни начиналось предложение-источник, перевод всегда стартовал с заглавной. Это некорректно, так как пользователь не всегда переводит предложение целиком, да и в целом, какие бы ни были причины, для перевода важно сохранить формат исходного текста.
Такое поведение [5] оказалось следствием данных, на которых строилось наше обучение: в корпусе нашлось 237 859 предложений на русском языке, начинающихся со строчной буквы, и у половины из них казахский перевод начинался с прописной.
Проверили вручную сотню случайных примеров. В большинстве случаев различие выглядело как артефакт подготовки корпуса; лишь небольшая часть требовала сохранить исходный регистр. Поэтому добавили правило: если исходное предложение начинается со строчной буквы, первый символ перевода тоже переводим в нижний регистр, остальной текст не меняем.
Мы хотели отсеять строки, в которых вместо текста — сотня восклицательных знаков или россыпь тире. Для этого считали долю букв и цифр в каждой строке и делили её на длину строки в степени 0,1:
оценка = (число букв и цифр / число всех символов) / длина строки0,1
Интуиция [6]: чем больше в строке знаков препинания и других небуквенных символов, тем меньше вероятность, что это настоящее предложение. Деление на длину в степени 0,1 дополнительно снижает оценку для длинных строк, поскольку мы оперируем на уровне предложений, и очень-очень длинная строка — это подозрительно. Пару оставляли, если у каждого из двух текстов оценка была не ниже 0,4.
Alignment score из подручных средств
Исследовали гипотезу, что, если источник и перевод сильно отличаются по длине в символах, это, скорее всего, не пара «текст — перевод». После изучения эталонных переводов из датасета FLORES+ и ручной проверки других данных приняли допустимое отношение длин от 0,5 до 2,0. То есть, если одно предложение из пары «source — target» длиннее другого более чем вдвое, пару удаляли.
В начале пайплайна мы уже удалили точные дубликаты по всей коллекции. После этого мы попробовали находить близкие дубликаты с помощью MinHash LSH — подхода для поиска похожих записей. Ожидание понятное: меньше повторов — разнообразнее обучение. Но в наших экспериментах после такой обработки качество итоговой модели ухудшилось.
Возможное объяснение — похожие предложения в условиях ограниченных данных работают как естественная аугментация. Модель видит вариации конструкций и получает дополнительные обучающие примеры. Это гипотеза, но практический вывод из эксперимента вполне конкретный: удаление близких дубликатов в финальный рецепт не вошло.
После общей очистки мы отдельно просматривали корпуса. У субтитров встречались собственные артефакты и мусорные символы, для которых понадобились специальные регулярные выражения. В другом источнике обнаружились искусственные номера в начале предложений. У некоторых длинных пар начало и конец относились к разному содержанию: выравнивание было лишь частичным.
Когда находили повторяющуюся проблему, обновляли обработку и запускали её заново. Метка источника позволяла ограничить специальное правило теми данными, для которых оно было нужно.
В результате состав корпуса изменился:
KazParC сохранили почти целиком после базовой проверки. При ручном просмотре и исходные тексты, и синтетическая часть показали высокое качество
Из OPUS оставили очищенные OpenSubtitles, QED, TED Talks, TED2020, Tatoeba-2022 и Tatoeba-2023
Данные TIL включили после более серьёзной очистки
MultiCCAligned и WikiMatrix исключили из-за проблем с качеством и выравниванием
После всех этапов осталось 9 054 960 пар предложений.
Токенизатор разбивает текст на небольшие части — токены, с которыми работает модель. Для kazRush обучили общий SentencePiece-токенизатор на русской и казахской частях очищенного корпуса. Размер словаря составил 8 000 подсловных единиц.
Проверили и вариант на 16 000 единиц. Он немного ухудшил итоговое качество, поэтому остановились на предыдущем варианте. Полученный SentencePiece преобразовали в токенизатор T5 из Hugging Face и использовали во всех экспериментах.
Мы использовали Transformer с энкодером и декодером на базе T5. Энкодер обрабатывает исходное предложение с учётом контекста, декодер поэтапно строит перевод и обращается к представлениям исходного текста через cross-attention. Мы обучали модель перевода на параллельных примерах и выбрали архитектуру, непосредственно подходящую для этой задачи. Попытка получить сильный переводчик на базе decoder-only модели с нуля потребовала бы рассматривать другой баланс данных, размера модели и вычислений.
Все модели обучались с нуля, со случайной инициализации. Готовые предобученные веса T5 не использовались.
Сначала сравнили стандартные конфигурации T5-Small, T5-Base и T5-Large. Затем собрали собственную: сохранили относительно небольшие размеры скрытого представления и внимания [7], как у T5-Small, но увеличили глубину энкодера и декодера, а также размер feed-forward блоков.
|
Параметр итоговой модели |
Значение |
|---|---|
|
Слои энкодера/декодера |
12/12 |
|
Размер скрытого состояния |
512 |
|
Головы внимания |
8 |
|
Размерность головы |
64 |
|
Размер полносвязного слоя |
4 096 |
|
Размер словаря |
8 000 |
|
Dropout |
0,1 |
|
Функции активации |
Gated GELU |
|
Количество параметров |
≈ 197 миллионов |
Предположение было таким: при нашем объёме данных увеличение глубины и ёмкости feed-forward блоков может быть полезнее сильного расширения размерности скрытого состояния и внимания. Почему такая конфигурация может выигрывать? Дополнительные слои позволяют последовательно уточнять представления текста: каждый следующий слой работает с результатом предыдущего. А увеличение промежуточной размерности feed-forward блоков позволяет вычислять больше признаков для каждого токена, что, в свою очередь, позволяет учитывать больше разных сочетаний признаков — например, лексических, грамматических и контекстных — при обновлении представления токена. При этом мы сохраняем компактные размерности скрытого состояния и внимания, ограничивая число параметров, которые нужно обучить на доступных параллельных данных. Так мы направляем дополнительную ёмкость модели в глубину обработки и преобразования признаков. В наших абляционных экспериментах такое распределение параметров оказалось удачнее, чем у стандартных конфигураций T5, включая существенно более крупную T5-Large.
Максимальную длину последовательности ограничили 128 токенами. Использовали batch size 128 с накоплением градиентов и смешанную точность BF16. Learning rate составлял 0,003, разогрев — 1 000 шагов, label smoothing — 0,1.
Обучение продолжалось до 300 тысяч шагов оптимизации. Чекпойнт выбирали по validation loss.
При сравнениях генерировали переводы одинаково: beam search с тремя лучами, без sampling и с early stopping.
Для валидации использовали датасет FLORES+ dev, а результаты сравнивали на датасете FLORES+ devtest. Смотрели на три метрики:
BLEU оценивает совпадения последовательностей слов с эталонным переводом и штрафует слишком короткие ответы
chrF сопоставляет символьные n-граммы. Для богатой морфологии это полезно — совпадение части словоформы тоже учитывается
COMET — нейросетевая оценка, которая использует исходный текст, перевод модели и эталон
Для всех трёх метрик значение больше — лучше.
Для направления «русский — казахский» получили следующие результаты:
|
Модель |
Параметры |
BLEU |
chrF |
COMET |
|---|---|---|---|---|
|
T5-Small |
64,8 млн |
15,6 |
51,2 |
0,8764 |
|
T5-Base |
220 млн |
16,2 |
51,8 |
0,8822 |
|
T5-Large |
738 млн |
15,8 |
51,6 |
0,8804 |
|
Custom-Large |
197 млн |
16,2 |
51,9 |
0,8836 |
Собственная конфигурация оказалась почти в 4 раза меньше T5-Large по числу параметров и получила лучшие chrF и COMET среди этих вариантов. По BLEU она разделила первое место с T5-Base.
В обратном направлении собственная архитектура тоже обошла T5-Small: BLEU вырос с 17,5 до 18,8, chrF — с 47,4 до 48,7, COMET — с 0,8556 до 0,8672.
Результаты для направления «казахский — русский» на FLORES+ devtest:
|
Модель |
BLEU |
chrF |
COMET |
|---|---|---|---|
|
T5-Small |
17,5 |
47,4 |
0,8556 |
|
Custom-Large |
18,8 |
48,7 |
0,8672 |
Создавая модель, невозможно не учитывать уже существующих решений. В этом контексте в первую очередь мы должны были провести сравнение с NLLB — большой мультиязычной моделью от Facebook, которая в том числе поддерживает пару «русский — казахский», хотя её вариации и не содержат таких компактных моделей, как наша. Сравнили модели на FLORES+ devtest для обоих направлений. Лучшие значения выделены отдельно для каждого направления.
|
Модель |
Параметры |
BLEU |
chrF |
COMET |
|---|---|---|---|---|
|
NLLB distilled 600M |
600 млн |
13,8 |
48,2 |
0,868 |
|
NLLB 1.3B |
1,3 млрд |
14,8 |
50,1 |
0,881 |
|
NLLB distilled 1.3B |
1,3 млрд |
15,2 |
50,2 |
0,884 |
|
NLLB 3.3B |
3,3 млрд |
15,6 |
50,7 |
0,889 |
|
kazRush |
197 млн |
16,2 |
51,8 |
0,883 |
|
Модель |
Параметры |
BLEU |
chrF |
COMET |
|---|---|---|---|---|
|
NLLB distilled 600M |
600 млн |
18,0 |
47,3 |
0,856 |
|
kazRush |
197 млн |
18,8 |
48,7 |
0,867 |
|
NLLB 1.3B |
1,3 млрд |
20,4 |
49,3 |
0,879 |
|
NLLB distilled 1.3B |
1,3 млрд |
20,8 |
49,6 |
0,881 |
|
NLLB 3.3B |
3,3 млрд |
21,5 |
50,7 |
0,887 |
На FLORES+ devtest русско-казахская модель kazRush превзошла все сравниваемые варианты NLLB по BLEU и chrF. Например, у NLLB 3.3B были 15,6 BLEU и 50,7 chrF, у kazRush в таблице этого сравнения — 16,2 и 51,8.
По COMET практически паритет с NLLB 3.3B: 0,889 против 0,883 у kazRush. Но размер моделей несопоставим: использовать NLLB для практической задачи было бы гораздо дольше.
При переводе с казахского на русский kazRush обошла distilled NLLB 600M, но уступила более крупным сравниваемым NLLB на 1,3 и 3,3 миллиарда параметров. Специализированная модель оказалась особенно успешной именно в направлении «русский — казахский».
Русско-казахская модель участвовала в соревновании LoResMT 2026. Основной метрикой ранжирования была chrF; система заняла первое место в русско-казахском треке.
Тест содержал 4 626 пар, поровну разделённых между публичной и приватной частями. Ниже — результаты на исходном тесте соревнования, все значения приведены в chrF.
|
Система |
Public |
Private |
|---|---|---|
|
kazRush |
76,77 |
76,24 |
|
NLLB-200 3.3B |
54,56 |
54,08 |
|
NLLB-200 1.3B |
53,97 |
53,38 |
|
TranslateGemma 27B |
51,48 |
51,08 |
|
KazLLM 8B |
51,38 |
51,12 |
|
Llama-3.1-8B-kkru |
50,35 |
49,64 |
На приватной части теста отрыв от NLLB-200 3.3B составил 22,16 пункта chrF.
Самые полезные решения оказались довольно конкретными. Сохранять происхождение каждой пары. Смотреть данные руками. Проверять числа, регистр, язык и смысловую согласованность отдельными этапами. Измерять эффект очистки на итоговой модели — в том числе когда новая фильтрация выглядит очевидным улучшением.
С архитектурой сработал похожий подход: сравнили несколько конфигураций и нашли удачное распределение параметров для своей задачи. Модель на 197 миллионов параметров оказалась сильнее более крупной T5-Large в наших внутренних экспериментах, а на соревновании уверенно обошла сравниваемые мультиязычные системы.
Ссылки на модель:
Автор: Kartoshkina
Источник [10]
Сайт-источник BrainTools: https://www.braintools.ru
Путь до страницы источника: https://www.braintools.ru/article/37983
URLs in this post:
[1] обучения: http://www.braintools.ru/article/5125
[2] fastText: https://huggingface.co/facebook/fasttext-language-identification
[3] LaBSE: https://huggingface.co/sentence-transformers/LaBSE
[4] Логично: http://www.braintools.ru/article/7640
[5] поведение: http://www.braintools.ru/article/9372
[6] Интуиция: http://www.braintools.ru/article/6929
[7] внимания: http://www.braintools.ru/article/7595
[8] https://huggingface.co/deepvk/kazRush-ru-kk: https://huggingface.co/deepvk/kazRush-ru-kk
[9] https://huggingface.co/deepvk/kazRush-kk-ru: https://huggingface.co/deepvk/kazRush-kk-ru
[10] Источник: https://habr.com/ru/companies/vk/articles/1103230/?utm_campaign=1103230&utm_source=habrahabr&utm_medium=rss
Нажмите здесь для печати.