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, как и базовая модель. Обучающие сегменты получены из аудиокниг и книг, права на которые принадлежат их владельцам; в состав модели они не входят, но это стоит учитывать при использовании.
Model tree for lab-ii/GigaAM-Sakha-Multilingual
Base model
ai-sage/GigaAM-MultilingualPaper for lab-ii/GigaAM-Sakha-Multilingual
Evaluation results
- WER (lexicon-free char LM + neural rescoring) on Sakha held-out test (unseen speaker)self-reported8.840
- WER (lexicon-free char LM) on Sakha held-out test (unseen speaker)self-reported9.500
- WER (beam + 4-gram LM + neural rescoring) on Sakha held-out test (unseen speaker)self-reported10.110
- WER (beam + 4-gram LM) on Sakha held-out test (unseen speaker)self-reported10.910
- WER (greedy) on Sakha held-out test (unseen speaker)self-reported14.810
- CER (beam + 4-gram LM) on Sakha held-out test (unseen speaker)self-reported2.130