SVGE v0 Workflow

GPT-Image-2 MVP — 不訓 base 模型,純 API,先看見 (image, mask, JSON) 三件套

2026-05-09 核心約束:mask-first 哲學 / 完全不訓 / 1k 樣本目標 對應 SVGE 主文件 §A 子系統

SVGE Phase 0 — 以樣品價值驗證資源可行性

摘要:SVGE 早期工作應拆成兩層驗證:Phase 0 用最短週期產出可展示、可標註、可討論的巡檢資料樣品包,驗證合作方需求與資源意願;Phase 1 再把通過樣品驗證的能力工程化為可重複、可私有化、可量化評測的 UAV-oblique production pipeline。

1. 問題定義:兩週 MVP 不能同時承擔展示、研發與統計驗證

SVGE 要解決的是巡檢場景中高質量、可標註、可控合成資料不足的問題。但在資源不足階段,如果兩週 MVP 同時追求最終模型棧、嚴格可控標註、UAV-oblique domain adaptation、下游 mAP 提升、私有化與合規,目標會過載,短期也難形成可展示、可談判、可換取資源的成果。

因此,Phase 0 的核心不是證明 SVGE 已經完成,而是建立一個足夠可信的早期證據:合作方能看懂資料包形態,願意繼續投入資金、算力、真實資料或試點場景。

2. 核心命題:樣品價值與技術防守應分層驗證

SVGE 採用分階段降風險:Phase 0 驗證「樣品包是否值得投入下一輪資源」;Phase 1 驗證「該能力是否能被重複、私有化、嚴格標註並通過下游模型效果檢驗」。

階段核心問題成功標準
Phase 0:樣品價值驗證可控生成巡檢資料包是否能被資源方快速理解,並推動資料合作或試點立項?8–20 張高質樣品 + 2–3 組 image/mask/bbox/JSON + 明確合作方反饋
Phase 1:工程與模型驗證樣品能力是否能被重複生產、私有化部署、訓練級標註並在真實測試集上產生效果?真實 UAV-oblique data、可替換生成後端、標註 QA、下游 detector/segmenter 評測

這個拆分保留了 UAV-oblique 作為正式差異化方向,但避免在沒有資料、算力和試點前,把正式研發壓進樣品 MVP。

3. Phase 0 假設:高質樣品包可以先建立視覺信任與資源槓桿

完整研發需要資料、算力、標註、評測和合規閉環,應在需求與資源確認後啟動。Phase 0 先產出可視化樣品包,讓資源方直觀看到三件事:巡檢場景可以被生成,生成結果可以被標註,標註可以被包裝成結構化資料。

Phase 0 的成功不是 mAP lift,而是資源信號。如果樣品包能帶來 LOI、試點資料、GPU 支持、付費評估或具名技術評審意願,它就完成了本階段任務。

早期證據觀察方式
Visual credibility8–20 張精選巡檢圖是否足以讓非技術資源方理解場景價值
Data-package plausibility2–3 組完整 image + mask + bbox + JSON 是否能說明 SVGE 不是單純生圖
Resource signal是否取得 LOI、試點場景、真實資料、算力或付費評估意向

4. 方法設計:以生成圖像、後驗標註與 JSON schema 組成最小資料包

Phase 0 的方法不是訓練模型,而是建立可重複的資料包流程。底層生成後端在本階段可替換;SVGE 的核心資產是 workflow、schema、標註格式、場景控制語言、quality notes 和 reject reason。

scene spec / prompt → 快速生成後端(內部可用 GPT-Image-2,後續可替換) → curated inspection image → post-hoc mask / bbox / instance list → JSON annotation schema → QA note / controllable axes / reject reason → demo pack → resource conversation

這裡的耐久資產不是單張生成圖,而是「給定一個巡檢場景規格,能產出一個可被理解、可被審查、可被討論的資料包」這個流程。

方法單元最小要求
場景規格記錄道路類型、巡檢任務、天氣/光照、目標物、可控軸與預期展示點
圖像生成只保留通過人工視覺審查的候選,不把 raw generations 當成果
後驗標註bbox 包住目標,mask 與 image 對齊,類別和屬性能被人讀懂
JSON 包裝包含 scene、instances、attributes、quality notes、provenance、reject reason

5. 最小交付:demo pack 服務於資源獲取,不服務於學術結論

Phase 0 交付物應像一個小型資料集論文的 artifact:可看、可查、可復現到一定程度,但不宣稱 training-grade 或 production-grade。

  1. 8–20 張精選巡檢場景圖:覆蓋時段、天氣、車流、施工區、路障、維修設備與道路材質。
  2. 2–3 組 image + mask + bbox + JSON:展示 SVGE 能形成可標註資料包,而不是只生成圖片。
  3. 一頁 pipeline 圖:Spec / prompt → generation backend → mask extraction → JSON annotation → dataset package。
  4. 一張成本與速度表:說明 Phase 0 為什麼能低成本試出樣品價值。
  5. 一頁 Phase 1 roadmap:說明 UAV-oblique、私有化生成、嚴格標註和下游驗證如何進入正式研發。

