visionA/docs/autoflow/02-prd/features/feature-converter-integration.md
jim800121chen fb7da5d180 chore(autoflow): migrate .autoflow/ 共享層文件至 docs/autoflow/
依 autoflow-agent workspace v2 設計把 PRD / 設計 / 架構 / 交付類
共享文件從個人層 .autoflow/(ignored)搬到 docs/autoflow/(進 git),
讓團隊可共享產品與架構文件,個人層只留 progress / review / testing 等
per-branch 筆記。

- 02-prd/        21 個檔(PRD、features、market-analysis 等)
- 03-design/     18 個檔(design-spec、wireframes、flows 等)
- 04-architecture/ 31 個檔(TDD、design-doc、ADR×14、API 規格等)
- 07-delivery/   3 個檔(project-summary、phase-0.6-handover、stage-deployment-setup)

合計 73 檔。原檔已從 .autoflow/ 移除(migration 工具執行 git mv,
但因 .autoflow/ 在 .gitignore 中、git 將此操作視為新增、無 rename history)。
2026-05-04 16:55:55 +08:00

15 KiB
Raw Permalink Blame History

Feature轉檔功能整合P0 — Phase 0.8 MVP

父文件:PRD.md | 對應 User StoriesUS-24、US-TODO-05

狀態變更2026-05-02Phase 0 規劃為「P2、只定 API 契約」Phase 0.8 提升為 P0 MVP 並落地實作。 本檔保留 Phase 0 的設計決策脈絡API 契約、ConverterClient 介面),新增 Phase 0.8 的 MVP 範圍與整合決策。


1. 概要

Kneron 的 .nef 是 Kneron 晶片專用格式,使用者手上常是 ONNX / TFLite需要轉檔才能在 KL520 / KL720 / KL630 / KL730 上跑。kneron_model_converter 已有完整轉檔 servicePhase 1 已完成 POST /api/v1/jobs 提交、GET 查狀態、POST /promote 把結果搬上 File Access Agent

Phase 0.8 的目標是在 visionA Cloud 接入 converter,讓使用者不離開 visionA就能完成「上傳原始模型 → 轉檔 → 進模型庫推論」的完整流程,把原本斷裂的兩個網站合併成一條動線。

跟「模型管理P0」的關係轉檔產生的 .nef 是模型庫的一個新來源(與「使用者直接上傳 nef」並列。轉檔成功後使用者自己決定是否要把 NEF 加進模型庫;加進去後走的是模型管理既有的 /api/models/init+finalize 流程,並標記 Source="converted" + SourceJobID=<converter job_id>


2. User StoriesPhase 0.8 MVP 範圍)

ID Story 優先級
US-24a 作為 AI 應用開發者,我有一個 ONNX 模型,想轉成 NEF 放到我的 KL720 device 上跑,希望全程在 visionA Cloud 完成 P0
US-24b 作為使用者,轉檔完成後我想決定是「加到模型庫直接推論」還是「下載 NEF 回去自己用」,或者兩個都做 P0
US-24c 作為使用者,轉檔失敗時我想看到清楚的錯誤原因(不是只有 failed),知道是檔案格式不支援、量化失敗、還是其他問題 P0

Phase 0 規劃中 US-24 的「自動把 NEF 推進模型庫」(端到端全自動)改為 Phase 0.8 的半自動設計user 顯式選擇)。理由:避免「使用者試了個轉檔但其實只想下載結果」也被自動塞進模型庫。


3. 功能需求Phase 0.8 MVP

F1「轉檔」進入點

  • 左側 sidebar 新增「轉檔」tab與既有的 Devices / Models / Inference 並列
  • 進入後顯示轉檔頁面:上傳區 + 設定區 + 開始按鈕
  • 不在 /models 頁面內混合(避免「上傳模型」按鈕同時要處理 nef / onnx / tflite 兩種流程UX 變複雜)

