# Kneron Toolchain Convert Orchestrator — 設計文件(Crash 即 Reset 版) ## 0. 目的與範圍 ### 目的 將 Kneron Toolchain 的模型轉換流程(ONNX → BIE → NEF)拆分為可水平擴充的 Worker Pool, 由 Scheduler 統一派工與狀態管理,並使用 MinIO 作為跨主機的 artifact 交換區, 以解決單一 VM / 單一 Toolchain instance 在高併發下造成 CPU 爆滿與 Crash 的問題。 ### 範圍 - Web UI:上傳 / 查詢狀態 / 下載結果 - Task Scheduler:建立任務、寫入狀態、推送 queue、接收完成事件 - Worker Pools: - ONNX Flow Worker Pool - BIE Flow Worker Pool - NEF Flow Worker Pool - Redis:暫存 job 狀態(**重啟即清空**) - Queue:暫存待處理任務與完成事件(**重啟即清空**) - MinIO:存放 input/output/logs(可保留或定期清理) ### 非目標(Non-goals) - 不做任務持久化(durability) - 不做 crash 後 resume - 不做 exactly-once / at-least-once 保證 - 不做 Scheduler HA - 不做自動 retry(失敗即請使用者重送) --- ## 1. 核心設計哲學:Crash 即 Reset - Redis 重啟 → 所有 job 狀態消失 - Queue 重啟 → 所有排隊任務消失 - Scheduler / Worker 重啟 → 不嘗試恢復任何舊任務 - UI 查不到 job → 顯示「系統已重啟,請重新送出」 - 任務資料不具不可遺失性(loss-tolerant) --- ## 2. 系統元件與責任 ### 2.1 Web UI - 提供使用者: - 上傳 model.onnx、quant.zip - 建立轉換任務 - 查詢任務狀態 - 下載 BIE / NEF - Web UI 不直接讀寫 Redis 或 Queue - Web UI 可直接與 MinIO 上傳 / 下載(或透過 Scheduler 取得路徑) - 狀態更新:以 SSE 為主,Polling 為備援(3-5 秒) ### 2.2 Task Scheduler(控制面) - 唯一的控制面元件 - 職責: - 建立 job_id - 建立 Redis job record - 將 job 推入對應 task queue - 接收 worker 完成事件(done queue) - 推進 job 狀態(ONNX → BIE → NEF → COMPLETED) - 流程固定:ONNX → BIE → NEF,不支援跳過或只跑部分 - Scheduler 不等待 worker、不執行 heavy CPU 任務 ### 2.3 Task Queue - 至少包含以下 queue: - queue:onnx - queue:bie - queue:nef - queue:done - Queue 僅用於「暫存」任務(重啟可清空) ### 2.4 Worker Pools - ONNX / BIE / NEF Worker 各自獨立 pool - Worker 特性: - 無狀態 - pull-based(自行從 queue 取任務) - 一次只處理一個 job - Worker 失敗: - 回報 fail - Scheduler 將 job 標記為 FAILED ### 2.5 MinIO(Artifact Store) - 所有 job 的 input / output / log 都放在 MinIO - 作為跨 worker / 跨主機的唯一資料交換區 --- ## 3. 命名與資料結構 ### 3.1 Job ID - 使用 UUID v4 - 全系統唯一 ### 3.2 MinIO 路徑規則(建議) Bucket:toolchain-jobs ``` jobs/{job_id}/ input/ model.onnx quant.zip output/ result.bie result.nef logs/ onnx.log bie.log nef.log ``` ### 3.3 Redis Job Record(Hash / JSON) Key:job:{job_id} ``` job_id created_at status: ONNX | BIE | NEF | COMPLETED | FAILED stage: ONNX | BIE | NEF progress: 0-100 updated_at output: bie_key nef_key error: step reason ``` --- ## 4. 成功流程(Happy Path) 1. 使用者透過 Web UI 建立轉換任務 2. Web UI 上傳 input 到 MinIO 3. Scheduler 建立 job record,push 到 queue:onnx 4. ONNX worker pull 任務、執行、push done 5. Scheduler 推進狀態,push 到 queue:bie 6. BIE worker 執行、輸出 result.bie、push done 7. Scheduler 推進狀態,push 到 queue:nef 8. NEF worker 執行、輸出 result.nef、push done 9. Scheduler 標記 COMPLETED 10. Web UI 取得下載路徑 --- ## 4.1 工作目錄與 Worker I/O 規格(落地版) 以下為實作落地時的檔案布局與 worker 互動規格(與 MinIO 路徑可一對一對應): ### 4.1.1 工作目錄 - API 取號後建立 `task_id` - API 將使用者上傳檔案放入工作目錄: - `{base_path}/{task_id}/` - 參考圖片固定放在 `ref_images/` ``` {base_path}/{task_id}/ # 唯一輸入檔(副檔名不固定) ref_images/ ``` ### 4.1.2 ONNX Worker - 輸入:工作目錄下的唯一檔案(不假設檔名 / 副檔名) - 輸出:`out.onnx` - 輸出位置:同一工作目錄 ### 4.1.3 BIE Worker - 輸入:`out.onnx` + `ref_images/*` - 輸出:`out.bie` - 輸出位置:同一工作目錄 ### 4.1.4 NEF Worker - 輸入:`out.bie` - 輸出:`out.nef` - 輸出位置:同一工作目錄 ### 4.1.5 Core / Toolchain 路徑一致性 - Worker 需將工作目錄 path 傳給 core - Core 需設定 toolchain 相關 path(輸出與中間檔)都指向該工作目錄 --- ## 5. 失敗行為(簡化) - Worker 例外 → 回報 fail - Scheduler 標記 job 為 FAILED - UI 顯示失敗並要求使用者重新送出 - Redis / Queue Crash → 所有 job 消失,視同 reset --- ## 6. API(Scheduler) ### POST /jobs 建立新 job Request: ``` { "model_key": "...", "quant_key": "..." } ``` Response: ``` { "job_id": "...", "status": "ONNX" } ``` ### GET /jobs/{job_id} 查詢狀態 Response: ``` { "job_id": "...", "status": "BIE", "output": { "bie_key": null, "nef_key": null } } ``` Job 不存在: ``` 404 JOB_NOT_FOUND ``` ### GET /jobs/{job_id}/events SSE 事件串流(主動推送狀態更新) 建議: - 若 SSE 斷線,改用 GET /jobs/{job_id} 每 3-5 秒輪詢 --- ## 7. Worker 行為規範 - 從對應 queue pull job_id - 從 MinIO 下載 input - 執行 Toolchain flow - 上傳 output - push done event: ``` { "job_id": "...", "step": "onnx|bie|nef", "result": "ok|fail", "reason": "optional" } ``` --- ## 8. 併發與限流 - BIE Worker 數量 = 最大同時 BIE 任務數 - 每個 BIE Worker 一次只跑一個 job - 不在 Scheduler 做複雜限流邏輯 --- ## 9. 最小部署建議 - web-ui x1 - scheduler x1 - redis x1(不開 persistence) - minio x1 - onnx-worker xN - bie-worker xM - nef-worker xK --- ## 10. MVP 驗證項目 - 單一 job 成功完成 - 多 job 排隊,BIE 不超量 - Worker 失敗 → job FAILED - Redis 重啟 → job 消失,UI 提示重送