Voice / ML Platform
Go-сервисы потоковой обработки аудио и ML-интеграций.
Интерактивная архитектура
Поток, отмена и трассировка.
Аудио приходит чанками
Аудио поступает отдельными чанками; обработка начинается до получения полной записи.
- Реплика
- учебный turn A
- Политика буфера
- ограничен
- Выход
- не начат
Условный абонент. Вход и выход остаются открытыми поверх потокового транспорта.
Прочитать все шаги
Путь одной условной реплики от чанков входа до чанков выхода.
Аудио поступает отдельными чанками; обработка начинается до получения полной записи.
На входе ограниченная очередь. При замедлении downstream нужна явная политика backpressure или отбрасывания, а не бесконечный рост памяти.
VAD определяет речь и тишину во входящих чанках до завершения текущего высказывания.
ASR может выдать гипотезу до финального результата. Синтетический пример: «Давайте…» → «Давайте обсудим систему».
Оркестратор владеет отменяемым контекстом реплики. Промежуточный результат нельзя считать окончательной командой.
Концептуальный вызов LLM готовит ответ. Контекст, deadline и границы ошибок передаются вместе с запросом.
TTS создаёт чанки текущей реплики. Выходная очередь ограничена; завершённую работу нельзя отменить задним числом.
Двунаправленный streaming возвращает ответ при открытом входе. Trace context связывает сервисы без раскрытия аудио и транскриптов.
Фиксировать spans, причины отмены и давление очередей. Демонстрация не генерирует вымышленные production-трассы и бюджеты задержек.
Меньше времени на каждый аудиочанк.
Я профилировал обработку аудио, устранил узкие места и сократил время обработки чанка с 200 до 30 мс.
Обработка аудиочанка
Общая шкала — 200 мс. Сокращение времени: (200 − 30) / 200 = 85%.
меньше времени на обработку аудиочанка
снижение задержки API после оптимизации SQL и взаимодействия сервисов
200 / 30 = 6,67×. Сокращение обработки освобождает время в общем бюджете задержки аудиопайплайна.
Улучшил классификацию намерений на 0,10 Macro F1 в абсолютном выражении.
Улучшил извлечение сущностей примерно на 0,10 F1 в абсолютном выражении.
Повысил долю ответов с корректной структурой JSON на 5–6 процентных пунктов.
Снизил частоту ошибок обработки отрицаний в четыре раза. Схема показывает относительную частоту.
Обзор
Разрабатываю Go backend для распределённой обработки аудио и ML-интеграций. Занимаюсь потоковыми интерфейсами, профилированием, запросами к БД и надёжностью сервисов.
Задача
У потоковых взаимодействий и асинхронных ML-задач разные жизненные циклы. Интерфейсы должны явно передавать отмену, обратное давление, ошибки и завершение на этих границах.
Мой вклад
Разрабатывал и поддерживал Go-сервисы распределённой обработки аудио в Zuzex. Участвовал в архитектуре и code review, профилировал узкие места, оптимизировал SQL и взаимодействие сервисов. Самостоятельно поддерживал CI/CD с Docker, unit-тестами и golangci-lint.
Решения и компромиссы
- Использовать явные контракты для потоковых и асинхронных границ.
- Передавать контекст между сервисами и связывать трассы через OpenTelemetry.
Streaming даёт постепенный обмен, но требует управления жизненным циклом и обратным давлением. Асинхронная обработка развязывает выполнение ценой задержки завершения и дополнительных состояний отказа.
Потоковая обработка между сервисами.
В Zuzex разрабатываю Go-сервисы обработки аудио, профилирую критические участки, оптимизирую SQL и поддерживаю CI/CD. Потоковые интерфейсы должны обрабатывать медленных consumers, прерванные запросы и частичные результаты без утечек работы.
Двунаправленный gRPC-поток разделяет жизненные циклы входа и выхода. Закрытие одного направления, отмена всего context и достижение deadline — разные события; контракт сервиса должен их различать.
Чанки и промежуточное распознавание.
Условный вход доставляет чанки в ограниченный буфер. VAD и потоковый ASR могут выдавать активность и промежуточное распознавание до финального текста. Частичный и окончательный результаты требуют разных событий; гипотеза как окончательная команда создаёт ошибки.
Оркестратор владеет текущей репликой, вызывает генерацию и возвращает TTS-чанки по открытому потоку. Порядка транспорта недостаточно: ID реплики должен отличать текущую работу от запоздавших чанков отменённого ответа.
Отмена прерванного ответа.
Если абонент говорит во время ответа, управление переходит новой реплике. Нужно отменить текущий синтез и ещё выполняющуюся отменяемую работу, инвалидировать выходную очередь и игнорировать поздние чанки старой реплики. Завершённый LLM-вызов не откатывается.
Отмена кооперативна и неидеально проходит границы сервисов. В Go передавать context, учитывать отмену у блокирующих операций и определять смысл закрытия направлений потока. Тесты должны различать half-close, deadline, отключение стороны и предметную отмену.
Backpressure — ещё и продуктовое решение.
Неограниченная очередь скрывает перегрузку до неприемлемой задержки или памяти. Ограниченная требует политики: блокировать upstream, отбрасывать старые чанки, отклонять работу или деградировать. Выбор зависит от того, безопаснее ли потерять чанк, чем доставить очень старую речь.
Batch request/response проще, но задерживает промежуточную пользу. Streaming даёт постепенный ответ ценой состояний жизненного цикла, backpressure и гонок отмены. Гибрид может оставить синхронное управление и вынести долгую работу за асинхронную границу.
Проверять пересечения, не только текст.
Предлагаемая матрица задерживает ASR-гипотезы, отменяет синтез, доставляет старый чанк после новой реплики, замедляет выход и отключает одну сторону потока. Проверять границы очередей, распространение отмены и отсутствие старого звука.
Проверяю отмену на каждой границе, в том числе после начала новой реплики. Основной инвариант: запоздавший чанк отменённого ответа не должен попасть в воспроизведение.
Latency budget требует критического пути.
Захват, буферизация, распознавание, генерация и синтез могут пересекаться. Отслеживаю критический путь, а не складываю параллельные spans. Отдельно отмечаю ожидание в очереди, первый полезный ответ, завершение и отмену.
Передаю trace и turn context между сервисами, не записывая аудио и тексты реплик в логи. Насыщение очередей, отмены, deadlines и отброшенные старые чанки помогают найти место задержки.
Результаты и следующие шаги
Сократил обработку аудиочанка с 200 до 30 мс — на 85%. Оптимизация SQL и взаимодействия сервисов также снизила задержки API на 15–20%.
Главный вывод
Проектировать границы: ответственность, отмена, восстановление и наблюдаемость важны не меньше реализации самого сервиса.