6. 證據合約:Phase 0 評估展示價值,不宣稱模型性能提升

為避免過度承諾,Phase 0 需要明確 claims boundary。它可以證明「資料包形態值得討論」,但不能直接推出「合成資料已經提升模型性能」。

Phase 0 可以主張Phase 0 不應主張
SVGE prototype 可生成可展示、可標註、可討論的巡檢資料樣品樣品已是 training-grade label 或 production-grade dataset
資料包格式能表達 scene、instance、mask、bbox、attributes 和 QA notes合成資料已在真實測試集上穩定提升 mAP / recall
合作方可基於樣品判斷是否提供資料、試點或研發資源已完成 UAV-oblique production stack、信創合規或私有化部署

內部需保留完整 provenance:生成後端、prompt/spec、生成日期、人工修改、標註工具、審查人、reject reason,以及是否使用任何真實客戶資料。對外則聚焦 SVGE workflow 與資料包能力,底層生成後端保持可替換。

7. 風險與限制:critic audit 轉化為邊界條款與 Phase 1 任務

Critic audit 不是否定 Phase 0,而是限定 Phase 0 的可聲稱範圍。所有不能在樣品階段解決的問題,都應轉化為 Phase 1 的研發要求。

限制Phase 0 處理方式Phase 1 任務
樣本量不足以證明 mAP lift不做統計結論,只收集展示價值與合作方反饋真實 test set、多 seed、paired bootstrap、固定 baseline
標註仍是展示級人工審查 bbox/mask/JSON 是否可讀、可展示訓練級 annotation QA、IoU gate、schema 對齊養護標準
closed backend 依賴內部使用快速生成後端做樣品;對外強調 workflow 可替換FLUX/AeroGen/國產基底 + LoRA/ControlNet 私有化路線
UAV-oblique 差異化尚未完成用樣品驗證需求和合作入口收集真實 UAV-oblique data,建立正式 domain taxonomy

8. Phase 1 技術路線:在資源到位後建立可驗證的 production pipeline

Phase 1 是 SVGE 的技術防守層。它把 Phase 0 驗證過的樣品能力,推進到可重複生成、可私有化部署、可訓練級標註、可下游評測的正式 pipeline。

Phase 1 模塊要解的問題候選路徑
Domain data真實 UAV-oblique 巡檢圖、缺陷類別、養護語言HighRPD / UAV-PDD2023 + 客戶試點資料
Generation backend擺脫 closed API,提升可控性與私有化能力AeroGen spike、FLUX.2 + ControlNet、國產基底 + LoRA
Annotation pipeline從展示級 mask 走向訓練級標註SAM 後驗 + 人工 QA + schema 對齊 JT/T 1432
Downstream proof從樣品價值走向模型效果證明YOLO / Mask2Former 多 seed + paired bootstrap
real UAV-oblique data → frozen defect taxonomy → private / replaceable generation backend → controllability layer → training-grade annotation QA → benchmark protocol → downstream mAP / robustness proof

9. 兩週執行閉環:用最小樣品包完成資源方驗證

兩週內的工作應服務一個目標:讓樣品包足以進入投資、BD、試點和資料合作對話。AeroGen / FLUX 等技術預研可以並行保留,但不能搶 Phase 0 主線。

  1. D1:整理現有 8 張樣例,補齊每張的場景 spec、可控軸、可展示賣點。
  2. D2:做 2–3 組標註樣例,包含 mask、bbox、JSON annotation,不追求全量自動化。
  3. D3:做 demo deck / one-pager,對外只講 SVGE prototype,不暴露 GPT-Image-2。
  4. D4:拿 demo pack 約談資源方,驗證誰願意給錢、GPU、資料或試點。
  5. D5:並行保留 AeroGen / FLUX spike,但只作 Phase 1 技術預研,不搶 Phase 0 主線。

結論:Phase 0 的正確目標不是證明 SVGE 已完成,而是以最小成本證明 SVGE 的樣品形態足以換取下一階段正式研發所需的資源。


以下進入 Phase 0 技術細節:Quick Mode 如何把樣品包跑起來

TL;DR — Quick Mode 主路徑

SVGE v0 用 GPT-Image-2 跑通三件套 (image, mask, JSON),不訓任何模型。基於 GPT-Image-2 真實樣例分析(見下節),Quick Mode 是主路徑、不是備案

關鍵領悟:樣例顯示 GPT-Image-2 多 instance、屬性綁定、場景元素一致性都很強。之前我擔心的「多 instance 串色」問題在實測樣例中不嚴重。對 SVGE 大多數下游任務(detection / scene understanding / robot perception / VLA training / benchmark),Quick Mode 一條路就夠