F2上傳與設定

  • 支援檔案格式.onnx.tflitePhase 0.8 不支援 .pt / .h5,由 converter 能力決定)
  • 必填欄位
    • 來源檔案(拖拽或選擇)
    • 目標 chipKL520 / KL630 / KL720 / KL730單選
  • 可選欄位
    • Reference images多張給 converter 做精度校準用)
    • 任務名稱(顯示用,預設用檔名)
  • 檔案大小限制
    • 模型檔:≤ 500 MBconverter 端的限制;應透過 config 對齊,建議 CONVERTER_MAX_MODEL_SIZE_MB
    • Reference images每張 ≤ 10 MB、總數 ≤ 100 張
  • 上傳行為upload 走 visionA backend streaming proxy(見 §6 整合決策 D1browser → backend → converter使用者看到的是「上傳到 visionA」的單一進度條XHR upload event

F3轉檔執行與進度

  • 上傳完成後自動切到「轉檔進度頁」(同一個 tab不開新分頁
  • 進度顯示用 polling(前端每 510 秒打一次 GET /api/conversion/{job_id}
    • status 機械化的四個狀態:queued / running / succeeded / failed
    • running 時若 converter 提供 progress 比例則顯示百分比,無提供則顯示「轉檔中⋯」+ 跑馬燈
  • 同 user 同時只能跑一個 active jobconverter 端會回 409 user_has_active_job;前端拿到 409 時 UI 提示「你已有一個轉檔任務正在進行,請等待完成或重新整理」並禁用「開始轉檔」

F4完成後的半自動結果處理

轉檔狀態變為 succeeded 後,頁面顯示:

  • 任務摘要(來源檔名、目標 chip、輸出 NEF 大小、checksum
  • 兩個並列按鈕
    • 「加到模型庫」:走 F6 流程
    • 「下載」:走 F7 流程
  • 兩個按鈕互不互斥(使用者可以兩個都按),按鈕點擊後不消失,可重複觸發
  • 提醒「7 天後 converter 會自動清除這個任務請在期限內完成處理」converter Phase 1 已有 7 天 GC 機制)

F5失敗錯誤訊息

  • 狀態變為 failed 時顯示翻譯後的 user-friendly 錯誤訊息
  • 對照表visionA backend 維護,避免暴露 converter 內部訊息):
converter error code 顯示給使用者的訊息
UNSUPPORTED_FORMAT 此模型格式目前不支援,請改用 ONNX / TFLite
INVALID_CHECKSUM 檔案傳輸過程毀損,請重新上傳
QUANTIZATION_FAILED 模型內含不支援的運算子,無法量化到目標晶片
MODEL_TOO_LARGE 模型超過 500 MB 上限
QUOTA_EXCEEDED 系統暫時繁忙,請稍後再試
其他 / unknown 轉檔失敗,請稍後重試。若持續發生請聯絡支援團隊(顯示 job_id 供回報)
  • 失敗任務也顯示 job_id縮短前 8 碼)供使用者報修參考

F6「加到模型庫」流程

  • 前端 → visionA backend POST /api/conversion/{job_id}/promote-to-models
  • visionA backend
    1. 確認 job 屬於該 user 且狀態為 succeeded
    2. 從 converter 取得 target_object_keypromote 階段已上 FAA
    3. server-to-server 從 FAA pull NEFfiles:download.read scope不走 delegated token
    4. 走既有 /api/models/init + /api/models/finalize 三段式流程進模型庫
    5. model.Source = "converted"model.SourceJobID = <converter job_id>internal/model.Model 已預埋此兩欄位,無需擴 schema
  • 完成後前端 toast「已加入模型庫」+ 提供連結跳到 /models/{model_id}
  • 若同一 job 已被加入過模型庫,回 409 並顯示「此任務已加入過,請至模型庫查看」

F7「下載」流程

  • 前端 → visionA backend GET /api/conversion/{job_id}/downloadserver-side 302 redirect → FAA
  • visionA backend
    1. 確認 job 屬於該 user 且狀態為 succeeded
    2. 跟 Member Center 換 delegated download tokenscope files:download.delegateTTL 5 分鐘)
    3. 直接回 HTTP 302 RedirectLocation: <FAA-URL>/files/{key}?access_token=<token>token 不暴露給 frontend JS
  • 前端觸發方式:
    • 用 anchor tag<a href="/api/conversion/{job_id}/download" download>)或 window.location.href = '/api/conversion/{job_id}/download'
    • Browser 跟著 302 redirect 到 FAA瀏覽器內建下載管理器接手
    • 觸發後 browser 內建下載管理器接手(無自訂進度條 — 但因為大檔下載 browser 自己有 UI是合理 trade-off
    • 不需要 FAA 加 CORSserver-side 302 redirect + browser navigation 完全不適用 CORSFAA owner 2026-05-02 確認 + FAA TestSite DownloadFileDirect 範例驗證)
  • Browser 直連 FAA(透過 302 跳轉),不經 visionA backend 中轉檔案內容,避免 N 次跨 internet 流量

