凌晨刷到 Feyn Labs 那个 FeyNoBg,第一反应是又来刷榜的。拿八个 benchmark,赢的四个放大,输的四个塞表格角落,再配一句「与最佳结果差距均小于 2%」——这剧本我看过太多遍了。
但这次我把表格完整看了一遍,愣了一下。
它把输的也列出来了。DUTS-TE 0.941 输给 S3ODNet 的 0.949,CAMO-TE 0.887 输给 BiRefNet 的 0.904,DUT-OMRON 输,COD10K 也输。四赢四输,白纸黑字。
刷榜的写法不是这样的。刷榜只报你赢的那四个。
赢的四项里有一项是真东西
UHRSD-TE,超高分辨率那个——4K、8K 场景的显著对象分割。0.981 对 BiRefNet 的 0.957,差两个多点,在抠图界这不算小了。
这个结果跟它架构上动的刀是自洽的。它就是在 BiRefNet 基础上把特征提取器第三阶段从 18 个 block 加到 24 个,参数从 222M 涨到 263M——加的 41M 全砸在细粒度特征上。高分辨率赢,八成就是这刀起的作用。
预训练权重的加载方式也老实:原模型兼容权重全保留,只有新增的六个 block 从零训。没有推倒重来,没有「我们的初始化方案更好」那种玄学。这种改法我信——收益能解释,代价 41M 参数也明码标价。
真正让我想写这篇的,是训练那一段
第一个训练阶段,他们只用合成数据集 MaskFactory。结果 CAMO 涨了,DIS5K 退步了。
一般论文到这儿就开始「我们提出了 XX 策略」了。他们没绕,直接承认单一数据源泛化不够,然后去攒了个 26.1K 张的混合集——十个数据集拼的,每个源封顶 4,000 张,全部混洗,分割掩码和 alpha matte 统一转成二值前景掩码再训。
7,000 步之后,DIS5K 从退步反转成全场最佳。0.961,超过 FlowDIS 的 0.951。
这个反转是整篇里我最信的部分。因为它符合我踩过的所有坑的形状:单一分布上过拟合,数据源一掺,短板自己补上来了。「每个源封顶 4,000 张」这个细节尤其对——不封顶的话,大数据集把小数据集一淹,CAMO 那 1,000 张在 26.1K 里连个水花都打不出来。他们显然是知道这个坑才这么干的。
泼盆冷水
S-measure 这东西,懂的都懂。0.981 和 0.975,放到生产环境的抠图流水线上,用户感知为零。用户感知到的是头发丝糊不糊、半透明纱帘后面是不是抠出一块马赛克。
DAVIS-S 上 0.977 对 0.975——0.002 的胜利,跑分意义上存在,工程意义上不存在。
所以八项里真正值得看的就 UHRSD-TE 那两个点。高分辨率恰好是抠图在生产里最容易翻车的场景:电商图、印刷物料,动不动 8K 原图扔进来,模型在 1080p 上调出来的边缘到高分辨率全是锯齿。这个场景赢两个点,是有含金量的。
NoBg 这个库,顺手提一句
FeyNoBg 是用他们自己开源的 NoBg 库训的,pip install nobg 就能装,跟 Hugging Face 的 AutoModel、AutoProcessor、Trainer 都打通了。他们跑了跟原始 BiRefNet 实现的对比,batch size 1/2/4 三档,吞吐、延迟、峰值显存全占优。
库的设计上有个我比较欣赏的点:分割和抠图两套东西统一到同一个接口底下,训练目标统一成二值前景掩码。做工程的都知道,「上游数据格式打架」这种事看着不起眼,实际耗的工时比模型本身还多。把这一层抹平,比多刷 0.5 个点的 S-measure 对社区有用。
模型在 Hugging Face 上,库在 GitHub 上,都开源。加载模型存透明 PNG 的代码、用 Trainer 训自己模型的示例都给了。
为什么我愿意替它说两句
不是因为它赢了四个。是因为它的叙事结构是「我们试了 A,A 在 B 上翻车了,分析为什么,用 C 修好」——这是真做实验的人写出来的东西。
刷榜论文的叙事结构是「我们提出了 X,X 全面超越 baseline」。全面超越的,我默认先怀疑数据挑选;主动交代自己翻过车的,我反而多信三分。这跟看事故复盘一个道理——通篇挑不出任何失误的复盘,多半是写给上面看的。
补一刀:这行里最稀缺的从来不是 SOTA,是「我们在哪翻车了」那一段。模型输四个基准不丢人,把输的那四个藏起来才丢人。
本期教训:评估一个新模型,先看它有没有把输的那一半亮出来。全赢的,等它进了你的流水线再说。