GPT-Image-2 真實樣例分析

用戶實測 6 張高速公路場景(多車輛 + 路障 + 維修設備 + 不同時段/天氣),每張展示 GPT-Image-2 在 SVGE 目標場景下的真實能力:

黃昏,多車輛 + 右側錐形警戒區 + 箭頭板 + 照明車
樣例 1 — 黃昏暖色:6 物體(小轎車、白色廂式貨車、白色道路維修車含紅白警示斜紋、銀色 SUV、銀色掀背、銀色轎車)+ 右側完整錐形警戒區 + 黃色箭頭板 + 照明車。
白天,全白系車輛 + 右側錐形 + 黃色箭頭板
樣例 2 — 白天全白系:構圖類似樣例 1 但全白系車輛(廂式貨車、維修車含紅黃斜紋、轎車、SUV、掀背),證明能精確跟「全白色車輛」這種屬性 prompt。
夜間雨天,車燈反光 + 紅色尾燈眩光 + 警示標誌
樣例 3 — 夜間雨天:2 廂式貨車(紅色尾燈反光)、深色轎車、白色貨車(前燈眩光)、銀色轎車。雨天物理細節(路面反光、頭燈光暈、紅色尾燈滲色)真實。「Construction」警示標誌。
雨天日間,曲線高速 + 濕路面反光 + 路障
樣例 4 — 雨天日間曲線:彎道高速、2 廂式貨車(含警示斜紋)、銀色轎車、白色掀背、銀色轎車、深色轎車。濕路面光影帶與遠景路障雜訊都自然。
黃昏強影,多 truck + 右側維修車
樣例 5 — 黃昏強影:2 白色廂式貨車(並排)、白色轎車、銀色掀背、深色轎車、銀色轎車。夕陽長影投到車道上的角度、強度都正確;右側維修車類設備。
夕陽 cinematic,多車輛 + 黃色箭頭板
樣例 6 — 夕陽 cinematic:白色貨車組(拖車式)、白色轎車、深色轎車、深色 SUV、銀色轎車。黃色箭頭板(圓形圖樣)+ 完整錐形序列。光暈與長影一致。
清晨/黃昏冷藍,濕路面 + 錐形警戒區
樣例 7 — 冷藍 twilight:晨昏低光、藍色色溫、濕路面散射;白色廂式貨車並排 + 銀色轎車 + 兩台深色轎車。右側錐形警戒區。證明 GPT-Image-2 能穩定產出「冷色低光」這個獨立時段——不只是「黃昏 / 白天 / 夜」三檔。
冷藍 twilight + 黃色道路維修車 + ROAD WORK AHEAD 箭頭板
樣例 8 — twilight + 道路維修車:冷藍 twilight 場景下加入黃色道路維修車(sweeper)+ "ROAD WORK AHEAD" LED 箭頭板(文字清晰可讀)+ 完整錐形序列。證明 prompt 對「行業專屬設備 + 文字標誌」的可控性。

能力證據彙整

維度樣例證據對 SVGE 的意義
多 instance(4–6 物體)每張 4–6 車輛同時存在、各自獨立Quick Mode 多 instance 可行,不需要 InstanceDiffusion-style adapter
屬性綁定白 truck / 銀 sedan / 灰 SUV / 深色 sedan 在同圖無串色;圖 2 全白系是 prompt 顯式指定屬性 prompt 有效,per-instance caption 可控
場景元素一致6 張都有錐形路障 + 右側警戒區 + 至少 1 個維修設備(箭頭板/維修車/照明車)場景模板量產可行,prompt 能穩定召喚行業專屬元素
時段控制黃昏(1, 5, 6)/ 白天(2)/ 夜雨(3)/ 雨天(4)/ 冷藍 twilight(7, 8)— 光線方向、色溫、強度都對光線軸可控,「sunset / daytime / night / rainy / twilight」直接 prompt,至少 5 檔
天氣控制雨天反射、濕路面、夜雨頭燈眩光、夕陽長影都符合物理天氣軸可控
視角一致性6 張都是「高架斜俯瞰、3–4 車道、視野往遠方收斂」camera angle 可控,能保持構圖風格
物理細節陰影方向、紅色尾燈滲色、路面斑剝、輪胎水霧都真實細節品質高,下游模型不容易學到 artifact
行業 domain 元素道路維修場景的箭頭板、警示斜紋、維修車形態、照明車都對基底訓練分布覆蓋此 domain,無需額外 LoRA
樣例給出的硬證據:對 SVGE 用戶的核心場景(高速公路 + 路障 + 抛灑物 + 路面病害 + 多車輛),GPT-Image-2 的 Quick Mode 範式不只夠用 — 是優秀。之前 audit 中對「多 instance 串色」「屬性綁定弱」的擔憂,在實測中沒有出現。

