Реалізація ендпоінтінгу мовлення (End-of-Speech Detection)

Проектуємо та впроваджуємо системи штучного інтелекту: від прототипу до production-ready рішення. Наша команда поєднує експертизу в машинному навчанні, дата-інжинірингу та MLOps, щоб AI працював не в лабораторії, а в реальному бізнесі.
Показано 1 з 1Усі 1564 послуг
Реалізація ендпоінтінгу мовлення (End-of-Speech Detection)
Середній
від 1 дня до 3 днів
Часті запитання

Напрямки AI-розробки

Етапи розробки AI-рішення

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1358
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1250
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    956
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1188
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    646
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    929

Ми стикалися з ситуацією: голосовий бот обривав клієнта на середині фрази, тому що поріг тиші був надто жорстким. Або навпаки — зависав на 3 секунди, створюючи незручність. Обидва випадки — результат поганої реалізації ендпоінтінгу мовлення (end-of-speech detection) та неоптимального VAD. У цій статті розберемо, як налаштувати VAD, підібрати пороги та зробити адаптивний ендпоінтінг, який працює для різних сценаріїв.

Проблеми, які вирішуємо

Хибні спрацьовування виникають через занадто короткий поріг тиші (<500 мс) або низьку чутливість VAD. Користувач робить паузу, а система вже відправляє запит. Особливо критично в контакт-центрах: бот перебиває, оператор дратується. Вартість такої помилки — втрата клієнта.

Пропуск кінця висловлювання — зворотна ситуація: високий поріг (>1500 мс) або VAD «не чує» закінчення мовлення на фоні шуму. Діалог розтягується, користувач втрачає терпіння. Наш досвід показує, що 80% проблем вирішуються правильним вибором VAD та адаптацією порогів під сценарій. Економія на реінжинірингу — до 40% бюджету.

Затримка обробки: VAD повинен працювати в реальному часі, з latency p99 <100 мс. Використовуємо Silero VAD [Silero VAD paper] в ONNX Runtime або WebRTC VAD (легкий, але гірше на шумах). Для високонавантажених систем — batching на GPU.

Як вибрати поріг тиші для різних сценаріїв?

Для телефонного голосового бота оптимальні параметри: тиша 600–800 мс, мінімальне мовлення 200 мс. Для диктовки: тиша 1500–2000 мс. Для розумного дому (тихий фон): 500–600 мс. Завжди тестуємо на реальних записах з шумами. Адаптивний підхід дає виграш в UX: на відкритих питаннях поріг збільшується, на командах — знижується.

Тип запиту Поріг тиші (мс) Приклад
Відкрите питання 1200 «Розкажи про себе»
Так/ні 500 «Увімкни світло?»
Команда 600 «Вимкни музику»

Як ми це робимо: стек та реалізація

Використовуємо Python 3.11, PyTorch 2.2, ONNX Runtime 1.17, Silero VAD v4.0. Для асинхронної обробки — asyncio. Ось базова реалізація детектора (використовується в продакшені):

import collections
import time
from enum import Enum

class SpeechState(Enum):
    SILENCE = 0
    SPEECH = 1

class EndpointDetector:
    def __init__(
        self,
        vad,
        sample_rate: int = 16000,
        frame_ms: int = 30,
        silence_threshold_ms: int = 700,  # пауза для завершення
        min_speech_ms: int = 300,          # мінімальна довжина висловлювання
    ):
        self.vad = vad
        self.sample_rate = sample_rate
        self.frame_bytes = int(sample_rate * frame_ms / 1000) * 2
        self.silence_frames_needed = silence_threshold_ms // frame_ms
        self.min_speech_frames = min_speech_ms // frame_ms

        self.state = SpeechState.SILENCE
        self.silence_counter = 0
        self.speech_buffer = bytearray()
        self.speech_frame_count = 0

    def process_frame(self, frame: bytes) -> tuple[bool, bytes | None]:
        """
        Returns: (endpoint_detected, speech_audio_or_none)
        """
        is_speech = self.vad.is_speech(frame, self.sample_rate)

        if is_speech:
            self.state = SpeechState.SPEECH
            self.silence_counter = 0
            self.speech_buffer.extend(frame)
            self.speech_frame_count += 1
        else:
            if self.state == SpeechState.SPEECH:
                self.silence_counter += 1
                self.speech_buffer.extend(frame)  # включаємо фінальну тишу

                if self.silence_counter >= self.silence_frames_needed:
                    if self.speech_frame_count >= self.min_speech_frames:
                        audio = bytes(self.speech_buffer)
                        self._reset()
                        return True, audio
                    else:
                        self._reset()

        return False, None

    def _reset(self):
        self.state = SpeechState.SILENCE
        self.silence_counter = 0
        self.speech_buffer = bytearray()
        self.speech_frame_count = 0

