6.1 KiB
6.1 KiB
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)
- 使用者透過 Web UI 建立轉換任務
- Web UI 上傳 input 到 MinIO
- Scheduler 建立 job record,push 到 queue:onnx
- ONNX worker pull 任務、執行、push done
- Scheduler 推進狀態,push 到 queue:bie
- BIE worker 執行、輸出 result.bie、push done
- Scheduler 推進狀態,push 到 queue:nef
- NEF worker 執行、輸出 result.nef、push done
- Scheduler 標記 COMPLETED
- 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}/
<single_input_file> # 唯一輸入檔(副檔名不固定)
ref_images/
<image files...>
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 提示重送