GigaAm-Sakha-Multilingual

Якутский (саха) ASR: дообучение ai-sage/GigaAM-Multilingual (large_ctc, 600M Conformer, посимвольный CTC) на 265 ч речи. Модель остаётся билингвальной — русский сохранён намеренно, потому что живая якутская речь постоянно на него переключается.

В комплекте 4-граммная языковая модель KenLM, обученная на 49 млн токенов якутского текста; с ней WER на незнакомом дикторе падает ещё на 26% относительных.

Отдельно поставляется декодирование без лексикона — символьная языковая модель 12-го порядка плюс переранжирование нейронной моделью на 103M параметров. На незнакомом дикторе оно даёт 8.84% против 10.98% у обычного словесного beam search: −19.5% относительных. Подробности ниже, в разделе «Декодирование без лексикона».

Обновление 2026-11: v8c

gigaam-sakha.ckpt заменён на v8c: та же архитектура и тот же алфавит (70 символов, ҕ→ғ, ҥ→ң), код использования не меняется. Прежний чекпойнт доступен по тегу 2026-09-05.

v8c — адаптация к спонтанной речи: старт с чекпойнта v4, дообучение на спонтанной речи из платформы разметки Тыл (только сегменты с согласием разметчиков, consensus) вместе с читкой-сопровождением; доля спонтанной речи в батче 23%, 4 эпохи, lr 1e-5.

Замер на отложенном спонтанном тесте (307 сегментов, 2335 слов, дикторы и записи в обучение не входили). Веса языковых моделей подбирались на одной половине высказываний и применялись к другой:

декодирование WER
жадное 14.48%
без лексикона, decoding/char12.binary, + нейронная 103M 8.99%
без лексикона, decoding/char12_full.binary, + нейронная 103M 8.35%

decoding/char12_full.binary — новая символьная KenLM (собрана на порядок 12 из corpus_full: книги, веб, вики, транскрипты обучения; утечки dev/test сняты). С ней лучший вес первого прохода — lm_weight=1.0, а не 1.5.

speechkit/ — v8c для CPU-инференса в сервисе speech-kit: model.int8.onnx (энкодер + CTC-голова, динамическая int8-квантизация весов MatMul, 798 МБ вместо 2.3 ГБ), melbank.f32 и window.f32 (мел-банк и окно ровно из torchaudio-препроцессора), manifest.json (входы/выходы, параметры фичей, sha256 исходного чекпойнта) и vocab.json. В vocab.json символы уже в якутской орфографии (ғ→ҕ, ң→ҥ), обратное отображение не нужно. lm.bin — словесная 3-граммная модель сервиса (13.7 млн n-грамм, 153 МБ) в его собственном формате; kenlm её не читает.

Не перемерено: таблицы ниже (unseen_speakers и другие срезы) относятся к прежнему чекпойнту. На начитке v8c не замерялась.

Результаты

WER / CER, %, на отложенном тесте. unseen_speakers — диктор, не встречающийся в обучении ни одной записью; это и есть честная оценка обобщения. seen_speakers — отложенные записи чтецов, которые в обучении присутствуют.

Срез Объём База (zero-shot) Дообучено, greedy + 4-gram LM
unseen_speakers 1 051 / 2.1 ч 88.10 / 29.96 14.81 / 2.75 10.91 / 2.13
seen_speakers 5 429 / 10.8 ч 87.15 / 31.80 11.11 / 1.94 9.80 / 1.75
external_sakha 291 / 0.5 ч 91.55 / 41.08 10.54 / 1.98 7.14 / 1.50
all_sakha 6 771 / 13.4 ч 87.43 / 31.79 11.66 / 2.06 9.90 / 1.80
guard: русский (CV) 678 / 1.0 ч 1.41 / 0.26 1.83 / 0.32 1.77 / 0.34
guard: киргизский (CV) 263 / 0.3 ч 6.81 / 2.63 8.36 / 2.79 9.41 / 3.25

Русский почти не пострадал (1.41 → 1.77): в обучении 7.4% Common Voice ru именно ради этого. Киргизский с языковой моделью просаживается — в её корпусе киргизского текста нет, и она штрафует киргизские гипотезы; акустическая модель при этом не менялась. Для киргизского декодируйте без LM.

Ключевая деталь: алфавит

Словарь базовой модели (70 символов) уже покрывает 36 из 38 якутских букв, включая ү, һ, ө. Недостающие две отображены на казахско-киргизские эквиваленты тех же фонем:

Якутский В модели Фонема
ҕ U+0495 ғ U+0493 /ʁ/, звонкий увулярный фрикатив
ҥ U+04A5 ң U+04A3 /ŋ/, велярный носовой

Благодаря этому CTC-голова не переинициализировалась: соответствующие выходы уже были обучены на нужные звуки казахскими данными GigaAM (1031 ч). Побочная выгода — модель сохранила русский, казахский, киргизский и английский.

