ASR / ПУТЬ ЗВУКАЛокальная техническая презентация · 28 октября 2026
Как читать схемы и сравнивать время
Почему batch выглядит медленнее? Здесь разделены сбор фразы, вычисление модели, доставка результата и ожидание предыдущего прогона. Нажмите на блок или стрелку — получите формат данных, границы таймера и ссылку на код. A и B запускаются последовательно. Числа в разных строках могут перекрываться; складывать их без проверки нельзя.
Браузер записывает один PCM. Сначала A распознаёт поступающие окна, затем B повторно подаёт те же байты со скоростью 1× и ждёт готовых фраз. Три модели разделяют worker; LinTO использует свои WS и HTTP endpoints. Результаты остаются диагностикой и не запускают чат или инструменты.
Граница: ASR Compare → текст в браузере
━━ Вызов / передача┄┄ Событие / поток··· Владение / зависимость? Нет отдельной точки замера
VERIFIED / SOURCE · цифры: выбранный реальный прогон · время разных часов не вычитается01
02 / 26 · СХЕМА ВЗАИМОДЕЙСТВИЙ
Почему batch кажется медленнее
Собственный таймер B стартует только после A. Малое время decoder не означает быстрый показ: B сначала собирает речь и тишину, затем вычисляет ответ. Общая шкала включает предшествующий A и показывает именно последовательность, которую наблюдает человек.
Собственный секундомер и общая кнопка запуска
━━ Вызов / передача┄┄ Событие / поток··· Владение / зависимость? Нет отдельной точки замера
VERIFIED / SOURCE · цифры: выбранный реальный прогон · время разных часов не вычитается02
03 / 26 · СХЕМА ВЗАИМОДЕЙСТВИЙ
До PCM: кто разрешает прогон
Страница получает ограниченный grant, резервирует существующий replay-слот и открывает аудиоклиент. Core закрепляет backend и processing_mode; браузер не может подменить их в PCM. Этот подготовительный интервал измерен целиком, а его отдельные командные RPC видны в экспорте.
HTTPS bootstrap и конечные NATS-команды
━━ Вызов / передача┄┄ Событие / поток··· Владение / зависимость? Нет отдельной точки замера
VERIFIED / SOURCE · цифры: выбранный реальный прогон · время разных часов не вычитается03
04 / 26 · СХЕМА ВЗАИМОДЕЙСТВИЙ
Из микрофона получается PCM16
getUserMedia передаёт браузеру EC, NS и AGC. CaptureController соединяет дорожку с AudioWorklet; локальный energy VAD в Compare выключен. Worklet квантует float32 в 16 бит и передаёт блоки в основной поток. Реальная обработка микрофона зависит от браузера и фиксируется requested/actual.
Один захват, без Opus и без MediaRecorder
━━ Вызов / передача┄┄ Событие / поток··· Владение / зависимость? Нет отдельной точки замера
VERIFIED / SOURCE · цифры: выбранный реальный прогон · время разных часов не вычитается04
05 / 26 · СХЕМА ВЗАИМОДЕЙСТВИЙ
Что именно летит из браузера
PCM не превращается в Base64 на браузерном пути. В начало пакета добавляются 8 байт sequence, затем идут little-endian отсчёты. NATS обрамляет этот payload своим протоколом и передаёт по WebSocket; flush подтверждает доставку брокеру, но не является таймером накопления фразы.
━━ Вызов / передача┄┄ Событие / поток··· Владение / зависимость? Нет отдельной точки замера
VERIFIED / SOURCE · цифры: выбранный реальный прогон · время разных часов не вычитается05
06 / 26 · СХЕМА ВЗАИМОДЕЙСТВИЙ
Ingress: 48 кГц превращаются в 16 кГц
NatsAudio проверяет sequence и формат, затем подаёт PCM в один PcmFifo. PyAV сохраняет задержку ресемплера между блоками. Выход делится на 320 отсчётов, то есть 20 мс. Замер CPU охватывает feed/resample/enqueue; он не является временем в сети.
Проверка владельца, непрерывный resampler и FIFO
━━ Вызов / передача┄┄ Событие / поток··· Владение / зависимость? Нет отдельной точки замера
VERIFIED / SOURCE · цифры: выбранный реальный прогон · время разных часов не вычитается06
07 / 26 · СХЕМА ВЗАИМОДЕЙСТВИЙ
Как NATS связывает два хоста
Ingress отправляет PCM локальному bridge. Для worker bridge публикует to.inference…, а H100 получает inference… через существующие account imports и leafnode. Обратные события получают префикс from.inference…. Эти отображения не перекодируют звук. Односторонний сетевой интервал здесь не измерен.
Subject mapping, account и leafnode — отдельные участники
━━ Вызов / передача┄┄ Событие / поток··· Владение / зависимость? Нет отдельной точки замера
VERIFIED / SOURCE · цифры: выбранный реальный прогон · время разных часов не вычитается07
08 / 26 · СХЕМА ВЗАИМОДЕЙСТВИЙ
Streaming VAD отдаёт звук до конца фразы
Bridge один раз обрабатывает каждое 32-мс окно Silero. После подтверждения речи он выдаёт pre-roll и последующие окна worker, не ожидая всей фразы. Закрытие по тишине запускает final. Поэтому сбор готовой фразы и начало decoder в streaming перекрываются.
512 samples · 32 мс · подтверждение начала и тишины
━━ Вызов / передача┄┄ Событие / поток··· Владение / зависимость? Нет отдельной точки замера
VERIFIED / SOURCE · цифры: выбранный реальный прогон · время разных часов не вычитается08
09 / 26 · СХЕМА ВЗАИМОДЕЙСТВИЙ
Worker распознаёт растущее окно
Worker принимает кадры и накапливает phrase.audio. Первое окно обычно не меньше 0,5 с, для Russian — 1 с. Scheduler выбирает live раньше replay; текущий native вызов не прерывается. Повторные вызовы могут обрабатывать перекрывающиеся samples, поэтому сумма decoder больше одного batch вызова.
Очередь live/replay, snapshot и один decoder lock
━━ Вызов / передача┄┄ Событие / поток··· Владение / зависимость? Нет отдельной точки замера
VERIFIED / SOURCE · цифры: выбранный реальный прогон · время разных часов не вычитается09
10 / 26 · СХЕМА ВЗАИМОДЕЙСТВИЙ
Whisper Turbo: что входит в decoder
Модель получает float32 массив 16 кГц. transcribe возвращает ленивые segments, поэтому таймер охватывает и list(segments). Сборка текста и диагностических оценок следуют за вычислением. Фильтры avg_logprob, no_speech_prob и compression_ratio выключены; непустые слова не отбрасываются этими оценками.
━━ Вызов / передача┄┄ Событие / поток··· Владение / зависимость? Нет отдельной точки замера
VERIFIED / SOURCE · цифры: выбранный реальный прогон · время разных часов не вычитается10
11 / 26 · СХЕМА ВЗАИМОДЕЙСТВИЙ
Whisper Russian: тот же транспорт, иная первая порция
Russian идёт через тот же worker и те же PCM/RPC контракты. Для первого streaming вызова требуется 1 с контекста; speculative partial ограничен бюджетом токенов. Final и batch сохраняют обычные настройки декодирования. Это существующее поведение, в текущей задаче оно не изменено.
Первый partial ждёт больше акустического контекста
━━ Вызов / передача┄┄ Событие / поток··· Владение / зависимость? Нет отдельной точки замера
VERIFIED / SOURCE · цифры: выбранный реальный прогон · время разных часов не вычитается11
12 / 26 · СХЕМА ВЗАИМОДЕЙСТВИЙ
GigaAM: PCM превращается в tensor и RNNT-текст
GigaDecoder получает тот же float32 массив, проверяет форму и создаёт tensor на CUDA. Acoustic encoder и RNNT greedy decoder возвращают текст. Whisper-оценок у этого backend нет: отсутствие avg_logprob здесь объяснимо устройством модели и не означает нулевую уверенность.
Тот же worker, другой модельный адаптер
━━ Вызов / передача┄┄ Событие / поток··· Владение / зависимость? Нет отдельной точки замера
VERIFIED / SOURCE · цифры: выбранный реальный прогон · время разных часов не вычитается12
13 / 26 · СХЕМА ВЗАИМОДЕЙСТВИЙ
Batch сначала собирает готовую фразу
CompareBatch раз в 1 секунду аудио повторно проверяет весь накопленный буфер. ready_ranges выпускает все найденные фразы лишь после 500 мс тишины за последней; более ранняя фраза может ждать завершения следующей. В двухфразовом примере первая фраза ждала 10,81–10,82 с. collection включает это ожидание, а vad_ms — только вычисления: складывать их нельзя.
Время речи + тишина + период проверки + вычисление VAD
━━ Вызов / передача┄┄ Событие / поток··· Владение / зависимость? Нет отдельной точки замера
VERIFIED / SOURCE · цифры: выбранный реальный прогон · время разных часов не вычитается13
14 / 26 · СХЕМА ВЗАИМОДЕЙСТВИЙ
Worker batch: WAV переносится частями через RPC
Bridge оборачивает готовую фразу в WAV и передаёт begin, затем последовательные chunk, затем recognize. Base64 увеличивает размер частей примерно на треть. Worker проверяет размер, SHA и WAV, декодирует один раз и отвечает JSON. Отдельный cancel освобождает upload owner после ответа.
Base64 появляется здесь, не на входе браузера
━━ Вызов / передача┄┄ Событие / поток··· Владение / зависимость? Нет отдельной точки замера
VERIFIED / SOURCE · цифры: выбранный реальный прогон · время разных часов не вычитается14
15 / 26 · СХЕМА ВЗАИМОДЕЙСТВИЙ
WorkerSamples: ожидание и вычисление раздельно
Загруженный WAV ещё не означает начало распознавания. WorkerSamples ждёт освобождения live и inference_lock, проверяет и преобразует WAV, затем запускает decoder в thread. Чистое время берётся внутри этой thread; подготовка и RPC измеряются отдельно. Все интервалы сохраняют собственные границы.
Полная фраза → один native вызов
━━ Вызов / передача┄┄ Событие / поток··· Владение / зависимость? Нет отдельной точки замера
VERIFIED / SOURCE · цифры: выбранный реальный прогон · время разных часов не вычитается15
16 / 26 · СХЕМА ВЗАИМОДЕЙСТВИЙ
LinTO streaming: PCM идёт в WebSocket
После streaming VAD bridge открывает LinTOPhrase. Через CONNECT создаётся WebSocket /streaming: сначала JSON config, затем бинарный PCM16LE, в конце EOF. LinTO может многократно декодировать внутренние окна; его native total берётся из ответа. Первая передача в сокет не выдаётся за точное начало decoder.
━━ Вызов / передача┄┄ Событие / поток··· Владение / зависимость? Нет отдельной точки замера
VERIFIED / SOURCE · цифры: выбранный реальный прогон · время разных часов не вычитается16
17 / 26 · СХЕМА ВЗАИМОДЕЙСТВИЙ
LinTO batch: один WAV по HTTP
Для целой фразы используется отдельный HTTP endpoint LinTO. Bridge сначала получает существующий файловый lock, затем через CONNECT отправляет multipart WAV и ждёт JSON. HTTP interval включает upload, backend и ответ. Внутренняя подготовка LinTO не измерена отдельно и не заменяется разностью случайных часов.
FileJobLock → multipart → native → release
━━ Вызов / передача┄┄ Событие / поток··· Владение / зависимость? Нет отдельной точки замера
VERIFIED / SOURCE · цифры: выбранный реальный прогон · время разных часов не вычитается17
18 / 26 · СХЕМА ВЗАИМОДЕЙСТВИЙ
CONNECT — туннель байтов, отдельный от ASR RPC
aiohttp_socks открывает HTTP CONNECT к существующему requester. Внутри туннеля проходят WebSocket либо multipart HTTP к LinTO. NATS subjects соединяют requester и receiver через inference account. Исходники текущего dtorry/nats-proxy недоступны в исследованных checkout: внутренний frame layout и timing отдельных hops остаются неизвестными.
Публичный браузерный WSS и внутренний proxy не смешиваются
━━ Вызов / передача┄┄ Событие / поток··· Владение / зависимость? Нет отдельной точки замера
VERIFIED / SOURCE · цифры: выбранный реальный прогон · время разных часов не вычитается18
19 / 26 · СХЕМА ВЗАИМОДЕЙСТВИЙ
Как результат попадает на экран
Bridge отправляет события Core, который сохраняет ограниченный diagnostic buffer и добавляет replay_sequence. Ingress передаёт их только владельцу events.audio. Страница удаляет дубли и обновляет DOM не чаще 10Гц. После END одна сверка восстанавливает пропущенное; heartbeat не является механизмом накопления текста.
Push, один владелец и одна сверка после END
━━ Вызов / передача┄┄ Событие / поток··· Владение / зависимость? Нет отдельной точки замера
VERIFIED / SOURCE · цифры: выбранный реальный прогон · время разных часов не вычитается19
20 / 26 · СХЕМА ВЗАИМОДЕЙСТВИЙ
Конец речи, final и конец прогона — три момента
Стоп сначала досылает хвост worklet и flush. Ingress завершает resampler и добавляет служебную paced silence минимум 1 с, чтобы VAD успел закрыть фразу. Затем подтверждает idle, заканчивает transport и освобождает replay-слот. Это время не относится к native decoder; final часто приходит раньше release.
Почему после PCM остаётся примерно секунда и более
━━ Вызов / передача┄┄ Событие / поток··· Владение / зависимость? Нет отдельной точки замера
VERIFIED / SOURCE · цифры: выбранный реальный прогон · время разных часов не вычитается20
21 / 26 · СХЕМА ВЗАИМОДЕЙСТВИЙ
Замеры на одном исходном PCM
Числа ниже — экспорт реального браузерного прогона, а не оценка по длительности файла. Каждый метод получает тот же исходный PCM; сервер дополнительно сверяет 16 кГц hash. Native — сумма вызовов; RPC, сбор и общий результат имеют другие границы и не складываются как независимые этапы.
Выберите прогон: цифры на блоках и стрелках меняются
━━ Вызов / передача┄┄ Событие / поток··· Владение / зависимость? Нет отдельной точки замера
VERIFIED / SOURCE · цифры: выбранный реальный прогон · время разных часов не вычитается21
22 / 26 · СХЕМА ВЗАИМОДЕЙСТВИЙ
Как рассчитывается каждый интервал
performance.now используется только внутри браузера; time.monotonic — внутри соответствующего сервиса. Разность часов разных машин не применяется. Неполученный показатель остаётся неизвестным. Ошибка «вычесть decode из всего и назвать остаток сетью» исключена: в остатке есть ожидание речи, VAD, RPC и cleanup.
Локальные часы, аудиошкала и вложенные интервалы
━━ Вызов / передача┄┄ Событие / поток··· Владение / зависимость? Нет отдельной точки замера
VERIFIED / SOURCE · цифры: выбранный реальный прогон · время разных часов не вычитается22
23 / 26 · СХЕМА ВЗАИМОДЕЙСТВИЙ
Где ограничивается память и заканчивается владение
Compare хранит максимум 30 с звука и ограниченный журнал. Новая телеметрия хранит только 1600 пар координат и времени; PCM не копируется. Скрытие страницы отменяет прогон. Native вызов завершается своим путём; нельзя освободить слот и одновременно оставить за ним незавершённую модель.
Наблюдения не должны добавлять безграничную очередь
━━ Вызов / передача┄┄ Событие / поток··· Владение / зависимость? Нет отдельной точки замера
VERIFIED / SOURCE · цифры: выбранный реальный прогон · время разных часов не вычитается23
24 / 26 · СХЕМА ВЗАИМОДЕЙСТВИЙ
Куда идти в коде за конкретным этапом
Frontend владеет захватом, повтором и отрисовкой. Chat ingress владеет транспортом и resampler; Core — допуском и принадлежностью результата. ASR bridge выбирает VAD и путь модели. Worker владеет планированием и native decode; LinTO и proxy имеют собственные границы наблюдаемости.
Одна карта модулей вместо скрытых абстракций
━━ Вызов / передача┄┄ Событие / поток··· Владение / зависимость? Нет отдельной точки замера
VERIFIED / SOURCE · цифры: выбранный реальный прогон · время разных часов не вычитается24
25 / 26 · СХЕМА ВЗАИМОДЕЙСТВИЙ
От кнопки до побочного эффекта
Ветка A открывает захват или повторяет PCM, B всегда повторяет готовый sample. Развилка processing_mode происходит в bridge после общего ingress. У модели меняется способ подачи аудио, а не критерии принятия результата. Тестовая страница не записывает новое сообщение чата.
Выборочное дерево вызовов для A и B
━━ Вызов / передача┄┄ Событие / поток··· Владение / зависимость? Нет отдельной точки замера
VERIFIED / SOURCE · цифры: выбранный реальный прогон · время разных часов не вычитается25
26 / 26 · СХЕМА ВЗАИМОДЕЙСТВИЙ
Что подтверждено, а где граница замера
Все утверждения о маршрутах опираются на приведённые исходники; фактические цифры — на приложенные экспорты тестов. Отдельные сетевые hops и внутренняя подготовка LinTO не измерены, поэтому на схеме так и подписано. Прогон синтетического PCM проверяет полный транспорт, но не физический микрофон и не универсальный WER.
Source, CI, runtime и браузер — разные доказательства
━━ Вызов / передача┄┄ Событие / поток··· Владение / зависимость? Нет отдельной точки замера
VERIFIED / SOURCE · цифры: выбранный реальный прогон · время разных часов не вычитается26
← → / PgUp PgDn · Home End · перетаскивание фона · +/− для масштаба
Автономный HTML: данные, графы и JavaScript встроены. Презентация ничего не отправляет и не запускает диагностику. Ссылки на исходники открываются только по нажатию. UNKNOWN не заменяется предположением или нулём.