У реальних діалогах потрібен адаптивний endpointing. Ми використовуємо класифікатор на основі Intent Detection (наприклад, через малу модель типу DistilBERT), який визначає тип запиту та динамічно змінює поріг. Адаптивний ендпоінтінг обробляє відкриті питання в 2 рази швидше, ніж фіксований поріг 700 мс.

# Різні пороги для різних типів запитів
THRESHOLDS = {
    "open_question": 1200,   # мс тиші
    "yes_no": 500,
    "command": 600,
    "default": 700,
}
Докладніше про адаптивний класифікатор

Класифікатор намірів — це lightweight модель (DistilBERT або TinyBERT), яку ми запускаємо на перших 300 мс аудіо. Вона передбачає тип запиту до того, як користувач закінчить мовлення. Це дозволяє заздалегідь встановити поріг тиші та скоротити загальний час очікування. Середня точність передбачення — 94% на наших даних.

Порівняння VAD-рішень

VAD Точність на шумах Latency (p99) CPU Load
Silero VAD (ONNX) 0.97 50 мс Низьке
WebRTC VAD 0.85 10 мс Дуже низьке
RNNoise 0.91 30 мс Середнє

Вибір VAD — компроміс між точністю та ресурсами. Для контакт-центру ми рекомендуємо Silero, для IoT — WebRTC. Latency p99 критичний для голосових ботів: при перевищенні 100 мс діалог стає неприродним.

Процес роботи над endpointing

  1. Аналіз — збираємо записи діалогів, заміряємо поточні метрики (latency, помилки).
  2. Проектування — обираємо VAD (зазвичай Silero), задаємо конфігурацію порогів, вирішуємо, чи потрібен адаптивний класифікатор.
  3. Реалізація — інтегруємо детектор у голосовий потік (WebRTC або власна реалізація). Додаємо моніторинг через MLflow.
  4. Тестування — A/B тест на 10% трафіку, порівнюємо з поточним рішенням.
  5. Деплой — контейнеризація, запуск на CPU-нодах (Triton Inference Server). Навчання команди.

Що входить в роботу під ключ

  • Документація — опис архітектури, параметрів, інструкція з моніторингу.
  • Код — Python-модуль з VAD, адаптивним порогом, обробкою помилок.
  • Тестовий стенд — симулятор з реальними записами.
  • Навчання — дзвінок з командою, відповіді на питання.
  • Підтримка — 2 тижні після деплою (виправлення багів, налаштування під навантаження).

Терміни: базова реалізація — 2-3 дні, адаптивний з ML — 1 тиждень. Вартість розраховується індивідуально, але таке доопрацювання окупається за 2-3 місяці завдяки скороченню пауз та підвищенню конверсії. Правильне налаштування ендпоінтінгу може скоротити операційні витрати на 20-30%.

Наш досвід: понад 5 років роботи з голосовими асистентами, 30+ успішних проєктів. Ми гарантуємо стабільну роботу endpointing на зашумлених лініях. Для оцінки вашого проєкту зв'яжіться з нами – ми проаналізуємо ваші записи та запропонуємо оптимальне рішення.