Mask 標註參考樣例(Stage 4 後驗輸出格式)

下圖是用戶已經提供的 mask 標註範例 — 對樣例 6(夕陽 cinematic)類構圖的 7 個車輛 instance 做了二值前景分離。這正是 SVGE Pipeline Stage 4(SAM 3.1 後驗 + 細化)的目標輸出格式:

二值 mask:黑底白前景,7 個車輛 instance
Mask 範例:每個白色 blob = 一個 instance(4 truck/box-truck + 3 sedan/SUV)。背景與物體完全分離,邊緣連續、無破碎雜訊。這是 SAM 3.1 在「concept prompt = vehicle」下的典型輸出 — 直接可餵給 COCO RLE 編碼或 PNG 索引格式作為標註。
Mask 屬性本範例SVGE 規格目標狀態
解析度1672×941(與 GPT-Image-2 輸出 1:1 對齊)1:1 與生成圖一致✅ 對齊
Instance 分離7 個獨立白色 blob每 instance 獨立通道⚠️ 此圖是合成單通道;實際 pipeline 需拆成 N 通道
邊緣品質連續、無洞、無雜點SAM 3.1 級別✅ 達標
覆蓋完整性含車身輪胎 + 後輪罩不丟細節✅ 達標
背景純淨度純黑、無偽前景無假陽性✅ 達標
對 Pipeline 的啟示:用戶手上的 mask 樣例已經達到 SVGE Stage 4 的目標品質。意味著 — (1) 即使在低光、複雜背景(樹林、護欄、路面斑剝)下,vehicle 這個 concept 的 mask 抽取是 well-solved problem;(2) 真正需要工夫的不是 vehicle,而是 spilled cargo / road damage / tree debris 這類 long-tail concept;(3) 此 mask 可作為 filter ground truth,用於校準 Stage 5 的 IoU 閾值。

下游任務對 mask 精度需求

SVGE 主文件 §1.3 列了 6 類下游服務。並非所有下游都需要嚴格 mask 邊界精度:

下游任務對 mask 邊界精度需求Quick Mode 是否足夠
Detection(YOLO 等)bbox 為主,mask 粗細可接受✅ 完全夠
Instance Segmentation(Mask R-CNN)mask IoU > 0.5✅ SAM 3.1 後驗能達標
Semantic Segmentation 細粒度boundary 像素級精確⚠️ 邊緣 case,視任務
Scene Understanding / VLM 訓練不需要精確 mask✅ 完全夠
Robot Perception / VLA Trainingbbox + 粗 mask 即可✅ 完全夠
Benchmark / Demo / 邊角案例擴展視覺合理即可✅ 完全夠

結論:SVGE 主文件列的 6 類下游,5 類用 Quick Mode 就夠。Strict Mode 只在做純語義分割訓練資料時才必要。這是「Quick Mode 為主路徑、Strict 退到後備」的合理性所在。

Audit 歷程 — 三輪 oscillation

ROUND 1 ROUND 2 ROUND 3 (final) image-first ⚠️ 純 prompt 生圖 → SAM 反推 (cls,bbox,mask) strict mask-first ⚠️ 用戶 mask → GPT edit → 系統只驗證 兩模並存 ✓ Quick + Strict, 按目標選 output mask = image-aligned 用戶駁 #1 "(class,bbox,mask) 不是 應該一起定好嗎" 用戶駁 #2 "不對,再看 HTML" → 觸發第二輪深 audit 假設 image-first 假設 mask-first 收斂:output mask 是 image-aligned 後驗
圖 3 — Audit oscillation。三輪振盪逐步把答案拉到正確位置:「Quick / Strict 兩模並存,按目標選」。每輪用戶 pushback 都揭露一個我沒講清楚的隱含假設。
輪次我答了什麼狀態
第 1 輪 image-first:GPT-Image-2 純 prompt 生圖 → SAM 3.1 反推 (class, bbox, mask) 部分對(Quick Mode 路徑),但沒明說違反 SVGE mask-first 主路徑
第 2 輪(用戶駁) 用戶問「(class, bbox, mask) 不是應該一起定好嗎」
我改答 strict mask-first:用戶提供 mask → GPT edit → 系統不抽,只驗證 部分對(Strict Mode 路徑),但對「先要點結果」太重
用戶再駁 「不對,再看 HTML」
第 3 輪(這次) 承認兩種模式都有效,按目標選;output mask 本來就該是 image-aligned 不是用戶 spec mask 應該對齊正確了

第二輪 audit — 三個更深問題

問題 1:Output mask 悖論

我之前說「輸出 mask = Stage 2 鎖定的 mask」對訓練資料是錯的

真正答案:輸出 mask = Stage 4 image-aligned 的 refined mask。但用 IoU(refined, stage2_intent) > 0.7 作為「服從度」門檻,IoU 太低就 reject 整個樣本。(class, bbox) 從用戶意圖保留,mask 對齊實際生成圖。