Вывод модели нужно отображать обратно, иначе получится не якутская орфография. Обратное отображение однозначно: своих ғ/ң в якутском нет.

Использование

import gigaam

model = gigaam.load_model("gigaam-sakha.ckpt")     # путь к файлу, не имя модели
TO_SAKHA = str.maketrans({"ғ": "ҕ", "ң": "ҥ"})

print(model.transcribe("audio.wav").text.translate(TO_SAKHA))

С языковой моделью (−26% отн. WER на незнакомом дикторе):

import torch, soundfile as sf
from pyctcdecode import build_ctcdecoder

decoder = build_ctcdecoder(
    list(model.decoding.tokenizer.vocab) + [""],          # blank последний
    kenlm_model_path="sakha4.binary",
    unigrams=[w.strip() for w in open("unigrams.txt", encoding="utf-8") if w.strip()],
    alpha=0.4, beta=-1.0,                                 # подобрано на dev
)

audio, sr = sf.read("audio.wav", dtype="float32")         # 16 кГц моно
wav = torch.tensor(audio).unsqueeze(0)
with torch.inference_mode():
    enc, enc_len = model(wav, torch.tensor([wav.shape[1]]))
    logprobs = model.head(enc).float().cpu()
text = decoder.decode(logprobs[0, : int(enc_len[0])].numpy(), beam_width=100)
print(text.translate(TO_SAKHA))

Построение декодера занимает ~25 с (trie из 2.25 млн словоформ) — делать один раз, не в цикле по файлам.

Окружение

Python 3.11 (не 3.13 — kenlm там не собирается), gigaam из git, не с PyPI:

uv venv --python 3.11 .venv && source .venv/bin/activate
uv pip install torch torchaudio numpy soundfile hydra-core omegaconf \
    sentencepiece tqdm pyctcdecode kenlm
uv pip install --no-deps "git+https://github.com/salute-developers/GigaAM.git"

Обучение

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

Источник Часов
Выровненные аудиокниги (4 чтеца) 231
Common Voice 19 русский 18.9
volodya-leveryev/sakha-asr 7.2
Common Voice 19 киргизский 6.0
lab-ii/asr-sakha 1.7

Гиперпараметры. lr 2e-5 (AdamW), warmup 10% и косинус, weight decay 0.01, клип 1.0, batch 64, bf16, 10 эпох, валидация каждые четверть эпохи, SpecAugment (2 частотные и 2 временные маски). Один H200, ~4 ч на прогон.

Первая попытка на lr 5e-5 разошлась сразу после выхода из warmup: loss удвоился с 10.7 до 25.8 и не восстановился. 2e-5 — документированный дефолт GigaAM для продолжения обучения готовой ASR-модели.

Аугментации. 14 000 кодсвитчинговых склеек (якутский сегмент + русский клип в одном семпле, выравнивание энергии, overlap-add с кросс-фейдом 50 мс) и 5 879 клипов с изменённой скоростью 0.9/1.1. Бутстрэп по высказываниям показал значимый эффект ровно на одном срезе — unseen_speakers, 15.26 → 14.81, 95% ДИ [−0.82, −0.06]. Остальные срезы неразличимы. Выигрыш, судя по всему, дало возмущение скорости; кодсвитчинговые склейки оценить нечем — все срезы одноязычные.

Языковая модель

4-грамма KenLM: 4.32 млн строк, 49.4 млн токенов, 2.25 млн словоформ, из книг и транскриптов обучающего сплита. Отсечение синглтонов третьего и четвёртого порядка (--prune 0 0 1 1), бинарник 456 МБ.

Из корпуса исключены 59 книг, которые читаются в dev и test — иначе языковая модель знала бы тестовые предложения дословно, и замер был бы недействителен. Это стоит учитывать при сравнении с системами, где такого исключения не делали.

Коэффициенты подбирались на dev, не на тесте: α=0.4, β=−1.0, beam 100. Оптимум очень пологий — вся область α∈[0.2, 0.5], β∈[−1.0, 0] укладывается в 0.2 пункта WER, — поэтому точное значение внутри неё роли не играет. Выше α≈0.9 качество резко падает: языковая модель начинает перебивать акустику.

Что не помогло

Проверены две очевидные ручки словной n-граммы. Каждая модель оценивалась со своим оптимумом, подобранным на одной и той же выборке dev из 2 500 высказываний; значимость — бутстрэп по высказываниям.

Вариант unseen_speakers Размер
4-грамма с отсечением (в комплекте) 10.92 456 МБ
4-грамма без отсечения 10.91 1.17 ГБ
5-грамма без отсечения 10.74* 1.73 ГБ

* при коэффициентах, выбранных не по dev; при честном подборе — то же, что и остальные.

