abin 5aa374625f docs: add autoflow project docs and test infrastructure
- Add .autoflow/ with health check, PRD, Design Doc, TDD, progress tracking
- Add tests/conftest.py with PyQt5/KP SDK stubs for unit testing
- Add pytest config to pyproject.toml (pythonpath, import-mode, test naming)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 19:31:52 +08:00

23 KiB
Raw Permalink Blame History

Design Doc — Cluster4NPU UI

作者Architect Agent

狀態Draft

最後更新2026-04-05

版本對應v0.0.3developer 分支)


1. 背景與目標

1.1 背景

Cluster4NPU UI 是一個桌面應用程式,讓使用者不需要撰寫程式碼,就能透過視覺化拖拽介面設計並執行 AI 推論 Pipeline並將工作負載分配到多個 Kneron NPU DongleKL520、KL720、KL1080上平行執行。

現有系統已完成核心 Pipeline 設計器與推論引擎的基礎建設,但缺乏:

  • 效能視覺化(無法直觀看到平行處理的加速效果)
  • 進階裝置管理介面
  • 自動化 Benchmark 系統
  • 優化建議引擎

1.2 目標

  1. 核心目標:使任何 AI 應用工程師都能在 5 分鐘內完成 Pipeline 設計並看到推論結果
  2. 差異化目標:清楚視覺化呈現多 NPU Dongle 平行處理帶來的效能加速2x、3x、4x
  3. 工程目標:提供可擴展的架構,支援 Phase 1-4 的功能迭代

1.3 範圍

本文件涵蓋:

  • 現有v0.0.3)核心架構的完整說明
  • Phase 1-3 待開發功能的架構設計方向

不涵蓋:

  • 雲端功能、非 Kneron 硬體、模型訓練、行動端

2. 系統架構總覽

2.1 整體分層架構