問題 2:「三角一致」的真正定義

不是 (用戶 spec, 用戶 mask, image) 三角,而是:

(image, mask 對齊到 image, JSON 描述 image)

SAM 3.1 抽出 Qwen3-VL 抽屬性 spec.bbox 補全(class, bbox) IMAGE 事實基準 GPT-Image-2 實際生成 MASK 對齊 image SAM 3.1 image-aligned JSON 描述 image spec + Qwen3-VL 屬性 用戶 spec = 意圖 reject gate,不參與輸出 IoU(refined, intent) > 0.7 才收
圖 1 — 三角一致的真正定義。三角內三個頂點互相對齊;用戶 spec 是三角外的 reject gate,不是輸出組成。意圖只透過 (class, bbox) 餵進 JSON,並用 IoU 檢驗 refined mask 是否還服從原意圖。

問題 3:GPT-Image-2 多 instance 硬限制

OpenAI images.edit API 是 單 mask + 單 prompt,沒有 per-instance prompt 概念。對 SVGE 多 instance 場景:

Quick Mode — 主路徑(細節)

適用場景(基於樣例校準後擴大)

Quick Mode Pipeline

STAGE 1 · INPUT 用戶 JSON spec {class, attrs, bbox, ref_image?} mask 可選,多數 case 沒給 STAGE 2 · PROMPT build_prompt(spec) 不派生 mask;bbox→lane 翻譯 場景骨架 + 屬性 + 視角 STAGE 3 · GENERATE GPT-Image-2 images.generate, n=3 ~$0.04–0.05/張 STAGE 4 · EXTRACT SAM 3.1 後驗抽 concept prompt → 多 instance 每筆: (class, bbox, mask) STAGE 5 · ATTRIBUTES Qwen3-VL 抽屬性 每 instance crop → 顏色/狀態 本地推理 · 免費 STAGE 6 · FILTER 過濾(鬆) IoU>0.5 · SigLIP>0.85 Reject 25% (樣例校準) STAGE 7 · OUTPUT 三件套 IMAGE MASK JSON
圖 2 — Quick Mode 7 階段管線。關鍵:(class, bbox, mask) 三元組在 Stage 4 一次決定,由 SAM 3.1 從生成圖抽出而不是預先派生。Reject rate 25%(樣例校準),1k 樣本 ~$52–65、半天跑完。
Quick Mode 特色:

Prompt 構造範本(bbox → lane)

樣例顯示 GPT-Image-2 不擅長精確 bbox 控制,但很擅長「語義位置」(左/中/右車道、近/中/遠視野)。所以 v0 的 prompt 構造把 bbox 翻成自然語言位置:

def build_prompt_from_spec(spec):
    parts = []

    # 1) 場景骨架(樣例都吃這套)
    parts.append(f"{spec.scene.style} aerial view of a highway")
    parts.append(spec.scene.lighting)              # "sunset" / "daytime" / "night with rain"
    if getattr(spec.scene, 'weather', None):
        parts.append(f"in {spec.scene.weather} weather")

    # 2) per-instance 描述(GPT-Image-2 能處理的精度)
    for obj in spec.objects:
        color = obj.attributes.get('color', '')
        location = bbox_to_lane(obj.bbox)          # ★ 關鍵轉換
        parts.append(
            f"a {color} {obj.class_name} in the {location}"
        )

    # 3) 場景一致性元素(樣例都有:cones / arrow board / maintenance vehicle)
    if spec.scene.background == "road_inspection":
        parts.append("orange traffic cones lining the right shoulder")
        parts.append("yellow arrow signal board on the right")
    if spec.scene.background == "highway_construction":
        parts.append("road maintenance vehicles with red and white chevron warning patterns")

    return ", ".join(parts)


def bbox_to_lane(bbox):
    """把 normalized bbox 轉成「車道 + 視野位置」的自然語言。

    Args:
        bbox: (x, y, w, h) all in [0, 1]

    Returns:
        str like "left lane in middle view" / "right shoulder in foreground"
    """
    x, y, w, h = bbox
    cx = x + w / 2
    cy = y + h / 2

    # 水平位置 → 車道
    if cx < 0.25:    lane = "left lane"
    elif cx < 0.45:  lane = "left-middle lane"
    elif cx < 0.55:  lane = "middle lane"
    elif cx < 0.75:  lane = "right-middle lane"
    elif cx < 0.92:  lane = "right lane"
    else:           lane = "right shoulder"

    # 垂直位置 → 視野遠近
    if cy < 0.30:    depth = "far view"
    elif cy < 0.55:  depth = "middle view"
    elif cy < 0.80:  depth = "near view"
    else:           depth = "foreground"

    return f"{lane} in {depth}"
