Архітектура та проєктування репозиторію
Ця сторінка призначена для розробників, яким необхідно зрозуміти, як структурована бібліотека, де розташовані основні компоненти та як розширити структуру, не порушуючи її модульність і контракти середовища виконання.
Фреймворк проти середовища
Слово «Neat» використовується для позначення двох пов’язаних, але різних аспектів:
- Neat Library: бібліотека C++/Python і середовище виконання, що міститься в цьому репозиторії. Вона завантажує модель. створює пакети, формує конвеєри, перевіряє контракти, працює на апаратному забезпеченні Modalix і надає доступ до публічного API.
- Neat SDK / середовище: контейнеризований процес розробки, що охоплює роботу з фреймворком. зокрема, DevKit Sync, спільні робочі простори та інструменти для агентів.
Під час внесення змін до цього репозиторію оптимізуйте його для властивостей фреймворку, які підтримують як людей, так і агентів: чіткі API, детермінована поведінка, структуровані засоби діагностики, сувора перевірка та стабільні публічні контр акти.
Для чого призначена ця бібліотека?
Основні користувачі
Розробники, які бажають:
- Створюйте конвеєри з використанням повторно використовуваних складових (без написання стандартного коду GStreamer).
- Забезпечте перевірку конвеєрів на ранніх етапах (з урахуванням вимог безперервної інтеграції) та швидко аналізуйте причини збоїв.
- Запускайте конвеєри та обробляйте кадри мовою C++ за допомогою
appsink. - За бажанням, можна передавати дані конвеєра через RTSP (за допомогою
gst-rtsp-server). - Надавайте код машинного навчання через вихідні дані, оптимізовані для тензорів, без необхідності писати складний код для GStreamer.
Права власності на пакет
Обраний основний артефакт є джерелом істини для пакетів Neat, LLiMa та Internal Debian, які встановлюються разом. Основний модуль використовує та передає цей артефакт без вибору або переписування версій залежностей. Пакет, що знаходиться поза межами артефакту, залишається у власності платформи; у разі виникнення несумісності платформу слід оновити, а не ремонтувати за допомогою основного модуля або LLiMa.
Типові робочі процеси
- Декодування/обробка: файл або RTSP -> демультиплексування/розбір -> декодування -> перетворення/налаштування параметрів -> appsink -> споживач, написаний на C++
- Перевірка: збірка + аналіз + попередня обробка (У СТАНІ ПАУЗИ), щоб на ранніх етапах виявити проблеми, пов’язані з узгодженням.
- Надання RTSP: передавайте синтезовані кадри в конвеєр RTSP-сервера, використовуючи
appsrc. - Адаптер тензорів зображень/відео: зображення/відео/RTSP -> декодування -> перетворення/масштабування ->
add_output_tensor(...)->Run::pull_tensors(). - Навчальні матеріали: почніть з Навчальні матеріали, щоб отримати доступ до структурованого навчального курсу, який можна використовувати на практиці.
Стандартизований виробничий конвеєр (джерело істини).
Канонічний «шлях для виробничого середовища» для цього репозиторію такий:
вхідні дані -> попередня обробка -> MLA -> постобробка. Джерело істини знаходиться тут:
tests/e2e_pipelines/obj_detection/sync_yolov8_test.cpp.
Коли цей тест змінюється, оновіть файл README та розділ «Архітектура», щоб забезпечити узгодженість документації.
Концептуальна модель (бізнес-логіка ↔ сполучна ланка конвеєра)
Ваша програма зберігає бізнес-логіку, а фреймворк забезпечує зв’язок між елементами конвеєра.
Business logic
|
v
Nodes/Graph fragments -> GStreamer fragments -> caps negotiation -> runtime (Run)
| |
+-----------------------------------------------------------+
Sample / Tensor
Основні поняття
Ця структура навмисно організована навколо невеликої кількості ключових понять. Більшість коду, який пише користувач, стосується лише Model, Graph, Run, Tensor та Sample; розробники, що працюють на нижчому рівні, також працюють з Node, повторно використовуваними фрагментами графа, аналізом MPK-контрактів і внутрішньою структурою графа.
| Концепція | Роль |
|---|---|
| Архів моделі | Запакований у формат .tar.gz артефакт, що містить контракт для виконання MPK, конфігурації, призначені лише для плагінів, бінарні файли моделі та артефакти ядра. |
Model | Публічний завантажувач для архіву моделі у ф орматі .tar.gz. Він аналізує контракт MPK, виконує планування маршруту, надає доступ до етапів моделі та забезпечує прості точки входу для виконання run(...) / Graph. |
Tensor | Введений числовий блок даних із зазначенням типу даних, розмірності, структури, способу зберігання, пристрою та семантичних метаданих. |
Sample | Оболонка для даних, що використовуються під час виконання, навколо тензорів, списків тензорів або наборів. Перевірте Sample::kind перед читанням полів. |
Node | Атомарна стадія конвеєра, яка генерує детермінований фрагмент GStreamer і повертає імена відповідних елементів. |
| Фрагмент графа, який можна повторно використовувати. | Готовий Graph, який розширюється до кількох вузлів, наприклад, декодованого вхідного потоку RTSP або етапів моделі. |
Graph | Межа збірки та перевірки. Вузли, моделі та фрагменти графа, які можна повторно використовувати, стають узгодженим, структурованим конвеєром. |
Run | Активний об’єкт конвеєра, який повертається функцією Graph::build(...); він відповідає за життєвий цикл операцій над даними (завантаження/вивантаження/середовище виконання). |
| Граф | Використовуйте граф для побудови DAG (направленого ациклічного графа) всередині одного конвеєра; використовуйте граф середовища виконання для координації етапів/виконань між різними конвеєрами. |
Читайте зв’язки зліва направо:
model archive on disk -> Model -> Graph fragments/Nodes -> Graph -> Run
|
v
Tensor/Sample flow
Model є початковою точкою для користувачів-початківців, але це не окремий модуль виконання. Він використовується для створення фрагментів/вузлів графа, які можна додавати до Graph. Graph є центральною концепцією для збирання; Run – це активний об’єкт після створення.
Принципи дизайну для авторів
Це основні принципи архітектури, що забезпечують надійність роботи фреймворку. Використовуйте їх, коли обираєте між різними варіантами реалізації.
- Детермінованість перемагає. Зберігайте назви елементів, згенеровані рядки для конвеєра, серіалізовані дані конвеєра. поля звіту та результати тестування мають бути відтворюваними. Діагностика та цикли роботи агента залежать від стабільних ідентифікаторів.
- Зручність налагодження є пріоритетною. У разі виникнення помилок мають генеруватися структуровані дані, а не лише текстові рядки:
GraphReport.error_code,repro_note, повідомлення шини та конвеєри бекенду, які можна повторно запускати. - Не використовуйте непомітний механізм резервного копіювання. Не приховуйте помилки вхідних даних моделі або збої апаратного забезпечення/середовища виконання, просто мовчки ігноруючи їх. перетворення форматів, зміна сімейств графів, перехід на використання центрального процесора або обробка помилок плагінів.
- Здійснюйте перевірку перед запуском. Віддавайте перевагу структурній перевірці, перевірці великих літер, форми та відповідності вимогам перед початком роботи в середовищі виконання. починаються потоки або виділяються апаратні ресурси.
- Контракт MPK є еталонним джерелом істини. Основні функції: маршрутизація, тип даних, форма, квантування та
рішення щодо кожного етапу мають надходити з файлів
mpk.json/*_mpk.json. Файли JSON для кожного етапу є приватною власністю плагіна. - Логічний ранг і геометрія, що використовується під час виконання, є окремими поняттями. Основний модуль зберігає дані, створені MPK.
frame_shapeвикористовується як логічний контракт вихідних даних і, за потреби, генерує чітку геометрію MLA. Об’єкт 2-го рангу приймається як NC або HW лише тоді, коли оголошені діапазони байтів ідентифікують єдину інтерпретацію; неоднозначні або суперечливі кон тракти призводять до помилок під час завантаження моделі. - Публічні API залишаються стабільними. Публічні заголовні файли, що містяться в
include/*, встановлюються та підтримуються. Віддавайте перевагу поступовим змінам і механізмам відмови від застарілих функцій, а не різким змінам у структурі. - Паралельність має бути обмеженою та відстежуваною. Робота в потоці даних має бути легкою; діагностика на стороні зонда потребує використання атомарних операцій або еквівалентних механізмів безпечної обробки в багатопотоковому середовищі; завершення процесу не повинно призводити до зависання.
Шлях виконання моделі.
Для конвеєрів, що базуються на моделях, загальна схема така:
input Sample/Tensor
-> optional preprocessing / format normalization
-> MLA inference stages selected from MPK contract
-> optional postprocessing / box decode
-> output Sample/Tensor
Видима для користувача угода Model навмисно простіша, ніж апаратна угода MLA.
MLA може вимагати використання INT8/BF16 і тесельованих макетів, тоді як код користувача зазвичай працює з FP32 і звичайними макетами тензорів. Фреймворк усуває цю різницю за допомогою адаптерних етапів, керованих маніфестом.
Попередня та остаточна обробка є чіткими етапами/параметрами фреймворку. Несумісність форматів, відсутність необхідних метаданих для попередньої обробки, недоступний диспетчер MLA, недійсний архів моделі або угода MPK, або невдала угода щодо обмежень повинні відображатися як структурована помилка, з якою можна працювати, а не як прихована корекція в середовищі виконання.
Структура репозиторію.
Структура високого рівня.
include/– загальнодоступні заголовкові файли (підтримуваний інтерфейс API).src/– реалізації.docs/– документація (цей файл)examples/– невеликі приклади, які можна запустити.tests/– модульні/інтеграційні тести.python/– вихідні коди пакетаpyneat, прив’язки nanobind і тести для Python.old_*— знімки застарілої монолітної реалізації, що зберігаються для довідки/переходу на нову систему.
Відкрите дерево заголовкових файлів (include/).
Загальнодоступні заголовкові файли розміщуються в include/<module>/....
Приклади: include/pipeline/Graph.h, include/model/Model.h.
Загальнодоступні заголовкові файли, що містять корисні функції:
include/neat.h(парасолька)include/neat/runtime.hinclude/neat/models.hinclude/neat/nodes.hinclude/neat/node_groups.h
Навмисно не передбачено загальнодоступного include/neat/graph.h заголовного файлу. Тести середовища виконання/компілятора, які потребують базової структури графа нижчого рівня, повинні безпосередньо використовувати вузький набір include/graph/... заголовних файлів. Програми, приклади та загальнодоступна документація повинні використовувати єдиний загальнодоступний simaai::neat::Graph з <neat.h>.
Внутрішні заголовки та шляхи до плагінів середовища виконання.
Публічні заголовкові файли, що розміщені в include/, встановлюються та розглядаються як стабільний API.
Внутрішні заголовкові файли, що розміщені в src/**/internal, не встановлюються; у прикладах/навчальних матеріалах слід використовувати лише публічний API.
Примітки щодо середовища виконання:
- Якщо ви використовуєте вбудовані плагіни GStreamer у
deps/gst-plugins, встановіть.GST_PLUGIN_PATHта/абоGST_PLUGIN_PATH_1_0, щоб додати цю директорію. - Якщо встановлено за допомогою
cmake --install, плагіни розміщуються в каталозі:${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/sima-neat/gst-plugins. Додайте цей шлях доGST_PLUGIN_PATHта/абоGST_PLUGIN_PATH_1_0. - Використовуйте
scripts/use_neatdecoder.sh, щоб задати шляхи до плагінів для поточної оболонки. - Якщо встановлюєте плагіни для всієї системи, перезберіть кеш GStreamer.
Запланований vs. стабільний (інтерфейс API)
| Площа / API | Статус | Примітки |
|---|---|---|
Основний API конвеєра (Graph, Run, Tensor, Sample) | Стабільний | Основна підтримувана поверхня C++. |
Внутрішні компоненти конструктора (Node, приватні допоміжні функції для роботи з векторними вузлами, GraphPrinter). | Внутрішній | Підтримка лише формату STL, попереднє компонування перед використанням GStreamer. |
API моделі (Model, фрагменти графа, які можна повторно використовувати) | Стабільний | Стандартний шлях інтеграції з архівом моделей. |
include/policy/* | Стабільний | Мінімальні перевірені контракти та налаштування політики за замовчуванням (Decoder, Encoder, Memory, RTSP). |
include/nodes/groups/ImageToH264RtspGroup.h | Заплановано | Порожня група-заповнювач. |
Зв’язки для Python (python/, pyneat) | Бета | З в’язування та пакування на основі Nanobind розміщуються безпосередньо в репозиторії; API зосереджується на Tensor, Graph/Run, Model та основних допоміжних функціях для вузлів/груп. |
Модулі та сфери відповідальності
builder/ — підтримка контрактів для вузлів і приватної лінійної композиції (без використання GStreamer).
Мета: Визначити, як конвеєри склада ються з логічних частин.
Основні типи:
Node– інтерфейс, реалізований кожною складовою конвеєра.- приватні допоміжні функції для роботи з векторами вузлів і
GraphPrinter— утиліти для створення композицій і засоби діагностики.
Правило: засіб створення має переважно використовувати лише STL. Він не повинен містити об’єкти середовища виконання GStreamer.
nodes/ – типові складові конвеєра.
Мета: Надати готові до використання реалізації Node, які генерують детерміновані фрагменти GStreamer.
Приклади:
nodes/io/HttpSource,nodes/io/RTSPInput,nodes/io/StillImageInputnodes/common/*(вхідні, черга, вихід тощо).nodes/sima/*(вузли для розкодування/кодування/аналізу/обробки платежів від SiMa.ai)nodes/rtp/*(вспомігальні функції для дешифрування/обробки корисного навантаження)nodes/groups/*(поширені рецепти для багатокомпонентних систем)
Контракт: Кожен вузол повинен забезпечувати:
backend_fragment(index)— фрагмент GStreamer для цього вузла за вказаним індексом.element_names(index)– детерміновані імена елементів, що належать цьому вузлу (для діагностики та забезпечення відповідності).
gst/ — набір невеликих утиліт GStreamer.
Призначення: Невеликі обгортки/допоміжні функції для типових шаблонів GStreamer.
Приклади:
- ініціалізація (
GstInit) - аналіз рядків для запуску (
GstParseLaunch) - розпакування/перетворення даних у рядок для шини (
GstBusWatch) - допоміжні функції для обробки великих літер / інтроспекція елементів (
GstHelpers,GstIntrospection) - тачпади / допоміжні інструменти для зондування (
GstPadTap)
Правило: gst/ не повинен залежати від pipeline/ (щоб уникнути циклічних залежностей і надмірного розростання «службового шару»).
pipeline/ – оркестрація середовища виконання та публічний API.
Мета: Керування повним життєвим циклом середовища виконання: створення -> аналіз -> запуск -> використання -> завершення, з можливістю діагностики.
Основні типи:
Graph— основна точка входу для користувачів.Run– обробник запущеного конвеєра з використанням API для надсилання та отримання даних.Sample— структурований блок даних, що повертається у відповідь на запити.GraphReport– структурована діагностика збоїв, зупинок і відтворення.Errors— винятки (NeatError), що містять звіт.
Семантика обробки помилок.
GraphReport.error_code — це стандартне поле для автоматизованої класифікації помилок. Структура середовища виконання/збірки/вхідних/вихідних шляхів відображає критичні помилки на стабільні групи коду:
misconfig.pipeline_shapemisconfig.capsmisconfig.input_shapemisconfig.input_capacitymisconfig.media_capsmisconfig.tensor_dtype_missingmisconfig.option_out_of_rangebuild.parse_launchbuild.pipeline_syntaxbuild.plugin_missingbuild.property_invalidruntime.pullruntime.element_failedruntime.output_timeoutio.parseio.openio.file_not_foundio.permission_deniedio.rtsp_connection_failedio.camera_not_foundcodec.*,resource.*,infra.*таinternal.*.
Помилки GStreamer проходять через один внутрішній парсе р, класифікатор і модуль рендерингу.
Класифікація віддає перевагу версіонованому ідентифікатору діагностики Neat, потім нативній області/коду GStreamer і фабриці елементів, а потім використовує більш вузькі відображення сумісності для старих плагінів. У разі невідомих помилок використовується runtime.element_failed; вони не повідомляються як misconfig.media_caps, якщо переговори фактично не завершилися невдало. Коли конвеєр генерує кілька помилок, відображається найбільш конкретна основна причина, і кожна помилка зберігається в журналі.
GraphReport.repro_note – це зведена інформація, призначена для користувача. Продуктивний рендеринг містить причину, виражену простою мовою, відповідні спостережувані/очікувані значення, конкретні дії користувача та стабільний ідентифікатор діагностики. Необроблені рядки плагінів, розташування джерел і область/код GStreamer призначені лише для налагодження. Закладений загальнодоступний код додається один раз під час створення NeatError.
GraphReport.bus є джерелом істини для деталей помилок плагінів/середовища виконання.
Для процесів build(input), GraphReport.build_adaptation фіксує вирішену політику/можливість форми, джерела для початкових/максимальних обмежень, джерело захисту байтів і застосовані/пропущені дії адаптації.
Для процесів отримання даних у середовищі виконання, які не викликають виключень, PullError.code використовує ту саму таксономію. Помилки робочого процесу вхідного потоку зберігають типізований код помилки та передають його через межу робочого потоку, тому Run::pull() і перекладач винятків Python відображають одну й ту саму NeatError.
Порядок пріоритетів підтримки:
- відро за
error_code - прочитайте
repro_note - спочатку перевірте наявність помилок у першому терміналі
bus. - відтворити з використанням
repro_gst_launch
Внутрішня діагностика конвеєра.
У рамках src/pipeline/internal/ (лише для внутрішнього використання):
Diagnostics.h– спільні типи діагностичних даних, що використовуються в середовищі виконання:DiagCtx(журнал шини + звіти вузлів + лічильники меж/елементів)BoundaryFlowCounters(атомарні лічильники, значення яких оновлюються з потоків даних).ElementTimingCounters(атомарний облік часу обчислень для кожного елемента)ElementFlowCounters(атомарна статистика потоку для кожного елемента)
GstDiagnosticsUtil.h— допоміжні функції для форматування та збору даних діагностики GStreamer.
Контракт щодо статичного контексту маніфесту SIMA.
Для конвеєрів моделей статичні дані про контракт для етапів/тензорів створюються у фреймворку та передаються як GstContext на рівні конвеєра:
- Тип контексту:
sima.model.manifest.v1 - Поля контексту:
manifest_versionmanifest_json(пакет даних для забезпечення сумісності зі старими версіями)manifest_accessor_v1(вказівник на таблицю доступу, сумісну з ABI)- необов’язковий
session_id,model_id
- Визначення прав власності/терміну дії пов’язане з терміном дії конвеєра; плагіни використовують покажчики та копіюють дані. їм це потрібно.
- Межа репозиторію: цей репозиторій не повинен додавати залежності, які виникають під час збірки, від репозиторіїв плагінів/диспетчерів.
Інтеграція здійснюється лише через інтерфейс (середовище виконання
GstContext, властивості, обмеження/метадані та контракти C-ABI).
Пріоритетність вирішення для перенесених полів є детермінованою:
- визначати на основі сигналу контракту/середовища виконання (форма/метадані/можливості)
- шлях до властивості в контексті/за замовчуванням
- критична помилка шини (ніколи не призводить до аварійного завершення/SIGSEGV)
StageTransformRuleRegistry (внутрішній) — це єдина таблиця відповідностей, яка визначає, які
не-MLA етапи успадковують контракти тензорів від вхідних даних MLA порівн яно з вихідними даними MLA, і коли відбувається поширення квантування вихідних даних. Це забезпечує чітке та перевіряєме визначення попередніх/подальших етапів обробки.
Для мігрованих плагінів SIMA, що використовують шаблон-агрегатор, конфігурація середовища виконання тепер базується на розв’язанні, що керується контекстом/властивостями:
- статичні поля на етапі збірки отримуються з контексту маніфесту.
- налаштування для середовища виконання беруться зі значень за замовчуванням, визначених у властивостях/контексті.
- якщо обов’язкові поля не заповнено, виникає явна помилка (у фреймворку не передбачено резервного варіанту у форматі JSON).
Для simaaiprocesscvu, схема з’єднань, отриманої з CM, спочатку визначає структуру, а sink_pad_tensor_index_map використовується для детермінованого відображення з багатьох входів; застарілі імена буферів вхідних даних використовуються лише як резервні.
Якщо вказано, logical_stage_id визначається на основі властивостей конвеєра stage-id/stage_id; в іншому випадку використовується назва елемента.
Конструктори фрагментів ш ляху моделі SIMA встановлюють stage-id для елементів simaaiprocesscvu, simaaiprocessmla та simaaiboxdecode за замовчуванням.
Клас YOLO26 BoxDecode, кількість контрактів.
Для моделей YOLO26, які використовують керування на основі моделі для виявлення об’єктів, визначення поз і сегментації, глибина класу MPK є авторитетним показником кількості класів. Model::Options::num_classes = 0 обирає це обчислене значення. Додатне значення має відповідати йому; у разі розбіжності виникає помилка під час створення контракту, і відображається налаштоване значення, значення, отримане з MPK, і тип декодування. Це запобігає використанню недійсної кількості класів для інтерпретації згрупованого макета необроблених даних. Моделі SSD і попередні версії YOLO26, які не використовують визначення поз, зберігають свою існуючу поведінку з явним перевизначенням, тоді як декодери для визначення поз і SuperPoint зберігають свої правила, специфічні для кожної родини моделей.
Контракт SuperPoint BoxDecode.
SuperPoint використовує ту саму межу між MPK і статичним маніфестом, що й інші родини BoxDecode, якими керує модель, з наступними додатковими інваріантами:
- Запис MPK містить ідентифікатори тензорів детектор-логітів і дескриптор-сітки, а також інформацію про зберігання. представлення, факти щодо типу даних/розміру, інформація про чисельний профіль, а також необов’язкові явні параметри NMS та параметри контролю меж. Основний модуль ніколи не визначає ці ролі на основі значень тензора.
- Основний модуль пов’язує рівно один тензор з кожною роллю, перевіряє відбиток профілю та підтримувані
представлення, застосовує явні
Model::Options::superpointперевантаження та обробляє лише пропущені значення за замовчуванням профілю. Зміна профілю повторно обчислює похідні значення за замовчуванням, зберігаючи при цьому параметри, які були явно визначені в MPK або API. - Версія статичного маніфесту ABI передає розв’язаний контракт до
simaaiboxdecode. Плагіни. під час налаштування слід використовувати лише тимчасові вказівники на маніфест, і необхідно скопіювати будь-які необхідні дані для подальшого використання в середовищі виконання; Основний модуль зберігає право власності на маніфест протягом усього часу роботи конвеєра. - Вихідні дані виробництва використовують дротяний формат
FEATURE_POINTS_V1і містять семантичні метадані.FEATURE_POINTS_LEGACY_A65_V0доступний лише за умови явного вибору для забезпечення сумісності; користувачі не повинні визначати формат на основі розміру буфера.
contracts/ – правила перевірки.
Мета: Забезпечити кодування інформації про те, як має виглядати «правильно налаштований конвеєр», а не лише підтвердження успішного виконання функції «gst_parse_launch».