В логах голосового агента LiveKit вы можете увидеть любое из следующих предупреждений вместе с сопутствующей задержкой:
- VAD inference is slower than realtime
- inference is slower than realtime
- VAD slower than realtime
Точный текст зависит от используемой версии LiveKit Agents и от того, написан ли ваш агент на Python или Node.js, но все они означают одно и то же.
Эти предупреждения никак не связаны с моделями STT, TTS и LLM, которые вы используете через LiveKit Inference. Они означают, что модель определения голосовой активности (VAD), выполняемая внутри процесса вашего агента, потратила слишком много времени на обработку небольшого фрагмента аудио.
Что делает VAD? VAD сообщает вашему голосовому агенту, когда говорящий начал и закончил говорить. Наряду с определением реплик (turn detection), это определяет, когда агент отвечает.
Как работает VAD? Ваш агент подключается к комнате LiveKit в качестве участника и получает аудио так же, как и все остальные в комнате. VAD работает внутри рабочего процесса вашего агента, где он анализирует это декодированное PCM-аудио для обнаружения голосовой активности. Аудио поступает в реальном времени, и у процесса вашего агента помимо VAD есть множество других задач, поэтому для успевания каждый 32-мс фрагмент аудио должен быть обработан менее чем за 32 мс.
Что идет не так? Если VAD не успевает обработать свой фрагмент аудио вовремя, он возобновляет работу с того места, где остановился, при следующем запуске. Повторяйте это снова и снова, и VAD будет отставать все сильнее. Отставание на 50 мс незаметно, но если ситуация не разрешится сама собой, аудио, с которым работает VAD, окажется заметно позади аудио, поступающего к вашему агенту.
Предупреждение срабатывает, как только VAD начинает отставать от конвейера аудиореального времени. Точный триггер немного отличается для агентов на Python и Node.js, но в обоих случаях вы увидите в логах предупреждение о том, что VAD больше не поспевает за поступающим звуком. Уточним: задержка, сообщаемая вместе с предупреждением, показывает, насколько сильно отстал VAD, поэтому задержка в 1000 мс означает, что VAD обрабатывает аудио с отставанием в 1 секунду от живого звука. Это не означает, что VAD работал в течение 1 секунды.
Также обратите внимание, что Python сообщает о задержке в секундах, в то время как Node.js — в миллисекундах.
Симптомы#
VAD, который не успевает за потоком, проявляется в виде самых разных, на первый взгляд не связанных друг с другом симптомов агента. Некоторые из них вызваны поздним срабатыванием END_OF_SPEECH, поскольку это ключевой входной параметр для определения реплик. Другие проистекают из того, что именно лишает VAD ресурсов в первую очередь:
- Агент медленно замечает, что вы закончили говорить.
- Агент перебивает людей и пропускает моменты прерывания речи.
- Приветствие обрезается, или в начале звонка возникают ложные прерывания.
- Звук прерывается в записях исходящего трафика, но звучит нормально в LiveKit Agent Insights.
- Потребление памяти растет в течение длительного сеанса и в крайних случаях приводит к предупреждениям о нехватке памяти для процесса.
Как это исправить#
Во-первых, короткую вспышку предупреждений в первые несколько секунд сеанса можно проигнорировать, так как она не влияет на точность VAD. Это наиболее вероятно, если вы все еще используете плагин Silero VAD.
Во-вторых, ряд проблем, вызывавших ложные сообщения об этом предупреждении, со временем были исправлены, поэтому убедитесь, что вы используете последнюю версию LiveKit Agents и детектора реплик LiveKit. Также стоит использовать встроенный по умолчанию inference VAD, который предоставляет AgentSession, а не отдельный плагин.
Два замечания по поводу вышесказанного:
- Это общие рекомендации. Как фреймворк, мы поддерживаем несколько моделей определения реплик и VAD, и в целом рекомендация всегда будет заключаться в использовании последней версии.
- При переходе с плагина Silero на inference VAD имейте в виду, что значение min_silence_duration по умолчанию также изменилось (плагин, инференс).
Затем, что самое главное, исключите блокировку цикла событий (event loop). Любой синхронный код в вашей программе, такой как блокирующий вызов HTTP, запись в базу данных во время звонка или тяжелые вычисления, нагружающие CPU, может привести к этому предупреждению, поскольку время ожидания блокирующего кода учитывается внутри таймера инференса VAD. Я написал отдельный блог о диагностике заблокированных циклов событий в LiveKit Agents, и самым простым решением для большинства клиентов было передать этот блог своему кодинг-агенту и попросить его найти проблемы.
И наконец, проверьте, не приближается ли нагрузка на CPU на вашей машине к пределу. Заблокировать цикл событий при низкой нагрузке на CPU все еще возможно, поэтому не стоит полагаться на то, что низкое использование CPU означает отсутствие блокировки цикла. Если вы используете self-hosted вариант, следуйте всем рекомендациям в нашей документации по self-hosted агентам, особенно требованиям к памяти и CPU, и проверьте, правильно ли установлены параметры load_fnc и load_threshold.
Фактически затраченное на инференс VAD время сообщается через событие metrics_collected для VAD, которое срабатывает примерно раз в секунду и содержит inference_duration_total и inference_count. Разделите одно на другое, чтобы получить среднюю стоимость за окно, следующим образом:
Стабильно высокое среднее значение указывает на нехватку ресурсов CPU (CPU starvation), в то время как значение, которое обычно близко к нулю, но дает всплески, указывает на проблемы с циклом событий. Дополнительную информацию и примеры метрик VAD см. в рецепте метрик VAD.
Другие шаги, которые вы можете предпринять:
- Используйте полную версию модели определения реплик по аудио, которая доступна всем агентам LiveKit Cloud. Она работает в облаке, в то время как облегченная модель работает локально и делит ресурсы вашего CPU.
- Если вы используете self-hosted вариант, проверьте, соответствует ли количество предварительно прогретых процессов вашему ожиданию, так как несоответствие может означать, что воркер имеет неверное представление о количестве доступных ему ядер CPU.
Чего делать не следует#
Не поддавайтесь искушению выделить VAD больше потоков, увеличить max_buffered_speech или увеличить num_idle_processes. Ничто из этого не поможет VAD поспевать за речью в реальном времени, а производительность может ухудшиться.
Если предупреждение появляется часто и носит постоянный характер, не игнорируйте его: у вас есть реальная проблема, которая ухудшает пользовательский опыт. Эффект может быть незначительным или эпизодическим, но его стоит исправить.
Не думайте, что это предупреждение связано с каким-то близким по времени сбоем в логах. Если они коррелируют, то обычно потому, что у них общая первопричина, чаще всего — нагрузка на CPU в процессе.
Все еще нужна помощь?#
Присоединяйтесь к нашему сообществу разработчиков на community.livekit.io