Привет, Хабр! Меня зовут Коля, я разработчик машинного обучения в команде речевых технологий Контура. Мы разрабатываем собственную систему распознавания речи (ASR), которая ежедневно переваривает миллионы звонков и записей видеоконференций, чтобы потом использовать их для речевой аналитики качества коммуникаций с клиентами и для создания протоколов и резюме встреч в Контур.Толке.
Мы постоянно работаем над тем, чтобы дать пользователям лучшее качество и опыт взаимодействия с нашими продуктами: борьба уже давно идет за десятые доли процента WER (Word Error Rate) – особенно сложные и трудные для распознавания случаи.
В конце прошлого года Nvidia изрядно встряхнула Open Source комьюнити, выкатив серию новеньких моделей распознавания речи. Одна из них нам особенно приглянулась: Canary-Qwen-2.5B на архитектуре SALM (Speech Augmented Language Model), установившая новый рекорд по качеству в HuggingFace OpenASR, благодаря использованию гибридного подхода, совмещающего речевой энкодер и LLM в своей работе.
Мы в Контуре решили не проходить мимо и проверить: а как эта новоиспеченная SOTA покажет себя на наших реалиях — на русском языке, в домене телефонии и видеоконференций, в условиях, когда у нас нет десятков тысяч часов размеченных людьми данных.
Спойлер: мы получили отличный прирост качества, нашли неочевидный архитектурный инсайт, но пока не спешим тащить это в прод. В статье расскажу, как мы строили этот R&D, почему LLM не переварила CTC-энкодер и с какими болями мы столкнулись.
Зачем же LLM в ASR?
Чтобы понять, в чем преимущества подхода Nvidia, давайте вспомним, в чем заключается фундаментальная проблема классического пайплайна распознавания речи. Исторически классический ASR строился по каскадному принципу и состоял из двух основных частей:
Акустическая модель — Её единственная задача — перевести спектрограмму звука в набор вероятностей фонем или букв. Она отлично справляется с акустикой, но обычно абсолютно невосприимчива к смыслу сказанного. Для неё слова — это просто набор звуков.
Языковая модель — Она берёт то, что наслушала акустика, и пытается собрать из этого осмысленные слова и фразы, опираясь на статистику того, как часто эти слова встречаются в языке вместе.
Эти компоненты работают последовательно, и на стыке между ними возникает проблема: как только акустическая модель схлопывает звук в дискретный текст, мы безвозвратно теряем акустическую информацию, а ошибка накапливается. Языковая модель получает на вход часто неправильный текст и вынуждена гадать, что там было на самом деле.
Такая ли это большая проблема? Поскольку акустическая модель оценивает только физику звука и ничего не знает про контекст, она зачастую пасует перед одинаково звучащими фразами (омофонами). В итоге на выходе мы часто получаем фонетически идеальную, но логически бредовую фразу.

Индустрия десятилетиями пыталась решить эту проблему разными способами, но это всегда были своего рода полумеры:
Интегрированное декодирование (Beam Search + LM): Идея состоит в подключении языковой модели напрямую в процесс поиска лучшей гипотезы с помощью Beam Search, чтобы не терять акустическую информацию. Это помогало, но такие LM обычно очень маленькие и ограничены в знаниях.
Авторегрессионные архитектуры (RNN-T / TDT): Здесь идея уже в попытке объединить звук и текст в одной нейросети, которая предсказывает следующий символ, опираясь на уже написанные. Это мощный инструмент, но он всё ещё учится с нуля на специфических ASR-датасетах, которые на порядки меньше тех объёмов текста, на которых учатся большие языковые модели.
ASR Error Correction (LLM поверх текста): С появлением полноценных LLM возник соблазн использовать их как внешнего редактора. Сначала ASR выдает текст как умеет, а потом LLM исправляет в нём ошибки. Это очень мощный способ, но по своей природе он является тем же самым каскадным подходом, описанным в начале, только теперь языковая модель очень большая. Следовательно, ограничения у подхода аналогичные.
И вот, мы сделали круг, вернувшись к тому, с чего начали. Неужели других вариантов нет?
Идея Nvidia: Как работает SALM
Вместо того чтобы сначала получать текст, а потом его исправлять, Nvidia предложили гибридную архитектуру, совмещающую в себе ASR энкодер и LLM как декодер.

