Голосовые системы

Ускорение сборки и поставки Monitor / ASR / LinTO

Результат на 27 октября 2026: изменения опубликованы в main трёх проектов. Выполнены полная регрессия механизма отбора, адресная сборка Front и bridge, три повторные кодовые сборки worker/LinTO и проверки существующего runtime. Новые application images в этих замерах не публиковались. Подготовка и выпуск уже работающего ASR digest прошли без pull, прогрева, update и закрытия admission.

Основная исходная потеря времени была в подготовке/поставке: build LinTO 24095 занял 389,321 с, а deployment 24099 отменили через 2617,397 с. Два незавершённых ASR pull и этот deploy суммарно заняли 6239,423 с runner — около 104 минут. Конкретный зависший Docker-вызов в старом логе не установлен. Быстрые ASR-тесты сохранены: 149 тестов занимают около 5,75 с.

Поставленные исходники

Проект Исходный SHA Итоговый SHA Строки + / − Файлы
Front / Monitor 553bc572 b40e84d7 +706 / −111 29
ASR / LinTO b4570f47 05a393a2 +549 / −67 17
rag-stack: ASR release 9ca0c303 88cc3ea7 +298 / −28 9

Итого +1553 / −206 строк, включая проверки и документацию, 55 файлов. Новых сервисов, таблиц, runtime-хранилищ и соединений — 0. Добавлены локальные механизмы выбора работ, ограниченного выполнения Docker CLI и их тесты. Полные diff находятся в evidence/changes-*.patch, SHA и статистика — в source-state.json.

Работа выполнена одним writer в изолированных checkout. Пользовательские изменения основной копии сохранены. Dockerfile.build, корпоративные версии build-labels/dry-stack, DRS и known_hosts не изменены. Runner, registry, daemon, DNS, SSH, сети, GPU, тома, PostgreSQL и NATS не перенастраивались.

Что изменилось

  1. Отбор по входам. Статическая матрица учитывает общий код, Docker COPY, push/MR/явную базу, удаление и переименование файлов. Неизвестная база или путь включает полный соответствующий набор. CI_FULL_CHECKS=1 включает все checks. Пропуск выводится как skipped, до установки зависимостей и запуска suite. Общие streaming/Vitest suites сохранены целиком.
  2. Сборки. Совместимый worker/LinTO автоматически использует закреплённый code-only runtime. Изменение зависимостей, моделей или рецепта базы переключает на полную сборку. Повторные LinTO releases принимают совместимые собственные overlays; одноразовый переход с vendor image остаётся отдельным случаем. Bridge копирует только используемый код, поэтому изменение worker не пересобирает bridge.
  3. Front. Production bundle собирается один раз в Docker. CI выполняет TypeScript, Vitest и runtime-settings; nginx проверяется в образе. Убрана обязательная сборка приложения в том же pipeline перед refresh. Проверки release-helper выполняются один раз в check job на основе фактически упакованного deployment image.
  4. Повторное использование. Release SHA и source SHA образа разделены. Можно передать проверенный digest; активация проверяет его наличие и SHA без повторного pull/разрешения latest. Здоровый текущий digest возвращает already_current.
  5. Поставка. Docker reads ограничены 90 с, code-image pull — 300 с, full GPU pull — 1800 с. Сохранены пределы прогрева/rollout, вложенные команды используют остаток бюджета. Длительные операции показывают этап, время и прогресс; буферы ограничены. После timeout проверяется фактическое состояние, автоматического повторного deploy нет. Конфигурация соседа и независимый restart его task проверяются раздельно.
  6. Обычный release. Front preflight больше не запрашивает погоду, stats и RootFS всех сервисов. Проверяются необходимые зависимости. Добавлены операции по компонентам; исторические migration/repair/retirement доступны через CI_MAINTENANCE=1.
  7. Кэш и contexts. npm/pip/tokenizer используют проектные пути GitLab cache с ключами зависимостей/среды/архитектуры. Хеши tokenizer проверяются при каждом использовании. Результаты тестов не кэшируются. Docker contexts исключают локальные зависимости, build outputs, временные файлы и .repowise, сохраняя необходимые Git-метаданные.

Приёмка