4. 非功能需求

類別 需求
大小上限 模型 ≤ 500 MBref image 每張 ≤ 10 MB、總計 ≤ 100 張
上傳體驗 上傳進度條XHR upload.progress 事件);上傳期間禁止離開頁面(beforeunload warning
並行限制 同 user 同時最多 1 個 active jobconverter enforce 409 user_has_active_job
任務保留 7 天後 converter 自動 GCUI 在結果頁顯示倒數提醒
安全 所有 visionA → converter 的呼叫帶 service account JWT使用者不直接接觸 converter 認證
可觀測性 visionA backend log 每個 job 的 lifecyclesubmit、poll status change、import、download token issued

5. Non-GoalsPhase 0.8 不做)

# 不做的事 原因 / 後續
N1 轉檔歷史清單(/converter/jobs Phase 0.8 只支援「眼前這個 job」不做 listconverter Phase 1 GC 7 天,做歷史也只能看 7 天的CP 值低
N2 取消正在跑的 job converter 已支援 POST /jobs/{id}/cancel,但 UX flow 與錯誤狀態複雜,留待 Phase 1
N3 多 chip 同時轉檔(一次轉成多個目標) converter 端尚不支援user 可重複跑
N4 SSE / WebSocket 進度推送 polling 已足夠前端複雜度低Phase 1 量大時再評估
N5 進階轉檔參數FP16、自訂量化 預設 INT8足以涵蓋 80% case
N6 模型版本管理(同來源轉多版)/ A/B 比較 與「模型管理 Phase 2」共同規劃
N7 轉檔配額計費 Phase 2 Billing 一併處理
N8 Webhook push 模式converter → visionA Phase 0.8 純 pollingwebhook 在 converter Phase 1 已實作但 visionA 暫不接,避免在 stage 環境管理 webhook URL / 簽章

6. 整合決策Phase 0.8 確認)

# 議題 決策 理由
D1 Upload 流量路徑 Browser → visionA backend → converterstreaming proxy 一次性上傳;不需 converter 改 endpoint保持「user 只認 visionA」單一信任邊界
D2 Download 流量路徑 Browser 直連 FAA用 delegated token 同一 NEF 可能被多 user / 多次下載到 device經 backend 中轉會 N 次跨 internet 燒流量
D3 結果處理 半自動user 顯式選擇 import / download / 都做) 避免「user 只是試試」的 NEF 被自動推進模型庫
D4 進度更新 Polling 510 秒一次 簡單可靠;轉檔本身耗時 110 分鐘polling 開銷可忽略
D5 通訊協定 converter API 採既有 REST /api/v1/jobs,不新增 endpoint converter 完全不用動
D6 進入點 Sidebar 獨立 tab不混進 /models UX 流程線性、避免「上傳模型」按鈕承載過多分支

7. 整合 Dependency 一覽

