Содержание статьи +
- Кратко
- Почему это важно
- Сначала разберёмся с названием
- Почему не взять встроенное распознавание браузера?
- Конвейер в браузере, шаг за шагом
- Два движка: WebAssembly против WebGPU
- Во что это реально обходится: загрузка, память и батарея
- Числовой пример: успевает ли устройство за живой речью?
- Whisper не создавался для реального времени – поэтому появился Moonshine
- Клиент или сервер? Решение, которое действительно важно
- Частая ошибка: использовать самую большую модель, какую только нашли
- Где здесь Фора Софт
- Главное
- Что почитать дальше
Кратко
Клиентское распознавание речи – это когда слова, сказанные в микрофон, превращаются в текст кодом, который работает прямо в браузере, на компьютере или телефоне самого пользователя, и звук при этом никуда не уходит с устройства. Фраза «faster-whisper-WASM» – это собирательное название для семейства инструментов, которые помещают модель Whisper от OpenAI в браузер, но за этим именем прячется важное различие: настоящие браузерные движки – это whisper.cpp, скомпилированный в WebAssembly, и Transformers.js, работающий на WebGPU, тогда как сам «faster-whisper» – отдельная серверная библиотека, которая в браузере не запускается вовсе. Эта статья распутывает названия, проходит весь конвейер в браузере от микрофона до субтитра на экране, объясняет два движка, которые делают тяжёлую работу, и правила браузера, которые их ограничивают, и даёт ясное решение, когда распознавать на устройстве выгоднее, чем отправлять звук на сервер. К концу вы будете знать, что реально, во что обходится каждый кусок по объёму загрузки и расходу батареи и какие функции вашего продукта действительно стоит держать на клиенте.
Почему это важно
Если ваш продукт работает со речью – инструмент для встреч, функция диктовки, языковое приложение, голосовой интерфейс или киоск – вы сталкиваетесь с одной архитектурной дилеммой ещё до написания первой строки кода: где должно происходить распознавание речи – на ваших серверах или на устройстве пользователя? Распознавание на устройстве обещает три вещи, которые особенно важны для продуктовых команд: аудио остаётся приватным, поскольку нигде не передаётся; функция продолжает работать без интернета; и вы не платите за облачные минуты, сколько бы пользователи ни говорили. Эта статья адресована продакт-менеджерам, основателям или техлидам, которые слышали фразу «да мы просто запустим Whisper в браузере» и хотят понять, насколько это реально, во что это на самом деле обходится и где этот подход может незаметно сломаться. Это парная статья к разбору серверного паттерна субтитров: там доказывается, что для групповых звонков лучше распознавать речь один раз на сервере, а здесь рассматривается противоположный путь – когда правильным местом для «слуха» становится именно устройство.
Сначала разберёмся с названием
Фраза «faster-whisper-WebAssembly в браузере» делает слишком много сразу, и разбить её на части – самый быстрый способ разобраться в теме. За ней скрываются три разных компонента, и путаница между ними – самая частая ошибка в этой области.
Начнём с модели. Whisper – это модель распознавания речи, выпущенная OpenAI в 2022 году: программа, обученная распознавать звуки и преобразовывать их в текст. Она доступна в нескольких версиях – от «tiny» с 39 миллионами параметров до «large» с примерно 1,5 миллиардами; чем больше параметров, тем выше точность, но тем больше объём и ниже скорость работы. Оригинальный Whisper – исследовательская версия, написанная на Python; сама по себе она не предназначена для работы в браузере и не оптимизирована под высокую производительность.
Теперь самая запутанная часть. «faster-whisper» – это отдельный проект, переписывание оригинальной реализации Whisper на основе быстрого движка вывода CTranslate2. Он обрабатывает ту же модель в несколько раз быстрее и с меньшим потреблением памяти. Однако faster-whisper работает на сервере или на десктопе, на Python, обычно с использованием видеокарты. Он не запускается внутри браузера, и официального «faster-whisper-WebAssembly» не существует. Когда люди произносят эту фразу, они почти всегда имеют в виду один из настоящих браузерных движков, перечисленных ниже, и используют громкое имя «faster-whisper» как синоним «быстрый Whisper». Понимание этого важно: если вы начнёте искать браузерную версию faster-whisper, вы её не найдёте и можете потратить неделю впустую.
Так что же реально работает в браузере? Тяжёлую работу выполняют два движка. Первый – whisper.cpp: переписанная версия Whisper на языках C и C++ без внешних зависимостей, которую можно скомпилировать в WebAssembly (сокращённо Wasm) – формат, позволяющий почти нативному скомпилированному коду выполняться прямо в браузере. Второй – Transformers.js: JavaScript-библиотека от Hugging Face, которая запускает Whisper через браузерный движок ONNX Runtime Web и умеет задействовать видеокарту устройства с помощью нового стандарта WebGPU. Третий, более лёгкий вариант – Moonshine, новая модель, специально разработанная для живой транскрипции на устройстве. Именно эти три решения – а не «faster-whisper» – стоит использовать, если цель – распознавание речи прямо в браузере.
Почему не взять встроенное распознавание браузера?
Прежде чем скачивать какую-либо модель, логично задать вопрос: а может, браузер уже делает это бесплатно? Почти делает. В браузере есть встроенная функция под названием Web Speech API, а внутри неё – интерфейс SpeechRecognition, который преобразует речь с микрофона в текст всего несколькими строками JavaScript. Если бы он справлялся с задачей, эта статья умещалась бы в один абзац.
Он её не решает по двум причинам. Первая – приватность, и она главная. В Chrome, основном браузере, поддерживающем эту функцию, распознавание по умолчанию вообще не происходит на устройстве. Браузер записывает микрофон и отправляет звук в веб-сервис Google, где тот расшифровывается, а затем текст возвращается обратно. То есть единственная функция, ради которой пользователи хотят оставить обработку звука на устройстве, по умолчанию делает ровно наоборот: передаёт аудио третьей стороне и требует подключения к интернету. Это подрывает цели приватности и работы в автономном режиме, ради которых клиентское распознавание вообще представляется привлекательным.
Вторая причина – поддержка. SpeechRecognition реализованы только в Chrome и других браузерах на базе Chromium, например, Edge; в Safari и Firefox она долгое время была непоследовательной или отсутствовала. Функция, которая работает в одном семействе браузеров и молча падает в других, – не та, которую можно безопасно внедрять для всех пользователей.
В новых версиях стандарта появился переключатель, позволяющий распознавать речь локально на устройстве, и браузеры постепенно внедряют локальные режимы. Однако вы не можете контролировать, какой браузер и какая его версия у пользователя, и не в состоянии гарантировать, что аудиоданные останутся на устройстве – ведь движок может отправить их на сервер. Если конфиденциальность или работа в автономном режиме являются критичными требованиями, нужен движок, который вы сами поставляете и контролируете – например, загруженная модель, запускаемая через whisper.cpp или Transformers.js. Об этом и пойдёт речь в остальной части статьи.
Конвейер в браузере, шаг за шагом
Поместить Whisper на веб-страницу – это не одно действие, а короткий конвейер. Пройти его от микрофона до субтитра – значит увидеть, где происходит настоящая работа и где лежат реальные затраты.
Начинается всё с захвата звука. Браузер запрашивает у пользователя доступ к микрофону через стандартный вызов getUserMedia, который возвращает живой аудиопоток. Этот поток идёт на той частоте дискретизации, что у устройства, обычно 44 100 или 48 000 отсчётов в секунду, но Whisper ждёт звук ровно на 16 000 отсчётов в секунду в один канал. Поэтому следующий шаг пересэмплирует и сводит звук в моно – небольшой кусок кода, обычно работающий в аудио-ворклете (фоновом обработчике звука, который не подвешивает страницу), превращает поток из микрофона в моно-поток 16 кГц, который нужен модели.
Дальше – гейт, и это главный трюк эффективности. Распознавание речи стоит дорого, а расшифровывать тишину – бессмысленно. Перед основной моделью стоит небольшой и дешёвый детектор активности речи – VAD, программа, отвечающая на простой вопрос: «да/нет – кто-то сейчас говорит?» В браузере часто используют компактную модель Silero VAD, запущенную через ONNX Runtime Web, которая оценивает каждый короткий фрагмент звука по шкале от 0 до 1 – в зависимости от вероятности наличия речи. Дальше обрабатывается только тот звук, который превышает установленный порог. Без этого гейта система будет обрабатывать каждую секунду фонового шума и напрасно расходовать заряд батареи.
Затем работает сама модель. Гейченый звук с частотой 16 кГц подаётся в Whisper – запускаемый либо как WebAssembly через whisper.cpp, либо на видеокарте с помощью Transformers.js – и модель возвращает текст. Этот текст отображается, а для живого опыта – в два этапа: сначала быстрая черновая догадка, пока человек ещё говорит, а затем окончательная версия после паузы. Поведение «черновик, потом финал» мы подробно разбираем в статье про живые субтитры; оно одинаково как на сервере, так и, как в данном случае, на устройстве.
Вся цепочка – микрофон, пересэмплинг, VAD-гейт, модель, показ – работает целиком внутри вкладки браузера. Звук нигде не покидает устройство. Именно это свойство вы и получаете, а конвейер – его стоимость.
Два движка: WebAssembly против WebGPU
Модель должна выполняться на «железе» устройства, и тут есть два пути. Они настолько различаются, что выбор одного из них определяет всю архитектуру вашей системы – поэтому важно понять оба варианта простыми словами.
Первый путь – WebAssembly, который использует whisper.cpp. WebAssembly – это технология, позволяющая выполнять код на быстрых компилируемых языках, таких как C, прямо в браузере почти с нативной скоростью. Он работает на центральном процессоре устройства – CPU. Для повышения производительности он использует два расширения: SIMD, позволяющее одной инструкции обрабатывать сразу несколько чисел, и потоки (threads), распределяющие вычисления по нескольким ядрам CPU одновременно. WebAssembly хорошо поддерживается и не требует видеокарты, что делает его надёжной «базой» – однако он ограничен производительностью CPU, поэтому на крупных моделях может не успевать за живой речью.
Второй путь – WebGPU, который использует Transformers.js. WebGPU – это новый веб-стандарт, разработанный той же группой, что и другие веб-стандарты, позволяющий веб-странице задействовать видеокарту устройства – GPU – не только для отрисовки графики, но и для общих вычислений. Поскольку GPU создан для выполнения тысяч мелких операций параллельно, он гораздо лучше подходит для матричной математики внутри языковых моделей, чем CPU. Hugging Face показали, что WebGPU запускает их модели до ста раз быстрее, чем WebAssembly, при выполнении той же задачи. Эта впечатляющая цифра зависит от конкретной задачи и не всегда достигается для каждой модели, но тенденция очевидна: когда GPU доступен, он кардинально меняет, какой размер модели можно запускать в реальном времени прямо в браузере.
С WebGPU есть нюанс: он новее, поэтому пока не везде доступен. Он стал включён по умолчанию в Chrome и Edge в 2023 году, появился в Safari от Apple и Firefox от Mozilla в течение 2025 года, и к концу 2025 года работал по умолчанию во всех основных браузерах – но на старом браузере или слабом устройстве его может не быть. Поэтому надёжный продукт рассматривает WebGPU как быстрый путь, а WebAssembly – как запасной: используйте видеокарту, когда она доступна, и переключайтесь на CPU, когда её нет.
Есть ещё одно правило, из-за которого команды спотыкаются на пути WebAssembly. Чтобы использовать потоки – параллельную работу на нескольких ядрах CPU – WebAssembly требует общий блок памяти, а браузеры разрешают это только при включённом режиме безопасности под названием cross-origin isolation (межисточниковая изоляция). На практике это означает, что ваш сервер должен отправлять с каждой страницей два конкретных HTTP-заголовка (для протокола – Cross-Origin-Opener-Policy и Cross-Origin-Embedder-Policy). Забудете их – и многоядерная обработка молча отключится, транскрипция перейдёт на одно ядро и начнёт тормозить. Это всего лишь строка в конфигурации, а не изменение кода, и именно это – самая частая причина, по которой демо Whisper в браузере, работавшее быстро на машине разработчика, начинает тормозить в продакшене.
Во что это реально обходится: загрузка, память и батарея
У клиентского распознавания нет облачного счёта за минуты, и это его главное преимущество. Но «бесплатно» – неверное слово, потому что затраты просто переезжают на устройство пользователя в трёх формах: загрузка, память, батарея. Назвать цифры – значит сохранить решение честным.
Первая статья – загрузка модели. Модель – это файл, который браузер должен скачать при первом посещении, а затем он кэшируется для последующих визитов. В формате whisper.cpp размеры следующие: модель «tiny» – около 75 мегабайт, «base» – около 142, «small» – около 466. Сжатие модели с помощью метода, называемого квантизацией – хранения чисел с меньшим количеством битов за счёт небольшой потери точности, – уменьшает их примерно до 31, 57 и 182 мегабайт соответственно. По-человечески: квантизованная модель «base» объёмом 57 мегабайт – это загрузка размером с короткий видеоролик: вполне нормально для домашнего Wi-Fi, заметно на телефоне со слабым сигналом и реальный фактор, если пользователь находится на тарифе с оплатой за трафик.
Вторая проблема – память. Модель должна находиться в оперативной памяти устройства во время работы. Грубая оценка: модели типа «tiny» требуют несколько сотен мегабайт, а более крупные – соответственно, больше. На современном ноутбуке это почти не заметно; на бюджетном смартфоне с несколькими запущенными приложениями это может стать причиной плавной или рывковой работы.
Третья статья расходов – батарея и нагрев, и она возникает только тогда, когда модель реально работает. Именно поэтому VAD-гейт в конвейере так важен: расшифровывая только речь и игнорируя тишину, вы сокращаете время работы модели – а значит, и расход батареи – до доли процента. Функция диктовки, запускающая модель только при удержании кнопки, практически ничего не стоит; а вечно слушающий транскрайбер без гейта может буквально нагреть телефон в руке.
Вот сделка одним решением: модель крупнее – точнее, но скачивается дольше, потребляет больше памяти и сильнее разряжает батарею. Для большинства практических задач на устройстве оптимальный выбор – модель «tiny» или «base», квантизованная, с VAD-гейтом и WebGPU там, где он доступен. Такая комбинация держит объём загрузки под сотней мегабайт, потребление памяти – в разумных пределах, а расход батареи – в зависимости от того, сколько люди реально говорят.
Числовой пример: успевает ли устройство за живой речью?
Вопрос, который определяет, возможна ли вообще живая транскрипция на устройстве, прост: успевает ли модель расшифровать одну секунду звука быстрее, чем за секунду? Если да – она поспевает за живой речью; если нет – отстаёт, и субтитры всё больше запаздывают с каждым предложением. Инженеры измеряют это коэффициентом реального времени (real-time factor, RTF) – временем, которое модель тратит на обработку звука, делённым на длительность этого звука. Значение ниже 1,0 означает, что модель работает быстрее реального времени; выше 1,0 – не успевает.
Разберём пример. Допустим, на некотором ноутбуке среднего уровня модель «base» Whisper, работающая на CPU через WebAssembly, тратит 1,2 секунды на расшифровку каждой 1 секунды звука:
RTF = время обработки ÷ длина звука
RTF = 1,2 с ÷ 1,0 с
RTF = 1,2 → выше 1,0, значит не успевает вживуюПри 1,2 она отстаёт – подходит для расшифровки готовой записи, но слишком медленна для живых субтитров. Теперь переключим ту же модель на GPU через WebGPU и предположим, что она обрабатывает ту же секунду звука за 0,25 секунды:
RTF = 0,25 с ÷ 1,0 с
RTF = 0,25 → заметно ниже 1,0, с запасом успевает вживуюПри 0,25 у неё есть запас. Этот разрыв – от «слишком медленно» до «комфортно» – и есть практическая причина, по которой WebGPU изменил то, что возможно в браузере. Точные цифры зависят от устройства, размера модели и нагрузки, поэтому измерять нужно на том «железе», которое реально используют ваши пользователи, а не полагаться на бенчмарк с топовой машины разработчика. Но общая картина надёжна: на CPU для реальной работы стоит использовать самые маленькие модели; с GPU можно запускать более крупные и точные модели и всё равно успевать.
Whisper не создавался для реального времени – поэтому появился Moonshine
Есть структурная причина, по которой живая транскрипция на Whisper получается неуклюжей, и стоит знать о новой модели, которая это исправляет. Whisper спроектирован так, чтобы обрабатывать звук фиксированными блоками по тридцать секунд. Подайте ему три секунды речи – он всё равно дополнит вход до тридцати секунд внутри себя и выполнит обработку полного окна, то есть для коротких живых фрагментов сделает кучу лишних вычислений. Для расшифровки подкаста это нормально; для субтитрирования живого разговора мелкими порциями – неэффективно.
Модель Moonshine 2024 года от компании Useful Sensors создана специально для решения этой задачи в реальном времени. Вместо фиксированных тридцатисекундных окон обработка в Moonshine масштабируется под реальную длину входного звука – три секунды речи требуют трёх секунд работы, а не тридцати. Разработчики утверждают, что она работает примерно в пять раз быстрее аналогичной модели Whisper «tiny» на коротких фрагментах, не теряя при этом точности, и при этом настолько компактна, что способна работать на смартфонах и даже на Raspberry Pi. Для приложений, где требуется живая транскрипция коротких реплик прямо на устройстве – голосовые команды, субтитры в реальном времени, диктовка – Moonshine всё чаще оказывается более подходящим решением, и запускается она на той же браузерной инфраструктуре, что и Whisper.
Вывод не в том, чтобы «всегда выбирать Moonshine». Whisper остаётся более проверенным и широко поддерживаемым решением с большим охватом языков и развитой экосистемой. Суть в том, что модель – это сменный компонент конвейера, показанного на Рисунке 2, и подбор модели под конкретную задачу (Whisper для общей транскрипции, Moonshine – для тесных живых циклов) – важная часть эффективного подхода.
Клиент или сервер? Решение, которое действительно важно
Всё вышесказанное сводится к одному продуктовому решению: распознавать речь на устройстве или отправлять аудио на сервер для расшифровки там? Оба варианта допустимы – правильный выбор зависит от задачи. Две статьи в этой паре аргументируют обе стороны. Вот честное сравнение.
| Критерий | Клиентский ASR (в браузере) | Серверный ASR (звук наверх) |
|---|---|---|
| Приватность звука | Сильная – звук не покидает устройство | Слабее – звук попадает к вам или к вендору |
| Работа офлайн | Да – после загрузки модели связь не нужна | Нет – нужна живая связь |
| Облачная плата за минуты | Нет – работает на «железе» пользователя | Есть – счёт за минуту звука |
| Затрата для пользователя сразу | Загрузка модели (31–182 МБ) + батарея | Нет – устройство только шлёт звук |
| Потолок точности | Ограничен тем, что мелкая модель тянет вживую | Высокий – крупнейшие модели на GPU-сервере |
| Работа на слабом телефоне | Иногда – упирается в память и CPU/GPU | Да – устройство лишь пишет и грузит |
| Согласованность у всех | Зависит от возможностей устройства | Одинаковая – один движок на всех |
| Лучше всего для | 1:1, диктовка, офлайн, приватность, киоски | Групповые звонки, запись, поиск, макс. точность |
Читайте по своему продукту. Если вы создаёте приложение диктовки с акцентом на приватность, полевой инструмент, который должен работать без сигнала, киоск или звонок один на один, где звук не должен попадать на сервер, – распознавание лучше выполнять на клиенте, и затраты (загрузка модели, расход батареи, более низкая точность мелкой модели) вполне оправданы. Если же вы разрабатываете групповые встречи, которые ещё и записываются, по которым можно искать и переводить, или вам нужна точность крупнейших моделей, – правильным решением станет сервер, и наш разбор серверного fan-out – как раз подходящий паттерн. Многие зрелые продукты используют оба подхода: запускают лёгкую модель на клиенте для мгновенного и приватного отклика, а звук отправляют на сервер, когда пользователь активирует функции повышенной точности. Конвейер из этой статьи – клиентская часть такой схемы.
Частая ошибка: использовать самую большую модель, какую только нашли
Самая частая и самая разрушительная ошибка в клиентском ASR – выбирать модель исключительно по точности и стремиться к более крупной, потому что на тихих тестах она показывает лучшие результаты. Она отлично работает на быстром ноутбуке разработчика с готовым аудиофайлом – и так же без изменений попадает в релиз.
На реальном телефоне среднего уровня крупная модель – катастрофа сразу в трёх отношениях. Это огромная загрузка – сотни мегабайт или гигабайт, – которую многие пользователи бросят, не дождавшись. Она требует больше памяти, чем может выделить бюджетное устройство, поэтому подвисает или падает. И она работает медленнее реального времени на CPU, поэтому живые субтитры, которые она должна была питать, отстают всё сильнее с каждым предложением. Функция, идеально отработавшая на демо, непригодна для тех, ради кого её строили.
Лечение – выбирать модель под худшее устройство, которое вы планируете поддерживать, а не под лучшее, и наращивать точность за счёт конвейера, а не за счёт размера модели. Используйте компактную квантизованную модель, активируйте её через VAD, чтобы она работала только при наличии речи, отдавайте предпочтение WebGPU, чтобы вычисления выполняла видеокарта, очищайте входной звук шумоподавлением, чтобы мелкая модель чётко различала слова, и предлагайте серверный путь тем, кому действительно нужна максимальная точность. Та же дисциплина, что мы применяем к мелким моделям на устройстве: правильная модель – это самая крупная, которую комфортно тянет ваше «полное» устройство, а не самая точная в лаборатории.
Где здесь Фора Софт
Мы создаём живые видео- и голосовые продукты, где выбор между клиентом и сервером возникает постоянно – видеоконференции, телемедицинские консультации, e-learning, полевые и киосковые приложения. Мы принимаем решение по каждой функции отдельно, а не раз и навсегда для всего продукта. Когда заказчику важно, чтобы звук оставался на устройстве ради приватности или продолжал работать без интернета, мы запускаем распознавание прямо в браузере по описанному здесь конвейеру: захват на 16 кГц, фильтрация через voice-activity detection, лёгкая квантизованная модель на WebGPU с резервным путём через WebAssembly, а также заголовки cross-origin isolation, чтобы действительно задействовать многоядерный режим. Если же задача – расшифровка записанной групповой встречи с последующей возможностью поиска и перевода, мы обрабатываем аудио на сервере. Поскольку мы работаем в здравоохранении и образовании, где приватность и офлайн-работа – жёсткие требования, а не приятные бонусы, мы относимся к клиентскому распознаванию как к полноценному решению и подбираем модели, ориентируясь на реальные устройства, которые используют пользователи наших заказчиков.
Главное
- «faster-whisper» – серверная библиотека; реальные браузерные решения – whisper.cpp (Wasm) и Transformers.js (WebGPU).
- Встроенный Web Speech API по умолчанию отправляет аудио в Google – обработка происходит не на устройстве.
- Конвейер: микрофон → 16 кГц моно → VAD-гейт → Whisper → субтитры, всё в одной вкладке.
- WebGPU запускает модель на GPU и работает до ~100 раз быстрее, чем CPU-реализация на WebAssembly.
- Потокам WebAssembly требуется cross-origin isolation (заголовки COOP + COEP), иначе они отключаются без предупреждения.
- Выбирайте модель под самые слабые устройства; повышайте точность за счёт VAD и шумоподавления, а не за счёт размера модели.