Memoria 开发记录 24:标签不是关键词表——MobileCLIP 粗分类、细分类与可达性
前言
相册自动标签看起来像是维护一个关键词列表:为每个标签生成文本向量,再与图片向量比较。但当标签数量增加到几十甚至上百个时,直接全量比较会产生大量误命中,而且相近标签之间难以建立稳定阈值。
Memoria 的标签系统逐步演进为分层检索:先判断图片属于哪些粗分类,再只在对应范围内计算细分类。它降低了搜索空间,也让标签浏览更有结构。但分层体系引入了一个新的正确性要求:每个细分类必须能够通过某个粗分类到达。
为什么直接对所有标签打分不稳定
CLIP 相似度是连续值,不是分类概率。若同时比较“海边、河流、天空、旅行、朋友、食物、文档、截图”等大量概念,总会有一些标签得到相对较高分,即使它们并不真正匹配。
标签数量越多,误命中的机会越大。不同标签的天然分数分布也不同,不能简单使用一个全局阈值。
分层检索将问题拆开:
图片向量
-> 粗分类:人物 / 食物 / 风景 / 文档 / 动物 ...
-> 选择可信粗分类
-> 只计算对应细标签
-> 动态 topK 与阈值过滤
这与大型分类系统中的 hierarchical classification 思路相同。
标签 prototype 为什么使用多个 Prompt
单个标签词往往过于抽象。例如仅使用 beach,可能无法覆盖海边合影、沙滩活动和海岸风景。系统可以为一个标签准备多个可观察描述,再对文本向量求平均形成 prototype。
多个 Prompt 能增加覆盖,但也可能稀释概念。如果把差异很大的描述平均,最终向量可能谁都不像。因此 Prompt 应围绕同一视觉概念,而不是把“海边旅行的美好回忆”这类价值判断混进去。
固定 Prompt 使用英语,是因为当前 MobileCLIP 文本空间对英语描述更稳定。
粗分类到细分类的可达性
当前细分类只有在其映射的粗分类被选中后才会打分。服务逻辑会读取 memoriaFineLabelToCoarseId[label],映射不存在或粗分类未命中时直接跳过。
这意味着 taxonomy 配置错误不会报错,只会让某个标签永远无法出现。典型问题包括:
- 细标签没有映射;
- 映射目标粗分类不存在;
- 粗分类没有任何有效细标签;
- 标签重命名后映射仍保留旧名称。
这类问题必须通过构建时测试发现,而不能依赖用户反馈。
“其他”分类的两面性
当没有可靠标签时返回“其他”,可以避免强行误分类。但如果大量照片落入“其他”,标签浏览就失去信息价值。
“其他”比例过高可能说明:
- 粗分类覆盖不足;
- Prompt 与实际相册分布不匹配;
- 阈值过高;
- 模型或预处理异常;
- taxonomy 映射不可达。
因此“其他”应该被当作质量指标,而不只是默认标签。开发工具应统计其比例并提供样本检查。
标签系统如何验证
稳定 taxonomy 至少需要三类测试:
结构测试
- 每个细标签映射到存在的粗分类;
- 每个粗分类包含有效细标签;
- 标签名称唯一;
- 所有 Prompt 非空且语言符合模型要求。
向量测试
- prototype 维度与模型输出一致;
- prototype 已归一化;
- 缓存版本与模型版本一致;
- 代表样本的正确标签分数高于相近错误标签。
产品测试
- 标签浏览中“其他”比例可控;
- 不同设备和模型版本结果没有明显漂移;
- 截图、文档等标签不会被直接等同于垃圾状态;
- 用户确认的低价值状态与视觉标签保持分离。
总结
自动标签不是简单的关键词匹配,而是一套模型空间、分类结构和产品语义共同约束的系统。
关键经验包括:
- 大标签集应使用粗到细的分层检索;
- Prompt 必须描述可观察视觉证据;
- 多 Prompt 平均需要避免概念稀释;
- taxonomy 映射错误会造成标签永久不可达;
- “其他”比例应作为质量指标;
- 视觉类别与垃圾治理状态必须保持分离;
- taxonomy 结构和代表样本需要自动测试。
对应提交:df0e301、4605149、0b59057、d9df02a、363f4cd、6bf61a2。
浙公网安备 33010602011771号