儲存庫架構與設計
本頁面是為貢獻者提供的,他們需要了解函式庫的結構、責任歸屬,以及如何在不破壞其模組和執行階段合約的情況下擴展框架。
已編譯的 Scheduler 邊界
Core 使用 SimaScheduler::frontend 與獨立擁有的 simaai::scheduler::client 型別。
數值建構、檢視、動態選擇、已停止圖的附接、所選記憶體存取與視訊佈局查詢都跨越此
已編譯邊界。Core 不開啟 Runner 工作階段,也不包含 Kernels 或 Codecs 實作介面。
flowchart LR
Core[Core graph and application policy] --> Scheduler[Scheduler client and GStreamer]
Scheduler --> Runner[Runner execution and memory authority]
Runner --> Kernels[Kernels numerical providers]
Scheduler --> Codecs[Codecs providers]
GenAI[Core GenAI API] --> LLiMa[LLiMa generation runtime]
Benchmark[Core benchmark reports] --> Sentinel[Optional Sentinel telemetry]
Model 與獨立的 Resize 共用僅含值的 ResizeInterpolation 列舉及單一取樣器權杖對應。Model 規劃會先解析可選的型別設定,再處理圖像意圖、階段投影與圖形來源資訊;既有字串僅保留在相容性邊界。
模型與獨立影像選項會轉換為相同的一般 Preproc 請求。固定來源運算保留原始 FP32 數值縮放、尺寸縮放後的平均值/除數,以及量化步長的運算邊界;它不是任意順序的轉換解譯器。輸入 dtype、量化及實體佈局仍由 MPK 決定。新選項需明確啟用,省略時保留舊版位元組。Core 只投影意圖與幾何資訊;數值檢查及執行由 Kernels 負責。
Kernels 仍是操作目錄與數值准入的權威來源。Scheduler 透過 Runner 轉送一般化要求; Scheduler 與 Core 都不維護韌體 ID 或逐操作派送表。Core 保留公開節點 API、幾何原則 與線路格式處理。Scheduler 在套件組驗證後具體化新的轉接器/解析器工廠。 快取的動態選擇保留其操作,但會綁定目前影格的記憶體。
GenAI 直接呼叫 LLiMa,不經過 Runner 或 Scheduler GenAI 配接器。MLA 剖析是獨立且預設停用的流程:Core 呼叫 Scheduler 的用戶端,由 Runner 執行已安裝的 mla-rt 命令列工具。它需要沒有其他 MLA 工作的閒置 DevKit。
GStreamer 介面擁有權
Scheduler 擁有 GStreamer 傳輸與結構化錯誤介面,包括已安裝的
gst/SimaaiGstErrors.h 標頭。Core 使用這些介面,不保留第二套實作。
Core 0.6.0 包含此檔案擁有權移轉。請一併升級相符的 Core/Scheduler
套件組;此套件版本不會變更平台或數值契約。
框架與環境
「Neat」一詞用於描述兩個相關但獨立的概念:
- Neat Library: 本儲存庫中的 C++/Python 函式庫和執行階段。它載入模型套件、組成管線、驗證合約、在 Modalix 硬體上執行,並公開 API。
- Palette SDK / 環境: 圍繞框架的容器化開發工作流程,包括 DevKit Sync、共享工作區和代理工具。
在修改此儲存庫時,請針對支援人和代理的框架屬性進行最佳化:明確的 API、確定性行為、結構化的診斷、嚴格的驗證和穩定的公共合約。
本函式庫的用途
主要使用者
希望:
- 從可重複使用的建置模塊中組裝管線(無需編寫原始 GStreamer 程式碼)
- 儘早驗證管線(適合 CI),並快速了解失敗原因
- 透過
appsink在 C++ 中執行管線並消費幀 - 可選擇透過 RTSP 提供管線(透過
gst-rtsp-server) - 透過適合張量的輸出提供機器學習程式碼,而無需編寫 GStreamer 程式碼
套件所有權
所選 Core 成品是一起安裝的 Core、LLiMa 與相符 Scheduler 相依套件的權威來源。Core 轉送完整相依集合,不重新選擇或改寫相依版本。成品以外的套件仍由平台擁有;平台不相容時應更新平台,而非透過 Core 或 LLiMa 修補。
Core 使用已安裝的 SimaScheduler 客戶端元件,而非下層 CMake 開發介面。
Scheduler 相依協調器驗證所選 Kernels/Runner/Codecs 集合,並保留其確切來源資訊。
僅含中繼資料的 SimaRuntime 相容性別名不擁有另一套實作。
建置入口仍依 Kernels → Runner → Scheduler → Core 順序,準備同層來源或重用明確
選定的套件。這協調的是建置,不是執行階段執行或韌體啟用。
請參閱本機相依建置。
繪製器與選用後端提供者
Core 擁有方框/遮罩發布原則。既有軸對齊 BBOX 酬載使用 int32 座標;獨立的 BBOX_OBB_V1 旋轉框格式保留 FP32 幾何資料,軸對齊繪製器會拒絕此格式。Scheduler 擁有 caps、生命週期與
準備階段的提供者准入。正式組合需要繪製器的具型別 int32 能力,不會將這些值重新
解讀成浮點數,或加入逐影格轉換。Kernels 擁有標準 A65 render 操作;Runner 擁有
執行與 ReadWrite 影像安全釋放。Scheduler 記錄已檢查的操作與使用的 Kernels/Runner
身分。Core 驗證此套件組並組合一般相依項目,不使用 a65apps 封存 檔。
Runner 將平台擁有的提供者與可再散布的相依項目分開記錄。Core 保留該憑證並檢查已安裝的平台;不從平台建置編號推斷相容性,也不把平台 DSO 納入消費端套件。提供者准入與組合方式請參閱本機相依項目。
執行階段傳輸擁有權
Core 使用已安裝的 SimaScheduler 套件。SimaScheduler::elements 擁有
neatcamerabridge、neatmultipartjpegdemux 與 neatlatestbystreammux,
包括其 GObject 型別與程序內註冊。Core 的 src/gst/ 入口是相容性轉送器,
不是第二套實作。這些元件不使用數值執行器,也不需要 Kernels。
Core 保留公開 C++/Python API、Node 選項、圖降階、Sample/Tensor 物件與圖私用額度。
src/pipeline/gst/RealtimeMuxCredits.cpp 透過 Scheduler 僅含值的借用介面投影這些
額度。多工器借用登錄與共用輸入影格計數器只有一個 Scheduler 擁有者。
攝影機 ABI 佈局來自相符的分配器標頭,而非 Core 私用副本。
多工器公平性/反壓、multipart 解析與擷取父物件生命週期的實作測試位於 Scheduler。 Core 保留公開 API、圖額度與端對端裝置測試。建置 Core 前請安裝相符的 Runner 與 Scheduler 套件;Core 內部測試直接連結其傳輸目標。 不要以不含提供者的主機測試宣稱硬體擷取或精簡 TensorBuffer 中繼資料已通過驗證。
新增數值核心
對於可透過既有張量與執行契約表達的操作,開發工作僅屬於 Kernels 與 Core:
- 在 Kernels 中新增操作專用的具型別要求、已檢查計畫、數值實作、執行物件工廠與 具名要求解碼器。在 Kernels 擁有的目錄中註冊一次操作,並新增正確性測試。
- 在 Core 中新增 Node,並將其選項轉為標準要求:操作、明確目標、輸入/輸出規格與 具型別參數。呼叫 Scheduler 的一般化準備 API;不要直接呼叫操作工廠,或在 Runner 或 Scheduler 新增操作分支。
- 依序重新建置/安裝 Kernels → Runner → Scheduler → Core。EV 目錄變更需要 明確組合相符韌體,即使 Runner 來源未變更也一樣。請使用獨占裝置程序驗證。
準備路徑為 Core → Scheduler → Runner → Kernels。Kernels 進行數值驗證; Runner 是一般化入口。準備階段檢查不開啟硬體或佈建執行資源。 請保留傳回的已檢查執行物件,並在准入完整階段前檢視其標準需求。 串流使用相同執行物件,不會再次解碼操作名稱。
動態變體使用在設定時綁定、由核心擁有的選用能力。Core 保留圖/中繼資料原則與 既有有界快取。快取未命中可細化不可變參數;提供者證明是否共用確切張量契約/資源, 或需要完整重新檢查。快取命中不會建立另一個操作,也不保留攝影機/編解碼器影格借用。
Runner 擁有執行、資源、一致性與安全釋放;Scheduler 擁有 Gst 載體、外掛程式與傳輸整合。
標準已安裝套件為 SimaRunner 與 SimaScheduler。僅含中繼資料的 SimaRuntime
相容性套件將歷史目標轉送至相同實作。標頭別名重用標準 Kernels 型別;
靜 態連結相依項目仍可能具有傳遞性。不會建立第二套張量結構描述、分配器、執行佇列或數值登錄。
數值階段產生 neatkernelrunner;沒有切換至已退役 ProcessCVU 外掛程式的選項或後備路徑。Core 擁有的公開輸出封裝仍是相依主機操作,保留原有量測邊界。Codecs 仍是獨立編碼/解碼後端;其 Gst 包裝層屬於 Scheduler,而非 Runner 或數值 Kernels。
建置憑證綁定確切安裝位元組與使用的相依身分,不代表硬體或效能驗證。 不要混用不相符套件的標頭、封存檔、韌體或 Codecs。
新的傳輸、張量表示法或執行能力屬於框架擴充,可能需要變更 Runner。 僅 Kernels/Core 的保證不涵蓋這些變更。逾時或取消絕不能證明 DMA 已安全釋放; 既有分配擁有者必須存活至確定完成,或經驗證的平台復原。
Core 依語意名稱選擇操作,而非韌體圖 ID。Kernels 公開不可變的操作名稱與編譯目標
目錄;Runner 與 Scheduler 轉送該目錄,不維護另一個操作登錄。
Core 擁有具型別圖改寫規則,包括強制的 DetessCast 與 DetessDequant 融合。
若必要融合實作無法使用,準備會失敗,而不是拆成獨立核心。
一個 Core 階段不一定對應一個操作:TrackKLT 仍準備其既有複合要求。
TrackKLT 的公開張量清單依位置排序:前一張影像、目前影像,接著是整數種子點。選用名稱用來確認這些角色,不會重新排序儲存空間。Core 在種子推導之前及佇列接納之前檢查已指定的輸入契約,不映射或複製張量資料。未命名張量仍依位置處理。此政策僅適用於明確指定的直接公開輸入,不適用於內部階段連結或模型輸入轉換。
追蹤器要求負責數值品質控制與選用的殘差發佈。Core 將殘差附加在點、狀態及任何要求的特徵之後,不會將狀態重新解釋為無條件的追蹤信賴度。停用偵測會移除該操作及其輸出配置。Kernels 負責具有版本的原生封包與數值驗證;Runner 和 Scheduler 繼續傳輸並繫結通用的已檢查要求。
直接驅動程式復原
deps/manifest.json 選擇 Scheduler 與 LLiMa。已安裝的 Scheduler 協調器驗證相符的 Kernels、Runner 與 Codecs 完整相依集合;Core 使用已驗證的套件組,不重複實作底層平台檢查。
復原屬於選定的平台,不依賴分派器錯誤比對。推論失敗後,Core 不會啟動 AppComplex、 重新啟動分派器服務或重設遠端處理器。Runtime 透過驅動程式契約回報完成與安全釋放; 無法確認完成不代表允許回收 DMA 儲存空間。平台開機時的 MLA 初始化仍屬平台相依項目。
記憶體擁有權
Core 使用 Scheduler 的配置與映射介面,不使用從中繼資料附加的實體位址、libsimaaimem 或第二套配置登錄。CPU 存取、映射生命週期、匯入記憶體與父批次限制,請參閱記憶體模型。
Core 不會依圖拓撲選擇快取一致性模式。RunAdvancedOptions::prepare_output_cpu_visible 保留以維持選項佈局相容性;真正映射前不會執行重複的提前同步。來源相容的 defer_output_invalidate 選項必須保持 true;false 會被拒絕,而不是恢復產生端的慢速路徑。
非同步 MLA 提交與有序輸出發送使用既有的分開路徑。完成回呼記錄終止狀態; 發送器發布結果而不進行 CPU 快取維護。發送進行時,提交路徑仍可接受後續影格, 但受有界通道容量與獨立分配擁有權限制。僅完成不會歸還准入額度: 已完成槽位仍被擁有,直到發送釋放它。輸出集區借用可能比該釋放更久,繼續阻止儲存空間重用。
此重疊不移除快取維護,也不縮短同一影格內的相依鏈。 它避免將獨立 CPU 與裝置工作表現為序列管線停頓,且無需另一個同步工作執行緒。 圖建構一次設定預算;不需要逐影格、操作專用的排程原則。
以 FrameLayout 規劃記憶體
Core 在每次建置中使用單一規劃流程:
- 選擇模型路由並保留呼叫身分。
- 編譯已檢查配方,每個執行端只解析一次。
- 解析根載體、檢視、使用端與擁有權群組。
- 選擇記憶體堆積,依共用實體 DAG 生命週期證據配置。
- 確定各階段的
FrameLayout與發布資訊,只呈現一次,不再修補放置。
任何 EV74 存取都需要 CMA;自有且僅供 MLA/A65 使用的載體使用 DMS。符合條件的新 A65 公開終端可使用 HostCpu。匯入儲存空間、位移、幾何與產生端借用維持固定。分支納入所有使用端,檢視共用根載體。
AllocationPolicy::PreferDmsThenCma 明確允許符合條件的自有 DMS 配置在容量不足時退回 CMA,不會選擇一般 Linux 記憶體。緩衝池邊界、Queue 邊界、獨立呼叫與保留的輸出限制生命週期重用 。
Scheduler 透過 Runner 準備各佈局的配置群組。索引與位移屬於個別緩衝群組;不同群組中的相同位移不會重疊。請一起重新建置相符的 Core 與 Scheduler 套件。
預設裝置到 CPU 一致性
只有一個已準備記憶體引擎。SIMA_CORE_DEMAND_COHERENCY_V1 與 Runner 的實驗性
建置選項已移除;新建置請勿使用它們。不再有環境啟用開關或整圖 Legacy 降級。
Core 僅使用 Scheduler 分配、映射與階段介面。公開張量幾何、Kernels 要求與數值行為不變。
共用的存取取得與生命週期契約定義於記憶體模型。
映射以 DMA 支援的邏輯張量
公開 Tensor::map() 及其 view() 別名保留既有儲存映射契約:套用一次
byte_offset,並可能公開尾端底層位元組。具名區段邊界與應用程式映射回呼仍是
權威來源。TensorBuffer::map() 仍直接映射儲存空間。
以形狀為界的內部使用端改用 map_dense_tensor_read()。
它依目前幾何檢查正值步幅與溢位,再只公開實體張量範圍,包括步幅間隙。
Core 擁有的 DMA 儲存空間可授權該確切範圍。包裝或自訂回呼保留既有映射與清理行為;
輔助函式先驗證回傳範圍,再縮小邏輯檢視。不會跨可變張量檢視快取幾何。
複合影像與已編碼或未解析幾何維持原有映射路徑;密集邏輯範圍不授權存取其他平面。
Scheduler 可對確切檢視重用 Runner 已驗證、目前世代的可見性。 裝置寫入後的首次讀取、未涵蓋範圍或未驗證匯入仍維持匯出端同步。 運作中的寫入端、待完成裝置工作與隔離狀態仍屬錯誤。 映射同時保留原始 Gst 樣本與目前公開儲存/產生端借用,直到 CPU 存取結束。 不變更擁有權模式、負載複製、WRITE-END 清理或公開物件佈局。
核心階段的 resource_busy 錯誤不一定表示提交容量用盡。
其經清理且有界的 Reason 保留原始存取、登錄、擁有權或容量診斷。
變更並行度前先檢視原因;擁有權或裝置完成仍未確認時,不要重用緩衝區。
編解碼器擁有權
Scheduler 擁有 neatdecoder、neatencoder 及其 GStreamer 適配層。Codecs 擁有解碼器/編碼器工作階段與數值實作。請使用相符的已安裝標頭與函式庫;不要將後端程式碼複製到 Runner,也不要將包裝層與不同的後端 ABI 組合。
硬體編碼器設定
SimaEncode 與原始 VideoSender 從協商的輸入 caps 推導解析度。
解析度在一次執行中維持固定;變更時必須開始新的執行。
編碼器選項不包含寬高,輸入適配器保留可見幾何而不縮放。
在上游輸入提供 尺寸前,未知輸入尺寸在建置時輸出合約中仍維持未知。
SimaEncode 一次準備原始輸入,並將編解碼器專用選項對應至 neatencoder。
Scheduler 擁有 GStreamer 轉接與輸出發布;Codecs 擁有編碼器工作階段。
Runner 保留記憶體擁有權與同步權威。Core 不新增編碼器執行緒。
舊版 H264EncodeSima 保留無轉接器的輸入契約,同時共用編碼器屬性產生方式。
公開類別佈局變更已納入 ABI 6,需要重新建置二進位使用端;既有來源入口仍可使用。
常見工作流程
- 解碼/導入: 檔案或 RTSP -> 拆分/多工/解析 -> 解碼 -> 轉換/caps -> appsink -> C++ 消費者
- 驗證: 建置 + 解析 + 預滾動(暫停)以儘早捕獲協商問題
- 提供 RTSP: 使用
appsrc將合成幀推送到 RTSP 伺服器管線 - 影像/影片張量適配器: 影像/影片/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、可重複使用的 Graph 片段、MPK 合約解析及圖的內部結構。
| 概念 | 角色 |
|---|---|
| 模型封存檔 | 一個封裝的 .tar.gz 成品,其中包含 MPK 推論合約、外掛程式私有設定、模型二進位檔和核心成品。 |
Model | 用於載入 .tar.gz 模型封存檔的公開載入器。它會解析 MPK 合約、執行路徑規劃、公開模型階段,並提供簡單的 run(...) / Graph 組成進入點。 |
Tensor | 帶有 dtype、shape、layout、儲存、裝置和語義中繼資料的類型化數值有效載荷。 |
Sample | 圍繞張量、張量列表或捆綁包的執行階段/媒體封套。在讀取欄位之前,請檢查 Sample::kind。 管線邊界會將整個捆綁包保留為單一影格。 |
Node | 一個原子管線階段,它會產生一個確定性的 GStreamer 片段和所擁有的元素名稱。 |
| 可重複使用的 Graph 片段 | 預先建立的 Graph,可展開為多個節點,例如已解碼的 RTSP 輸入或模型階段。 |
Graph | 組裝和驗證邊界。節點、模型和可重複使用的 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、匯流排訊息和可重現的後端管線。 - 不允許靜默回退。 不要透過靜默地轉換格式、變更圖族群、回退到 CPU 或忽略外掛程式錯誤來隱藏模型輸入錯誤或硬體/執行階段失敗。
- 在執行前進行驗證。 偏好在執行階段執行緒啟動或取得硬體資源之前進行結構、上限、形狀和合約驗證。
- MPK 合約是模型的事實來源。 核心路由、dtype、形狀、量化和階段決策必須來自
mpk.json/*_mpk.json。每個階段的 JSON 檔案都是外掛程式專用的。 - Detess 邏輯秩與執行階段幾何分開處理。 保留 MPK 撰寫的
frame_shape;只有位元組範圍能識別唯一幾何時,才接受秩 2 的 NC/HW 解釋。融合 DetessDequant 透過同一個逐影格合約攜帶兩個描述元:tile 秩決定核心秩,前導批次維度維持分離,語意軸、位元組範圍、步幅與明確的分塊儲存編碼仍具權威。Core 透過 Scheduler 轉送這些標準具型別合約;Kernels 驗證所選操作與編碼。不要在 DSO 邊界重建 ProcessCVU 預備請求。 - 數值後端原則只有一個權威。 已檢查能力擁有支援目標與 AUTO 偏好。明確指定的階段或工作階段目標只能在要求且受支援的後端執行,否則失敗;後續依角色覆寫不得違背此決定。
- 公開 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 和標準張量佈局。此框架透過以資訊檔為基礎的配接器階段來彌合此差距。
前處理與後處理是明確的框架階段/選項。格式不符、缺少必要的前處理中繼資料、選定的硬體傳輸不可用、模型封存檔或 MPK 合約無效,或 caps 協商失敗,都應回報可採取行動的結構化錯誤,而不是暗中在執行階段修正。
公開執行計畫
Model::execution_plan(...) 會傳回以相同引數呼叫 build(...) 時將執行的內容:依管線順序列出模型的圖節點、每個節點的執行位置(A65、EV74 或 MLA),以及節點之間邊上的張量。它會在關閉啟動預檢的情況下呼叫 build(...),讀取建置在配置與發布中繼資料規劃後記錄於 DiagCtx 的計畫,然後關閉管線,因此需要與 build(...) 相同的裝置。這是公開的診斷檢視,與下文所述的內部 ModelExecutionPlan 不同。其 JSON 合約為 schemas/execution_plan_v1.schema.json;schema_version 只會在變更破壞現有讀取端時才會改變。 記憶體摘要只計算每個自有配置一次,並標示為 CMA、DMS、HostCpu 或 Mixed;明確的 DMS 回退政策會以首選堆積表示。
板子遙測
TelemetryMonitor 會透過 /run/simaai-sentinel/api.sock 上的 HTTP API,從板子遙測常駐程式 Sentinel 讀取功耗與板子遙測資料;Core 不會直接讀取電源監控晶片。start() 會讀取 Sentinel 的樣本快取一次,以取得指標定義、取樣間隔與最新樣本;該樣本早於視窗開始,因此不會計入。接著,一個工作執行緒會在每個樣本預定產生前不久要求最新樣本,並依時間戳記識別每個新樣本,將其只計入一次持續更新的摘要。當某個時間戳記與上一個已計入的時間戳記相差不是一個間隔時,工作執行緒會從快取中計入遺漏的樣本;該快取保存 Sentinel 最新的 240 個樣本。監控器不會在 Sentinel 中建立任何東西,因此可以同時執行任意數量的監控器,而被終止的程序也不會留下任何殘留。
預設監控器使用上述通訊端。明確指定 TelemetryMonitor(socket_path) 時,只會為該執行個體選擇另一個 Sentinel Unix 通訊端;Model::benchmark() 仍使用預設端點。
Model::benchmark() 使用相同監視器,而不是第二套追蹤引擎。
它會在吞吐量計時前準備連線與等待中的工作執行緒,在量測開始後啟動視窗,
並在所有必要輸出完成後、量測停止前封閉視窗。啟動與封閉不分配記憶體、不取得互斥鎖,
也不等待執行緒結束或連線至 Sentinel。之後基準測試才等待工作執行緒結束並最後讀取快取。
進行中的輪詢受其停止檢查前的 UTC 讀值限制,因此封閉後不會接受較晚樣本。
基準測試歸因會驗證 UTC 樣本時間戳記與成對的 UTC/穩定時鐘邊界;
偵測到時鐘不連續會使遙測失效,而不會改變已量測吞吐量。
獨立監視器保留時鐘回退後依快取順序復原的行為。
Sentinel 約每 2 秒取樣一次,因此吞吐量階段至少會執行 BenchmarkOptions::min_duration_ms(預設為 10 秒)。延遲階段也遵循相同的下限,因此兩個階段依相同規則停止。當 Sentinel 未執行或量測期間沒有樣本時,基準測試仍會傳回延遲與 FPS;功耗欄位為零,並由 telemetry.status 說明原因。tools/install_neat_framework.sh 的板子模式 會安裝 Sentinel,或將其升級至最新的正式版建置。若安裝失敗,安裝程式會發出警告並繼續;之後可執行 sima-cli neat install sentinel,或像 CI 一樣設定 NEAT_INSTALLER_SENTINEL_REQUIRED=ON,讓失敗中止安裝。已棄用的 Run 電源監控器(RunOptions::power_monitor)的資料同樣來自 Sentinel:Core 會輪詢其最新樣本,不會透過 I2C 讀取電源監控晶片。
MLA 剖析透過兩個預設為 false 的 BenchmarkOptions 欄位明確啟用:include_mla_layer_stats 與 include_mla_stage_stats。延遲與吞吐量執行器關閉後,Core 會透過 Scheduler 的用戶端測量已解壓縮模型的 MLA 執行檔,並依序逐一進行剖析。MLA 層統計只涵蓋所選推論路徑(含其終端政策)中的 MLA 階段。Runner 會為每個執行檔在獨立程序中執行 mla-rt。MLA 層統計還會使用編譯器統計 YAML;MLA 階段統計會將每個 MLA 執行檔連續不中斷執行 200 次,並從 mla-rt 統計檔讀取 tile.lat 平均值。Runner 負責驗證輸入與輸出並清理暫存檔;若單次執行超過 120 秒,它會停止 mla-rt。MLA-RT 負責硬體剖析,以及將控制權交回核心執行路徑。剖析不得與其他 MLA 工作負載重疊。基準測試閘門只會序列化基準測試呼叫,不涵蓋其他推論 API 或應用程式。
失敗、當機或已停止的 mla-rt 執行可能讓 MLA 工作未完成,因此 Runner 不會在該程序中再啟動 mla-rt。之後的剖析流程會回報 MLA 需要復原。在確認 MLA 已復原之前,請讓 DevKit 保持閒置。
剖析採盡力而為(best effort)方式。若找不到 mla-rt、其執行失敗、逾時或寫出無法使用的輸出,Core 會保留主要測量值,讓對應清單保持為空,印出警告,並將原因寫入 mla_layer_stats.status 或 mla_stage_stats.status。其他情況下,狀態為 "not requested" 或 "ok"。
BenchmarkReport::mla_layer_stats 包含每個已編譯 MLA 層從零開始的執行階段索引、名稱,以及每層以一次剖析階段測得、以微秒表示的硬體延遲。BenchmarkReport::mla_stage_stats 包含以相同方式編號的各 MLA 階段索引,以及以微秒表示的平均硬體延遲。這些測量使用獨立的剖析階段,因此各層延遲的總和不等於階段延遲,也不等於整體延遲。BenchmarkReport::save(file_path) 會使用公開欄位名稱與單位,明確寫入完整報告:.json 選擇 JSON;.yaml 與其他結尾選擇 YAML。報告包含遙測資料與兩個狀態;停用剖析時,MLA 清單為空。此方法會建立不存在的父目錄,並以原子方式取代既有的目標檔案。
已淘汰的 PreparedRunner 選項必須維持預設值。並行處理使用 processcvu.async 和 GraphOptions::async_queue_depth;舊反量化與剖析旗標沒有直接替代。請維持 advanced_execution.defer_output_cache_sync=true,並透過 Tensor/GstMemory 映射存取 CPU 輸出。RunOptions::advanced.prepare_output_cpu_visible 是相容性用的無作用欄位,不要求預先快取同步。
已編譯模型執行合約
DMA-BUF 驅動程式遷移會將模型語意與每影格儲存空間分開。
Core 將模型載入時的事實編譯成單一、不可變的內部 ModelExecutionPlan:
- 值包含精確名稱、所需位元組數、可選的邏輯型別事實,以 及可選的根相對讀取運算式
{source ValueId, byte offset, byte strides}; - 作業包含精確且有序的邊,以及作業專用設定;
- MLA 後端連接埠包含 ELF/模型順序、精確的所需位元組數、對齊權威與存取方向;以及
- 公開輸出只包含發布順序及其提供的值。
MPK 資訊清單使用 MpkDecoder。MpkDecoder::load 是唯一的資訊清單入口:模型載入、預備執行階段建置與 PCIe 主機都透過它只讀取一次 mpk.json,並以接納流程解碼的同一份位元組建立語意 MpkContract。可選的 model_sdk_version 字串會保留為來源資訊,不限制接納。
解碼器只接受精確註冊的 (processor, kernel) 詞彙,解析完整張量名稱、
驗證作業位元組方程式,並逐一將每個 MPK MLA 階段與其精確的 ELF IFM/OFM 拓撲核對。
解碼器以編譯器定義的邏輯階段 ID 與資訊清單可執行檔 token 共同關聯可執行證據;
封存順序與檔名後綴不具有語意證據效力。
產生的不可變計畫為每個 MLA 作業提供經檢查的
{stage index, op ID, logical stage ID, executable} 鍵,以及預先建立索引的有序連接埠範圍。
歧義、缺少槽位或證據衝突都是模型載入錯誤;附屬 JSON、子字串比對、
環境狀態與執行階段緩衝區都不是證據。
當對應關係沒有歧義時,Core 可以核對不同的輸入與輸出緩衝區順序,包括批次輸入與輸出。 應用程式保留模型的公開張量名稱、順序與樣本順序。
具有一般空間儲存配置的單輸入、批次一模型,可以使用自動輸入通道填補。 應用程式保留模型的邏輯張量形狀;自訂空間儲存填補不在支援範圍內。
副檔名為 .so 的 AFE 成品依 MPK 階段分類。對於 processor="MLA",Core 不載入主機程序,而是驗證 ELF 拓撲,再將成品交給 MLArt。具有編譯器 input_names、input_types 與 output_types 的 A65 主機模組會成為具型別 TVM 程式。舊有 EVO 對齊仍為明確的 4096 位元組 LegacyPolicy;新的具型別契約需宣告自己的對齊。
執行階段影格不複製靜態計畫。直接路徑攜帶標準 DMA-BUF 所有權、
經檢查的絕對 {fd, offset, length} 檢視,以及有界的影格槽位生命週期。
Unpack 與 Slice 是使用端讀取運算式,不是執行階段作業:
解碼器只有在證明精確偏移、位元組步長與實體範圍後,才會將它們組合為單一已實體化的根載體。
Pack、鑲嵌與精度轉換仍是生產端/計算語意,除非降階處理證明精確的後端生成或等效融合。
這可避免儲存空間配置暗中改變 MLA 連接埠元數或模型行為。
FrameLayout 是各階段的儲存合約,包含配置清單、配置內範圍、輸入路由與輸出擁有權。ReuseInput 保留已識別輸入的配置群組。Core 一次配置自有載體;Scheduler 透過 Runner 準備緩衝池。MLA 填補後的實體容量與邏輯發布位元組數分開。匯入儲存空間及產生端借用維持固定。
Core 的不可變 MPK 套件是推論契約權威來源。邏輯公開形狀仍與原生 MLA 樣本範圍、 整批 CVU 執行檢視與底層容量分開。只有實際輸入/輸出位元組幾何識別出無歧義的 執行形狀時,才正規化二階 Detess 檢視。融合透過語意操作探索選擇, 絕不使用 Core 擁有的圖 ID 表。
標準身分與所選發布
Core 建構已編譯契 約時,會定案數值階段身分。它正規化支援的模型名稱寫法, 並拒絕操作、系列與系列列舉值不一致的情況。舊式圖與描述元 ID 不是執行權威。 身分正規化不會將不完整語意契約標為完整;Kernels 仍擁有操作探索與數值准入。
對於模型管理的 Preproc 交接,影像幾何與儲存範圍是不同資訊。 平鋪填補可能使必要儲存空間大於密集純量數量。Core 會根據具型別模型計畫驗證已吸收 的轉換鏈,完成載體放置與所選輸出路由,再建構公開輸出檢視。 執行階段描述元、路由與公開檢視必須參照相同且已定案的儲存空間。 較大的父分配不能授權過小的邏輯檢視,位元組數相等也不能證明幾何一致。
獨立封裝式 Preproc 在發布資訊或分配 arena 前,會向標準已檢查執行物件查詢儲存需求, 不會以邏輯維度相乘來推導封裝容量。多 ROI 容量在公開形狀中保留批次軸; 單影像獨立檢視保留既有 HWC 形狀。
具型別模型描述元涵蓋完整張量,包括批次維度。對明確指定批次的四階 HWC 張量,首軸為 N。其執行重複次數為一: 語意批次大小不代表要求重複執行整個張量。交錯封裝的批次輸出頭採用逐樣本繫結,並為每個輸出頭發布一個完整張量,並保留保持順序的單元素軸檢視。批次大小本身不會停用 DetessCast 或 DetessDequant 融合。融合的 DetessCast 與 DetessDequant 在 發布階數與執行幾何不同時,保留經明確證明的私用單元素軸檢視。
此單元素交接規則不取代刻意篩選的輸出檢視,例如 KLT 狀態發布。 變更發生於準備階段,而非影格執行。保留融合操作、明確位移與量化中繼資料; 不要以暫存複製或數值備援修復契約不符。
具型別轉換準備
Core 在圖準備期間解析一次外部 dtype 名稱與 MPK 張量描述元。
交接包含具有標準 TensorSpec 與 DType 契約的已檢查執行物件,包括逐輸入精度。
Runner 與 Scheduler 不重新解析操作專用的 dtype 字串。
Core 的發布與載體中繼資料保持明確,並與數值型別權威分開。
執行形狀與發布形狀不必相同。Core 根據語意輸出契約明確授權單元素軸檢視, 並根據已編譯模型的傳輸契約授權封裝實體儲存檢視。 Scheduler 在準備階段依此關係檢查每個輸出綁定,包括 dtype、佈局、步幅與儲存邊界。 僅位元組數相等不能授權變更形狀。這些檢視保留底層分配,不新增張量複製或數值轉換。 輸出契約變更需要重新驗證,包括動態準備的變體。
等價 dtype 寫法不區分大小寫。未知名稱與互相矛盾的描述元在執行前就會失敗。 共用的舊式 BF16/INT16 編碼需要明確語意型別。 要求錯誤會顯示原因,不必啟用詳細 GStreamer 診斷。
已檢查數值階段
FrameSpan 位移屬於個別配置與緩衝群組,不是整張圖的全域位址。不同群組中的相同位移不會重疊。BoxDecode 和 ArgMax 將輸出頭相對張量位移與儲存位移分開。直接記憶體輸入與執行階段實體繫結輸入維持原有定址方式。
Core 將 Preproc、轉換與視覺階段,包括 ArgMax、BoxDecode、SuperPoint 與 LiDAR/BEV 核心節點(SimaVoxelize、SimaPillarScatter、
SimaBEVPoolPlan 與 SimaBEVPool),降階為
標準要求與明確張量埠對應。Scheduler 的一般化張量階段引擎擁有 GStreamer 綁定與
發布;Runner 擁有相依、非同步執行與執行期間緩衝區生命週期。
Core 從上游分配契約或輸入儲存空間匯入載體容量,絕不只根據邏輯形狀推斷。
BoxDecode 與 SuperPoint 數值輸出保持私用;相依的 Core 線路序列化執行物件保留
公開 BBOX 與特徵負載,不重複解碼運算。 旋轉框使用獨立的版本化 BBOX_OBB_V1 序列化器,並保留相同的數值運算完成相依關係;數值運算失敗時不得發布過期結果。
不可變的核心配方會在具型別節點契約轉換後,保留生產者定義的張量傳輸格式。冷路徑發布會將此格式套用至新建與快取的 caps,絕不從核心名稱或位元組形狀推斷語意。公開 OBB 張量維持為具有 BBOX_OBB_V1 語意的密集一維 UInt8。
InputStream 會在發布 Sample 之前,將定義的格式投射至每個傳回的張量,包括自有複本與快取中繼資料路徑。因此,原始 Sample.tensors 與 TensorList 便利 API 具有相同的偵測語意。
對於已驗證的 MLA 圖塊數值輸出,Core 僅在形狀和 dtype 與已驗證的產生端一致時,才將實體配置附加到各邏輯輸出。InputStream 會在初始化解碼快取時解析這些不可變的 caps 中繼資料,然後保留在快取的 Tensor 範本中。原始位元組別名,以及位元組排列已符合密集 NHWC 的 INT8 儲存格圖塊,均維持不變。TessSpec::storage_bytes 區分明確的圖塊儲存與舊有僅標示格式的註記。copy_payload_bytes() 和 clone() 保留儲存位元組、填補與配置;密集複製、具型別存取與 DLPack 則拒絕明確的圖塊儲存。支援此配置的圖消費端會接收已驗證的配置,不會執行隱藏轉換。
影像尺寸變更會在綁定前選擇不可變且資源相容的已準備 BoxDecode 變體, 不會修 改在途影格使用中的操作。RCNN 第 1 階段保留逐層 top-K 計數加 FP16 提案群組。 Core 不得載入已淘汰的 objectdecode 外掛程式作為備援。
A65 是執行目標,不是 GStreamer 記憶體域。外掛程式仍匯入 DMA-BUF 載體。
直接張量輸入使用共用 CMA 分配,例如
Tensor::from_vector(values, shape, TensorMemory::EV74);所選執行物件仍在 A65 執行。
儲存庫佈局
高階結構
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/... 標頭檔。應用程式、範例和公開檔案應使用來自 <neat.h> 的單一公開 simaai::neat::Graph。
內部標頭檔和執行階段外掛程式路徑
位於 include/ 下的公開標頭檔會被安裝並視為穩定的 API。
位於 src/**/internal 下的內部標頭檔不會被安裝;範例/教學應該僅使用公開 API。
Core 共用 CMake 目標匯出 C++20 與公開的 GStreamer、OpenCV、JSON 需求。Core 使用已安裝的 Scheduler frontend 與 LLiMa 建置;底層執行階段函式庫仍是部署相依項目,而非 Core 直接使用的開發介面。靜態消費端需明確要求 Static 元件並提供其實作連結相依項目。
執行階段環境注意事項:
- 已安裝 Scheduler 外掛程式位於
${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/neat/gst-plugins。使用非系統前綴時,請將該目錄加入GST_PLUGIN_PATH或GST_PLUGIN_PATH_1_0。 - Runner 執行階段函式庫位於
${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/neat/runtime;請使用已安裝的 CMake 目標,而非建置樹內的函式庫。 - 系統範圍外掛程式更新後,請重建系統 GStreamer 快取 。
建置 Core 與其已安裝使用端時,請使用與所選 LLiMa 套件 ABI 相容的 JSON 標頭版本。 LLiMa 匯出帶有 JSON 的 C++ 方法;僅來源語法相容不能證明連結相容。 SDK/程式庫憑證與實際連結檢查優先於套件寬鬆的最低版本標籤。
規劃與穩定 (API 介面)
| 區域/API | 狀態 | 備註 |
|---|---|---|
核心管線 API (Graph、Run、Tensor、Sample) | 穩定 | 主要支援的 C++ 介面。 |
建置器內部元件 (Node、私有節點向量輔助工具、GraphPrinter) | 內部 | 僅使用 STL,支援 GStreamer 之前的組合。 |
模型 API (Model、可重複使用的 Graph 片段) | 穩定 | 標準模型檔案整合路徑。 |
include/policy/* | 穩定 | 最少的已驗證策略合約和預設值 (Decoder、Encoder、Memory、RTSP)。 |
include/nodes/groups/ImageToH264RtspGroup.h | 已規劃 | 空的佔位符群組。 |
Python 綁定 (python/、pyneat) | Beta | 基於 Nanobind 的綁定和封裝位於儲存庫中;API 介面著重於 Tensor、Graph/Run、Model,以及核心節點/群組輔助工具。 |