docs(observatory): record realtime plan and measured latency evidence
This commit is contained in:
@@ -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