Это исходный отчёт фазы как есть — со всеми таблицами и методикой. Живая версия: 🎙️ Распознавание речи.
Фаза 2: распознавание речи (STT) на NAS
Прогон: 18 октября 2026
Хост: UGREEN DXP4800 Pro, i3-1315U, 32 GB, iGPU Intel RPL-U (Xe-LP, 64 EU)
Что меряли: насколько точно и быстро разные модели распознают русскую речь на CPU и на iGPU, сколько им нужно памяти и как быстро они стартуют. Нужно для голосового ассистента (короткие команды) и расшифровки записей (длинное аудио).
Коротко
- Лучший вариант для NAS — whisper-large-v3-turbo int8 в OpenVINO Model Server (OVMS) на iGPU.
- 4.3% ошибок в словах на чистой речи (лучший результат 4.1%), 10.9% на шуме и 5.9% на 5-минутных записях (второе место в обоих).
- Фраза ~11 с распознаётся за 2.5 с, 5 минут записи — за 35 с (RTF 0.12).
- Нужно 2.3 GiB памяти, старт 12 с. API OpenAI-совместимый.
- По точности лидеры почти равны. Whisper-turbo в любом рантайме даёт 4.1–4.5% ошибок, Qwen3-ASR 1.7B 4.8–4.9%, Parakeet v3 5.4%. Разница не больше 1.3 п.п., это около 25 слов из 1974. Почти все ошибки в именах собственных (Киву, Дель Потро) и в записи чисел.
- Parakeet TDT 0.6B v3 на CPU самый быстрый из точных: 1.4 с на фразу, 2.6 GiB, iGPU при этом свободен. Два минуса:
- на длинных записях вдвое хуже лидеров (12.5% против 5.7–6.1%);
- на коротких кусках после VAD иногда переходит на украинский: «місяці», «сильний вітра», «двадцять п ять лістових». Язык ему не задать. На целых фразах такого не было ни разу, но короткие голосовые команды нужно проверить отдельно (фаза 4).
- whisper.cpp медленный. Модель и качество те же, что в OVMS, но на том же iGPU через Vulkan он в 3.3 раза медленнее (8.4 с на фразу). На CPU не успевает за реальным временем (RTF 1.47). Квантование q5_0 скорости не добавляет.
- Qwen3-ASR 1.7B (llama.cpp, Vulkan) — точный, хорошо держит длинные записи (5.7%), но 3.9 с на фразу и до 8.4 GiB памяти. Версия 0.6B заметно хуже: 10.2% ошибок, 21.2% на шуме.
- Vosk ru 0.42 самый быстрый и лёгкий: 0.5 с на фразу, RTF 0.05, 0.6 GiB. Числа он пишет словами, поэтому WER 8.5%; без фраз с цифрами 4.8%, почти как у лидеров. На шуме хуже (13.6%).
- Не нужны:
- Canary-1B-v2 — хуже и в 3 раза медленнее Parakeet;
- Parakeet v3 int8 — 7.7% ошибок против 5.4% у полной версии, а быстрее всего на 0.15 с;
- whisper-small — 11.6% ошибок;
- Vosk small — на фразах длиннее ~10 с падает с ошибкой энкодера, с нарезкой через VAD даёт 12.6%.
-
Borealis (Вихрь) — энкодер Whisper-large-v3 плюс Qwen2.5-0.5B, есть только для PyTorch. На этом CPU он медленный и на FLEURS неточный:
- 10.4% ошибок на чистой речи, 17.1% на шуме, ~20 с на фразу (RTF 1.77), 7.3 GiB;
- в bf16 ещё в 3.5 раза медленнее, у процессора нет аппаратного bf16;
- числа пишет словами; на длинных фразах иногда сочиняет продолжение («и волоса, которые могут предположить о своих достижениях…»).
Свои заявленные 6.3% авторы мерили на других наборах, так что их цифры с нашими не сравнить. - Voxtral-Mini-4B-Realtime не запускается: в llama.cpp пока влита только внутренняя поддержка потокового аудио, без серверной части.
Как мерили
- Данные — FLEURS ru_ru, тестовая часть (CC-BY-4.0): прочитанные вслух предложения из Википедии, разные дикторы, 16 kHz.
- Чистые: первые 100 фраз, 19.6 мин, 1974 слова. Медиана фразы 11 с, в 18 фразах есть цифры.
- Шум: первые 50 из них с бубнежом (наложение других фраз FLEURS) и розовым шумом при SNR 10 dB. Примерно как разговор на кухне при работающем телевизоре.
- Длинные: 2 записи по ~5 мин, склеенные из 25 фраз. Модель получает файл целиком; нарезкой (окна или VAD) занимается сам рантайм.
- Метрики:
- WER и CER считаются по всему набору после нормализации: регистр, «ё»→«е», без пунктуации. Числа к словам не приводятся. Поэтому «6-6» против «шесть шесть» засчитывается как ошибка. Колонка «без цифр» показывает, сколько из ошибок на это приходится.
- RTF: время распознавания, делённое на длительность аудио.
- Задержка фразы: время ответа на одну фразу целиком. Первый запрос (прогрев) в задержку не входит, но входит в «старт».
- Точность сравнения: на 1974 словах 1 п.п. WER — это примерно 20 слов. Разница меньше ~1.5 п.п. между моделями в пределах шума выборки.
- Рантаймы:
- whisper.cpp (
ghcr.io/ggml-org/whisper.cpp:main/main-vulkanот 18.10.2026),whisper-server,-l ru -t 6; - llama.cpp build 11718 (
server-vulkan), Qwen3-ASR в GGUF с mmproj, OpenAI-эндпоинт/v1/audio/transcriptions; - OpenVINO Model Server 2026.4.1 (
openvino/model_server:latest-gpu), моделиOpenVINO/whisper-large-v3-turbo-*-ov, эндпоинт/v3/audio/transcriptions; - onnx-asr 0.12.0 на onnxruntime CPU: Parakeet, Canary, Vosk. Длинные файлы режет Silero VAD.
- transformers 4.55.4 + PyTorch 2.8.0 CPU для Borealis, коммит
8f8f39e. Декодирование жадное, а не сэмплирование с температурой 0.2, как в карточке модели: так прогоны повторяемы. Используется fp32: в bf16 модель в 3.5 раза медленнее. Модель принимает не больше 30 с аудио, поэтому длинные записи не гоняли.
- whisper.cpp (
- Порядок: каждый движок в своём контейнере (
--memory 20g), по одному. Клиент отправляет фразы последовательно, по одной. Остальные сервисы NAS работали как обычно. - Память: раз в 2 с снимается RSS процессов контейнера и
docker stats, в таблицу идёт максимум. Для Parakeet, Canary и Vosk ru 0.42 память снималась отдельным проходом на 20 фразах. У Qwen3-ASR пик, скорее всего, приходится на 5-минутные записи: llama.cpp кодирует аудио целиком. - Воспроизведение:
- на NAS:
fetch.sh(образы и модели),prepare_data.py(наборы),run_stt.sh <движок> [наборы],run_matrix.sh; - клиенты:
stt_client.py(HTTP),onnx_runner.py(в процессе); - оценка:
score_stt.py; - сырые расшифровки и логи лежат в
raw/, таблицу ниже генерируетpython3 make_report.py.
- на NAS:
Качество и скорость
WER/CER в %, ниже лучше; нормализация: регистр, «ё», пунктуация, числа не приводятся к словам. «Без цифр» — WER только по фразам, в эталоне которых нет цифр (сколько ошибок дают «1960» против «тысяча девятьсот шестьдесят»). Чистые — 100 фраз FLEURS ru (19.6 мин), шум — первые 50 из них с бубнежом и розовым шумом при SNR 10 dB, длинные — 2 записи по ~5 мин целиком. RTF — время распознавания / длительность аудио (0.1 = в 10 раз быстрее реального времени). «Фраза» — медианная задержка на одной фразе (~11 с речи). «Старт» — от запуска контейнера до первой расшифровки (загрузка модели, у OVMS ещё и компиляция под устройство, + первая фраза). RAM — пик памяти (максимум из RSS процессов и docker stats).
| Модель | Рантайм | Устройство | WER чистые | без цифр | CER | WER шум 10 dB | WER длинные | RTF фразы / длинные | Фраза, с | Старт, с | RAM, GiB |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Parakeet TDT 0.6B v3 | onnx-asr | CPU | 5.4 | 4.6 | 1.6 | 11.6 | 12.5 | 0.13 / 0.15 | 1.4 | 9 | 2.6 |
| Parakeet TDT 0.6B v3 int8 | onnx-asr | CPU | 7.7 | 6.2 | 2.4 | — | — | 0.11 / — | 1.3 | 6 | 1.5 |
| Canary-1B-v2 | onnx-asr | CPU | 7.4 | 5.8 | 2.4 | 13.4 | 11.7 | 0.39 / 0.42 | 4.0 | 53 | 4.2 |
| Vosk ru 0.42 | onnx-asr | CPU | 8.5 | 4.8 | 4.8 | 13.6 | 10.3 | 0.05 / 0.06 | 0.5 | 8 | 0.6 |
| Vosk small ru + VAD | onnx-asr | CPU | 12.6 | 8.8 | 5.7 | — | — | 0.05 / — | 0.5 | 4 | 0.7 |
| Qwen3-ASR 0.6B Q8 | llama.cpp | iGPU Vulkan | 10.2 | 8.7 | 3.5 | 21.2 | 11.4 | 0.19 / 0.21 | 2.1 | 7 | 7.0 |
| Qwen3-ASR 1.7B Q8 | llama.cpp | iGPU Vulkan | 4.9 | 3.9 | 1.8 | 13.0 | 5.7 | 0.34 / 0.33 | 3.9 | 9 | 8.4 |
| Qwen3-ASR 1.7B Q8 | llama.cpp | CPU | 4.8 | 3.8 | 1.8 | — | — | 0.75 / — | 7.6 | 8 | 6.0 |
| whisper-large-v3-turbo int8 | OVMS | iGPU OpenVINO | 4.3 | 3.2 | 1.4 | 10.9 | 5.9 | 0.22 / 0.12 | 2.5 | 12 | 2.3 |
| whisper-large-v3-turbo fp16 | OVMS | iGPU OpenVINO | 4.5 | 3.4 | 1.5 | — | — | 0.22 / — | 2.5 | 52 | 3.0 |
| whisper-large-v3-turbo int8 | OVMS | CPU | 4.2 | 3.1 | 1.3 | — | — | 0.73 / — | 8.5 | 11 | 2.2 |
| whisper-large-v3-turbo q8_0 | whisper.cpp | iGPU Vulkan | 4.1 | 3.3 | 1.2 | 9.3 | 6.1 | 0.72 / 0.44 | 8.4 | 12 | 1.4 |
| whisper-large-v3-turbo q5_0 | whisper.cpp | iGPU Vulkan | 4.4 | 3.5 | 1.3 | — | — | 0.73 / — | 8.5 | 15 | 1.2 |
| whisper-large-v3-turbo q8_0 | whisper.cpp | CPU | 4.1 | 3.3 | 1.3 | — | — | 1.47 / — | 17.1 | 19 | 1.1 |
| whisper-small q8_0 | whisper.cpp | iGPU Vulkan | 11.6 | 10.6 | 3.4 | — | — | 0.20 / — | 2.2 | 6 | 0.7 |
| Borealis (Вихрь) fp32 | transformers | CPU | 10.4 | 7.1 | 5.0 | 17.1 | — | 1.77 / — | 20.6 | 24 | 7.3 |
Выводы и рекомендации
Что ставить
| Сценарий | Рекомендация | Почему |
|---|---|---|
| Расшифровка записей, голосовые заметки | whisper-large-v3-turbo int8, OVMS, iGPU | в двойке лучших на длинных записях и шуме, 5 мин за 35 с, 2.3 GiB |
| Голосовой ассистент (короткие команды) | пока он же; Parakeet v3 на CPU как кандидат | Parakeet втрое быстрее отвечает и не занимает iGPU, но его скачки в украинский нужно проверить на командах в фазе 4 |
| iGPU занят (индексация Immich, LLM) | Parakeet v3 на CPU | whisper-turbo на CPU — 8.5 с на фразу, для диалога медленно |
| Очень слабое железо (телефон) | Vosk ru 0.42 | 0.5 с на фразу и 0.6 GiB на CPU NAS; на телефоне не проверяли |
Что видно в цифрах
- Рантайм важнее модели. Одна и та же whisper-large-v3-turbo на одном и том же iGPU через OpenVINO в 3.3 раза быстрее, чем через Vulkan в whisper.cpp. На CPU OpenVINO тоже вдвое быстрее whisper.cpp (RTF 0.73 против 1.47).
- Whisper тратит время на окно 30 с, а не на длину фразы. Он всегда кодирует 30 секунд аудио, поэтому задержка почти постоянна: 2.5 с медиана и 5.3 с максимум на OVMS. На длинных записях окно используется полностью, и RTF падает до 0.12. Короткая команда на 2 с будет стоить примерно те же ~2–2.5 с. Parakeet и Vosk работают пропорционально длине, у них на командах выигрыш будет больше.
- int8 против fp16 на iGPU: скорость одинаковая (RTF 0.22), качество в пределах шума, памяти на 0.7 GiB меньше. Значит, int8.
- Шум 10 dB ухудшает всех в 2–2.5 раза. Устойчивее всех whisper-turbo (9.3–10.9%), хуже всех Qwen3-ASR 0.6B (21%). Синтетический бубнёж — жёсткая проверка: реальная кухня с телевизором может быть и легче, и тяжелее.
- iGPU один на всех. На нём же будут работать Immich ML (OpenVINO) и LLM (Vulkan). Одновременную нагрузку здесь не мерили, это вопрос для постоянного стека.
Заметки для фреймворка
- API у всех разный:
- OVMS:
/v3/audio/transcriptions, имя модели задаётся в конфиге; - whisper.cpp: свой
/inference; - llama.cpp:
/v1/audio/transcriptions, но Qwen3-ASR возвращает текст с префиксомlanguage Russian<asr_text>, его надо срезать; - у onnx-asr и Borealis сервера нет, нужна своя обёртка.
- OVMS:
- OVMS при первом запуске качает модель с HF и компилирует её под iGPU (fp16 стартовал 52 с против 12 с у int8). Модели лучше держать в
/volume2, как сделано здесь. - onnx-asr не загружает модели из HF-кэша с симлинками (ONNX Runtime отказывается читать внешние данные через симлинк), нужна обычная папка.
Ограничения
- FLEURS — прочитанные вслух предложения из Википедии. Много имён и чисел, разговорной речи нет. На бытовых фразах ошибок, скорее всего, будет меньше, на быстрой разговорной речи — больше.
- 100 фраз (1974 слова). Различия меньше ~1.5 п.п. — шум выборки.
- Короткие команды (1–3 с) не мерили, это фаза 4 вместе с TTS и LLM.
- Запросы шли по одному, параллельно работали остальные сервисы NAS (Home Assistant и другие домашние сервисы). Одновременную нагрузку на iGPU не проверяли.