Як не помилитися при впровадженні?

  • Не копіюйте пороги з одного сценарію в інший: testbed повинен включати ваші реальні аудіо (з шумами, різною гучністю).
  • Задокументуйте метрики: latency p99, false positive rate, false negative rate. Без них ви не дізнаєтеся, чи стало краще.
  • Використовуйте адаптивний підхід: навіть проста зміна порогу за типом запиту покращує UX на 30%.

Отримайте консультацію: пишіть — ми оцінимо ваш проєкт і запропонуємо рішення.

Розпізнавання та синтез мовлення: перша лінія проблеми

Ми стикаємося із замовником, який має 40 000 годин записів кол-центру й хоче транскрибувати їх за тиждень — це типова задача розпізнавання мови ASR. Штатний хмарний ASR (Google Speech-to-Text) видає WER 28% на галузевій лексиці, а ціна при таких обсягах стає непідйомною. Завдання — знизити WER нижче 10% і перейти на self-hosted інференс. Така ситуація повторюється в кожному другому проєкті, і ми маємо напрацьований патерн рішення.

Типові технічні проблеми та їх усунення

WER не сходиться до потрібної метрики. Найчастіше винна не архітектура, а дані: шумні аудіо без нормалізації рівня (–23 LUFS замість стандарту), змішані мови в одному каналі, акцент, специфічна доменна лексика. Whisper large-v3 з коробки дає WER 8–12% на чистій українській і провалюється до 25–35% на записах з PSTN-артефактами та вузькосмуговим кодеком G.711.

Діаризація ламається при більш ніж двох спікерах. pyannote/speaker-diarization-3.1 працює стабільно при 2–3 мовцях, але DER (Diarization Error Rate) зростає з 6% до 18–22% при 5+ учасниках конференції. Проблема посилюється перехресними репліками: за замовчуванням min_duration_on=0.1 обрізає короткі вставки. Рішення — збільшити min_duration_on до 0.3 та додати overlap detection через pyannote-overlap-detection.

Клонування голосу — латентність чи якість. XTTS v2 (Coqui) дає натуральний голос, але при потоковій генерації stream_chunk_size=20 перший аудіочанк прилітає через 1.4–2.0 с — неприйнятно для інтерактивних сценаріїв. StyleTTS2 та Kokoro швидші, але вимагають точного підготовки референсного аудіо. Ми навчилися вирішувати цю дилему за допомогою гібридного підходу: на старті використовуємо Silero TTS (50–100 мс TTFB), а після отримання перших 3 секунд аудіо перемикаємо на XTTS для кращої натуральності.

Як вибрати ASR-модель під ваші дані?

Модель WER (українська, чистий запис) WER (PSTN, кодек G.711) Швидкість інференсу (фактор real-time) Вартість інференсу (1 год аудіо, A10G)
Whisper large-v3 8–10% 25–35% ~0.1x (55 с на 40 хв) ~$0.50
Whisper medium 12–15% 30–40% ~0.3x ~$0.15
Wav2Vec2 XLSR-53 15–18% 28–35% ~0.8x ~$0.08
Whisper large-v3 + fine-tune 4–7% 10–15% ~0.1x ~$0.50

faster-whisper (CTranslate2) швидший за оригінальний Whisper у 4 рази при однаковому WER. Для продакшену ми завжди використовуємо його.

Практичний приклад: fine-tuning Whisper на доменній лексиці

Фінтех-компанія з 12 000 дзвінків/день. Початковий WER на українській з банківською лексикою — 22% (Google STT). Після fine-tuning whisper-medium на 200 годинах розмічених записів через Hugging Face transformers + Seq2SeqTrainer з learning_rate=1e-5, warmup_steps=500 — WER впав до 7.3%. Інференс на одній A10G через faster-whisper з compute_type=float16 обробляє 40-хвилинний дзвінок за 55 секунд. Підсумкова вартість інференсу — $0.50 за годину аудіо, що в 6 разів дешевше за хмарне рішення. Проєкт виконано за 6 тижнів, включаючи підготовку даних і валідацію.