Критерий Результат и доказательство
Front-only / worker-only / docs-only / helper-only PASS: обе матрицы и Git rename fixture; реальный docs-only build 24518 вывел services: {}. Application builds — 0. Helper-only выбирает только соответствующие release checks, приложение не собирается.
Shared contract, неизвестный путь/база, полный ручной режим PASS: matrix checks в 24387 и 24437.
Два последовательных кодовых выпуска LinTO PASS в release-contract tests для HTTP и WebSocket: 13 тестов / 37 assertions, 24439. Два настоящих обновления модели ради теста не выполнялись.
Изменение зависимостей запрещает code-only PASS: настоящие Git fixtures с изменёнными requirements worker/LinTO; evidence/base-compatibility.log. Полный GPU image ради этого условия не собирался.
Один production bundle Front PASS: 24405, один RUN npm run build; в frontend checks Vite build отсутствует. nginx layer успешно переиспользован из кэша.
Реальная сборка bridge PASS: 24475, pip check, импорт StreamingBridge и вычисление локального VAD окна.
Подготовленный / уже работающий digest PASS: 24489 подготовил существующий digest без pull; 24490 вернул already_current, без pull/candidate/update.
Timeout, потеря подготовленного образа, mutable tag, restart соседа PASS: bounded-process tests, Front release tests, LinTO tests и 22 ASR release tests / 68 assertions. Проверены остановка клиента, ограничение вывода, отказ до изменения target и отсутствие повторного update.
Полная Front регрессия PASS: все пять checks pipeline 5437. Python: 248 passed, 13 subtests, 103 skipped; они не выдаются за выполненные. Отдельно реально выполнены 84 integration tests с PostgreSQL/NATS и 4 browser/NATS tests; Vitest — 444 теста.
ASR и release checks PASS: streaming — 149 тестов; bridge/status — 7/6; LinTO — 13. После исправления COPY выполнена только выбранная streaming-группа в 5440, release suites явно пропущены. rag-stack checks и реальный already_current — 5441.

Итоговый Front commit содержит только результаты замеров поверх проверенного кода ed1553be. Его pipeline 5442 проверил docs-only: все пять application suites пропущены, выполнена проверка исходников/документации. Статус pipeline manual означает оставшиеся ручные jobs; это не утверждение, что каждый deployment job выполнен.

Измерения «было → стало»

Время ниже — длительность jobs без очереди. Это отдельные наблюдения на существующем runner, не нормативы и не контролируемое сравнение одинакового состояния кэша.

Работа Было, с Стало, с Разница, с Разница, %
Все пять Front checks 380,182 315,774 −64,408 −16,94%
Python checks 109,385 95,957 −13,428 −12,28%
Browser NATS checks 20,273 20,563 +0,290 +1,43%
Frontend checks 46,140 51,777 +5,637 +12,22%
Ruby checks 12,199 15,241 +3,042 +24,94%
Integration checks 192,185 132,236 −59,949 −31,19%
Front preflight 90,245 19,026 −71,219 −78,92%
ASR prepare: ранее с pull → существующий digest 14,917 10,470 −4,447 −29,81%

Первая строка сопоставляет jobs 24120–24124 и 24384–24388. Preflight — 24147 → 24409. Более быстрые общие результаты не означают, что ускорился каждый suite: таблица показывает и выросшие времена.

Docs-only больше не исполняет application suites. Пять коротких guard jobs суммарно заняли 57,231 с: по сравнению с прежними пятью полными checks 380,182 с это −322,951 с (−84,95%). Это намеренное сокращение выполняемой работы, а не ускорение тех же тестов. Сохранились затраты на запуск jobs, checkout, cache lookup и старт integration services. Сам build-wrapper в docs-only job занял 12,417 с целиком; образ приложения не собирался.

Три повторные кодовые сборки

Режим: одинаковый source 7f68a453, CI_FORCE_BUILD=1, CI_SKIP_PUSH=1, прогретые слои. Сборка запускалась корпоративным build-labels → Bake. В каждом логе подтверждён автоматический code-only выбор.

Компонент Job / выполнение / очередь, с Медиана job, с Медиана участка Buildx, с
Worker 24442: 12,762 / 47,995; 24465: 11,279 / 1,318; 24467: 9,633 / 1,517 11,279 0,422
LinTO 24444: 13,089 / 59,686; 24466: 9,554 / 43,291; 24468: 9,727 / 1,683 9,727 0,500

Ранее опубликованные code-only jobs: worker 24200 — 17,322 с, LinTO 24291 — 14,666 с. Численная разница с нынешними медианами составляет −6,043 с (−34,89%) и −4,939 с (−33,68%), но её нельзя целиком приписывать оптимизации: старые jobs включали push, новые — нет; состояния кэша различаются. Полные worker 519,535 с и LinTO 389,321 с относятся к ещё более ранним сборкам. Сам code-only подход уже существовал до этой задачи; здесь он стал автоматическим и пригодным для последовательных выпусков.

Разделение этапов

