From aebbe87c164872d3ba103676f78e5abf9586d04a Mon Sep 17 00:00:00 2001 From: rui40000 Date: Thu, 16 Jul 2026 11:48:35 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E6=A0=87=E6=B3=A8=20caption=20?= =?UTF-8?q?=E4=B8=8E=20point=5Fmask=20=E7=9A=84=E6=9D=83=E9=87=8D=E5=B7=AE?= =?UTF-8?q?=E5=BC=82=EF=BC=8C=E5=B9=B6=E5=8A=A0=E8=BF=90=E8=A1=8C=E6=97=B6?= =?UTF-8?q?=E8=AD=A6=E5=91=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 实测发现 SDMatte 与 SDMatte*(plus) 两个权重能力不同,根源是官方 README 所载的训练集差异:前者含 RefMatte(指代表达式抠图,点/文本提示的来源), 后者用 COCO-Matte 替换了它。 实测(官方效果图羊驼,MAD 越低越好): - point_mask:SDMatte 正常(0.0135);SDMatte_plus 输出全黑(max 仅 0.079) - caption :SDMatte 上语义有效,'alpaca' 0.01072 优于留空 0.01120、'tree' 0.01111; SDMatte_plus 上语义失效甚至反向,'alpaca' 0.01160 反差于 'tree' 0.01119, 即仅为 cross-attention 的噪声扰动 据此: - 补全 caption / point_radius / prompt_type 的 tooltip,写明各自的适用权重与含义 - README 增列两个权重的能力对照表与 caption 实测数据 - point_mask 输出接近全黑时打印警告 —— 该情形不报错,只会悄悄给出空结果 --- README.md | 33 ++++++++++++++++++++++++++++++--- sdmatte_node.py | 25 ++++++++++++++++++++++--- 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 6aadd20..facff5f 100644 --- a/README.md +++ b/README.md @@ -591,8 +591,9 @@ SDMatte 检查点覆盖。官方 HuggingFace 仓库本身也只发布 `.pth` 加 | `prompt_type` | 视觉提示类型,见下表 | | `inference_size` | 默认 `1024`,与官方测试一致 | | `is_transparent` | 玻璃、纱、烟雾等透明物体**务必打开** | -| `caption` | 可选文本描述,留空即官方默认行为 | -| `point_radius` | 仅 `point_mask` 生效,默认 35 | +| `caption` | 目标物体的英文描述。**仅 `SDMatte.pth` 有效,`SDMatte_plus.pth` 请留空**,见下文 | +| `point_radius` | 仅 `point_mask` 生效。每个点晕开的高斯 sigma,默认 35 | +| `seed` | 仅 `point_mask` 生效(10 个点是随机取的) | `prompt_type` 选择: @@ -600,9 +601,35 @@ SDMatte 检查点覆盖。官方 HuggingFace 仓库本身也只发布 `.pth` 加 |---|---|---| | `bbox_mask` | 取掩码外接框作为提示 | **默认,官方测试脚本的主路径,通常最稳** | | `mask` | 直接用掩码本身 | 已有较准的粗分割时 | -| `point_mask` | 在掩码内随机取 10 个点 | 复现论文的点提示实验 | +| `point_mask` | 在掩码内随机取 10 个点 | **仅 `SDMatte.pth` 支持**,见下文 | | `auto_mask` | 不给定位信息 | 画面只有单一主体 | +#### ⚠ 两个权重的能力不同(实测) + +官方 README 里,**SDMatte** 与 **SDMatte\***(即 `SDMatte_plus`)的训练集不同: +前者含 **RefMatte**(指代表达式抠图数据集,点提示与文本提示的来源), +后者用 **COCO-Matte** 替换了它。这导致 plus 版**不具备点提示与文本指代能力**: + +| | `SDMatte.pth` | `SDMatte_plus.pth` | +|---|---|---| +| `bbox_mask` / `mask` / `auto_mask` | ✅ | ✅ | +| `point_mask` | ✅ MAD 0.0135 | ❌ **输出全黑**(max 仅 0.079) | +| `caption` 语义 | ✅ 填对小幅提升 | ❌ 无作用,填了反而更差 | + +`caption` 实测(羊驼图,MAD 越低越好): + +| caption | `SDMatte` | `SDMatte_plus` | +|---|---|---| +| `""`(留空) | 0.01120 | **0.01135** ← 最好 | +| `"alpaca"`(语义正确) | **0.01072** ← 最好 | 0.01160 ← 最差 | +| `"tree"`(语义错误) | 0.01111 | 0.01119 | + +在 `SDMatte` 上,语义正确的描述确实更准;在 `plus` 上语义完全失效甚至反向, +说明它只是给 cross-attention 注入了噪声扰动,并非在理解文本。 + +**结论**:用 `SDMatte_plus.pth` 时保持 `caption` 留空、`prompt_type` 用 `bbox_mask`; +想用点提示或文本指代,请换 `SDMatte.pth`。节点在 `point_mask` 输出接近全黑时会打印警告。 + #### 典型接法 ``` diff --git a/sdmatte_node.py b/sdmatte_node.py index 2d3626d..3d39a5d 100644 --- a/sdmatte_node.py +++ b/sdmatte_node.py @@ -218,7 +218,9 @@ class RuiSDMatte: "tooltip": "视觉提示类型。\n" "bbox_mask:取掩码外接框作为提示,官方测试脚本的默认路径,通常最稳;\n" "mask:直接用掩码本身,适合已有较准的粗分割;\n" - "point_mask:在掩码内随机取 10 个点;\n" + "point_mask:在掩码内随机取 10 个点。\n" + " ⚠ 仅 SDMatte.pth 支持;SDMatte_plus.pth 用它会输出全黑,\n" + " 因为 SDMatte*(plus) 的训练集用 COCO-Matte 替换了 RefMatte,未训练点提示;\n" "auto_mask:不给定位信息,全图自动,画面只有单一主体时可用。" }), "inference_size": ([512, 640, 768, 896, 1024, 1152, 1280], { @@ -234,11 +236,19 @@ class RuiSDMatte: "optional": { "caption": ("STRING", { "default": "", "multiline": False, - "tooltip": "可选的文本描述(对应 RefMatte 的表达式)。留空即为官方测试时的默认行为。" + "tooltip": "目标物体的英文描述(对应 RefMatte 的指代表达式),经 CLIP 编码后\n" + "注入 UNet 的下采样/上采样两段 cross-attention。\n" + "· SDMatte.pth:有语义作用,填对能小幅提升(实测羊驼图 MAD 0.01120→0.01072)\n" + "· SDMatte_plus.pth:无语义作用,填了反而更差,请留空\n" + " (plus 的训练集用 COCO-Matte 替换了 RefMatte,未学过文本指代)\n" + "留空即官方测试时的默认行为。" }), "point_radius": ("INT", { "default": 35, "min": 5, "max": 100, - "tooltip": "仅 point_mask 生效。官方测试期取 35(训练 radius 25 + 10)。" + "tooltip": "仅 prompt_type=point_mask 时生效,其余模式完全不参与运算。\n" + "含义:在提示区域随机取 10 个点,每点用 sigma=该值的高斯核晕开成光斑,\n" + "再逐像素取最大值合成提示图 —— 即每个点的影响半径。\n" + "官方训练用 25,测试期用 25+10=35,故默认 35。" }), "seed": ("INT", {"default": 0, "min": 0, "max": 0xFFFFFFFF}), }, @@ -325,6 +335,15 @@ class RuiSDMatte: alphas.append(torch.from_numpy(np.clip(a, 0.0, 1.0))) alpha = torch.stack(alphas) # [B,H,W] + # SDMatte*(即 SDMatte_plus)的训练集以 COCO-Matte 替换了 RefMatte,未学过点提示, + # 喂 point_mask 会输出接近全黑。这不会报错,只会悄悄给出空结果,故主动提示。 + if prompt_type == "point_mask" and float(alpha.max()) < 0.1: + print( + "[Ruinode-SDMatte] 警告:point_mask 提示下输出接近全黑。" + "官方 SDMatte_plus(SDMatte*) 不支持点提示(其训练集用 COCO-Matte 替换了 RefMatte)。" + "请改用 bbox_mask,或换成 SDMatte.pth。" + ) + cutout = image.detach().cpu().float() * alpha.unsqueeze(-1) return (alpha, cutout)