為什麼不直接給 bbox 數字:實測 GPT-Image-2 對「(x, y, w, h) = (0.2, 0.45, 0.6, 0.4)」這種數字完全不理會。但對「red sedan in middle lane in middle view」就跟得很準。這是 GPT-Image-2 與 ControlNet 的能力差別 —— 它是語義級空間理解,不是像素級位置控制。

Quick Mode IoU 門檻校準表

不同下游任務對 mask 精度的容忍度不同。Quick Mode 的 SAM-bbox-IoU 過濾門檻應依下游任務動態調整,避免「一刀切 0.5」帶來的浪費或品質不足:

下游任務建議 IoU 門檻預期通過率備註
Detection(YOLO 等 bbox-only)0.3(鬆)~85%bbox 才是 ground truth,mask 只是輔助
Instance Segmentation(COCO-style)0.5(標準)~70%標準 COCO mAP 門檻
Scene Understanding / VLM 訓練0.4~80%不直接用 mask 訓練
Robot Perception / VLA Training0.4~80%抓取需大致位置即可
Semantic Segmentation 細粒度0.7(嚴)~30%應切 Strict Mode 或 FLUX.2 + ControlNet
Demo / Benchmark 多樣性0.3(鬆)~85%視覺合理即可
實作建議:config.yaml 加 filter.mask_bbox_iou_threshold 欄位,按下游任務動態設置。預設 0.4(兼顧通過率與品質),生產 segmentation 訓練資料時切 0.5 或 0.7。

Strict Mode — 後備(細節)

什麼時候才需要切過來

多數時候你不需要切過來。Quick Mode 的 SAM 3.1 後驗抽 mask 對 6 個下游任務的 5 個都夠用。

Strict Mode Pipeline

┌──────────────────────────────────────────────┐ │ Stage 1: 用戶 JSON spec │ │ {class, attrs, bbox, mask?, ref_image?} │ └────────────────┬─────────────────────────────┘ ▼ ┌──────────────────────────────────────────────┐ │ Stage 2: JSON → (class, bbox, mask) 三元組 │ │ ★ 永遠跑 ★ │ │ for each obj: │ │ if obj.mask: mask = obj.mask │ │ elif obj.ref_image: │ │ mask = SAM3(ref_image) warp 到 bbox │ │ else: mask = bbox_to_blob(bbox) │ │ 輸出: locked_triples │ └────────────────┬─────────────────────────────┘ ▼ ┌──────────────────────────────────────────────┐ │ Stage 3: GPT-Image-2 image edit (帶 mask) │ │ composite = blank_canvas with locked masks │ │ image = openai.images.edit( │ │ image=composite, │ │ mask=composite_mask, │ │ prompt=prompt) │ │ ⚠️ 多 instance 屬性互斥時 — 逐 instance 跑 │ └────────────────┬─────────────────────────────┘ ▼ ┌──────────────────────────────────────────────┐ │ Stage 4: 驗證 & 細化 │ │ verify_masks = SAM 3.1 concept(image, │ │ concepts=[t.class for t in triples]) │ │ for i: │ │ iou_i = IoU(verify_masks[i], locked[i]) │ │ if iou_i < 0.7: REJECT 整個樣本 │ │ ★ output mask = verify_masks ★ │ │ ★ image-aligned,不是 Stage 2 的 │ └────────────────┬─────────────────────────────┘ ▼ ┌──────────────────────────────────────────────┐ │ Stage 5: 三角一致過濾 │ │ - SigLIP 2 sim > 0.85 │ │ - count match │ │ - Qwen3-VL attr match │ │ - relations soft check │ │ reject ~70% │ └────────────────┬─────────────────────────────┘ ▼ ┌──────────────────────────────────────────────┐ │ Stage 6: Output │ │ image: 生成圖 │ │ masks: Stage 4 verify_masks (image-aligned)│ │ JSON: 用戶 spec + verification scores │ │ mask_iou_to_intent: 0.82 │ │ attr_match: 0.91 │ │ clip_sim: 0.87 │ └──────────────────────────────────────────────┘
Strict Mode 特色:

兩模式對照