Этап Наблюдение
Очередь Записана отдельно для каждого job в jobs.csv. У первого Front check: 2104,301 → 5,836 с. Это состояние очереди; эффектом кода не считается. Очереди нескольких jobs перекрываются и не суммируются.
Подготовка зависимостей В текущем полном прогоне pip Python — 66,648 с, pip integration — 56,553 с, npm ci — 7,386 с; интервалы до следующей команды из timestamped trace. Старый integration pip был около 45 с: улучшения на этом этапе не показано.
Tokenizer Integration step — 1,540 с против прежних примерно 91 с; разница около −89,460 с / −98,31%. При этом cache restore сообщил miss, поэтому результат не является доказательством действия GitLab cache. Проверка SHA-256 сохранена.
Только тесты ASR 149 — 5,750 с; Vitest 444 — 21,030 с; browser/NATS 4 — 9,507 с; integration 84 — суммарно 37,848 с внутри test runners.
Build Front job 40,764 с, из них npm run build в Docker — 16,0 с; bridge job 31,140 с, импорт/VAD — 3,8 с. Повторные worker/LinTO показаны выше.
Push В новых измерениях отключён. Текущая пропускная способность registry не измерялась.
Pull В реальных prepare 24489 и activation 24490 — 0 вызовов / 0 с. В прежнем prepare 24215 — 5,318 с; прежняя activation 24216 повторяла pull ещё на 1,737 с. Отсутствие pull также проверено на ветке активации нового подготовленного образа в контрактных тестах.
Прогрев В текущем already_current — 0 запусков / 0 с. Исторический candidate 24216 — 16,299 с. Новый cold/warm GPU rollout не измерялся перезапуском неизменённого приложения.
Rollout В текущем already_current — 0 update / 0 с. Job с проверкой текущего состояния целиком — 10,324 с. Исторический настоящий deploy 24216 — 56,309 с; это другой объём работы.
Закрытый admission В этой поставке CI/helper — 0 с: запрос drain не выполнялся. Время остановки при следующем настоящем изменении модели должно измеряться отдельно; исторический интервал по имеющимся логам надёжно не восстановлен.

Ограничения и найденные ошибки

  • GitLab package cache: конфигурация сохранения/восстановления добавлена, записи cache создаются, но последующие jobs на текущем runner снова сообщают Cache file does not exist. Поэтому ускорение за счёт этого кэша не подтверждено. Инфраструктурная причина не исправлялась; Docker layer cache в повторных сборках действительно работает.
  • Artifacts: первый ASR preflight 24457 успешно подготовил digest, затем упал при загрузке dotenv: lookup gitlab ... server misbehaving. Итоговая схема не зависит от загрузки artifacts: точные SHA/digest передаются существующими переменными job/pipeline и проверяются до активации. Исправленная подготовка 24489 и activation 24490 прошли. DNS не менялся.
  • Исправлены выявленные регрессии: старый тест требовал обязательный app build перед refresh; runtime-settings тест ожидал production dist; bridge COPY ошибочно обращался к каталогу diarization, хотя это diarization.py. Полные логи неуспехов сохранены, итоговые проверки перечислены выше.
  • Тайм-аутные сценарии и два последовательных LinTO update проверены контрактными тестами. Принудительные сбои живого Docker daemon и два ненужных перезапуска модели не выполнялись.

Фактический runtime и использование

В 24459 и 24490 подтверждены ASR source 3f00eeaa1bb1fe86092919d53ab8883bd23e24f5, готовность трёх моделей и digest:

builder-registry.builder.giscloud.ru/gis/webrtc-komaroff/voice-chat/webrtc_streaming_asr/main@sha256:85f73b8793889dc45e894e517918e6670c03a6e596f619fc312c767c82a7ffe5

Это source приложения; release-helper использует новый rag-stack SHA 88cc3ea7. HTTP LinTO preflight 24447 подтвердил Python 3.12.15, CTranslate2 4.8.2 и faster-whisper 1.2.1+linto. Новые Front/bridge/worker/LinTO application versions этим изменением не разворачивались. Runtime-версии остальных сервисов не переаттестовывались.

Обычный поток работы:

  1. Выбрать компонент и достоверную Git-базу. Для web/API — CI_SCOPE_BASE_SHA; при повторном использовании образа — его CI_REUSE_IMAGE_SOURCE_SHA.
  2. Проверить selected/skipped в логах. Собирать только изменённые входы; CI_FORCE_BUILD=1 оставлен для явного benchmark/recovery.
  3. Передать проверенный digest: Front — CI_APPLICATION_IMAGES; ASR — CI_WEBRTC_ASR_SOURCE_SHA и CI_WEBRTC_ASR_IMAGE_DIGEST; LinTO/bridge — соответствующая переменная digest из документации проекта.
  4. Подготовить и проверить образ до drain. При смене ASR использовать существующие отдельные Front drain/resume; новых межпроектных доступов и оркестратора нет.
  5. Активировать подготовленный digest, проверить target, открыть admission. При timeout сначала сверить фактическое состояние; автоматического повторного deploy нет.

В каталоге отчёта: measurements.json — расчёты, jobs.csv — jobs/queue/SHA, measure.py — воспроизводимый расчёт, source-state.json — объём изменений, evidence/ — редактированные от credentials полные логи и diff.

Исходник

Скачать Markdown · К материалам исследования