Под капотом это работает следующим образом:
Акустический энкодер: Извлекает глубокие акустические фичи из сырого аудио. FastConformer отлично справляется с длинными аудиозаписями и формирует плотные репрезентации звука.
Адаптер модальностей: Размерность эмбеддингов, которые выплёвывает FastConformer, не совпадает с тем, что ожидает на вход LLM. Адаптер проецирует аудио-эмбеддинги в пространство токенов LLM.
Декодер: Проецированные аудио-эмбеддинги подаются на вход LLM в качестве мягкого промпта (soft-prompt). LLM воспринимает их не как жестко заданные буквы, а как непрерывный поток смыслов.
Обычно мы общаемся с большими языковыми моделями через промпт: мы пишем текст, он разбивается на дискретные токены (слова/слоги), а LLM достаёт из своего словаря соответствующие им числовые векторы (эмбеддинги) и начинает с ними работать.
В случае с soft-prompt мы полностью выкидываем стадию текста. Адаптер генерирует готовые многомерные векторы, и мы отдаём их напрямую в языковую модель, в обход её словаря. LLM получает на вход не дискретный текст, а непрерывные аудио-эмбеддинги. Уже благодаря своим знаниям о языке, грамматике и логике мира, она генерирует осмысленный текст прямо из звука.
Более того, в архитектуре Canary применяется ещё один изящный трюк: в процессе обучения базовые веса LLM (в нашем случае Qwen) остаются замороженными. Проблему разрыва модальностей (audio-to-text alignment) берут на себя только обучаемый адаптер и LoRA (Low-Rank Adaptation) слои, интегрированные в LLM. Это даёт нам бонус: модель не страдает от катастрофического забывания. При необходимости мы можем просто отключить речевой энкодер с адаптером, снять LoRA-веса, и использовать Qwen как независимую, полноценную LLM для чисто текстовых задач (например, для суммаризации того же звонка).
Звучит как серебряная пуля. Мы вооружились этой архитектурой, собрали наш доменный датасет и пошли обучать модель. Но, как это часто бывает в R&D, реальность быстро расставила всё по местам.
Наш R&D сетап
Nvidia занимает топы лидербордов, обучая свои модели на десятках тысяч часов ручной разметки (и это не считая псевдоразметки). У нас таких объёмов чистого золота нет. Да и кластеры из H200 у нас не простаивают. Поэтому наш R&D — это классическая история про перенос SOTA-технологий в условия реального мира и ограниченного бюджета.
Данные: Русскоязычная телефония и записи видеоконференций (ВКС). Это сложно для любой ASR: спонтанная речь, люди перебивают друг друга, глотают окончания, говорят параллельно, фонят микрофоны, низкая частота дискретизации аудио, а сверху всё это приправлено корпоративным сленгом и аббревиатурами.
Энкодер: Мы пошли прагматичным путём. В качестве базы взяли открытую акустическую модель, которую дообучили на наших данных. Да, она компактнее модели Canary, которая используется в оригинальной архитектуре Nvidia, но это даже интереснее. Нам было важно понять: насколько мощный акустический энкодер на самом деле нужен, чтобы «прокормить» такую LLM и получить профит от гибридной архитектуры?
Декодер: А вот с LLM всё не так однозначно. Пробовали Qwen3-0.6B и Qwen3-1.7B, со вторым качество было лучше, на нём и остановились, несмотря на значительное увеличение требований к железу. Основная цель нашего R&D — понять, насколько полезна LLM как декодер в ASR, так что на ней решили не экономить.
Как строили эксперимент
Чтобы честно оценить влияние именно LLM-декодера, нам нужен был железобетонный бейзлайн. Мы не стали сравнивать SALM с опенсорсом из коробки — это было бы банально нечестно, ведь опенсорс не знает нашего домена.
Мы взяли мощный открытый претрейн акустического энкодера и добросовестно зафайнтюнили его на нашем доменном датасете (телефония + ВКС). Получили рабочую ASR-модель, замерили на ней метрики качества (CER/WER) — это наша отправная точка.
Далее взяли тот же самый зафайнтюненный энкодер. Прикрутили к нему линейный проектор и LLM с LoRA-адаптерами, заморозив только веса большой языковой модели. Эту систему мы обучали на низком learning rate и сравнивали с бейзлайном, озвученным чуть выше.
Какие грабли собрали по пути
На бумаге план выглядел надёжно, как швейцарские часы: берём энкодер, цепляем к Qwen, обучаем и радуемся. В реальности мы столкнулись с дикой капризностью LLM. Модель оказалась весьма чувствительна к гиперпараметрам и часто не сходилась, казалось бы, без видимой на то причины.
Но главные проблемы были архитектурными. Мы выделили три, которые пришлось победить.
1. В тихом омуте…
Изначально мы пошли по пути Whisper: на вход подавалось аудио фиксированной длины простоты ради. Если фраза была короче, мы добивали её тишиной на уровне waveform (сырого звука).
Такой подход привёл к частым «галлюцинациям», которыми болеет и сам Whisper. Модель начинала генерировать в эти моменты «тишины» абсолютный мусор, что не только рушило WER, но и просаживало скорость инференса (модель пыталась генерировать текст там, где ничего нет).
Решение оказалось простое: мы отказались от паддинга на уровне аудио и стали использовать классический паддинг[PAD] токенами уже в конце последовательности. Галлюцинации ушли.
2. Как модальности дружили
Прежде чем рассказать, какой адаптер мы выбрали, давайте сделаем короткий шаг назад и разберёмся, что вообще такое разрыв модальностей (modality gap) и почему это главная головная боль любых мультимодальных моделей (будь то аудио + текст или картинка + текст).
Текстовая модальность: Языковая модель мыслит жестким словарем. У нее есть условные 100 000 токенов. Каждому токену соответствует свой вектор (эмбеддинг) строго определенной размерности (допустим, 2048). LLM ожидает на вход стройный ряд именно таких, знакомых ей векторов.
Аудио-модальность: Акустическая модель обрабатывает спектрограммы (удобное представление аудио для нейросетей) и на своих последних слоях выдаёт векторы своей размерности (допустим, 512), которые уже очень близки к конкретным фонемам или буквам. Обычно достаточно всего одного линейного слоя, чтобы превратить их в вероятности текста по словарю.
Казалось бы, раз эмбеддинги акустической модели уже выдают что-то максимально близкое к буквам, а LLM с буквами работать умеет, то в чем проблема? Однако если просто взять выход энкодера и напрямую скормить его LLM, чуда не случится. И дело даже не в том, что размерности матриц банально не совпадут.
Допустим, мы подогнали размер аудио-векторов под вход LLM. Для языковой модели этот сигнал всё равно останется лишь шумом. Почему? Потому что в процессе независимого предобучения градиентный спуск развел эти модели по совершенно разным латентным пространствам (latent spaces).
Энкодер сошелся к репрезентациям, которые хорошо описывают акустику и фонетику. LLM сошлась к векторам, кодирующим грамматику и смысл текста. И хотя математически эти линейные пространства теперь совместимы и с ними можно делать тензорные операции, семантически — это два абсолютно разных языка. Акустический вектор, помещенный в систему координат LLM, не значит для нее вообще ничего. Эта смысловая пропасть между векторами и называется разрывом модальностей.
Чтобы их подружить, нам как раз и нужен адаптер модальностей. Его задача — взять аудио-фичи, преобразовать их размерность и спроецировать в пространство токенов LLM так, чтобы языковая модель восприняла их как те самые soft-prompts (свои родные векторы). Мы протестировали три варианта:
Многослойный перцептрон (MLP на 2 слоя).
ConformerEncoder (на 2 слоя). Задумка была красивой: за счёт сжатия скрытых состояний энкодера ещё в 4 раза (итого в 16 раз) модель начинала работать значительно быстрее и могла переваривать более длинный контекст.
Линейная проекция (Linear projection).
Conformer оказался слишком тяжелым (много параметров), а экономия на контексте нам была не особо нужна — из-за VAD (Voice Activity Detector) на входе мы и так работаем с короткими аудио. MLP давал чуть лучшую точность, но разницы между Linear proj почти не было, а параметров было больше.
Итого: наилучший трейд-офф затрат и качества показала простая линейная проекция (ровно как и у разработчиков Canary).
3. Энкодер имеет значение
В качестве отправной точки мы взяли наш классический CTC-энкодер. Задача речевого энкодера — сопоставить длинную аудиодорожку (сотни фреймов) с коротким текстом (десятки букв). Архитектура CTC (Connectionist Temporal Classification) решает это в лоб: она делает независимое предсказание для каждого кусочка аудио (например, каждые 20-40 мс). На нашем домене в претрейне он исторически показывал себя лучше всего. Казалось бы, идеальный донор фичей. Результат разочаровал: пайплайн разваливается. Модель сходится к результатам, которые заметно хуже, чем у базового CTC без всяких LLM.
Честно признаемся: мы не проводили глубокого реверс-инжиниринга эмбеддингов, чтобы математически доказать причину. Этот факт мы получили сугубо эмпирическим путем. Но у нас есть рабочая гипотеза.
Фундаментальная разница кроется в независимости фреймов. CTC-архитектура делает независимое предсказание для каждого кусочка аудио. Авторегрессионная природа LLM, напротив, требует контекста — ей нужен плавный, осмысленный поток токенов.
Трансдьюсеры (RNN-T/TDT) изначально спроектированы так, чтобы выдавать логиты авторегрессионно, опираясь на уже сгенерированный текст. Вероятно, структура их выходных эмбеддингов (более плотных и зависимых друг от друга) оказалась гораздо более пригодной для языковой модели, и линейной проекции хватило, чтобы успешно подружить эти модальности. В итоге модель на базе RNN-T успешно сошлась к результатам куда лучше чем основе CTC.
Результаты
Чтобы оценить эффект LLM-декодера, мы сравнивали его с базовым энкодером, обученным на тех же данных. Замеры проводились в строгом greedy-режиме (без низкотемпературного ядерного сэмплирования, которое обычно даёт ещё минус ~0.1 WER).