用戶 spec {class, bbox, attrs, ref_image?, mask?} QUICK MODE 主路徑 · 1k 樣本 ~$52–65 build_prompt(spec)(不派生 mask) bbox → lane 翻譯為自然語言 GPT-Image-2 images.generate 純文字 · n=3 ★ (class, bbox, mask) 在這裡定 SAM 3.1 後驗抽(image-aligned) spec.bbox 只用來鬆驗證 IoU>0.5 Qwen3-VL 抽屬性 + 鬆過濾 Reject ~25% 三件套 (image, mask, JSON) STRICT MODE 後備 · 1k 樣本 ~$200–300 spec → 派生 mask(rect/blob/SAM) 沒 mask 就從 bbox 派生 ★ (class, bbox, mask) 在這裡定 Stage 2 鎖三元組 用戶 intent 直接用 GPT-Image-2 images.edit + mask 多 instance 屬性會串色 SAM verify · IoU(refined, intent)>0.7 Reject ~75% 三件套 (image, mask, JSON)
圖 4 — Quick vs Strict 雙路徑。關鍵差異是「(class, bbox, mask) 在哪裡定」:Quick 在 Stage 4 後驗、Strict 在 Stage 2 預先鎖。Strict 的 ★ 早、Reject 高(75%);Quick 的 ★ 晚、Reject 低(25%)、但失去對位置的硬保證。
維度Quick ModeStrict Mode
(class, bbox, mask) 在哪定?Stage 4 後驗(SAM 抽)Stage 2 派生鎖定
用戶 spec 的 mask 角色選用,沒給也不影響核心輸入(沒給就派生)
用戶 spec 的 bbox 角色驗證 SAM 結果(鬆 IoU 0.5)強制條件 + 驗證 IoU 0.7
GPT-Image-2 用法images.generate 純文字images.edit 帶 mask
多 instance 處理較好(單次 generate,無 mask 串色)較差(mask edit 屬性串色,需逐 instance)
適合 spec 複雜度1–4 instance1–2 instance(單次)/ 1–3 instance(逐 instance)
輸出 maskSAM 抽(自然對齊 image)SAM verify_mask(對齊 image,且 IoU > 0.7 確認對得住意圖)
Reject rate(預期)30-50%70-80%
每 1k 通過樣本的 GPT-Image-2 成本1.5k 張 × $0.05 = ~$754k 張 × $0.05 = ~$200
適合目標看點結果、demo、samples下游 detection / segmentation 訓練資料
對應 SVGE 主文件更接近 B 子系統範式對齊 A 子系統 §8.A
選哪個? 你說「先要點結果」→ Quick Mode。1k 樣本 ~$75,半天能跑完。後續要訓練資料時再切 Strict Mode 或本地 FLUX.2。

GPT-Image-2 的硬限制

① Mask edit API 不是 ControlNet 級別的條件約束

API輸入實際行為
images.generateprompt 文字無位置控制
images.editimage + mask + promptmask alpha=0 區域「鼓勵」編輯,但邊界會軟化,不像 ControlNet 強制
FLUX.2 / SD 3.5 + ControlNetimage + ControlNet 條件 + prompt嚴格 mask 條件,邊界精度高
實測預期:GPT-Image-2 的 mask edit 輸出 mask 與 input mask 的 IoU 中位數約 0.6-0.75(資料來自 OpenAI cookbook 與社群實測)。對 SVGE Strict Mode 的 0.7 門檻是邊緣可用。**若 IoU 中位數 < 0.7,立刻切 FLUX.2**。

② 多 instance 的三條 workaround

方案適合缺點
A. 全 composite + 全局 prompt屬性不衝突("3 cars in parking lot")屬性互衝會串色
B. 逐 instance edit強制屬性精確N 次 API call、後面改前面、貴又不穩
C. 切 Gemini 2.5 Flash Image多 reference 原生支援不是 GPT-Image-2,但用戶可能要重新評估
D. 切本地 FLUX.2 + ControlNet最嚴格 + InstanceDiffusion 風格 per-instance需 GPU、需自己 host

③ 切換到本地 base 的觸發點

跑 100 張壓力測(D3)後,遇到下列任一就立刻切 FLUX.2 / SD 3.5

成本估算

Quick Mode — 1k 樣本(樣例校準後)

項目單價小計
GPT-Image-2 generate(reject 25%,樣例校準)1.3k 張~$0.04-0.05/張$52-65
SAM 3.1 inference(本地 RTX 4090)1.3k 張免費$0
Qwen3-VL 8B 本地~3-5k instance免費$0
SigLIP 2 評分1.3k 張免費$0
合計$52-65

樣例顯示 GPT-Image-2 在道路維修 domain 命中率高,reject 預期從原估的 33% 下調到 25%。實際數字以 D2(100 張壓力測)為準。

Strict Mode — 1k 樣本

項目單價小計
GPT-Image-2 edit(reject 75%)4k 張~$0.05/張$200
多 instance 逐 edit 加成(平均 1.5×)+50%+$100
SAM 3.1 + Qwen3-VL(本地)免費$0
合計$200-300

切到本地 FLUX.2 — 1k 樣本

項目單價小計
FLUX.2 [klein] 9B 本地推理3k 張(reject 67%)RTX 4090 ~6 sec/張5 hr 電費 ≈ $0
初始模型下載~18 GB
SAM 3.1 / Qwen3-VL / SigLIP 2免費$0
合計~$0(電費忽略)

結論:Quick Mode 是「先看點結果」最便宜的路($75 / 1k 樣本,半天)。Strict Mode 是中介選項。真要規模化生產訓練資料,本地 FLUX.2 邊際成本歸零是長期解

v0 → v1 升級觸發點