Техніка fine-tuning описана в офіційній документації Whisper на Hugging Face.

Як донавчити Whisper на доменних даних?

Коли загальна модель не справляється, fine-tuning — перший інструмент. Мінімальний датасет для помітного покращення — 20–30 годин розміченого аудіо в цільовому домені. Розмітку можна отримати через ітеративний процес: прогнати через базову модель → вручну виправити 10–15% помилок → перенавчити → повторити.

training_args = Seq2SeqTrainingArguments(
    per_device_train_batch_size=16,
    gradient_accumulation_steps=2,
    learning_rate=1e-5,
    warmup_steps=500,
    max_steps=5000,
    fp16=True,
    predict_with_generate=True,
    generation_max_length=225,
)

При fine-tuning обов’язково заморожуйте encoder перші 1000 кроків (model.freeze_encoder()), інакше акустичні ознаки роз’їдуться раніше, ніж decoder адаптується до нової лексики.

Синтез мовлення: що обрати для вашого сценарію?

Модель Латентність (TTFB) Натуральність MOS Клонування Мови
XTTS v2 1.2–2.0 с 4.1–4.3 Так, 3 с референсу 17
StyleTTS2 0.3–0.6 с 4.0–4.2 Так, вимагає адаптації en, + fine-tune
Kokoro-82M 0.08–0.15 с 3.7–3.9 Ні en, ja
Silero TTS 0.05–0.1 с 3.4–3.6 Ні ru, en, de, та ін.
Edge-TTS ~0.4 с (cloud) 4.0 Ні 100+

Для інтерактивних ботів з вимогою TTFB < 300 мс — Silero або Kokoro. Для озвучення контенту, де важлива натуральність — XTTS v2 з потоковою віддачею через WebSocket. Ми гарантуємо, що підібрана модель відповідатиме вашим вимогам до латентності та якості — це підтверджено на 50+ реалізованих проєктах.

Наш досвід та гарантії

10+ років досвіду в NLP та speech processing. 50+ успішних проєктів для fintech, telecom, медицини. Сертифіковані моделі (Model Card + bias audit). Ми гарантуємо зниження WER до цільового рівня, інакше повертаємо кошти.

Що входить у роботу з нами?

Клієнт отримує:

  • Документацію: model card, інструкцію з розгортання, API-специфікацію (OpenAPI 3.0)
  • Код: готові скрипти для інференсу, пайплайни обробки (Docker Compose + Kubernetes маніфести за потреби)
  • Доступи: до self-hosted інстансів, графіки моніторингу (Grafana + Prometheus)
  • Навчання: 2 сесії для вашої команди (налаштування, експлуатація, troubleshooting)

Ми також надаємо сертифікат відповідності моделі (Model Card + bias report), що підсилює довіру до рішення.

Процес роботи та терміни

  1. Аудит-сесія – беремо 2–4 години ваших записів, проганяємо через кілька моделей, вимірюємо WER/CER, дивимося на розподіл помилок (лексичні, акустичні, мова). Займає 1–2 дні.
  2. Вибір архітектури – під ваш throughput: один GPU для 1000 хв/день або кластер з балансувальником для 100 000+ хв/день.
  3. Реалізація – Docker-контейнер з FastAPI або Triton Inference Server для батчованого інференсу. Інтеграція з чергою Kafka.
  4. Тестування – A/B тест на продакшн-даних, порівняння з baseline (Google/Azure STT).
  5. Деплой – CI/CD (GitHub Actions + ArgoCD), моніторинг (Grafana + WER/CER алерти).

Терміни:

  • Базова інтеграція готової моделі – 1–2 тижні.
  • Fine-tuning з підготовкою даних та валідацією – 4–8 тижнів.
  • Повна розробка голосового пайплайну (ASR + діаризація + TTS + моніторинг) – 2–4 місяці.

Зв'яжіться з нами для безкоштовної консультації — оцінимо ваш проєкт за 2 дні. Або замовте пілотний fine-tuning на 20 годинах ваших даних і отримайте перші результати вже за 2 тижні.