┌─────────────────────────────────────────────────────────┐
│                    使用者介面層UI Layer                │
│                                                          │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐   │
│  │ Login Window │  │  Dashboard   │  │  Dialogs     │   │
│  │   (login.py) │  │(dashboard.py)│  │ (deployment, │   │
│  └──────────────┘  └──────────────┘  │  performance)│   │
│                          │           └──────────────┘   │
│  ┌──────────────────────────────────────────────────┐   │
│  │              三面板佈局Three-Panel Layout        │   │
│  │  ┌──────────┐  ┌──────────────┐  ┌──────────┐   │   │
│  │  │  左面板   │  │    中面板    │  │  右面板  │   │   │
│  │  │ 節點面板  │  │ Pipeline 編輯│  │ 設定/監控│   │   │
│  │  │(palette) │  │ (NodeGraphQt)│  │(properties│   │   │
│  │  └──────────┘  └──────────────┘  └──────────┘   │   │
│  └──────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────┘
                           │
┌─────────────────────────────────────────────────────────┐
│                  應用程式核心層Core Layer              │
│                                                          │
│  ┌────────────────────┐  ┌──────────────────────────┐   │
│  │  Pipeline 分析引擎  │  │      節點系統Nodes     │   │
│  │  (pipeline.py)     │  │  (base/input/model/       │   │
│  │                    │  │   preprocess/postprocess/ │   │
│  │  - Stage 偵測      │  │   output nodes)           │   │
│  │  - 結構驗證        │  │                           │   │
│  │  - 路徑分析        │  │  - 業務屬性管理           │   │
│  │  - 設定匯出        │  │  - 設定序列化             │   │
│  └────────────────────┘  └──────────────────────────┘   │
│                                                          │
│  ┌──────────────────────────────────────────────────┐   │
│  │           推論執行層Inference Execution Layer    │   │
│  │                                                   │   │
│  │  ┌──────────────────────┐  ┌─────────────────┐   │   │
│  │  │  InferencePipeline   │  │   MultiDongle   │   │   │
│  │  │                      │  │                 │   │   │
│  │  │  - 多 Stage 協調      │  │  - NPU 裝置管理  │   │   │
│  │  │  - 執行緒管理         │  │  - 非同步推論    │   │   │
│  │  │  - 佇列管理          │  │  - 前後處理      │   │   │
│  │  │  - FPS 計算          │  │  - 多裝置排程    │   │   │
│  │  └──────────────────────┘  └─────────────────┘   │   │
│  └──────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────┘
                           │
┌─────────────────────────────────────────────────────────┐
│               硬體抽象層Hardware Abstraction Layer     │
│                                                          │
│  ┌──────────────────────────────────────────────────┐   │
│  │                 Kneron KP SDK                     │   │
│  │                                                   │   │
│  │  KL520 Dongle  │  KL720 Dongle  │  KL1080 Dongle │   │
│  └──────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────┘

2.2 模組間依賴關係

main.py
  └── ui/windows/login.py (DashboardLogin)
        └── ui/windows/dashboard.py (DashboardWindow)
              ├── ui/windows/pipeline_editor.py
              │     └── core/pipeline.py (PipelineAnalyzer)
              │           └── core/nodes/*.py
              ├── ui/components/properties_widget.py
              │     └── core/nodes/*.py
              └── core/functions/InferencePipeline.py
                    └── core/functions/Multidongle.py
                          └── kp (Kneron KP SDK)

3. 核心元件說明

3.1 Pipeline 分析引擎(core/pipeline.py

職責: 分析 NodeGraphQt 視覺圖形,識別 Pipeline 的 Stage 結構、驗證合法性、產生執行設定。

關鍵類別:

類別/函式 職責
PipelineStage 代表一個推論 Stage包含 ModelNode 與可選的 Pre/Postprocess Node
analyze_pipeline_stages(node_graph) 從視覺圖形中識別所有 Stage依距離排序
get_stage_count(node_graph) 計算 Pipeline 中的 Stage 數量(用於 UI 顯示)
validate_pipeline_structure(node_graph) 驗證 Pipeline 是否包含必要節點Input、Model、Output
get_pipeline_summary(node_graph) 回傳 Pipeline 統計摘要節點數、Stage 數、驗證結果)

設計決策:

  • 採用多重節點識別策略(__identifier__type_NODE_NAME、class 名稱、特定方法的存在)以提高相容性
  • Stage 排序依據:計算各 ModelNode 到輸入節點的最短路徑距離BFS
  • 所有圖遍歷方法都包含 defensive exception handling避免 NodeGraphQt 物件狀態不一致時崩潰

介面:

# 主要公開介面
get_stage_count(node_graph: NodeGraph) -> int
analyze_pipeline_stages(node_graph: NodeGraph) -> List[PipelineStage]
validate_pipeline_structure(node_graph: NodeGraph) -> Tuple[bool, str]
get_pipeline_summary(node_graph: NodeGraph) -> Dict[str, Any]

3.2 節點系統(core/nodes/

職責: 定義 Pipeline 中的各類節點,提供業務屬性管理與設定序列化能力。

繼承架構:

NodeGraphQt.BaseNode
  └── BaseNodeWithPropertiesbase_node.py
        ├── InputNodeinput_node.py
        ├── ModelNodemodel_node.py
        ├── PreprocessNodepreprocess_node.py
        ├── PostprocessNodepostprocess_node.py
        └── OutputNodeoutput_node.py

BaseNodeWithProperties 核心能力:

  • create_business_property(name, default, options) — 建立帶驗證選項的業務屬性
  • validate_property(name, value) — 數值範圍、選項列表驗證
  • get_node_config() / load_node_config(config) — JSON 序列化/還原
  • create_node_property_widget(node, prop_name, value, options) — 根據屬性型別自動生成 Qt Widget

ModelNode 屬性(主要節點):

屬性 型別 說明
model_path file_path .nef 模型檔案路徑
dongle_series choice KL520 / KL720 / KL1080
num_dongles int (1-16) 分配給此 Stage 的 Dongle 數量
port_id string USB Port ID或 auto
batch_size int (1-32) 推論批次大小
max_queue_size int (1-100) 輸入佇列最大長度

3.3 推論執行引擎(core/functions/InferencePipeline.py

職責: 管理多 Stage Pipeline 的生命週期、協調執行緒間資料流、計算效能指標。

主要資料結構:

@dataclass
class StageConfig:
    stage_id: str
    port_ids: List[int]
    scpu_fw_path: str        # SCPU 韌體路徑
    ncpu_fw_path: str        # NCPU 韌體路徑
    model_path: str          # .nef 模型路徑
    upload_fw: bool          # 是否上傳韌體
    max_queue_size: int      # 佇列大小(預設 50
    multi_series_config: Optional[Dict]  # 多系列模式設定
    input_preprocessor: Optional[PreProcessor]
    output_postprocessor: Optional[PostProcessor]

@dataclass
class PipelineData:
    data: Any                # 當前資料(影像、中間結果)
    metadata: Dict[str, Any] # 時間戳、處理資訊
    stage_results: Dict[str, Any]  # 各 Stage 推論結果
    pipeline_id: str         # 唯一識別碼
    timestamp: float

執行緒模型:

主執行緒UI
  │
  ├── InferencePipeline.coordinator_thread協調器
  │     │  從 pipeline_input_queue 取資料
  │     │  依序分配給各 Stage
  │     └── 收集結果放入 pipeline_output_queue
  │
  ├── PipelineStage[0].worker_threadStage 0 工作執行緒)
  │     └── 從 input_queue 取資料 → MultiDongle 推論 → 放入 output_queue
  │
  ├── PipelineStage[1].worker_threadStage 1 工作執行緒)
  │     └── ...
  │
  └── stats_thread效能統計回報

FPS 計算方式: 採用累積式計算(completed_counter / elapsed_time),與 Kneron 範例程式的計算邏輯一致,只計算真實推論結果(排除 async/processing 狀態)。

佇列管理策略:

  • 輸入佇列滿時:捨棄最舊的幀(為了即時串流的實時性)
  • 輸出佇列上限 50 筆:超出時捨棄最舊的結果,避免記憶體無限增長

3.4 硬體抽象層(core/functions/Multidongle.py

職責: 封裝 Kneron KP SDK提供統一的 NPU Dongle 管理介面支援單裝置與多裝置multi-series模式。

核心抽象類別:

class DataProcessor(ABC):
    def process(self, data: Any, *args, **kwargs) -> Any: ...

class PreProcessor(DataProcessor):
    # 影像縮放resize+ 格式轉換BGR → BGR565/RGB8888

class PostProcessor(DataProcessor):
    # 支援 4 種後處理類型:
    # - FIRE_DETECTION火焰分類
    # - CLASSIFICATION一般分類
    # - YOLO_V3物件偵測
    # - YOLO_V5物件偵測使用參考實作
    # - RAW_OUTPUT原始輸出

裝置規格DongleSeriesSpec

系列 Product ID GOPS 算力
KL520 0x100 2 GOPS
KL720 0x720 28 GOPS
KL630 0x630 400 GOPS
KL730 0x730 1600 GOPS

推論結果資料結構:

@dataclass
class ClassificationResult:
    probability: float
    class_name: str
    class_num: int
    confidence_threshold: float

@dataclass
class ObjectDetectionResult:
    class_count: int
    box_count: int
    box_list: List[BoundingBox]
    # Letterbox 映射資訊(用於還原到原始影像座標)
    model_input_width, model_input_height: int
    pad_left, pad_top, pad_right, pad_bottom: int

3.5 使用者介面層(ui/

職責: 呈現視覺化 Pipeline 設計環境,管理節點屬性設定、效能監控顯示。

主要視窗:

  • DashboardLoginui/windows/login.py):啟動畫面、最近專案清單、新建/載入 Pipeline
  • DashboardWindowui/windows/dashboard.py):主工作介面,三面板佈局
  • PipelineEditorui/windows/pipeline_editor.py):內嵌 NodeGraphQt 視覺編輯器

三面板配置:

面板 寬度比例 主要內容
左面板 25% 節點面板拖拽來源、Pipeline 操作按鈕
中面板 50% NodeGraphQt 視覺編輯器、全域狀態列
右面板 25% Properties Tab節點設定、Performance Tab效能監控、Dongles Tab裝置管理

3.6 應用程式入口(main.py

職責: 應用程式初始化、單一實例保護、Qt 環境設定。

單一實例機制: SingleInstance 類別採用雙重保護:

  1. Qt QSharedMemory(跨平台)
  2. 檔案鎖Unix: fcntl / Windows: O_CREAT|O_EXCL
  3. 自動清理 5 分鐘以上的過期鎖定檔案

4. 資料流

4.1 設計階段資料流Design Time

使用者拖拽節點
      │
      ▼
NodeGraphQt 視覺圖形
      │
      ▼
core/pipeline.py
  analyze_pipeline_stages()
      │
      ▼
List[PipelineStage](邏輯 Stage 列表)
      │
      ├──→ UI 顯示 Stage 數量(狀態列)
      └──→ 驗證錯誤提示Validation Errors

4.2 執行階段資料流Runtime

輸入來源(相機 / 影片 / 圖片)
      │
      ▼
camera_source.py / video_source.py
      │  numpy.ndarrayBGR 影像幀)
      ▼
InferencePipeline.put_data()
      │
      ▼
pipeline_input_queueQueue, maxsize=100
      │
      ▼
coordinator_thread協調器執行緒
  建立 PipelineData 包裝器
      │
      ▼(依序通過每個 Stage
PipelineStage[0].input_queue
      │
      ▼
worker_thread[0]
  1. input_preprocessor可選的 Stage 間前處理)
  2. MultiDongle.preprocess_frame()BGR → BGR565 格式轉換)
  3. MultiDongle.put_input()(送入推論佇列)
  4. MultiDongle.get_latest_inference_result()(非阻塞取結果)
  5. 更新 PipelineData.stage_results
      │
      ▼
PipelineStage[0].output_queue
      │
      ▼(下一個 Stage...
      │
      ▼
pipeline_output_queueQueue, maxsize=50
      │
      ├──→ result_callbackUI 更新)
      └──→ stats_callback效能統計

4.3 .mflow 檔案格式

Pipeline 儲存為 JSON 格式:

{
  "nodes": [
    {
      "type": "ModelNode",
      "name": "Stage 1 Model",
      "properties": {
        "model_path": "/path/to/model.nef",
        "dongle_series": "720",
        "num_dongles": 2
      },
      "position": [100, 200]
    }
  ],
  "connections": [
    {"from_node": "input_0", "from_port": "output", "to_node": "model_0", "to_port": "input"}
  ]
}

5. 技術決策紀錄ADR

ADR-001選用 PyQt5 作為 GUI 框架

決策:使用 PyQt5>= 5.15.11

原因:

  • NodeGraphQt 依賴 PyQt5無法使用其他框架
  • PyQt5 在 Windows 上有成熟的支援
  • 提供豐富的 Widget 與 Signal/Slot 機制

取捨:

  • 限制 Python 版本在 3.93.11PyQt5 + Kneron SDK 相容性)
  • PyQt6 不向下相容,短期不考慮遷移

ADR-002選用 NodeGraphQt 作為視覺節點編輯器

決策:使用 NodeGraphQt>= 0.6.40

原因:

  • 提供完整的拖拽節點圖形編輯能力,開發成本低
  • 支援節點連接、屬性面板、視覺化輸出

取捨:

  • NodeGraphQt 的 UI 客製化能力有限(如節點顏色、形狀)
  • 節點識別採用多重 fallback 機制(透過 __identifier__NODE_NAME 等),因 NodeGraphQt 版本差異可能造成 API 不一致

ADR-003多執行緒 Pipeline 架構

決策:每個 Stage 一個 Worker Thread + 一個 Coordinator Thread

原因:

  • 推論為 CPU/硬體密集操作,多執行緒可避免 UI 阻塞
  • 各 Stage 獨立執行緒允許流水線pipelining並行提升吞吐量

取捨:

  • 協調器採用循序sequential方式傳遞資料並非真正平行真正平行需要 DAG 調度器)
  • 使用 queue.Queue 進行執行緒間通訊,有固定的記憶體上限

ADR-004非阻塞式推論結果取得

決策MultiDongle.get_latest_inference_result() 採用非阻塞模式

原因:

  • 與 Kneron 範例程式碼example.py的設計模式一致
  • 避免推論延遲阻塞整個 Pipeline 執行緒

取捨:

  • 結果可能為 None尚未完成需要 async/processing 狀態的過濾邏輯

ADR-005FPS 計算採用累積式

決策completed_counter / elapsed_time(從第一個結果開始計算)

原因:

  • 與 Kneron 官方範例的計算方式一致,確保可比性
  • 排除熱機warm-up期間的異常低 FPS

取捨:

  • 無法反映即時的 FPS 波動(適合穩定場景,不適合延遲敏感場景)

ADR-006PyInstaller 打包

決策:使用 PyInstallermain.spec)產生獨立可執行檔

原因:

  • 目標用戶(系統整合商)可能沒有 Python 環境
  • 簡化部署流程

取捨:

  • 打包後的執行檔體積較大
  • Kneron KP SDK 的動態函式庫需要正確包含在打包設定中

6. 已知限制與技術債

6.1 已知 Bug

Bug 狀態 影響
節點屬性顯示問題 未修復v0.0.2 記錄) 右面板 Properties Tab 可能顯示錯誤
輸出視覺化異常(含後處理結果) 未修復v0.0.2 記錄) 輸出畫面可能不正確

6.2 技術債

項目 嚴重度 說明
根目錄 debug 腳本未整理 debug_*.pyforce_cleanup.py 等應移至 tools/
tests/ 命名混亂 42 個腳本缺乏系統性分類,部分非 test_ 開頭
缺乏 pytest 測試框架 核心模組InferencePipeline、MultiDongle無 pytest 覆蓋
Coordinator 為循序設計 真正的 Stage 並行需要重構協調器為 DAG 模式
節點識別多重 fallback 可讀性差,應統一為單一識別策略
RTSP 串流僅基本支援 完整 RTSP 功能未在當前路線圖中

6.3 效能限制

  • 協調器為循序傳遞:目前 Coordinator 依序將資料傳給 Stage 0 → Stage 1無真正的平行推論真正平行需重構為流水線佇列模式
  • FPS 計算不反映即時波動:累積式 FPS 在長時間執行後準確,但短期波動不可見
  • 輸出佇列上限 50:高吞吐量場景下可能成為瓶頸

7. 未來架構演進方向

Phase 1效能視覺化對應 DEVELOPMENT_ROADMAP Phase 1

需要新增的架構元件:

# 新增模組core/performance/
class PerformanceBenchmarker:
    """自動化效能測試器"""
    def run_sequential_benchmark(self, pipeline_config) -> BenchmarkResult
    def run_parallel_benchmark(self, pipeline_config) -> BenchmarkResult
    def calculate_speedup(self, seq: BenchmarkResult, par: BenchmarkResult) -> float

class PerformanceHistory:
    """效能歷史記錄(本地 JSON 儲存)"""
    def record(self, result: BenchmarkResult)
    def get_history(self, limit: int) -> List[BenchmarkResult]

UI 層新增:

  • ui/components/performance_dashboard.py:即時 FPS/延遲折線圖(使用 pyqtgraph 或 matplotlib
  • ui/dialogs/benchmark_dialog.pyBenchmark 啟動與結果呈現

架構考量:

  • Benchmark 需要能控制 InferencePipeline 以單裝置/多裝置模式執行,需要在 StageConfig 層級提供模式切換介面
  • 效能圖表更新須在獨立執行緒中產生資料,透過 Qt Signal 傳遞到 UI 執行緒

Phase 2裝置管理對應 DEVELOPMENT_ROADMAP Phase 2

需要新增的架構元件:

# 強化 core/functions/Multidongle.py
class DeviceManager:
    """裝置管理器"""
    def scan_devices() -> List[DeviceInfo]
    def get_device_health(device_id: str) -> DeviceHealth
    def assign_device(device_id: str, stage_id: str)
    def get_load_balance_recommendation() -> Dict[str, str]

@dataclass
class DeviceInfo:
    device_id: str
    series: str        # KL520/KL720/KL1080
    status: str        # online/offline/busy
    gops: int          # 算力(來自 DongleSeriesSpec
    assigned_stage: Optional[str]

UI 層新增:

  • ui/components/device_management_panel.py:裝置狀態儀表板

Phase 3優化引擎對應 DEVELOPMENT_ROADMAP Phase 3

需要新增的架構元件:

# 新增模組core/optimization/
class OptimizationEngine:
    def analyze_pipeline(self, stats: PipelineStats) -> List[OptimizationSuggestion]
    def predict_performance(self, config: PipelineConfig) -> PerformancePrediction

@dataclass
class OptimizationSuggestion:
    type: str          # "rebalance_devices" | "remove_redundant_node" | ...
    description: str
    estimated_improvement: float  # 預估效能提升 %
    action: Callable   # 可執行的改善動作

架構演進的長期考量

  1. Coordinator 重構:當前循序協調器在多 Stage Pipeline 中形成瓶頸。長期應重構為流水線pipeline模式讓 Stage N+1 在 Stage N 處理下一幀時就開始處理上一幀的結果。

  2. 測試架構建立:建立 pytest 測試框架,核心模組需達到 80% 以上覆蓋率(特別是 InferencePipeline 的佇列邏輯、pipeline.py 的 Stage 分析邏輯)。

  3. 型別標註完善:目前部分模組缺乏完整型別標註,建議逐步加入 mypy 靜態分析。