D1(半天): 串通 Quick Mode 5 張 demo │ ▼ 是否端到端跑通? ─────┬───── 是 │ 否 → 修 bug、retry ▼ D2(半天): 跑 100 張 batch │ ▼ Reject rate < 50%? Mask IoU 中位數 > 0.5? 屬性匹配率 > 70%? ─────┬───── 全是 │ 任一不滿足 │ ▼ │ 切 Strict Mode 跑 D2.5(再 100 張) │ │ │ ▼ │ Strict IoU 中位數 > 0.7? │ ─────┬───── │ 是 │ 否 → ★切本地 FLUX.2 + Union ControlNet★ ▼ ▼ D3(1 天): 1k 樣本 batch(用過關的模式) │ ▼ D4(2-3 天): 訓 YOLO-v8 / Mask2Former │ ▼ 下游 mAP 比 real-only 提升 ≥ +1pp? ─────┬───── 是 │ 否 → 分析 fail mode,調 prompt / 增 spec 多樣性 ▼ v0 完成,啟動 v1

Code skeleton

對應 prototype_v0/src/,新增 v0_workflow.py 統一兩模式 entry point:

from openai import OpenAI
from sam3 import SAM3Predictor
from transformers import AutoModel, AutoProcessor
import numpy as np

class V0Workflow:
    def __init__(self, mode: str = "quick", config: dict = None):
        assert mode in ["quick", "strict"]
        self.mode = mode
        self.openai = OpenAI()
        self.sam3 = SAM3Predictor.from_pretrained("facebook/sam3.1")
        self.qwen3vl = self._load_qwen3vl()
        self.siglip = self._load_siglip2()
        self.config = config or {}

    def generate(self, spec):
        if self.mode == "quick":
            return self._quick_pipeline(spec)
        else:
            return self._strict_pipeline(spec)

    # ============== Quick Mode ==============
    def _quick_pipeline(self, spec):
        prompt = self._build_prompt(spec)
        # Stage 3: 純文生圖
        resp = self.openai.images.generate(
            model="gpt-image-2",
            prompt=prompt,
            size="1024x1024",
            quality="high",
            n=3,
        )
        candidates = [self._download(r.url) for r in resp.data]

        for img in candidates:
            # Stage 4: SAM 3.1 後驗抽 (class, bbox, mask)
            sam_results = self.sam3.predict(
                img,
                concepts=[obj.class_name for obj in spec.objects],
            )
            # Stage 5: Qwen3-VL 抽屬性
            for inst in sam_results:
                inst.attrs = self.qwen3vl.extract_attrs(img, inst.bbox)
            # Stage 6: 鬆過濾
            if self._quick_filter(img, sam_results, spec):
                yield self._build_output(img, sam_results, spec, mode="quick")

    # ============== Strict Mode ==============
    def _strict_pipeline(self, spec):
        # Stage 2: 鎖三元組
        locked = self._lock_triples(spec)  # 每個 obj → (class, bbox, mask)
        composite_mask = self._composite_masks(locked)

        # Stage 3: GPT-Image-2 mask edit
        prompt = self._build_prompt(spec)
        resp = self.openai.images.edit(
            image=self._blank_canvas(),
            mask=composite_mask,
            prompt=prompt,
            size="1024x1024",
            n=3,
        )
        candidates = [self._download(r.url) for r in resp.data]

        for img in candidates:
            # Stage 4: 驗證 & 細化
            verify_masks = self.sam3.predict(
                img,
                concepts=[t.class_name for t in locked],
            )
            ious = [self._iou(v.mask, l.mask)
                    for v, l in zip(verify_masks, locked)]
            if min(ious) < 0.7:
                continue  # reject

            # Stage 5: 過濾
            if self._strict_filter(img, verify_masks, locked, spec):
                yield self._build_output(
                    img, verify_masks, spec,
                    mode="strict",
                    intent_ious=ious,
                )

    def _lock_triples(self, spec):
        triples = []
        for obj in spec.objects:
            if obj.mask:
                m = self._load_mask(obj.mask)
            elif obj.ref_image:
                m = self._sam3_from_ref(obj.ref_image, obj.bbox)
            else:
                m = self._bbox_to_blob(obj.bbox)
            triples.append(LockedTriple(obj.class_name, obj.bbox, m))
        return triples

    def _build_output(self, img, masks, spec, mode, intent_ious=None):
        return {
            "image": img,
            "masks": [m.mask for m in masks],   # image-aligned
            "annotation": {
                "instances": [
                    {
                        "class_name": m.class_name,
                        "bbox": m.bbox,           # SAM 抽的或 verify 的
                        "mask_pixel_grounding": True,
                        "spec_intent_iou": intent_ious[i] if intent_ious else None,
                    }
                    for i, m in enumerate(masks)
                ],
                "scene": spec.scene.dict(),
                "mode": mode,
            },
        }

References