docs(observatory): record realtime plan and measured latency evidence
This commit is contained in:
@@ -0,0 +1,273 @@
|
||||
# Observatory: четыре этапа создания полного real-time Perception-профиля
|
||||
|
||||
Дата: 2026-09-01; обновлено 2026-09-02 00:41 МСК. Текущая цель — переносимые полные профили и снижение задержек всей цепочки; допустимый лабораторный overload не блокирует разработку и не выдаётся за real-time PASS. В двух новых source-paced пилотах с перекрытием CPU и последовательного GPU этапа получены 128/128 результатов без drops; source→local receiver p95 143.32/153.44 ms, p99 198.22/194.25 ms. Среднее ожидание очереди 7.20/8.31 ms против 13.65/25.48 ms в serial-контролях. Это перспективный экспериментальный scheduler, не квалификация и не замена рабочего runtime. Этап 1 частично выполнен; этапы 2–4 не начаты. Static-obstacle слой и coarse `hard_surface` остаются достаточными для сельского прототипа; профиль не сводится к одной модели.
|
||||
|
||||
Текущий evidence: [отчёт этапа 1](../experiments/perception/PERCEPTION_STREAM_STAGE1_2026-09-01.md), [ADR 0049](adr/0049-stream-first-perception-profiles.md), [candidate manifest](../config/perception/k1-perception-ddrnet39-rfdetr-tgs-prototype-v1.json). Запрет full-source preload закреплён в новом контракте; старый batch materializer пока не удалён и продуктовый путь не переключён.
|
||||
|
||||
## Цель и граница завершения
|
||||
|
||||
Собрать отдельный самостоятельный Docker-профиль полного восприятия рига: DDRNet-39 GOOSE + RF-DETR native + LiDAR-ассоциация/метрические расстояния + TGS/costmap + temporal/motion + диагностическая оценка препятствий и mission-policy. Совместимый источник поступает потоком на выделенный Worker; все выходы рассчитываются в этом запуске, без подмешивания ранее рассчитанных масок, детекций, local-surface или threat-ledgers. Запись подаёт наблюдения по исходному времени с темпом 1× и заменяет физический источник, но не меняет вычислительный граф.
|
||||
|
||||
Сценарий владельца: записывать множество маршрутов K1 с камерой, точками и pose; в Observatory последовательно применять разные профили и сравнивать результаты; затем выбрать проверенную версию того же профиля в будущей live-миссии с зарегистрированным оборудованием. Конкретная запись — вход запуска, а не зашитый компонент Docker. Размер коллекции (в том числе 500 записей) не требует 500 приложений или 500 исполняемых адаптеров. Во время будущего движения профиль обрабатывает новые живые наблюдения, а не воспроизводит старые решения для маршрута.
|
||||
|
||||
Первый результат — один полный, измеренный на RTX 4090 прототип с общим runtime и потоковыми результатами, пригодный для последующей проверки на полигоне. Управление моторами, автопилот, построение маршрута и реализация всего конфигуратора миссии в этот прототип не входят. EoMT-L Cityscapes сохраняется как отдельный резервный вариант; его упаковка/оптимизация не блокирует первый профиль и не запускается рядом с DDRNet. Сборка Docker и совпадение digest не являются доказательствами real-time; успешный replay не является допуском к автономному движению.
|
||||
|
||||
Приёмка первого прототипа требует: самостоятельного образа; реального расчёта всех заявленных слоёв; одного live-compatible контракта для replay и будущего физического источника; воспроизведения нескольких совместимых записей без правки кода; bounded latency/queues/memory; явных unknown/degraded состояний; сохранённого отчёта производительности и обнаруженных ошибок. Отсутствующий сейчас беспилотник не блокирует приёмку replay-прототипа, но physical-live, качество в поле и actuation остаются явно непроверенными.
|
||||
|
||||
## Авторитетный контекст и подтверждённое CURRENT
|
||||
|
||||
Рабочий репозиторий: `/Users/dcconstructions/Downloads/mnt/NODEDC/NODEDC_MISSION_CORE_m5_observatory`. На момент обзора: ветка `codex/m5-1-observatory`, HEAD `7025e173a3370a1b70afaad8579db20903436157`, множество существующих tracked/untracked изменений. Выводы относятся к прочитанному рабочему дереву, не только к HEAD. Чужие изменения сохраняются.
|
||||
|
||||
Источники и их назначение:
|
||||
|
||||
- [Последний отчёт](/Users/dcconstructions/Desktop/MISSING_CORE_OBSERVATORY_DOCKER_LABS_FINAL_STATUS_2026-09-01.md) — история предыдущих запусков и актуализированная цель полного профиля. Исторические измерения не являются новой проверкой текущего состояния Worker.
|
||||
- [Предыдущая архитектурная итерация](/Users/dcconstructions/Desktop/MISSING_CORE_OBSERVATORY_DOCKER_LABS_ARCHITECTURE_2026-09-01.md) — история и идеи, не распоряжения к выполнению и не актуальное подтверждение готовности.
|
||||
- [Правила репозитория](/Users/dcconstructions/Downloads/mnt/NODEDC/NODEDC_MISSION_CORE_m5_observatory/AGENTS.md), [существующие gates проекта](/Users/dcconstructions/Downloads/mnt/NODEDC/NODEDC_MISSION_CORE_m5_observatory/docs/01_IMPLEMENTATION_PLAN.md) — действующие ограничения. Этот план не открывает навигационные, actuator- или quality/truth-gates проекта.
|
||||
- `/Users/dcconstructions/Desktop/CODEX_V5` — прочитаны все пять документов. Применены разделение CURRENT/TARGET, приоритет цели и доказательств над процедурами, этапы с проверяемым выходом и один поддерживаемый ExecPlan. Шаблоны не копируются поверх правил проекта.
|
||||
- Последние уточнения владельца от 2026-09-01 имеют приоритет: один активный полный профиль, внутри него детектор + выбранная сегментация + LiDAR/TGS; EoMT и DDRNet остаются альтернативами. Не переносить старое ошибочное ограничение «одна модель/AI-процесс» на состав полного профиля.
|
||||
|
||||
Проверенная по локальному коду карта:
|
||||
|
||||
| Участок | CURRENT | Следствие для TARGET |
|
||||
| --- | --- | --- |
|
||||
| Portable definition / preflight | Есть идентичность source/model/executor и проверка совместимости, но нет полного timing-контракта и измеренного real-time допуска; `ready` в основном структурный | Сохранить идентичность и admission, добавить отдельную квалификацию конкретного профиля на конкретном runtime/hardware |
|
||||
| Передача источника / runtime | Полная материализация → выполнение → финальная публикация | Инкрементальный data plane с ограниченными буферами, без обязательной подготовки всей записи |
|
||||
| Installed LAB package | Одноразовые контейнеры: prepare → весь EoMT → весь DDRNet → assemble | Сначала один постоянный полный DDRNet/RF-DETR/LiDAR/TGS runtime; EoMT — отдельный будущий вариант, без зависимости DDRNet от его результата |
|
||||
| Модельные адаптеры | Все кадры, PNG/маски/overlay и итоговые архивы на критическом пути | Обработка поступающих наблюдений и выдача результата до окончания источника; архивирование не задаёт темп inference |
|
||||
| Backend / Worker | В claim есть глобальный запрет второго активного job; Worker 006 зашит в части контракта | Эксклюзивность и fencing на уровне `worker_id`; не глобальный запрет работы независимых Worker |
|
||||
| Frontend | Выбор setup и terminal job/result; нет достаточного контракта потокового состояния | Общие состояния и renderer capabilities, без отдельного микроприложения для каждой модели |
|
||||
| Ранее существовавшие эксперименты | Есть pacing 1×, bounded queues, freshness/age и multirate измерения | Переиспользовать проверенные механизмы, но не совмещать EoMT с DDRNet или разные профили; RF-DETR и DDRNet входят в один полный профиль. Чужие бюджеты автоматически не копируются |
|
||||
|
||||
Опорные файлы для продолжения:
|
||||
|
||||
- [Portable contracts](/Users/dcconstructions/Downloads/mnt/NODEDC/NODEDC_MISSION_CORE_m5_observatory/src/k1link/observatory/portable_run_definitions.py), [runtime](/Users/dcconstructions/Downloads/mnt/NODEDC/NODEDC_MISSION_CORE_m5_observatory/src/k1link/observatory/portable_worker_runtime.py), [source transport](/Users/dcconstructions/Downloads/mnt/NODEDC/NODEDC_MISSION_CORE_m5_observatory/src/k1link/observatory/worker_http_transport.py).
|
||||
- [Queue / ownership](/Users/dcconstructions/Downloads/mnt/NODEDC/NODEDC_MISSION_CORE_m5_observatory/src/k1link/observatory/recorded_jobs.py), [Worker agent](/Users/dcconstructions/Downloads/mnt/NODEDC/NODEDC_MISSION_CORE_m5_observatory/src/k1link/observatory/worker_agent.py), [preflight API](/Users/dcconstructions/Downloads/mnt/NODEDC/NODEDC_MISSION_CORE_m5_observatory/src/k1link/web/observatory_api.py).
|
||||
- [Installed runner](/Users/dcconstructions/Downloads/mnt/NODEDC/NODEDC_MISSION_CORE_m5_observatory/src/k1link/observatory/installed_lab_package_runner.py), [combined package builder](/Users/dcconstructions/Downloads/mnt/NODEDC/NODEDC_MISSION_CORE_m5_observatory/experiments/perception/worker/observatory_portable/promote_installed_lab_v1_package.py).
|
||||
- [EoMT adapter](/Users/dcconstructions/Downloads/mnt/NODEDC/NODEDC_MISSION_CORE_m5_observatory/experiments/perception/worker/observatory_portable/run_portable_lab_v1_eomt_component.py), [DDRNet adapter](/Users/dcconstructions/Downloads/mnt/NODEDC/NODEDC_MISSION_CORE_m5_observatory/experiments/perception/worker/observatory_portable/run_portable_lab_v1_ddrnet_component.py).
|
||||
- [Observation graph](/Users/dcconstructions/Downloads/mnt/NODEDC/NODEDC_MISSION_CORE_m5_observatory/src/k1link/perception/graph.py), [recorded source](/Users/dcconstructions/Downloads/mnt/NODEDC/NODEDC_MISSION_CORE_m5_observatory/src/k1link/perception/recorded_source.py), [E9 runner](/Users/dcconstructions/Downloads/mnt/NODEDC/NODEDC_MISSION_CORE_m5_observatory/experiments/perception/worker/run_e9_multirate_perception.py), [E21 envelope](/Users/dcconstructions/Downloads/mnt/NODEDC/NODEDC_MISSION_CORE_m5_observatory/experiments/perception/e21_realtime_envelope_profile.json).
|
||||
- [Equipment/capture compatibility](/Users/dcconstructions/Downloads/mnt/NODEDC/NODEDC_MISSION_CORE_m5_observatory/src/k1link/sessions/equipment.py), [Observatory workspace](/Users/dcconstructions/Downloads/mnt/NODEDC/NODEDC_MISSION_CORE_m5_observatory/apps/control-station/src/workspaces/observatory/ObservatoryWorkspace.tsx).
|
||||
|
||||
Из последнего отчёта: источник `20260828T130511Z_viewer_live` содержит 6830 кадров за 808.779495667 s, средняя частота ≈8.4448 FPS. Остановленный запуск после примерно 32 min 54 s ещё не дошёл до DDRNet/публикации. Это свидетельство непригодности прежнего полного пути для поставленной задачи, но не изолированный benchmark самой модели.
|
||||
|
||||
Последующий read-only аудит 2026-09-01 проверил Docker inventory, mounts и фактические installed manifests на Worker 006 через strict-pinned `mission-gpu`. Portable M4.9 содержит TGS и `models: []`; LAB V1 выполняет `prepare → EoMT → DDRNet → assemble`, без detector/geometry/threat stages. Legacy perception Worker и Triton существуют отдельно, со значимыми host mounts; это не самостоятельный полный portable-профиль. Никакие контейнеры при аудите не запускались и не останавливались.
|
||||
|
||||
Скриншот M4.9T5 показывает композицию результатов: собственный CPU TGS, отдельный M4 detector/geometry/threat и заранее рассчитанный E47/EoMT. Отдельный [RF-DETR reference runtime](/Users/dcconstructions/Downloads/mnt/NODEDC/NODEDC_MISSION_CORE_m5_observatory/src/k1link/perception/m48s_reference_graph_runtime.py:209) реально собирает geometry, temporal, motion, rolling и threat. Сохранённый [M49 integrated result](/Users/dcconstructions/Downloads/mnt/NODEDC/NODEDC_MISSION_CORE_m5_observatory/.runtime/m49-integrated-12fps-003/result.json:72) сообщает 4489/4489 кадров, 11.860865 FPS и p95 совместной готовности 46.825886 ms. Это historical RF-DETR + CPU TGS shadow на подготовленных входах, не полный новый профиль: TGS не меняет graph state, EoMT там не вычисляется, `local-surface.npz` подготовлен заранее.
|
||||
|
||||
Ближайший сохранённый [multirate candidate](/Users/dcconstructions/Downloads/mnt/NODEDC/NODEDC_MISSION_CORE_m5_observatory/config/perception/lab-v1-vegetation-integrated-multirate-phased-shadow-v3.json:12) добавляет DDRNet 6 Hz к RF-DETR/TGS timeline 12 Hz с phase offset 40 ms, но `semantic_output_persisted=false`: это исходная точка исследования нагрузки, а не доказанная сквозная реализация нового продукта.
|
||||
|
||||
Во время read-only проверки на Worker также работали `sentinel-frigate` и `sentinel-ollama` с GPU DeviceRequests; общая занятая VRAM составляла 9256 MiB. Это не доказывает их одновременный inference, но чистое GPU-окно не установлено. Перед измерением требуется согласованное освобождение ресурса; этот план не разрешает самостоятельно останавливать сервисы другого продукта.
|
||||
|
||||
## Жёсткие границы и принятый TARGET
|
||||
|
||||
Уточнение владельца 2026-09-02 (МСК): проект — экспериментальная платформа
|
||||
переносимых профилей, применяемых к разным совместимым записям. Текущий приоритет —
|
||||
снижение задержек всей цепочки, прозрачное измерение и оптимизация runtime,
|
||||
IPC/сети, копирований и оркестрации. Вычислительно тяжёлый профиль не удаляется
|
||||
из-за FAIL на 4090: результат сохраняется вместе с hardware/transport-specific
|
||||
квалификацией. Возможен перенос на более мощный Worker или бортовой компьютер.
|
||||
Локальное размещение устраняет внешний сетевой участок, но не само по себе
|
||||
декодирование, внутренний IPC, очереди и вычисления.
|
||||
|
||||
Лабораторный эксперимент с ограниченной перегрузкой допустим и не блокирует
|
||||
разработку упаковки/общего runtime. Разделяем **функциональную готовность**,
|
||||
**готовность к лабораторным сравнениям** и **real-time qualification на конкретной
|
||||
связке profile/config/hardware/source/transport**. Бюджеты 125 ms и остальные
|
||||
исходные критерии остаются измерительными ориентирами, а FAIL не превращается
|
||||
в PASS. По-прежнему обязательны bounded memory/queues, учёт drops/unknown,
|
||||
исходный clock 1×, отсутствие подмены старых данных новыми и отсутствие actuation.
|
||||
|
||||
- Текущий аппаратный baseline — один Worker 006 с RTX 4090, один активный полный профиль одного источника. RF-DETR и DDRNet являются компонентами этого профиля и могут быть прогреты одновременно; GPU-работа в первом прототипе подчинена одному сериализованному scheduler. CPU-геометрия/TGS и транспорт имеют свои ограниченные очереди, не создавая второй конкурирующий AI-профиль. Нет EoMT+DDRNet вместе, фоновых моделей, обучения или параллельных benchmark. Неактивный профиль не удерживает GPU. Новый профиль не стартует до подтверждённого освобождения предыдущего.
|
||||
- Один беспилотник обслуживается одним независимым Worker. Масштабирование на десять устройств означает десять Worker, а не десять потоков на 4090. Сейчас не строится полноценная система управления флотом; контракты и тесты не должны закрепить глобальный singleton.
|
||||
- Профиль — полный вычислительный граф и его входные/выходные требования, а не одна модель. DDRNet и EoMT — альтернативные сегментационные ветви разных профилей. Общий runtime/SDK и инфраструктурный агент допустимы; профильные backend/frontend приложения — нет. На первом этапе нужен один новый полный Docker-профиль, не обязательная разработка сразу двадцати вариантов.
|
||||
- Переносимы образ/контракт/конфигурация, а не произвольный hardware performance claim. RTX 5090 и Apple Silicon не являются условиями успеха. Для иной GPU/платформы нужна отдельная проверка; CUDA-образ не объявляется автоматически совместимым с Metal.
|
||||
- Запись и live различаются адаптером входа, не реализацией inference. Реальная совместимость определяется объявленными каналами, форматами, временем, калибровкой и capture-параметрами, не названием LAB или единственным session ID.
|
||||
- Работа остаётся в локальном контуре Mission Core + Worker 006; нет Synology/external-server rollout и deploy-canon workflow. План не является командой на запуск Worker или изменение оборудования. На Mac нет модельной нагрузки, тяжёлых параллельных работ и новых временных серверов; канонический сервис 8000 сохраняется.
|
||||
- Существующие записи, raw evidence, секреты, результаты и рабочие изменения сохраняются. Нет управления движением, изменения scanner-протокола или самостоятельного запуска физического сканирования. Старые доказательства не переименовываются в новые успешные испытания.
|
||||
|
||||
Предлагаемая схема имён, согласованная с обязательным namespace `ndc-`:
|
||||
|
||||
| Название профиля в приложении | Docker image | Экземпляр на Worker 006 |
|
||||
| --- | --- | --- |
|
||||
| K1 Perception — DDRNet-39 + RF-DETR + TGS | `ndc-k1-perception-ddrnet39-rfdetr-tgs:prototype-v1` | `ndc-k1-perception-ddrnet39-rfdetr-tgs-worker006` |
|
||||
| K1 Perception — EoMT-L + RF-DETR + TGS, резервный TARGET | `ndc-k1-perception-eomt-rfdetr-tgs:<version>` | `ndc-k1-perception-eomt-rfdetr-tgs-worker006` |
|
||||
|
||||
Машинный profile ID стабилен и связан с display name; runtime выбирается по sealed manifest/image digest, не только по изменяемому tag. Существенное изменение весов, preprocessing, output labels, precision или execution policy меняет версию профиля и требует нового свидетельства. `K1` в названии описывает capture-совместимость, но не должен зашивать K1 в общий runtime.
|
||||
|
||||
Первый прототип поставляется одним самостоятельным образом и запускается одним контейнером: runtime, обе модели, TGS, preprocessing/postprocessing, конфигурация и manifest находятся внутри образа. Нет зависимости от чужого Triton, checkout, скрытого host-cache, готовой LAB или скачивания моделей на первом запуске. Внутренние supervised процессы/изолированные Python environments допустимы, если решают одну задачу восприятия и управляются общим lifecycle; broker, БД и приложение в этот образ не добавляются. Снаружи только Docker/NVIDIA runtime, входной поток/запись, выходы и явно переданные секреты. Shared base layers допустимы для будущих профильных образов. Сохраняются ownership labels `com.nodedc.product`, `com.nodedc.stack`, `com.nodedc.role`, `com.nodedc.managed-by`. Текущие контейнеры не переименовываются этим планом.
|
||||
|
||||
## Контракт первого полного профиля
|
||||
|
||||
| Слой | Обязательный выход | Граница интерпретации |
|
||||
| --- | --- | --- |
|
||||
| DDRNet-39 GOOSE | Semantic mask, существующее coarse material mapping, freshness и исходные class IDs для evidence | В первом сельском прототипе `hard_surface` допустим без разделения асфальта/тротуара/велодорожки; геометрическое препятствие всё равно блокирует |
|
||||
| RF-DETR native | Объекты, class, confidence, bbox и source frame identity | Person/cat/dog и существующие классы; точное название статического препятствия не требуется, дополнительный bollard-классификатор не нужен |
|
||||
| LiDAR + calibration + pose | 3D support, расстояние с определённым estimator/frame, неизвестные геометрические препятствия и связь с детекциями | Нет подходящих точек/калибровки/синхронизации — range unavailable, а не придуманное расстояние или free |
|
||||
| Temporal / motion | Track identity, оценка движения, current/held/stale/unknown | Тип объекта не доказывает движение: стоящая машина и движущийся человек требуют измерения во времени |
|
||||
| TGS + rolling geometry | Ground support, occupied, rejected, unobserved; локальная costmap и свежесть каждой ячейки | Ground support не равен traversable; map может запретить, но сама не выполняет объезд |
|
||||
| Fusion / policy shadow | Общая scene, согласованные слои, объяснимый allowed-candidate/high-cost/blocked/unknown и advisory events | Не direct motor/control commands; unknown/stale не создают разрешение двигаться |
|
||||
|
||||
Входы: camera frames/encoded chunks, registered point increments, pose, intrinsics/extrinsics, coordinate frames и timestamps с clock mapping. Нужно различать sensor→camera калибровку и будущую sensor→vehicle/body калибровку. Для прототипа виртуальный footprint допускается только с явной отметкой simulation; реальный зазор до корпуса не заявляется до измеренного mount/vehicle profile.
|
||||
|
||||
Решение владельца для первого сельского прототипа: используем существующий coarse `hard_surface` (`asphalt`, `sidewalk`, `bikeway`, `cobble`) как допустимый материал. Разделение дорог, тротуаров и велодорожек, городские правила движения, дополнительная сегментационная модель и обязательный новый road-only классификатор не нужны и не блокируют реализацию. Сохранять исходные class IDs полезно для evidence, но создавать отдельную fine-grained policy сейчас не требуется. Остальные материалы определяются явным выбранным preset/config; слово «сельский» само по себе не разрешает все грунты/растительность. Camera semantics никогда не снимает occupied/unknown запрет геометрии.
|
||||
|
||||
Для столбиков и других неподвижных препятствий переиспользуется существующее представление `static_obstacle` / `static.unknown`, уже присутствующее в vocabulary и визуальном слое; точное имя предмета не требуется. Пользователь ссылается на сохранённый RAV004 как имеющий это поведение. Задача нового профиля — воспроизвести этот слой из текущего потока и проверить его, а не изобрести ещё одну taxonomy, обучить распознаватель столбиков или загрузить старые masks вместо вычисления. Геометрическое препятствие сохраняется независимо от того, нашёл ли detector узнаваемое имя.
|
||||
|
||||
Профиль содержит измерительные модели/алгоритмы и возможности policy; выбранное правило миссии, оборудование, footprint и thresholds входят в effective run configuration. Пара `(immutable profile + effective mission/equipment configuration)` одинакова в Observatory и последующем live; изменение значимого параметра требует нового сравнения/квалификации. Запись не содержит «разрешение будущему автопилоту», только воспроизводимые входы и свидетельство проверки.
|
||||
|
||||
## Этап 1 — Полный состав профиля, контракты и технический baseline
|
||||
|
||||
**Цель:** закрыть состав первого полного профиля и оставшиеся технические разрывы до изменения продуктового пути; получить исходную точку для измерений на 4090.
|
||||
|
||||
**Вход:** локальный обзор, оба отчёта, существующие pinned weights и source-paced эксперименты. Новые измерения требуют доступного выделенного Worker без другой AI-нагрузки.
|
||||
|
||||
**Работа:**
|
||||
|
||||
- Завершить матрицу CURRENT → TARGET для backend, frontend, Worker, recording/live adapters, model runtime и хранения. Зафиксировать keep/replace/deprecate, не переписывая устойчивые admission/publication механизмы.
|
||||
- Описать versioned observation/result contracts: source/stream/epoch/sequence, timestamp/clock domain, payload formats, camera/cloud/pose, calibration и coordinate-frame references; на выходе все слои таблицы выше. Для полного первого профиля cloud и pose необходимы. Не привязывать совместимость к одному session ID или байтам media-init, не существенным для capabilities.
|
||||
- Описать lifecycle с одним владельцем Worker, правило переключения профиля, incremental result contract и различие «установлен», «работоспособен», «прошёл real-time квалификацию», «экспериментальный/не прошёл». Состояния availability, qualification и running/busy не сводить в один флаг `ready`.
|
||||
- Зафиксировать до приёмки численные бюджеты каждого профиля: входной поток, требуемая частота результатов, p95/p99 end-to-end age, допустимые пропуски, очередь, startup/warmup, память и stop-time. Не снижать требования задним числом ради зелёного результата. Неопределённые продуктовые компромиссы выносить владельцу, а не скрывать в scheduler.
|
||||
- Разделить reusable online algorithms и recorded-only подготовку. Проследить, чем заменяются чтение готового `local-surface.npz`, заранее подготовленные TGS rolling inputs, E47 masks и M4 ledgers. Vendor-registered исходные точки/pose допустимы как вход K1; собственные perception-результаты должны вычисляться текущим запуском.
|
||||
- Проверить совместимость зависимостей в одном образе: текущий DDRNet использует Python 3.9 / PyTorch 1.13.1 cu117 / super-gradients 3.2.0, RF-DETR — TensorRT 11, TGS — C++. Не объявлять их совместимыми в одном interpreter без проверки. Выбрать минимальную изоляцию внутри одного контейнера либо доказанное преобразование модели с parity check; не менять веса/качество молча ради сборки.
|
||||
- После согласованного освобождения GPU выполнить короткие baseline компонентов первого профиля последовательно и пилот общего расписания. Разделить decode/preprocess, H2D, inference каждой модели, online geometry/TGS, fusion/policy и доставку результата. Отдельно измерить cold startup и warmed steady state; не начинать с полного старого batch-run.
|
||||
- Сохранить существующие EoMT artifacts и точный checkpoint. Его отдельное исследование/упаковка — последующий вариант профиля, не обязательная ветка первого прототипа. Не запускать EoMT во время работ DDRNet-профиля.
|
||||
- Проверить текущие class/score/box-size/FOV фильтры RF-DETR на требования прототипа, включая близкий крупный объект и маленькое животное; наличие имени класса в модели не доказывает достаточное обнаружение. Не менять пороги без новой версии и сравнительного evidence.
|
||||
|
||||
**Результат и evidence:** точный manifest первого полного профиля, карта входов/выходов и owner boundaries, план единого образа с проверенной dependency strategy, численные инженерные критерии и baseline первого состава. Зафиксированы class coverage, distance estimators, unknown policy и отсутствие motor authority.
|
||||
|
||||
**Выход / зависимость:** GO на этап 2 после фиксации состава, существенных контрактных границ и воспроизводимого baseline. По уточнению владельца от 2026-09-02 performance FAIL на текущем железе не является запретом на развитие лабораторной платформы/упаковки и не требует выбрасывать профиль. На 2026-09-01 выполнены карта/reuse, executable contract, candidate manifest, component baseline и совместный causal pilot полного графа. Дальше измеряем и уменьшаем задержки, исправляем preroll/layered freshness и сохраняем отрицательные результаты; real-time статус выдаётся отдельно, только по факту прохождения критериев. Network whole-path и самостоятельная упаковка относятся к следующему runtime и не объявляются проверенными по локальному collector. Диагностический контейнер с mounts не является runtime этапа 2.
|
||||
|
||||
## Этап 2 — Самостоятельный Docker с полным потоковым вычислением
|
||||
|
||||
**Цель:** один самостоятельный контейнер принимает поток и реально рассчитывает DDRNet, детекции, расстояния, motion, TGS/costmap и policy-shadow; ничего не дорисовывается из старых LAB.
|
||||
|
||||
**Вход:** контракты и baseline этапа 1.
|
||||
|
||||
**Работа:**
|
||||
|
||||
- Реализовать общий lifecycle open/warmup/process/flush/stop, stage interfaces и supervisor. RF-DETR и DDRNet загружаются один раз при активации полного профиля. GPU inference сериализован; CPU TGS/geometry и I/O не блокируют GPU через неограниченную очередь. Разные частоты слоёв задаются явно и измеряются; retained mask не считается новым inference.
|
||||
- Подключить recorded adapter с исходными timestamp и pacing 1×; live adapter подаёт тот же тип наблюдений без знания длительности/конца записи. Не требовать полного tar/download, конкатенации всей камеры, полного PNG-cache или полного source hash-pass перед первым результатом. Допустить ограниченный декодерный pre-roll для codec dependencies, не просмотр будущих наблюдений моделью.
|
||||
- Выбрать и проверить бинарный data plane по реальным объёмам video/cloud, CPU cost и latency. Control plane остаётся отдельным. У модели нет произвольного доступа к сети/host; поток приходит через контролируемый proxy/IPC или явно ограниченный transport. Не включать privileged/host-network ради удобства.
|
||||
- Реализовать online local-surface/geometry и causal rolling TGS из поступивших points/pose. Сохранять неизвестные геометрические препятствия без semantic class. Camera–LiDAR association, distance estimator, track/motion и footprint references выдаются явно; отсутствие поддержки не подменяется нулём/бесконечностью.
|
||||
- Связать результаты слоёв в общий scene contract во время исполнения, а не только склеить тайминги после завершения. Привязать semantic labels к текущей геометрии с temporal/coordinate validity и bounded TTL. TGS и semantic policy становятся реальными входами диагностического rule evaluation, не только соседними слоями viewer.
|
||||
- Подключить существующее coarse material mapping и простую advisory policy: `hard_surface` — допустимый материал для первого сельского прототипа; geometry/TGS occupied и missing/stale evidence имеют приоритет над этим допуском. Тротуар и велодорожка не являются отдельными отказными случаями. Не добавлять второй segmenter или новую fine-grained road policy. Допуск поверхности не выбирает объезд и не выдаёт motor commands.
|
||||
- Сделать ограниченные очереди, явные cadence/drop/TTL правила, backpressure и stop/cancel. Завершение lease, смерть процесса и смена владельца должны прекращать старое исполнение; новый профиль не стартует, пока старый GPU-владелец не освобождён. Restart не воспроизводит накопившийся устаревший live backlog.
|
||||
- Выдавать результаты и технические метрики до EOF; хранение/overlay/video export не блокируют inference. Для сохранения evidence тоже задаётся ограничение ресурсов и честное состояние при переполнении. Не выдавать повтор предыдущей маски за новое измерение.
|
||||
- Упаковать первый полный образ с pinned model assets, TGS/runtime и нужными библиотеками. Проверить запуск без developer checkout, host model cache, внешнего Triton и model downloads. Не добавлять backend/БД/broker в контейнер. EoMT остаётся сохранённым отдельным вариантом вне активного первого профиля.
|
||||
|
||||
**Результат и evidence:** короткий replay 1× выдаёт все заявленные результаты до конца источника, память и очереди ограничены. Каждый слой имеет trace от inputs этого запуска; старые E47/M4/local-surface artifacts не предоставляются. Проверяются person/cat/dog, существующее static-obstacle представление без точного имени, допустимый `hard_surface` и препятствие поверх него, missing LiDAR, stale mask, burst/gap/out-of-order/cancel/lease-loss. Synthetic tests на Mac не загружают тяжёлые модели; реальные модельные случаи проверяются на Worker.
|
||||
|
||||
**Выход / зависимость:** GO на этап 3 после подтверждения работоспособности самостоятельного полного образа, streaming lifecycle и GPU ownership. Если полный граф не проходит короткий budget, сначала локализуется причина внутри этапа; FPS одного DDRNet и добавление UI не закрывают этот gate.
|
||||
|
||||
## Этап 3 — Сквозное подключение backend и frontend без LAB-микроприложений
|
||||
|
||||
**Цель:** приложение выбирает совместимый профиль и показывает его работу через общие контракты.
|
||||
|
||||
**Вход:** полный standalone runtime и образ первого профиля из этапа 2.
|
||||
|
||||
**Работа:**
|
||||
|
||||
- Расширить generic registry/preflight/claim: требуемые input capabilities, pinned executor identity, актуальная доступность Worker и соответствующее performance evidence. Совместимость, установленность и real-time квалификация проверяются отдельно; несовпадение capture/weights/runtime/hardware делает прежний допуск неприменимым.
|
||||
- Привязать leases, fencing, ограничения активности и live/recorded ownership к конкретному `worker_id`. Исключить двойной запуск на одном Worker. Независимые Worker не блокируют друг друга глобальным SQL/константой. Проверить эту независимость лёгкими fake-worker тестами, не параллельными GPU-запусками.
|
||||
- Интегрировать incremental results/progress/cancel и последующую immutable publication. Потоковое отображение не ожидает terminal archive. Существующие provenance, digest validation и восстановление публикации сохраняются.
|
||||
- В едином Observatory показать полный состав профиля и понятное название, совместимость источника, effective mission-rule, занятость Worker и qualification status. Один recording можно запускать на разных версиях профиля, один профиль — на разных совместимых recordings. Наличие двадцати профилей не создаёт двадцать приложений.
|
||||
- Расширить общие renderer/result capabilities: semantic mask, boxes/class/track, LiDAR support/ranges, TGS/costmap, motion и policy-shadow с явной свежестью. Все слои ссылаются на текущий run; исторический overlay разрешён только как явно выбранное сравнение, не скрытый fallback. EoMT и DDRNet не считаются одной ontology.
|
||||
- Сохранять run matrix с recording/capture/profile/effective mission configuration, техническими результатами и инженерной оценкой ошибок. Подготовить versioned profile reference для будущего mission configurator: он должен выбирать тот же immutable image/config, а не другой «live вариант» с тем же названием. Сам конфигуратор миссии и управление оборудованием в этом этапе не реализуются.
|
||||
- Применить UI skill и действующие архитектурные/UI документы перед UI-реализацией. Технические counters/p95/drop reasons размещать в соответствующих деталях, не превращать основное рабочее место в консоль отладки.
|
||||
|
||||
**Результат и evidence:** несколько совместимых recordings последовательно запускаются через приложение на одном полном профиле без правки кода; до конца записи видны все слои текущего run. Несовместимый источник и второй профиль на занятом Worker отклоняются. Видимый qualification-status совпадает с evidence; результат и сравнение версий сохраняются после перезапуска. Второй реальный модельный профиль не требуется придумывать ради этого gate: независимость каталога проверяется контрактными fixtures.
|
||||
|
||||
**Выход / зависимость:** GO на этап 4 после интеграционных, контрактных и последовательных browser-проверок общего пользовательского пути. Успешный UI smoke ещё не означает full-session real-time acceptance.
|
||||
|
||||
## Этап 4 — Квалификация полного прототипа на записях и подготовка к полигону
|
||||
|
||||
**Цель:** доказать вычислительную работоспособность полного профиля на 4090, найти его ошибки на записях и передать воспроизводимый прототип для последующего полигона, не объявляя готовую автономию.
|
||||
|
||||
**Вход:** сквозной путь этапа 3; численные критерии заморожены до испытаний.
|
||||
|
||||
**Работа:**
|
||||
|
||||
- Перед каждым профилем/испытанием проверить единственного владельца GPU, версии, питание/ограничения и warmup. Запуски строго последовательные. Сначала bounded canary; полный recording только после его прохождения. Не повторять заведомо неуспешный длинный EoMT-run ради завершения плана.
|
||||
- Провести full-session replay 1× всего профиля DDRNet + RF-DETR + geometry/motion + TGS + fusion/policy с учётом всех наблюдений. Проверить отсутствие растущего отставания, cadence/age/drop/memory budgets каждого слоя и общего выхода до приложения. Отдельно измерить startup, steady state и export; prepared geometry/masks не выдаются за online вычисление.
|
||||
- Проверить смысловые сценарии: допустимый `hard_surface` без препятствия и с препятствием, static-объект без уточнения имени, человек/животное, движение и неподвижность, отсутствие LiDAR/pose, истёкшая маска и конфликт семантики с геометрией. Тротуар/велодорожка относятся к принятой coarse категории, а не к отрицательным road-only случаям. Это инженерная проверка сельского прототипа, не общая accuracy и не городской автопилот. Новая разметка/обучение не являются условием первого запуска.
|
||||
- Проверить другую совместимую запись без изменения прикладного кода и отрицательные случаи: отсутствующий канал, неверная калибровка/формат, изменённые веса, другой hardware. Если второй источник отсутствует, соответствующее доказательство остаётся pending. Проверка другой машины/платформы не симулируется заявлением «это Docker».
|
||||
- Проверить interruption/reconnect, медленный consumer, burst/loss, stop, lease-loss, restart и публикацию. Проверить live-compatible вход с неизвестной заранее длительностью, без чтения будущего, на том же runtime. Физический live через K1/роутер/беспилотник проводится позже при доступности оборудования и согласованного окна; его отсутствие не блокирует replay-прототип. Целевые 300–500 Mbps не являются доказанным каналом: физический gate потребует uplink/jitter/loss/clock alignment/end-to-end age.
|
||||
- После приёмки нового пути убрать combined EoMT→DDRNet setup из активного real-time каталога, затем ограниченно вывести устаревшие adapters/микроприложения. Исторические записи/результаты и проверенный legacy M4.9 не удалять. Изменять конкретные declarations; для каждой runtime-миграции иметь точный predecessor и восстановление, без массового docker rename/delete.
|
||||
|
||||
**Результат и evidence:** один standalone image полного профиля, его manifest и инструкция запуска; таблица проверенных recordings/условий/ошибок; честный статус replay-prototype-qualified либо blocked. Подтверждены sequential exclusivity, переносимость на совместимые записи и регрессии сохранённых результатов. EoMT сохранён отдельно, не потерян и не включён в нагрузку первого профиля.
|
||||
|
||||
**Выход:** закрыть scope первого прототипа только при прохождении его replay/standalone gates. Отдельно оставить `physical-live-pending`, `independent-quality-pending`, `vehicle-integration-pending`, `actuation-disabled`. Ни новый известный маршрут, ни прошлый успешный recording, ни хороший FPS не включают автономию. Будущие EoMT/другие профили проходят те же gates отдельно, без расширения текущего этапа до бесконечного поиска моделей.
|
||||
|
||||
## Как измеряем и принимаем результат
|
||||
|
||||
Для каждого испытания сохраняются точный profile/image/weights/config digest, effective mission policy, equipment/capture/calibration identity, Worker/hardware, драйверы/runtime, source identity, интервалы и численные критерии, cold/warm режим, исходные counters и итоговый verdict. Изменение значимого измерительного контекста требует новой квалификации, а не ручного `ready=true`. FPS измеряется для полного output contract; отсутствие обязательного слоя не считается ускорением профиля.
|
||||
|
||||
Считаются source cadence, released/received/selected/inferred/emitted/dropped/expired/failed observations, queue depth, release lag, decode/preprocess/inference/postprocess, online geometry/TGS/fusion/policy и доставка результата до приложения, RSS/VRAM и объём передачи. Все входы должны быть учтены по однозначным терминальным категориям; processed FPS, successful-result cadence и fresh-result cadence — разные величины. У общего scene-result сохраняются возраст и source sequence каждого вложенного слоя, а не только свежий timestamp оболочки.
|
||||
|
||||
P95/p99 model-time не заменяет end-to-end age. Для разных машин нельзя вычитать несогласованные часы: clock mapping и его погрешность входят в evidence; внутрипроцессные интервалы измеряются monotonic clock. Startup/warmup не скрывается, но не смешивается с steady-state FPS. Устройство/модель не считается ready до завершения warmup.
|
||||
|
||||
Разрешённые пропуски определяются контрактом до запуска. К примеру, 6830/808.779495667/5 ≈1.689 результата/s: прежнее требование EoMT ≥1.8 FPS несовместимо со stride 5 на этом среднем исходном потоке. Требуется согласованная cadence-политика, а не механический перенос прежнего профиля. Quality-check для оптимизированных весов/precision/preprocessing отдельный: этот рефакторинг не создаёт ground truth и не даёт навигационную безопасность.
|
||||
|
||||
Проверки идут от дешёвых схем/negative/unit tests к isolated Worker canary, затем integration/full replay и доступному physical live. На Mac запускаются только ограниченные релевантные проверки; никаких model benchmark или full stress suite. После каждого этапа фиксируются выполненный результат, ссылки на evidence, известные ограничения и GO/PAUSE/BLOCKED. Следующий этап не начинается при незакрытом обязательном критерии предыдущего.
|
||||
|
||||
## EoMT: проверенные внешние сведения и предел вывода
|
||||
|
||||
EoMT — семейство ViT-моделей сегментации изображений; архитектура применяется к semantic, instance и panoptic segmentation. Наш конкретный checkpoint — Cityscapes semantic EoMT-L 1024, а не универсальное обещание качества на любой камере/домене. Это следует из [карточки конкретной модели](https://huggingface.co/tue-mps/cityscapes_semantic_eomt_large_1024) и [исходной статьи](https://arxiv.org/html/2503.19108v1).
|
||||
|
||||
В [официальном DINOv2 model zoo](https://github.com/tue-mps/eomt/blob/master/model_zoo/dinov2.md) для Cityscapes EoMT-L 1024×1024 указаны 25 FPS; условия таблицы — NVIDIA H100 с default `torch.compile`, если не оговорено иное. Это не показатель RTX 4090 и не end-to-end скорость нашей системы. Поэтому оснований объявить всё семейство «не real-time» нет, но и оснований квалифицировать наш профиль по этой цифре нет. Сохранение EoMT — отдельный исследовательский/резервный профиль, без обязательства неограниченно его ускорять.
|
||||
|
||||
## Progress
|
||||
|
||||
- 2026-09-01 18:15 UTC: локальный обзор backend/frontend/Worker и двух документов выполнен в предыдущей итерации; ограничения и отсутствие свежей Worker-проверки перенесены в этот план.
|
||||
- 2026-09-01 18:15 UTC: прочитаны все пять документов CODEX_V5; уточнение владельца о взаимоисключающих профилях внесено в TARGET. Проверены первичные источники EoMT. Создан план ровно из четырёх этапов.
|
||||
- 2026-09-01, последующий аудит: прочитаны M4.9T5/E47/M4 и integrated artifacts; через SSH выполнены только read-only Docker inventory/inspect, чтение installed manifests и GPU status. Подтверждено расхождение между viewer composition, reusable graph и portable package; выявлены другие GPU-capable сервисы.
|
||||
- 2026-09-01 18:48 UTC: по уточнённому сценарию владельца план переработан под один полный standalone Perception-профиль DDRNet + RF-DETR + geometry/motion + TGS + policy-shadow. Два обязательных сегментационных образа больше не являются целью первого прототипа. Road-only/coarse-material разрыв и dependency compatibility включены в этап 1.
|
||||
- 2026-09-01, следующее решение владельца: fine-grained road-only исключён из первого прототипа; coarse `hard_surface` принят, сельская среда — текущий контекст. Static-obstacle представление переиспользуется без распознавания отдельных видов предметов. Предыдущее требование road-vs-sidewalk gate снято; dependency compatibility остаётся технической задачей.
|
||||
- 2026-09-01 19:15–19:58 UTC, этап 1: по прямому разрешению владельца остановлены Ollama/Frigate, Docker restart=no закреплён в runtime и Compose, добавлены manual-only profiles. Данные/модели/записи сохранены. После замеров эти два сервиса не восстанавливаются; остальные временно остановленные Mission Core Worker-контейнеры восстановлены.
|
||||
- 2026-09-01 19:31–19:57 UTC: выполнены последовательные 64-sample baseline DDRNet, RF-DETR, TGS core и synthetic online local-surface. Ограничение BLAS/OMP/MKL до одного потока снизило mean synthetic local-surface с 198.0 до 63.2 ms без изменения алгоритмических порогов. Полный профиль этими цифрами не измерен.
|
||||
- 2026-09-01 19:49–19:57 UTC: построен локальный диагностический image с Python 3.9 DDRNet environment, TensorRT 11/native Triton base, Python 3.12 geometry и C++ TGS. Все четыре исполнились отдельными последовательными probes одного image ID; DDRNet masks совпали на 64 кадрах. Модели ещё монтируются явно, общего supervisor/IPC нет; standalone/full-profile статус не присвоен.
|
||||
- 2026-09-01: добавлены ADR 0049, transport-neutral stream/freshness/measurement contracts и pinned candidate manifest без image digest/active registry mutation. 78 focused tests прошли (51 новых contract + 27 существующих live-ingress/synchronizer/shadow); Ruff и mypy новых контрактов прошли. Модельные baseline и нагрузочные проверки на Mac не выполнялись.
|
||||
- 2026-09-01 20:51 UTC: совместный граф выполнен на исходных camera/point/pose arrivals 1×. Исправлена bounded causal body history для motion/threat и векторизован costmap lookup. До оптимизации 120/128, 8 drops, p95/p99 353.98/401.19 ms; после — 128/128, 0 drops, 174.09/190.62 ms. Fresh input у 75/128 кадров; остальные явно unavailable. 86 focused tests прошли. Все результаты и отрицательные gates сохранены в отчёте этапа 1.
|
||||
- 2026-09-02 00:20–00:41 МСК: уточнение владельца о долгосрочном экспериментариуме внесено в план, ADR, Desktop status и candidate `experiment_policy`. Тяжёлые профили сохраняются; functional, quality и hardware/source/transport-specific performance статусы независимы.
|
||||
- 2026-09-02: добавлены CUDA-event/host-IPC timing и экспериментальные варианты DDRNet layout/CUDA Graph; оба не показали устойчивого выигрыша полного графа и не стали defaults. Затем реализован `--schedule overlap-cpu`: один serial GPU worker, один chronological CPU consumer, общий бюджет двух pending кадров, единый bounded учёт входов. Первый fixed-slot вариант потерял один кадр и сохранён как отрицательный результат; dynamic shared-slot вариант дважды дал 128/128 без drops. Маски, proposals, metric observations, tracks, threats, costmap и non-timing TGS output совпали с reference на всех 128 кадрах; age-based policy проверяется отдельно.
|
||||
- 2026-09-02: 91 focused tests PASS (12 pilot, 52 contract, 27 existing live-ingress/synchronizer/shadow), Ruff PASS, Python 3.9 child lint PASS. Семь последовательных Worker runs и версии кода сохранены в `.runtime/perception-latency-20260902T0020MSK/manifest.json`. Worker-сервисы восстановлены, Triton ready=200, local 8000=200; Frigate/Ollama exited/restart=no. Никаких продуктовых defaults/registry cutover.
|
||||
- Этап 1: частично выполнен; совместный пилот и ограниченный latency experiment выполнены. Performance gate остаётся FAIL, но сам по себе больше не является запретом экспериментальной упаковки. Следующие задачи: устранить source-adapter preroll/layered-freshness разрыв, перенести измеренное расписание в общий runtime, затем измерить transport/application boundary. DDRNet/online-surface jitter остаётся отдельным profiling направлением. Нельзя закрывать whole-path gate по compute-only метрике или отсутствию drops.
|
||||
- Этапы 2, 3, 4: не начаты. Продуктовый backend/frontend path, active registry, canonical local 8000 и физический источник не переключались. Старый full-source materializer остаётся legacy; новый streaming transport ещё не реализован.
|
||||
|
||||
## Surprises / открытые вопросы
|
||||
|
||||
- Глобальная блокировка очереди противоречит независимости будущих Worker; нужно перенести ownership scope, а не просто оставить `max_concurrency=1` во всех слоях.
|
||||
- Старые combined-package manifests сохраняют batch-семантику и не исполняют detector/geometry/TGS/threat. Красивый общий viewer использует отдельные сохранённые результаты; это не готовый профиль.
|
||||
- FPS исходного recording и старые sampling/min-FPS требования математически расходятся. Численные product budgets должны быть закрыты в этапе 1; пользователь не задал их в этом уточнении.
|
||||
- Чистое GPU-окно для ограниченных component probes получено: после остановки сторонних и старых Mission Core GPU-процессов 0% utilization и около 529–531 MiB системного/display VRAM. Ollama/Frigate отключены постоянно из автозапуска по явному разрешению владельца. Source uplink, clock alignment и долгий эксклюзивный full-profile run не подтверждены; 300–500 Mbps и будущее hardware остаются гипотезами до проверки.
|
||||
- Существующий `static_obstacle` достаточен для неподвижных препятствий; точные semantic имена не являются пробелом scope первого прототипа. Динамика определяется temporal evidence, не классом объекта.
|
||||
- Потеря различия дорога/тротуар/велодорожка в `hard_surface` — осознанно принятый владельцем компромисс сельского прототипа, не блокер. Геометрический запрет остаётся выше material allowance.
|
||||
- Самостоятельный полный образ ещё не построен. Совместные lifecycle/IPC, resident модели и последовательный GPU schedule проверены в bounded пилоте с mounts, но performance gate FAIL. Экспорт нового образа заблокирован отсутствующим cached Triton blob / NVCR 403. Будущая поставка обязана включить веса и явно задать scratch/cache; рабочий mounted probe не равен standalone. В Triton base отсутствуют Python grpc/protobuf/cv2/TensorRT SDK: native trtexec не означает их наличия. Внутренний RF-DETR HTTP adapter позволил выполнить пилот без них.
|
||||
- CPU online local-surface — выявленный latency risk даже после ограничения BLAS threads. TGS core около 1 ms на prepared clouds не включает online rolling preparation/costmap; нельзя подставлять эту цифру как стоимость всего геометрического слоя.
|
||||
|
||||
## Decision log
|
||||
|
||||
- 2026-09-01, решение владельца: EoMT и DDRNet не считаются вместе на Worker 006. Первоначальная трактовка «никаких двух моделей внутри профиля» отменена последующим уточнением: RF-DETR и DDRNet нужны внутри одного полного профиля; запрет сохраняется для альтернативных профилей и EoMT+DDRNet.
|
||||
- 2026-09-01, решение владельца: один дрон — один Worker; текущий baseline RTX 4090. Следствие: worker-scoped exclusivity, без GPU-multiplexing и без зависимости от покупки hardware.
|
||||
- 2026-09-01, решение владельца: EoMT сохранить отдельно, даже если не проходит real-time на текущей карте. Следствие: отрицательный benchmark оформляется как честный статус, а не повод блокировать DDRNet или бесконечно оптимизировать.
|
||||
- 2026-09-01, рабочее решение плана: сначала контракты и baseline, затем runtime, затем продуктовая интеграция, затем квалификация и ограниченная миграция. Ровно четыре этапа; уточнения ведутся внутри них в этом же документе.
|
||||
- 2026-09-01, решение владельца: первым нужен самостоятельный Docker с DDRNet, объектной детекцией, LiDAR-расстояниями и TGS для проверки многих записей K1 и последующего полигона. Следствие: цель — полный Perception-профиль, а не голая сегментация; нет зависимости от прежних вычисленных LAB результатов.
|
||||
- 2026-09-01, решение владельца: беспилотника и motor integration сейчас нет. Следствие: текущий scope заканчивается проверенным perception/policy-shadow прототипом; actuator commands, autonomy acceptance и полный mission configurator — будущие отдельные gates, не скрытая часть этой реализации.
|
||||
- 2026-09-01, рабочее решение прототипа: в одном контейнере допускаются несколько внутренних runtime-процессов одной задачи для сохранения модельной совместимости; все имеют одного supervisor и одного GPU scheduler. Изолированные среды не превращаются в отдельно устанавливаемые LAB-сервисы.
|
||||
- 2026-09-01, решение владельца: никаких новых классов для столбиков/подобных предметов; существующего static-object / obstacle достаточно. Следствие: reuse текущего слоя и regression на RAV004, не новая модель/разметка перед первым прототипом.
|
||||
- 2026-09-01, решение владельца: coarse `hard_surface` достаточен в сельской среде, включая тротуары/велодорожки. Следствие: прежние обязательные road-only/fine-class требования отменены; один segmenter DDRNet, без urban autonomy scope. Геометрия и unknown/freshness сохраняют приоритет.
|
||||
- 2026-09-01, решение владельца: Ollama и Frigate больше не нужны в постоянной нагрузке. Остановить сейчас, убрать автозапуск после reboot, не восстанавливать после benchmark; сохранить данные для ручного использования. Выполнено и проверено по Docker/Compose, без физического reboot системы.
|
||||
- 2026-09-01, инженерное решение: стартовый replay stride=1, source clock=1×, ≤16 MiB inflight и два pending camera frames; whole-path p95/p99 ≤125 ms остаются preregistered candidate. Перегрузка должна быть видна и проваливать strict gate; нельзя скрыто замедлить источник/сменить stride/подменить слой старым результатом.
|
||||
|
||||
## Восстановление и остановки
|
||||
|
||||
При неудаче короткого canary остановить только принадлежащий испытанию профиль, сохранить диагностику и проверить освобождение GPU; не убивать посторонние процессы и не продолжать full-session. Неясный владелец GPU или потеря lease требуют fail-closed остановки нового запуска, а не захвата ресурса поверх старого процесса. Переключение на другой профиль — отдельная последовательная операция, не автоматический GPU fallback.
|
||||
|
||||
Новые схемы/декларации вводятся версионно. Возврат к точному предыдущему образу/конфигурации не превращает старый batch-путь в real-time; при откате сохраняется честный статус unavailable/not-qualified. Общую старую очередь нельзя ослаблять без worker-scoped fencing. Опубликованная история и исходники записи не переписываются для прохождения проверок.
|
||||
|
||||
Новый scope, изменение аппаратной/операторской границы, необходимость физического действия, отсутствие нужного доступа или существенный выбор latency/quality — повод остановить соответствующую часть и запросить решение владельца. Обычные локальные исправления внутри согласованных границ не требуют переписывания плана. Настоящий прогресс, evidence и решения обновляются здесь, без новых параллельных планов на каждую проверку.
|
||||
|
||||
## Outcomes / retrospective
|
||||
|
||||
Результат этапа 1 на текущий момент: исполняемые invariants, pinned manifest-кандидат, component baseline и измеренный совместный граф с bounded causal history, очередью и исходным 1× clock. Локальная оптимизация убрала drops на 128 кадрах, но real-time gate не прошёл. Transport, network end-to-end, переносимость по нескольким записям и standalone packaging остаются непроверенными. Экспорт image дополнительно упёрся в отсутствующий cached Triton blob / NVCR 403; временный mounted pilot не заменяет поставляемый образ. Ollama/Frigate остались выключенными, остальной временно остановленный Mission Core-контур восстановлен.
|
||||
|
||||
После этапа 4 здесь будут перечислены digest самостоятельного полного образа, измеренные статусы и ошибки по recordings, реально проверенные source/hardware/config комбинации, состояние сохранённого EoMT-варианта и оставшиеся physical-live/quality/vehicle-integration ограничения. Готовый Docker и готовая автономия не отождествляются.
|
||||
@@ -0,0 +1,509 @@
|
||||
# Stream-first Perception — этап 1, контракты и ограниченный baseline
|
||||
|
||||
Дата: 2026-09-01. Experiment ID: `perception-stream-stage1-20260901T1930Z`.
|
||||
Worker: RTX 4090, 24564 MiB, NVIDIA driver 610.47.
|
||||
Статус: **частичный результат этапа 1; не полный runtime и не real-time qualification**.
|
||||
Обновление 20:51 UTC: совместный source-paced пилот выполнен. После оптимизации
|
||||
128/128 кадров без drops; p95/p99 174.09/190.62 ms — FAIL исходного latency gate.
|
||||
Подробности и evidence нового experiment `perception-joint-pilot-20260901T2040Z`
|
||||
находятся ниже. Последнее дополнение — 2026-09-02 00:41 МСК: семь bounded
|
||||
latency runs; shared-budget CPU overlap дважды дал 128/128 без drops,
|
||||
но p99 194.25–198.22 ms не проходит исходные 125 ms. Подробности — в последнем
|
||||
разделе. Это не product cutover и не самостоятельный образ.
|
||||
|
||||
## Решение и сделанный объём
|
||||
|
||||
Первый профиль зафиксирован как `K1 Perception — DDRNet-39 + RF-DETR + TGS`:
|
||||
одна сегментация, детектор, online LiDAR/расстояния/static obstacles,
|
||||
temporal/motion, TGS/costmap и advisory policy. EoMT не запускался и не удалялся.
|
||||
Моторы, автопилот и Synology deployment не затрагивались.
|
||||
|
||||
Добавлены:
|
||||
|
||||
- [Версионные контракты](../../src/k1link/perception/realtime_contract.py):
|
||||
bounded start без размера/длительности/полного архива, обязательные каналы,
|
||||
epoch/lease/profile bindings, шесть выходных слоёв, causal freshness и
|
||||
отрицательные критерии whole-path real-time проверки.
|
||||
- [Candidate manifest](../../config/perception/k1-perception-ddrnet39-rfdetr-tgs-prototype-v1.json):
|
||||
pinned модели/алгоритмы, accepted coarse `hard_surface`, static.unknown,
|
||||
serial GPU policy, исходные фильтры, пределы памяти/очередей/задержки.
|
||||
Он не зарегистрирован как готовый executor; image digest остаётся `null`.
|
||||
- [ADR 0049](../../docs/adr/0049-stream-first-perception-profiles.md): карта
|
||||
CURRENT → TARGET, reuse существующего raw-first ingress, lifecycle,
|
||||
no-preload правило и стратегия изоляции зависимостей внутри одного образа.
|
||||
- [Ограниченные диагностические программы](worker/streaming_profile_stage1/).
|
||||
|
||||
**Старый `source_materializer.materialize(job)` не удалён и рабочий LAB-путь
|
||||
не переключён.** Запрет полного предварительного копирования сейчас закреплён
|
||||
в новом контракте и тестах. Реального нового сетевого runtime эти изменения
|
||||
ещё не создают. gRPC остаётся кандидатом, а не проверенным транспортом.
|
||||
|
||||
Новый путь должен выдавать текущие результаты до EOF; полное хеширование,
|
||||
распаковка, PNG-cache и конечная публикация не могут быть условием первого
|
||||
inference. Текущие запись и raw-first hooks сохраняются; второй acquisition
|
||||
контур для K1 не создаётся. Защита от перегрузки обязана учитывать суммарные
|
||||
байты, а не только число сообщений.
|
||||
|
||||
## Условия измерений
|
||||
|
||||
Все модельные проверки выполнены **последовательно**, только на Worker.
|
||||
На Mac — лишь ограниченные unit/regression проверки, без моделей и нагрузки.
|
||||
На время GPU-проб останавливались старый Triton, perception-worker и installed
|
||||
LAB agent; после проб они восстановлены. До нагрузки GPU utilization был 0%,
|
||||
память около 529–531 MiB (системный/display остаток). Независимые профили не
|
||||
запускались вместе. Внутренние CUDA auxiliary streams одного RF-DETR engine
|
||||
не означают параллельные профили.
|
||||
|
||||
Контейнеры проб: `--rm`, фиксированные image IDs, labels `mission-core` /
|
||||
`observatory`, `--network none`, read-only root/assets, dropped capabilities,
|
||||
ограниченные CPU/RAM/PIDs/tmpfs. GPU-пробы: 6 CPU / 8 GiB; CPU-пробы:
|
||||
2 CPU / 2 GiB. Никакие веса не скачивались. Использовались уже имеющиеся на
|
||||
Worker входы; полная запись не пересылалась и не хешировалась перед пробой.
|
||||
|
||||
Это короткий component baseline, **не source-paced replay**. Восемь warmup
|
||||
итераций DDRNet не входят в 64 измеренных кадра; декодировано 65 исходных
|
||||
кадров. RF-DETR измерен на синтетическом uint8 tensor. TGS использовал первые
|
||||
64 уже подготовленных causal rolling clouds: это разрешено для изолированного
|
||||
замера ядра, но запрещено как замена online preparation в полном профиле.
|
||||
Local-surface использовал 64 синтетических облака по 4000 точек, stationary
|
||||
sensor, seed `20260901`; логические timestamps 10 Hz не были pacing-механизмом.
|
||||
|
||||
## Компонентные результаты
|
||||
|
||||
Время в миллисекундах. Здесь нельзя складывать p95 или обращать отдельные
|
||||
значения в обещанный FPS полного профиля. Для сохранённых массивов использован
|
||||
nearest-rank percentile `ceil(q*N)-1`; RF-DETR — percentiles самого trtexec.
|
||||
При N=64 p99 nearest-rank равен максимуму и не характеризует редкие хвосты.
|
||||
|
||||
| Проверка | Среднее | p95 | p99 | Что не включено |
|
||||
| --- | ---: | ---: | ---: | --- |
|
||||
| DDRNet, исходный image, FP32, decode/preprocess/H2D/forward/post/D2H | 21.523 | 43.064 | 47.150 | Сеть, остальные слои, публикация |
|
||||
| RF-DETR TRT11, DMA включён | 2.301 | 2.505 | 2.986 | Реальное изображение/качество, host filtering, сеть |
|
||||
| TGS C++ на prepared rolling clouds | 1.034 | 1.242 | 1.519 | Подготовка rolling cloud, costmap, транспорт |
|
||||
| Online local-surface, synthetic, BLAS threads=1 | 63.219 | 66.066 | 73.904 | Реальная траектория, object association, motion/policy |
|
||||
|
||||
DDRNet load + first decode + model warmup: 9.160 s, без создания/распаковки
|
||||
Docker-контейнера и без сетевого старта. Torch allocated peak 276.35 MiB,
|
||||
reserved 316 MiB — **не** общий VRAM peak профиля. Существующий runner сохраняет
|
||||
floor-percentiles; таблица пересчитана из его 64 raw rows, не из округлённых
|
||||
агрегатов. Веса, preprocessing и FP32 не менялись.
|
||||
|
||||
RF-DETR: `--warmUp=1000 --duration=0 --iterations=64 --avgRuns=1
|
||||
--percentile=95,99 --includeDataTransfers --noCudaGraph --noSpinWait`.
|
||||
TRT11 по умолчанию отключает transfers и включает CUDA graph/spin-wait;
|
||||
первый диагностический результат без DMA не принят как сравнимый baseline.
|
||||
В принятом запуске средние H2D / GPU / D2H: 0.120 / 2.173 / 0.009 ms.
|
||||
Это engine latency, не latency готовых объектов в приложении.
|
||||
|
||||
С default numeric-library threading synthetic local-surface занимал в среднем
|
||||
198.043 ms. При `OPENBLAS_NUM_THREADS=1`, `OMP_NUM_THREADS=1`,
|
||||
`MKL_NUM_THREADS=1` — 63.219 ms. Пороги геометрии не менялись; bitwise parity
|
||||
геометрических выходов не проверялась. Все 64 состояния — valid.
|
||||
Thread limits добавлены в candidate execution policy. CPU-геометрия остаётся
|
||||
существенным риском бюджета: это уже больше времени, чем оба отдельных
|
||||
модельных измерения, а online association/motion/fusion ещё не замерены вместе.
|
||||
|
||||
## Проверка общей базы образа
|
||||
|
||||
Собран **диагностический**, не самостоятельный продуктовый образ:
|
||||
`ndc-perception-stage1-dependency-probe:20260901`, local image ID
|
||||
`sha256:664824aa25de1db178f177d67a81b01541a938b479812b9383ddbf03f6b59dbe`.
|
||||
Создан 2026-09-01 19:49:38 UTC; сборка без network/pull из существующих баз:
|
||||
|
||||
| База | Проверенный local image ID |
|
||||
| --- | --- |
|
||||
| Installed DDRNet step | `e6c986100613ec804f0e0076ca8695abf43ff88ef9d5d85f6857e0b41db74051` |
|
||||
| TRAVEL TGS | `7b412020f4d8392d1d1ed1b33beadc44140f0ea8f781e62dd69796042334300f` |
|
||||
| Triton 26.06 | `58df7489c3f2276f9591d500a012dee03e23d35543ce3c390b4c001e6bf90794` |
|
||||
|
||||
В final base скопированы старое `/opt/conda` и C++ TGS binary. Проверены
|
||||
отдельными последовательными запусками **одного и того же image ID**:
|
||||
|
||||
- DDRNet Python 3.9 / Torch 1.13.1 cu117: 64 кадра; среднее 20.781 ms,
|
||||
p95 39.665 ms, p99 47.251 ms; model-load/first-decode/warmup 8.422 s.
|
||||
SHA последовательности masks совпал с исходным image:
|
||||
`7b4cc5e10f0ee7a5cc20ff0679f4b972607975555b7d16670fff19e4ca491adb`.
|
||||
Это ограниченный parity check 64 кадров, не всего датасета.
|
||||
- RF-DETR native TRT11: 64 synthetic queries, среднее 2.303 ms, p95 2.356 ms,
|
||||
p99 2.794 ms, те же явные флаги DMA/graph/spin-wait.
|
||||
- Python 3.12 online local-surface: 64 valid состояния, mean 63.518 ms.
|
||||
- Скопированный C++ TGS binary: 64 prepared clouds, mean 1.060 ms.
|
||||
|
||||
Таким образом, базовый ABI/import/execution разрыв решаем через изолированные
|
||||
процессы/interpreters в **одном образе**, без обновления DDRNet checkpoint.
|
||||
**Совместно resident модели, общий supervisor/IPC/scheduler и полный граф в
|
||||
одном экземпляре контейнера не проверены.** Пробы используют явные read-only
|
||||
mounts весов, runner и входов; они не доказывают standalone packaging.
|
||||
Диагностический image сохранён для воспроизводимости, активного контейнера нет.
|
||||
|
||||
Выявленные требования к настоящей сборке:
|
||||
|
||||
- Старый DDRNet image не содержит checkpoint в объявленном logical asset path.
|
||||
Начальная проба image-only завершилась до inference. Веса/runner должны быть
|
||||
внутри нового образа, а не неявным host-cache.
|
||||
- Super-gradients требует writable log directory; предоставлялся ограниченный
|
||||
tmpfs `/root/sg_logs`. Matplotlib использовал temporary cache; будущий runtime
|
||||
должен явно задавать writable scratch/cache paths и их ограничения.
|
||||
- В Triton base есть native trtexec/server и Python 3.12/NumPy, но не найдены
|
||||
Python `tensorrt`, `grpc`, `cv2`, `google.protobuf`. Нельзя считать SDK/codec
|
||||
окружение готовым. Допустим внутренний supervised native Triton; зависимости
|
||||
supervisor/transport необходимо явно включить и проверить.
|
||||
- TensorRT plan связан с runtime/hardware совместимостью. Переносимость Docker
|
||||
не означает автоматическую совместимость engine с другой GPU/Apple Silicon.
|
||||
|
||||
## Ollama / Frigate: изменение по прямому разрешению владельца
|
||||
|
||||
Оба сервиса остановлены и **не восстановлены** после измерений:
|
||||
`sentinel-ollama`, `sentinel-frigate`. Docker restart policy обоих — `no`.
|
||||
Данные, модели и записи камер не удалялись.
|
||||
|
||||
Изменён источник Compose на Worker:
|
||||
`D:\_PROJ\NODEDC\NODEDC_AEGIS\docker\docker-compose.frigate.yml`.
|
||||
Frigate получил `profiles: [manual-frigate]`, Ollama — `[manual-ollama]`,
|
||||
оба `restart: "no"`. Проверка 2026-09-01 19:58:13 UTC: обычный
|
||||
`compose config --services` не включает ни одного из этих сервисов;
|
||||
явные manual profiles содержат нужные сервисы с restart=no.
|
||||
Проверенные task/startup entries по именам сервисов не обнаружены.
|
||||
Физическая перезагрузка Windows не выполнялась: проверена конфигурация
|
||||
автозапуска, а не результат реального reboot.
|
||||
|
||||
Backup сохранён рядом:
|
||||
`docker-compose.frigate.yml.before-manual-only-20260901T1915Z`.
|
||||
SHA-256 до: `2f762ca0361411091a6ca184fbef73fdce7739957476bc25270b9464ad3c205b`.
|
||||
После: `5e5b1f52e5d328a1fcae8a026a71dec81342734e6770a8fbf3bb8ddd38e7c331`.
|
||||
Не заменять весь Compose слепо при будущем rollback: сначала проверить drift.
|
||||
Редкое использование Ollama требует явного ручного запуска; это не повод
|
||||
возвращать её в постоянную GPU-нагрузку.
|
||||
|
||||
Остальной durable Mission Core Worker-контур восстановлен. Triton readiness
|
||||
проверен HTTP; локальный canonical Mission Core `127.0.0.1:8000` возвращает 200.
|
||||
У legacy perception-worker до проб наблюдался restart loop (387 restarts);
|
||||
восстановление контейнера не означает исправления этого прежнего дефекта.
|
||||
Не связанные с задачей сервисы/данные не менялись.
|
||||
|
||||
## Проверки и evidence
|
||||
|
||||
78 focused tests прошли: новый contract suite (51) плюс существующие
|
||||
`test_live_perception`, `test_live_perception_synchronizer`,
|
||||
`test_live_perception_shadow` (27). Ruff новых contract/test и обеих Python
|
||||
probe программ — PASS; mypy contract module — PASS. Для DDRNet probe lint
|
||||
использует Python 3.9 target, не несовместимый с ним `datetime.UTC`.
|
||||
Это не полный backend/frontend suite и не нагрузочный тест.
|
||||
|
||||
Unit tests показывают, среди прочего, что существующий raw-first ingress
|
||||
отдаёт наблюдение до `end_session`, а новый contract не принимает batch mode,
|
||||
full-source fields, cross-epoch/future/stale relabeling, неполный scene,
|
||||
скрытые пропуски, замедленный replay и превышение инженерных бюджетов.
|
||||
Они не доказывают доставку application ↔ Worker по сети.
|
||||
|
||||
Raw timings/logs и replay commands сохранены вне Git:
|
||||
`.runtime/perception-stream-stage1-20260901/`. UTC/monotonic anchors DDRNet:
|
||||
baseline `2026-09-01T19:31:47.850689+00:00`, monotonic
|
||||
`43059737808266` → `43070282556549`; combined-image
|
||||
`2026-09-01T19:54:58.292953+00:00`, `44450232680793` → `44459991768361`.
|
||||
Эти monotonic значения не вычитаются из часов Mac. trtexec logs содержат UTC
|
||||
и device-local durations; межмашинный clock mapping ими не измерен.
|
||||
|
||||
| Raw artifact | SHA-256 |
|
||||
| --- | --- |
|
||||
| ddrnet-baseline.json | `6c33cd98c09bbe91c4a0ef45a75dcdc8426b8b3227988e772225b011167da528` |
|
||||
| rfdetr-trtexec.log | `078f6a311cb00ad7326d5b9d99799bf45c97546a6f244f5507037b56ebe9917a` |
|
||||
| tgs-baseline.json | `fe264d31a6a5215edea68c5497eb5c862d5f002a4711190e95dbd0ac952a9430` |
|
||||
| surface-default-threads.json | `aa7df56e250b8a179f6e61ddd34a312c0594d409122259813e366d75511e066c` |
|
||||
| surface-single-thread.json | `190794710cd3dbb40313bdbba57fe7e182e2f3dc32c7809b246ae5d257368b19` |
|
||||
| ddrnet-combined-image.json | `72930d502ce3aab5b146c4c18a8a2b24abfc7bda25b3c6a16425a2e7f8ac6c2e` |
|
||||
| rfdetr-combined-image.log | `cbff78a8644a6a59132cda64717fd4f206589c52f6fbc5426457445fc451b6a8` |
|
||||
| surface-combined-image.json | `5d76520bceee57d2f39e2404eb9fa8776d38d2f837a3b116a295538c040463da` |
|
||||
| tgs-combined-image.csv | `c80faa6cc54860d86af57079954d6654db1a58eecccd432d3992684ba941267a` |
|
||||
|
||||
Model/config pins находятся в candidate manifest; существующие raw recordings,
|
||||
clouds и приватные logs не добавлялись в Git.
|
||||
|
||||
## Оставшиеся gates: не объявлять этап 1 или real-time автоматически закрытыми
|
||||
|
||||
1. Численные budgets зафиксированы **как инженерный candidate**, не как
|
||||
измеренное достижение или vehicle safety approval: whole-path p95/p99
|
||||
≤125 ms, layer age ≤250 ms, release lag ≤25 ms, inflight ≤16 MiB,
|
||||
camera pending ≤2, zero capacity drops при начальном stride 1.
|
||||
Их нельзя ослаблять задним числом ради успешного прогона.
|
||||
2. Совместный causal pilot выполнен 2026-09-01 в 20:51 UTC; его результаты
|
||||
приведены ниже. Оба модельных процесса resident, GPU inference последователен.
|
||||
После локальной оптимизации получены 128/128 результатов, но p95/p99
|
||||
174.09/190.62 ms и backlog growth 51.44 ms не проходят исходные бюджеты.
|
||||
Измерение выполнено; real-time qualification не получена.
|
||||
3. Риски detector filters для маленького животного/близкого крупного объекта
|
||||
установлены по коду (min box 64 px, max fraction 0.5, FOV 0.5), но quality
|
||||
acceptance на этих случаях не выполнен; пороги сохранены без изменений.
|
||||
4. Standalone упаковка всех assets, streaming transport/codec/clock mapping,
|
||||
per-worker fencing, общий supervisor и end-to-end receiver timestamps
|
||||
остаются следующими реализационными задачами. Нет автоматического GO на
|
||||
полный recording-run, UI cutover, физический live или автономное движение.
|
||||
|
||||
Этапы 2–4 не объявляются начатыми/пройденными за счёт диагностического image.
|
||||
Существующие исторические результаты и batch acceptance сохранены без
|
||||
переписывания. Продолжение ведётся в одном
|
||||
[четырёхэтапном ExecPlan](../../docs/OBSERVATORY_REALTIME_PROFILES_EXECPLAN.md).
|
||||
|
||||
## Совместный потоковый пилот — 2026-09-01, 20:51 UTC
|
||||
|
||||
**Результат:** полный вычислительный граф действительно исполняется в одном
|
||||
временном контейнере на RTX 4090. Это уже не сумма отдельных model benchmarks.
|
||||
Оптимизированный запуск завершил окно 128 кадров без capacity drops, но
|
||||
**performance gate остаётся FAIL**. Продуктовый batch-путь не переключён.
|
||||
|
||||
### Граница и метод
|
||||
|
||||
- Один контейнер `ndc-k1-ddrnet-rfdetr-tgs-joint-pilot`, один supervisor,
|
||||
постоянный DDRNet Python 3.9, native RF-DETR TensorRT/Triton, CPU supervisor
|
||||
Python 3.12 и C++ TGS. DDRNet завершается до вызова RF-DETR; EoMT отсутствует.
|
||||
- Рассчитываются DDRNet masks → RF-DETR proposals → online local surface →
|
||||
LiDAR association/ranges → temporal/motion/rolling obstacles → simulated
|
||||
threat assessment → TGS/costmap → hard-surface-only advisory policy.
|
||||
На каждой камере работают обе модели. При отсутствии допустимых текущих
|
||||
cloud/pose метрические слои возвращают unavailable, а не выдуманный результат.
|
||||
- Источник RAVNOVES00, session `20260720T065719Z_viewer_live`: существующее
|
||||
camera video `cadd1696…`, camera index из job
|
||||
`recorded-camera-602ac89026ed12978619801d`, normalized LiDAR replay v2
|
||||
`8fc0fb418578b8ee2ac88d502d2acbc63ae533437a9da14f1a9f9d8916f613ce`.
|
||||
Из архива последовательно читаются original host-arrival timestamps,
|
||||
point increments и pose. Старый E10 pack используется **только** для трёх
|
||||
малых статических calibration arrays. Нет готовых masks, surface, TGS,
|
||||
detections или threat ledgers в качестве входа графа.
|
||||
- Источник подаётся отдельным producer по исходным временам 1×, не по окончанию
|
||||
inference. Камерное окно занимает 12.684938 s между первым и последним кадром.
|
||||
Интервалы: min 2.724 ms, median 99.594 ms, max 215.529 ms; 10 интервалов
|
||||
короче 50 ms. Поэтому равномерный synthetic 10 Hz не эквивалентен этой записи.
|
||||
- Прогрев моделей предшествует admission. Начальный sensor preroll ≤500 ms;
|
||||
raw rolling cloud ≤1 s / 64000 points; pending camera ≤2; aggregate queued +
|
||||
active observation bytes ≤16 MiB. Один кадр декодируется после его due time.
|
||||
В финальном запуске прочитано 229/4570 point records, 241/4598 poses,
|
||||
545590/10751258 XYZ rows, включая отброшенный начальный sensor prefix.
|
||||
Полная запись не копировалась, не хешировалась и не декодировалась до старта.
|
||||
- Scene сериализуется и разбирается фактическим **локальным** collector внутри
|
||||
контейнера. `source_due_to_receiver_ms` включает release/decode/queue/весь граф
|
||||
и этот collector, **не включает сеть Mission Core ↔ Worker и viewer**.
|
||||
Сохранение диагностического JSONL происходит после receiver timestamp;
|
||||
его возможная задержка следующего кадра остаётся видна в queue timings.
|
||||
- CPU libraries: BLAS/OMP/MKL=1; container 8 CPUs / 8 GiB. CPU quota throttling
|
||||
в финальном измерении отсутствовал (`nr_throttled=0`). Это не доказывает
|
||||
отсутствие любого host/driver jitter. Измеренная memory — cgroup memory,
|
||||
не сумма RSS процессов; sampled VRAM содержит системную/display составляющую.
|
||||
|
||||
### Исправления, которые выявил именно совместный запуск
|
||||
|
||||
1. Разделены `PYTHONPATH` Python 3.9/3.12: общий путь к Pillow 3.12 ломал DDRNet
|
||||
при загрузке. Первый canary остановился до admission, без кадров.
|
||||
2. Threat/motion использует прошлую body pose. Адаптер «только текущая поза»
|
||||
остановил первое 128-frame окно после 63 результатов. Добавлена bounded
|
||||
история 64 уже вычисленных body frames; запрос будущего frame запрещён.
|
||||
Body frame — только camera-forward simulation с прежними height/slope
|
||||
ограничениями, **не** future-trajectory resolver и не реальная установка рига.
|
||||
3. Vectorized lookup заменил Python tuple/dict loop по точкам costmap, сохранив
|
||||
grid membership, holes и индексы. Synthetic exact-parity test прошёл;
|
||||
DDRNet masks совпали на всех 120 общих кадрах двух запусков. Это не полная
|
||||
parity всей temporal scene: набор обработанных кадров различался из-за drops.
|
||||
4. Publication guard учитывает возраст камеры **и** исходных cloud/pose.
|
||||
Устаревшее evidence остаётся доступным для диагностики, но все его terrain
|
||||
actions принудительно NO_GO. Только coarse hard_surface с поддержанной
|
||||
геометрией может быть ALLOW_candidate; rural bare_soil здесь не разрешён.
|
||||
|
||||
### Измерения (nearest-rank percentiles, без отбрасывания медленных кадров)
|
||||
|
||||
| Запуск | Результаты / вход | Drops | Source→local receiver p95 / p99 | Решение |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| Canary 32, рабочий ABI | 32 / 32 | 0 | 232.39 / 253.02 ms | FAIL latency/backlog |
|
||||
| 128, bounded causal body history | 120 / 128 | 8 | 353.98 / 401.19 ms | FAIL latency/overflow |
|
||||
| 128, vectorized costmap | 128 / 128 | 0 | 174.09 / 190.62 ms | FAIL latency/backlog |
|
||||
|
||||
Финальный запуск `joint-pilot-128-vectorized`, UTC start
|
||||
`2026-09-01T20:51:35.734802+00:00`, Worker monotonic start `47847791349665`.
|
||||
Replay mapping: source zero `200950673923333` → Worker zero `47857207269471`.
|
||||
Последний result `47870540878573`. Часы разных машин не вычитаются напрямую.
|
||||
|
||||
Дополнительные результаты финального окна:
|
||||
|
||||
- mean source→receiver 87.94 ms; max 213.89 ms. Compute→receiver p95/p99
|
||||
115.25/122.98 ms, но **этой более узкой метрикой нельзя заменить end-to-end**.
|
||||
- Queue wait p95/p99 68.68/90.36 ms; прирост средней очереди последних восьми
|
||||
относительно первых восьми кадров 51.44 ms при лимите 25 ms.
|
||||
- Source release max 12.78 ms по всем трём каналам — PASS ≤25 ms.
|
||||
- Первый результат через 546.12 ms от начала sensor-preroll clock, до конца
|
||||
пилотного окна и до EOF записи. Model/runtime warmup 9.36 s; stop 4.07 s.
|
||||
- Peak sampled GPU memory 1932 MiB; peak cgroup memory 3342.25 MiB;
|
||||
observation inflight 7194040 bytes (6.86 MiB), pending peak 2; residual 0.
|
||||
- TGS/costmap/policy среднее по всем кадрам снизилось с 21.25 до 4.09 ms;
|
||||
эти средние включают unavailable-кадры. Модельные веса и detector filters
|
||||
не менялись. Новые бюджеты для получения PASS не вводились.
|
||||
|
||||
### Что реально посчитано и чего этот результат не доказывает
|
||||
|
||||
75/128 кадров имели допустимую текущую cloud/pose пару; для них рассчитаны
|
||||
online surface и TGS. На 53 кадрах — unavailable. В записи 43 камеры без нового
|
||||
point increment и 39 с pose age >100 ms (множества пересекаются). Отдельно первый
|
||||
кадр отвергнут из-за объединённых preroll increments возрастом до 408 ms —
|
||||
это ограничение текущего адаптера, не доказательство неисправности сенсора.
|
||||
Не следует повышать свежесть до «current» повторной маркировкой старого облака.
|
||||
|
||||
Опубликованы 398 метрических obstacle observations, из них 275 geometry-only;
|
||||
детектор на данном отрезке выдавал `person`, `car`, `truck`. Рассчитаны motion
|
||||
и simulated threats; 62 assessment имели decision=threat, но это **не**
|
||||
подтверждённые физические угрозы или accuracy score. Cat/dog/близкий крупный
|
||||
объект и регрессия RAV004 этим отрезком не квалифицированы. Повторяющиеся
|
||||
наблюдения не считаются уникальными физическими объектами.
|
||||
|
||||
21 scene получили stale publication guard, в том числе 3 с допустимым входом,
|
||||
устаревшим в вычислениях/очереди; ни у одной stale scene нет ALLOW. Body/threat
|
||||
qualification относится к виртуальному corridor contract, не к полигону.
|
||||
Scene lineage сохраняет реальные времена точек/pose; старые domain-observation
|
||||
timestamps всё ещё привязаны к camera anchor. Общий layered freshness ABI
|
||||
этапа 2 должен учитывать это явно, а не объявлять текущий адаптер финальным.
|
||||
|
||||
### Packaging и состояние системы
|
||||
|
||||
Native bases проверены по ранее зафиксированным image IDs. Сборка кода,
|
||||
Pillow и C++ прошла, но экспорт нового полного image остановлен: у Docker
|
||||
Desktop отсутствует compressed layer `0e5f8475…` исходного Triton, а NVCR
|
||||
возвращает 403. Настройки/секреты авторизации не менялись. Pilot-assets (33.52 MB)
|
||||
экспортированы из уже доступных локальных build files и подключены read-only
|
||||
к работоспособной общей базе `sha256:664824aa25de1db178f177d67a81b01541a938b479812b9383ddbf03f6b59dbe`.
|
||||
Веса также explicit read-only mounts. Это **не самостоятельный поставляемый
|
||||
Docker** и не обход отсутствующего image-release gate. Для обычного образа
|
||||
Dockerfile требует `--target pilot`; `--target pilot-assets` — только диагностика.
|
||||
|
||||
До model runs: 533 MiB VRAM, 0% GPU; прежние Mission Core GPU-сервисы временно
|
||||
остановлены. После проб временных контейнеров нет; Triton и два Mission Core
|
||||
worker agents восстановлены, Triton ready=200 / healthy, local Mac 8000=200.
|
||||
Прежние transport/restart проблемы agents зафиксированы до остановки
|
||||
(perception-worker 33 restarts, installed-agent 3), но не ремонтировались этим
|
||||
пилотом. Frigate/Ollama остаются stopped/restart=no, данные сохранены.
|
||||
|
||||
### Evidence, проверки и следующий gate
|
||||
|
||||
Raw reports, scenes и subprocess logs:
|
||||
`.runtime/perception-joint-pilot-20260901T2040Z/`; такие же run directories
|
||||
сохранены на Worker под `D:/NDC_MISSIONCORE/runtime/experiments/`.
|
||||
Команды, pins и ограничения — в `manifest.json` этого evidence directory.
|
||||
|
||||
| Артефакт | SHA-256 |
|
||||
| --- | --- |
|
||||
| joint-pilot-128-causal-history/report.json | `370bbd97dab1f7881614b18932e0b841dc791b9e5bfebf3e80707c7b437252e8` |
|
||||
| joint-pilot-128-vectorized/report.json | `80d6843d793dea50a738a4bdf77dc3c6e1bd3a186b8dd58b89ba400611eaacd9` |
|
||||
| joint-pilot-128-vectorized/scenes.jsonl | `d8cf53dee06cc08bd244d8676e8469a455f610328c44442f0192b2f37ed4afc7` |
|
||||
| pilot_graph.py, финальная версия | `fd4d5307d4135250791cce73607c04c46f037481860cac691fc50d25e1daa1c4` |
|
||||
| run_joint_pilot.py, финальная версия | `9ae8d62ea90a5140e90c09f035c29d933887392fe5d2d15635cf912c94d73808` |
|
||||
| C++ pilot-tgs binary | `1ecb25a1db8dd90609754d4a98aa4ac24f50feb3023cf445a669c6c1cf72aa20` |
|
||||
|
||||
Focused verification: 86 tests (8 новых pilot + 51 contract + 27 existing
|
||||
ingress/synchronizer/shadow); Ruff, включая Python 3.9 child target. Full
|
||||
backend/frontend suite и field/physical-live не выполнялись.
|
||||
|
||||
**Итог gate:** совместный пилот как измерение выполнен; stage-1 performance
|
||||
приёмка остаётся открытой. Следующая техническая работа — стоимость/джиттер
|
||||
DDRNet и online surface, расписание единого графа при реальных burst intervals,
|
||||
отдельные arrivals/age/unknown для модальностей и корректный preroll admission.
|
||||
Не разрешены скрытый stride, замедление clock, повышение порогов или подмена
|
||||
метрик. После этого повторить тот же bounded pilot, затем переходить к
|
||||
standalone/transport этапа 2. Полная запись и автономный выезд не разрешены
|
||||
самим фактом 128 успешных callback результатов.
|
||||
|
||||
## Дополнение 2026-09-02: снижение задержек, не отсечение тяжёлых профилей
|
||||
|
||||
Уточнение владельца: Observatory — долгосрочный экспериментариум переносимых
|
||||
полных профилей для разных совместимых записей. Overload на 4090 допускается
|
||||
как явно измеренный результат и не блокирует экспериментальную упаковку.
|
||||
Functional readiness, качество и real-time qualification на конкретной связке
|
||||
profile/config/hardware/source/transport фиксируются раздельно. Перенос на борт
|
||||
может убрать внешнюю сеть, но не отменяет decode, IPC, queues и compute.
|
||||
Это уточнение заменяет прежнюю зависимость «обязательно performance PASS до
|
||||
развития этапа 2»; gates и запрет actuation при этом не ослаблены.
|
||||
|
||||
### Что изменено и проверено
|
||||
|
||||
- `pilot_ddrnet_runtime.py`: host/CUDA-event timing отдельно для H2D, model,
|
||||
sigmoid, layout, argmax и D2H. Измерение модельного GPU-интервала не является
|
||||
profiler-доказательством compute saturation: в нём возможны scheduling gaps.
|
||||
- Исследованы перестановка scores перед argmax и локальный CUDA Graph capture
|
||||
фиксированного FP32 DDRNet. Sigmoid сохранён: его saturated ties могут сделать
|
||||
`argmax(logits)` неэквивалентным исходной модели. Реальная GPU tie-проверка и
|
||||
все 128 mask hashes у обоих вариантов совпали с reference.
|
||||
- `pilot_scheduler.py`: один GPU thread исполняет DDRNet → RF-DETR строго
|
||||
последовательно, CPU association/surface/motion/TGS/policy обрабатывает
|
||||
предыдущий кадр в исходном порядке. Второго профиля и GPU concurrency нет.
|
||||
- Очередь завершённых GPU результатов и ingress делят **два pending места**;
|
||||
output slot резервируется до следующего GPU вызова, поэтому скрытого
|
||||
«третьего готового кадра в заблокированном put» нет. Активные входные payloads
|
||||
остаются в общем 16 MiB учёте до окончания CPU; Docker ограничен 8 GiB.
|
||||
- Backlog growth в последней версии учитывает ожидание и ingress, и GPU→CPU.
|
||||
Старые raw reports не переписаны. Запись не замедлялась, кадры не прореживались,
|
||||
веса, FP32 DDRNet, RF-DETR engine и алгоритмические пороги не изменены.
|
||||
|
||||
### Все семь прогонов, включая отрицательные
|
||||
|
||||
Одна исходная запись, первые 128 camera frames, original host-arrival clock 1×,
|
||||
12.685 s camera window, те же raw points/pose/calibration и локальный collector.
|
||||
Прогоны последовательные, короткие, не рандомизированные: это инженерный
|
||||
эксперимент, не статистически завершённая performance qualification.
|
||||
|
||||
| Run | Results / 128 | Drops | Mean source→collector | p95 | p99 | Mean ingress wait |
|
||||
| --- | --- | --- | --- | --- | --- | --- |
|
||||
| reference-128, serial eager | 128 | 0 | 93.75 ms | 157.82 ms | 189.69 ms | 13.65 ms |
|
||||
| channels-last-128, serial eager | 128 | 0 | 87.68 ms | 190.56 ms | 203.23 ms | 11.95 ms |
|
||||
| cuda-graph-128, serial | 128 | 0 | 93.38 ms | 175.32 ms | 213.41 ms | 15.22 ms |
|
||||
| overlap-cpu-128, fixed 1+1 slots | 127 | 1 | 79.57 ms | 121.21 ms | 131.42 ms | 4.74 ms |
|
||||
| overlap-shared-128, shared 2 slots | 128 | 0 | 81.30 ms | 143.32 ms | 198.22 ms | 7.20 ms |
|
||||
| serial-repeat-128 | 128 | 0 | 105.08 ms | 232.29 ms | 256.86 ms | 25.48 ms |
|
||||
| overlap-shared-repeat-128 | 128 | 0 | 83.54 ms | 153.44 ms | 194.25 ms | 8.31 ms |
|
||||
|
||||
Вывод: layout и CUDA Graph не дали устойчивого whole-graph выигрыша; defaults
|
||||
не изменены. Fixed-slot p95 ≤125 ms нельзя выдавать за успех — он потерял кадр
|
||||
и провалил p99. Shared-budget overlap перспективен по очереди/средней задержке,
|
||||
но его p99 хуже первого serial reference и лучше serial repeat. Поэтому нет
|
||||
утверждения о гарантированном ускорении tails. Все варианты пока — явные flags
|
||||
диагностического стенда; default остаётся serial/eager/reference.
|
||||
|
||||
У обоих shared-budget runs все 128 масок, source lineage, proposals,
|
||||
метрические observations, tracks, threats, costmap states/materials и TGS counts
|
||||
без `algorithm_ms` совпали с reference. Runtime age и соответствующая policy
|
||||
естественно различаются и не исключаются из safety guard. В повторе 16 stale
|
||||
scenes; ни одной с ALLOW. Все actuation/commands=false. Это output parity на
|
||||
данном окне, не quality/accuracy acceptance.
|
||||
|
||||
Последний повтор: fresh cloud/pose 75/128, 398 metric observations; preroll и
|
||||
layered freshness остаются открыты. Warmup 11.34 s, первый result 549.58 ms
|
||||
от начала bounded preroll, stop 4.07 s; source-release max 8.72 ms. Pending
|
||||
peak 2, input payload peak 5,202,376 bytes, residual bytes/slots 0; backlog
|
||||
growth 0.224 ms. Sampled VRAM peak 1932 MiB; GPU utilization mean 34.88%,
|
||||
max 83%; cgroup memory peak 6410.07 MiB (не только Python heap).
|
||||
Таким образом, **«менее 5% загрузки GPU» не подтверждено**: доля VRAM и
|
||||
GPU utilization — разные метрики. Исчерпание 24 GiB тоже не наблюдалось.
|
||||
|
||||
### Evidence и эксплуатационное состояние
|
||||
|
||||
Raw reports/scenes/logs, точные команды, SHA и пять code snapshots сохранены
|
||||
в `.runtime/perception-latency-20260902T0020MSK/manifest.json`; копия evidence
|
||||
на Worker: `D:/NDC_MISSIONCORE/runtime/experiments/perception-latency-20260902T0020MSK`.
|
||||
Domain-code assets и model pins прежние; snapshots отражают именно версию
|
||||
probe каждого прогона. Никакие raw reports не заменены «лучшими» результатами.
|
||||
|
||||
| Артефакт | SHA-256 |
|
||||
| --- | --- |
|
||||
| reference-128/report.json | `50ed0cb20ecafda6b011f4658a01629816fbd10b11a63f90196ea700738bf2b6` |
|
||||
| overlap-shared-128/report.json | `76c9309fe6ef2281798b81c40e4f5c97b6289f9babe76f917db3f6bc3d7ffe7e` |
|
||||
| serial-repeat-128/report.json | `28f0af8dec12db63de5142637d92245e31fac9389f16b9e845e68a8da1ee5acd` |
|
||||
| overlap-shared-repeat-128/report.json | `e7fea02198c816f82e7f2a54d81ed0f1467867fb84bf5fe3252f06e9905cec2e` |
|
||||
| overlap-shared-repeat-128/scenes.jsonl | `87b9a14091b37337a2a0df5f80b56b7ea3ec52fc4e0d369d88e77afe45a2dc10` |
|
||||
| shared-budget-v2-code.tar.gz | `be7058b92352064580bca832e0db2f76c99485ad2f97e28cc4fa894dbf196860` |
|
||||
|
||||
91 focused tests PASS: 12 pilot, 52 contract, 27 existing live-ingress/
|
||||
synchronizer/shadow. Ruff PASS, child lint с Python 3.9 target PASS. Mac не
|
||||
выполнял модельной нагрузки. Full frontend/backend suite, другие маршруты,
|
||||
network benchmark, physical-live и actuation в этих пробах не проверены.
|
||||
|
||||
Временный pilot-контейнер удалён штатно `--rm`. Три временно остановленных
|
||||
Mission Core контейнера восстановлены; Triton ready=200, canonical Mac 8000=200.
|
||||
Frigate/Ollama по решению владельца остаются exited/restart=no; reboot не
|
||||
выполнялся. Продуктовые defaults, registry и backend/frontend не переключены.
|
||||
Standalone image и приложение↔Worker transport всё ещё не реализованы этим
|
||||
стендом. Следующая работа — preroll/layered freshness, общий runtime с
|
||||
измеряемыми очередями и реальный binary data plane; performance FAIL на 4090
|
||||
не повод выбросить профиль или остановить развитие экспериментариума.
|
||||
Reference in New Issue
Block a user