LLM-декодер уверенно обошёл свой базовый энкодер во всех сценариях. В среднем мы отыграли 0.3-0.5 WER относительно базового энкодера.
Для стороннего наблюдателя это звучит как погрешность. Но в мире коммерческого ASR, где годами бьются за десятые доли процента качества на сложных доменах (телефония, шумные залы), получить такой прирост за счёт изменения архитектуры декодера — это очень солидно.
Более того, модель, обученная на относительно скромных ~500 часах ручной разметки (без псевдоразметки), уверенно обошла наш предыдущий продакшен-релиз. И здесь важно подчеркнуть одну деталь: объем ручной разметки у них был абсолютно одинаковым. То есть модели находились в почти равных условиях, с той лишь разницей, что старый прод дополнительно учили на гигантских массивах псевдоразметки. Однако ему это сильно не помогло, как видите.
Да, мы пока немного не дотянули до нашего самого свежего релиза на проде (который впитал в себя еще больше ручной разметки и псевдоразметки). Но посмотрите на разрыв: LLM-декодер «из коробки» буквально дышит ему в затылок. Тот факт, что гибридная архитектура показывает качество продовой модели, доказывает, что применение LLM в качестве декодера и вправду имеет смысл.
И, думаю, ни для кого не секрет, что если мы скормим и LLM-декодеру столько же псевдоразметки, то мы получим результат значительно лучше чем даже текущий релиз.
Суровая реальность
А теперь о том, почему мы не открываем шампанское и не катим это в реалтайм-прод прямо завтра. Любое улучшение качества имеет свою цену. В случае с архитектурой SALM эта цена — чудовищно раздутые требования к инференсу и поддержке инфраструктуры.
Добавление LLM на 1.7 миллиарда параметров (плюс веса адаптера) кратно увеличивает размер модели. Если раньше акустическая модель легко помещалась в память почти любой видеокарты, то теперь нам нужен совсем другой объём VRAM просто для того, чтобы поднять модель.
К тому же авторегрессионная генерация токенов тяжелой языковой моделью — процесс небыстрый. По нашим замерам, в бейзлайне LLM-декодер занимает более 90% времени работы всей ASR-модели (vLLM делает ситуацию значительно лучше, но это всё ещё тяжелый пайплайн). На данный момент это непростительное падение производительности, которое временно ставит крест на технологии: никто не желает значительного увеличения стоимости услуги взамен на не самое поражающее улучшение в качестве.
И последнее, но не по значимости: гибридная архитектура создает массу вопросов об эффективном инференсе. Чтобы акустический энкодер работал максимально быстро и эффективно, его привычно крутить на Triton Inference Server. А чтобы LLM хоть как-то шевелилась, её хочется держать на специализированных движках вроде vLLM (ради оптимизации PagedAttention и грамотного батчинга).
Как подружить их в продакшене? Гонять данные между разными сервисами по сети — это лишние задержки. Пытаться поднять Triton и vLLM на одном инстансе (или одном слайсе GPU) — это задача со звездочкой, которая превращает поддержку пайплайна в ту еще головную боль.
Выводы
Эксперимент с переносом архитектуры Nvidia SALM на наши реалии оказался невероятно полезным. Мы не просто пощупали новую SOTA-технологию, но и набили свои собственные шишки, поняв, как именно LLM переваривает звук.
Работает ли идея LLM-декодера?
Да, безусловно. Прирост качества на сложных доменных данных (особенно спонтанной речи) очевиден. За счёт встроенных знаний о языке LLM круто вытаскивает логику и исправляет фонетические огрехи там, где акустический энкодер сдаётся.
Стоит ли оно того прямо сейчас?
А вот тут всё зависит от ваших задач. Если вам нужно выжать максимальное качество транскрипции в офлайн-режиме (например, для глубокой речевой аналитики колл-центра или формирования протокола встречи в Контур.Толке), и у вас есть свободные GPU — это отличный инструмент, который работает прямо из коробки.
Но у этой архитектуры есть ещё одно, неочевидное, но мощное применение. Такую тяжеловесную модель можно использовать в качестве учителя на этапе псевдоразметки сырых аудиоданных. Модель оффлайн генерирует качественную транскрипцию, и затем мы дистиллируем эти знания в более компактные, быстрые и дешёвые классические модели, которые пойдут в прод.
Что дальше?
На этом наш R&D не заканчивается. Мы планируем смотреть в сторону оптимизации инференса и с нетерпением ждём появления ещё более компактных языковых моделей, специализированных исключительно на русском языке. Возможно, тогда гибридные ASR станут новым индустриальным стандартом.
Ryuk124
Ура мой любимый блог