系統 Phase 0.8 是否需要動? 細節
kneron_model_converter 完全不用動 POST /api/v1/jobsGET /api/v1/jobs/{id}POST /api/v1/jobs/{id}/promote 全部已實作Phase 1 完成)
File Access Agent (FAA) 完全不用動 server-side 302 redirect 模式不需要 CORSFAA owner 2026-05-02 確認 + TestSite 範例驗證);既有 PUT /files/{key}GET /files/{key}?access_token=、delegated download token validation 都已實作
Member Center (MC) ⚠️ 確認 visionA service client 4 個 scope 已授權 converter:job.writeconverter:job.readfiles:download.readfiles:download.delegate
visionA-backend 新增 /api/conversion/* 路由群 + ConverterClient HTTP 實作 internal/model.Model 已預埋 SourceSourceJobID,無需 schema migration
visionA-frontend 新增「轉檔」tab + upload / progress / result 三個畫面 UI 設計依現有設計系統

跨團隊 P0/P1 工作項目詳見 kneron_model_converter/docs/TODO-visionA-integration.md


8. 成功指標KPI

指標 目標Phase 0.8 量測方式
第一個內部使用者轉檔成功率 > 80% converter job status 統計succeeded / total
從上傳到拿到 NEF 的 P95 時間 < 10 分鐘(含上傳 + 轉檔 + promote visionA backend 在 import / download 觸發點 log timestamp
「加到模型庫」按鈕點擊率 > 50%(驗證半自動設計合理) 前端事件埋點 / backend /promote-to-models 呼叫次數
轉檔失敗錯誤訊息可理解率 100% 失敗 case 都對應到 §F5 表內訊息 失敗 log review
Stage 環境每週至少 5 次成功 e2e converter job log 統計

9. 驗收條件Phase 0.8

功能驗收

  • 左側 sidebar 顯示「轉檔」tab
  • 可上傳 .onnx 模型 + 選 KL720 chip + 0 張 ref image跑通 e2e
  • 可上傳 .onnx + KL720 + 5 張 ref imagese2e 成功
  • 上傳進度條正確顯示0% → 100%
  • 轉檔中頁面 polling 正確顯示 queued / running / succeeded 狀態變化
  • 完成頁顯示「加到模型庫」與「下載」兩個按鈕
  • 點「加到模型庫」後 /models 頁可看到新模型,標記為「轉檔來源」
  • 點「下載」後 browser 開始下載 NEF檔名合理
  • 同一個 job 可重複按「加到模型庫」(第二次顯示 409 已加入過)
  • 同一個 job 可重複按「下載」拿到新 token
  • 同 user 已有 active job 時submit 第二個 job 顯示 409 提示
  • 上傳 600 MB 檔案被拒(前端先擋 + 後端兜底)
  • 上傳 .pb(不支援格式)顯示明確錯誤
  • 轉檔失敗時顯示翻譯後的錯誤訊息 + job_id

整合驗收

  • visionA service client 在 MC 已有 4 個 scope人工確認
  • 端到端browser → visionA backend → converter → FAA → browserstage 環境跑通
  • model.Source="converted" + SourceJobID=<job_id> 正確寫入 DB
  • FAA delegated token TTL 5 分鐘正確;過期後再次點下載拿到新 token

10. 後續 Phase 規劃Non-Goals 升級路線)

Phase 項目 說明
Phase 1 轉檔歷史清單 列出該 user 過去 7 天的 jobs配合 converter 提供 GET /api/v1/jobs?user_id=
Phase 1 取消 job UI 加「取消」按鈕,呼叫 POST /jobs/{id}/cancel
Phase 1 自訂下載進度條 / 暫停恢復 改成 visionA backend stream proxy 模式(多一跳但有完整 UI 控制);只在使用者要求時做,目前 browser 內建下載管理器足夠
Phase 1 Webhook push 進度 converter → visionA backend webhook用於精確進度與避免 polling 浪費
Phase 2 進階參數FP16 / 自訂量化) converter 暴露更多 knob 後接入
Phase 2 多 chip 同時轉 一次提交產出多個 NEF
Phase 2 模型版本管理 同來源 ONNX 不同 chip 的多版 NEF 視為同一邏輯模型的 variant
Phase 2 轉檔配額 / Billing 與 Billing feature 一併處理

11. 給 Architect / Design 的注意事項

  • Architect
    • visionA backend 需新增 internal/converter/ 套件實作 HTTPConverterClient(取代 Phase 0 的 Stub
    • 上傳要走 streaming proxyio.Copy + multipart.Reader不可 buffer 全 RAM、不可寫 disk
    • polling 端點 /api/conversion/{job_id} 要做 user-scoped 授權檢查
    • promote-to-models 流程要 idempotent同 job 重複呼叫不重複建模型)
  • Design
    • 轉檔 tab 的 wireframeupload → progress → result需獨立設計
    • 失敗狀態的視覺處理(顏色 / icon參考既有錯誤模式
    • 「加到模型庫」與「下載」兩個按鈕的視覺平衡(不要讓使用者覺得有預設答案)
    • 進度條設計要區分「上傳階段」0100% 精確)與「轉檔階段」(不確定百分比)

12. 連結

  • 回:PRD 索引
  • 相關:模型管理介面契約
  • 跨專案:kneron_model_converter/docs/TODO-visionA-integration.mdkneron_model_converter/apps/task-scheduler/docs/openapi.yaml