Отказ от отсечения не даёт ничего измеримого: разница −0.01, 95% ДИ [−0.17, +0.15]. И это несмотря на то, что отсечение выбрасывало 94% всех четырёхграмм (40.7 млн → 2.59 млн). Повышение порядка до пяти тоже ничего не даёт. Поэтому в комплекте идёт обрезанная модель — она втрое меньше при неотличимом качестве.

Почему словная n-грамма упёрлась в потолок, видно из разбора ошибок: 97% пропусков её словаря — это известная основа с невиданной суффиксальной цепочкой, то есть учебниковая агглютинативная проблема. Литература предлагает морфемные модели, но с оговоркой, которая ровно про наш случай: у Enarvi et al. (2017) при полном словаре в 2.4 млн форм и OOV 2.31% сабвордная n-грамма не дала ничего (31.7 против 31.7). У нас 2.25 млн форм и OOV 2.23%. Классические выигрыши морфемных моделей получены при словарях в 50–400 тысяч, где OOV достигал 9%; мы уже за пределами того режима. Вдобавок pyctcdecode сабвордные модели не поддерживает конструктивно — его языковая модель словная по устройству.

Что помогло: переранжирование n-best

Единственная ручка, давшая эффект за пределами шума. Оракул по n-best (выбор заведомо лучшей гипотезы из списка) даёт 7.95% против 10.98% у 1-best — верная гипотеза обычно уже присутствует и просто ранжируется ниже неверной. n-грамма исправить это не может: случаи, где она ошибается, требуют контекста шире четырёх слов.

В комплекте neural_lm/ — небольшая Llama (33.1M параметров, 8 слоёв, 512, SwiGLU/RMSNorm/RoPE, сабвордный BPE на 16 тыс.), обученная на том же корпусе с тем же исключением 59 книг. Перплексия 93.4.

Система WER Против 1-best 95% ДИ
1-best декодера 10.98 — —
+ переранжирование 10.11 −0.87 (−7.9%) [−1.08, −0.66]

Веса линейной комбинации подобраны на dev и применены к тесту без изменений: акустика 1.0, n-грамма 1.0, нейросетевая модель 1.2, длина 0.0. Реализация — scripts/rescore.py в репозитории проекта.

Обучена своя модель, а не взята готовая: публичные Sakha-LM сильнее, но их обучающие данные неизвестны, и выигрыш нельзя было бы отличить от знакомства с тестом.

Важно: выигрыш привязан к домену. Те же веса на других срезах:

Срез 1-best после Разница
unseen_speakers (начитка) 10.98 10.11 −0.87
labii_bench (чужой домен) 10.84 11.55 +0.71
guard_ru 1.74 1.72 −0.02

На материале, не похожем на обучающий корпус языковой модели (литературный книжный текст), переранжирование ухудшает. Разбор по языкам показал, что регрессия сидит в якутской части чужого домена, а не в русской, то есть дело не в слабом русском, а в стилистике. Применяйте для начитки и литературного нарратива; для произвольного UGC нужен более широкий текстовый корпус.

Декодирование без лексикона

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

Измерение цены этого ограничения (unseen_speakers, эталонные слова разделены по наличию в списке из 2.25 млн форм):

декодер WER AER в словаре ВНЕ словаря
жадное 14.78% 4.15% 86.2% 57.9%
словесный beam, 4-грамм 10.98% 3.61% 90.8% 34.2%
без лексикона, символьная 12-го порядка 9.50% 3.18% 91.6% 56.6%
+ нейронная 103M 8.84% 2.91% 92.2% 57.6%

По всем срезам, одна акустическая модель и одни эмиссии. Веса переранжирования подобраны на dev и применены без изменений.

Срез Словесный beam Без лексикона + переранжирование
unseen_speakers 10.93% 9.50% 8.84%
seen_speakers 9.80% 9.32% 8.93%
external_sakha 7.14% 5.23% 4.60%
labii_bench (чужой домен) 10.87% 11.75% 10.93%
guard: русский 1.74% 1.80% 1.71%
guard: киргизский 8.80% 8.91% 9.52%

Русский не пострадал и даже слегка улучшился. Киргизский переранжирование ухудшает (8.91 → 9.52): языковые модели саха-язычные и штрафуют киргизские гипотезы, акустическая модель при этом не менялась. Для киргизского декодируйте первым проходом без переранжирования.

На labii_bench цепочка выходит вровень со словесным beam: бутстрэп даёт +0.06 п.п. с интервалом [−0.62, +0.74], то есть тестовый набор их не различает. Первый проход без лексикона сам по себе там проигрывает 0.88, а переранжирование это отыгрывает.

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

Бутстрэп по высказываниям против словесного beam: −2.13 п.п., 95% ДИ [−2.47, −1.80], P = 100%.

