Как выжать из железа максимум: эволюция инференса в Алисе Привет… — Yandex for Developers — TG.ME

🥹 Как выжать из железа максимум: эволюция инференса в Алисе

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

🅰️ Железо фиксировано, а модели растут

На колонке одновременно крутится несколько нейросетей:

🔴 Активационные модели, которые реагируют на слова «Алиса» или «Яндекс»

🔴 Командные споттеры — модели, которые поддерживают набор популярных команд, например, для управления музыкой или умным домом

🔴 Интонационные споттеры, которые делают общение с ассистентом более естественным и понимают, когда вы обращаетесь к колонке без слова «Алиса»

Все они работают в реальном времени и должны укладываться в жёсткие лимиты по latency, CPU и RAM. Докинуть ресурсы на устройство нельзя, поэтому единственный путь — оптимизация инференса.

🅰️ Как ситуация обстояла раньше

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

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

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

🅰️ Переезд на C++ и библиотеки инференса

С появлением нормальной поддержки C++ на чипах мы стали переписывать рантайм. На смену корутинам пришла наша внутренняя библиотека YNMT, изначально сделанная для моделей перевода. Она представляет модель как статический вычислительный граф, из-за чего отпала необходимость в корутинах. А потом, когда YNMT стала уступать по скорости опенсорсному TFLite, мы переехали на него. Он поддерживает встроенные оптимизации под разные архитектуры чипов.

🅰️ Два захода в квантизацию

Первый подход был простым и безопасным: мы сжимали веса модели с FP32 до INT8, но перед вычислением разжимали их обратно. Затем научились квантовать и активации. Теперь мы на лету сжимаем вход до INT8, перемножаем матрицы в INT16 и деквантизуем выход. Выигрываем и по памяти, и по скорости за счёт более быстрых целочисленных SIMD-инструкций.

🅰️ Ещё одна инфраструктурная оптимизация — мультиспоттер

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

🅰️ Главные уроки

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

Сейчас мы в процессе миграции на TFLite, готовимся использовать встроенную квантизацию вместо ручной и продолжаем пилить кастомные операции. Всё это позволяет делать колонки умнее и при этом сохранять доступность для пользователей.

⏩️ А больше технических деталей можно узнать в полной записи доклада с Я.Железо. Смотрите на ютубе и в VK Видео.

Подписывайтесь:
💬 @Yandex4Developers
👍7❤5🔥4
August 7, 2026 3.5K 20