AER (Affix Error Rate) — доля правок в цепочках грамматических аффиксов. Для агглютинативного языка WER смешивает не расслышанное слово и не расслышанную грамматику; AER их разделяет. Он падает вдоль всей цепочки (3.61% → 2.91%), то есть окончания улучшаются вместе со словами, а не за их счёт.

Что в комплекте

  • decoding/char12.binary — символьная KenLM 12-го порядка, 9.3 млн строк корпуса (книги плюс новые саха-тексты, из которых исключены источники, пересекающиеся с dev/test);
  • decoding/char12_full.binary — та же символьная 12-го порядка на большем корпусе (corpus_full); с v8c лучше char12_full.binary, lm_weight=1.0 (см. «Обновление 2026-11»);
  • decoding/neural_lm_103m/ — Llama на 103.4M параметров (12 слоёв, 768, RoPE/SwiGLU/RMSNorm, BPE на 24 тыс.), 148M токенов обучения.

Декодер — LexiconFreeDecoder из flashlight-text, веса первого прохода lm_weight=1.5, sil_score=0, луч 100; скорость 0.10–0.18 с на высказывание. Скрипты scripts/decode_lexicon_free.py и scripts/rescore_combined.py в репозитории проекта.

Сборка требует внимания. И kenlm, и flashlight по умолчанию ограничены 6-м порядком n-грамм, а для символьной модели это примерно одно слово контекста: обе библиотеки нужно собирать с KENLM_MAX_ORDER=12. Подробный рецепт со всеми подводными камнями — в docs/agglutinative-decoding.md.

Что не сработало

Морфологическое ограничение декодера — самая естественная идея для тюркского ASR — опровергнуто измерением: форма, которую выдаёт модель, разбирается анализатором чаще (71.4%), чем та, которую она заменила (52.0%). Фильтр по разборности помог бы в 12.6% подмен и навредил бы в 32%. Модель не изобретает несуществующих форм, а ставит реальное частотное слово не на своё место.

Также измерены и не работают: морфемная языковая модель поверх символьной (вес 0 при подборе), выбор по минимальному байесову риску (−0.02 п.п.), расширение луча вчетверо (−0.03 п.п.). Полные таблицы — в docs/ablations.md.

Ограничения

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

Сравнение с lab-ii/gigaam-multimodal

Обе модели на одних и тех же срезах, каждая в своей штатной конфигурации.

Срез lab-ii + своя LM наша + LM наша + переранж.
unseen_speakers 18.70 10.92 10.11
labii_bench 9.57 10.87 11.55
guard_ru 4.16 1.74 1.72

На нейтральном срезе — дикторе, которого нет ни в чьём обучении, — мы лучше в 1.85 раза (ДИ [−8.51, −7.05]). На их собственном бенчмарке лучше они: тест нарезан из корпуса, на котором они учились, а мы его целиком исключили. Киргизский несопоставим — в словаре lab-ii киргизских букв нет.

Ограничения

  • Нет пунктуации и регистра — метки нормализованы; нужен отдельный постпроцессинг.
  • Редупликации пишутся раздельно (дии дии, а не дии-дии) — так устроен обучающий корпус. Осознанный выбор, не дефект.
  • Читаная речь. Обучение — аудиокниги и краудсорсинговые начитки. Телефония, спонтанная и перекрывающаяся речь не проверялись.
  • Ошибки концентрируются в морфологии. 85% ошибок — подмены, 41% из них сохраняют основу и отличаются окончанием, чаще всего гармоническим вариантом гласного. Словная n-грамма здесь упирается в потолок: 61% её словаря встречается ровно один раз, а 97% пропусков словаря — известная основа с невиданной суффиксальной цепочкой. Морфемная или сабвордная LM — очевидное следующее улучшение.
  • Разрыв seen/unseen — 9.80 против 10.91 с языковой моделью. Упирается в число дикторов, а не в технику.

Лицензия и происхождение данных

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

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for lab-ii/GigaAM-Sakha-Multilingual

Quantized
(10)
this model

Paper for lab-ii/GigaAM-Sakha-Multilingual

Evaluation results

  • WER (lexicon-free char LM + neural rescoring) on Sakha held-out test (unseen speaker)
    self-reported
    8.840
  • WER (lexicon-free char LM) on Sakha held-out test (unseen speaker)
    self-reported
    9.500
  • WER (beam + 4-gram LM + neural rescoring) on Sakha held-out test (unseen speaker)
    self-reported
    10.110
  • WER (beam + 4-gram LM) on Sakha held-out test (unseen speaker)
    self-reported
    10.910
  • WER (greedy) on Sakha held-out test (unseen speaker)
    self-reported
    14.810
  • CER (beam + 4-gram LM) on Sakha held-out test (unseen speaker)
    self-reported
    2.130