Files
zt-closet-backend/.codebuddy/plans/classify-service-align-clothes-model_e429d660(未完成).md
2026-09-11 01:41:52 +08:00

6.9 KiB
Raw Permalink Blame History

name, overview, todos
name overview todos
classify-service-align-clothes-model 根据 mysqlmodel.Clothes 的 15 个分类维度字段,优化 thirdparty/classification_server/main.py 分类服务:补齐缺失的分类维度(副颜色/厚度/袖型/衣长/领型/正式程度/适用场合/视觉冲击力)、响应字段命名与 model 对齐,并将多次模型前向推理合并为单次批量前向以提升性能。
id content status
add-prompt-groups 在 main.py 新增 7 组缺失维度 prompt 定义、副颜色阈值常量与维度适用性映射表 pending
id content status dependencies
batch-forward 实现 _classify_all 单次批量前向推理,按组 softmax 并完成子类别按大类过滤与副颜色 top-2 提取 pending
add-prompt-groups
id content status dependencies
rewrite-classify-api 重写 /classify 接口响应,字段对齐 Clothes 模型命名并实现不适用维度置空逻辑 pending
batch-forward
id content status dependencies
preprocess-and-verify 优化图片预处理(仅透明图合成白底)并运行 python 语法与启动自检验证 pending
rewrite-classify-api

产品概述

根据 mysqlmodel.Clothes 的 15 个分类维度字段,优化 Fashion-CLIP 衣物分类服务(thirdparty/classification_server/main.py),使分类输出与模型字段完全对齐、维度补齐、推理性能提升。

核心功能

  • 字段命名对齐:响应字段由 type/subcategory/color/fit 改为 category_main/category_sub/color_main/version 等 snake_case 命名,与模型及 DTO 的 json tag 一致,便于 Go 侧直接映射落库
  • 补齐 8 个缺失维度:新增副颜色(color_sub,从颜色 top-2 提取)、厚度(thickness)、袖型(sleeve_type)、衣长类型(clothes_type)、领型(neckline_type)、正式程度(formality,1-5)、适用场合(occasions,多个场合逗号分隔)、视觉冲击力(visual_impact,1-5)
  • 单次批量前向推理:将当前 7 次逐组模型前向合并为 1 次批量前向,按组 softmax 归一化,推理耗时大幅下降
  • 品类适用性控制:按大类判断维度适用性(如鞋/配饰无袖型、领型,置空不输出),避免给出不合理标签
  • 图片预处理优化:仅对含透明通道的图片合成白底,普通 JPEG 直接转 RGB,减少冗余计算

边界说明

  • 改动仅限 thirdparty/classification_server/main.py 单文件
  • Go 侧目前无消费方,字段改名无兼容性风险
  • Formality/VisualImpact 返回 "1"~"5" 字符串(模型字段为 string 类型)
  • 子类别过滤逻辑保持"避免牛仔裤出现在上装里"的原有语义

技术栈

  • 沿用现有:Python 3 + FastAPI + Transformers(Fashion-CLIP)+ PyTorch
  • 不改动模型、不引入新依赖

实现方案

核心策略

  1. 维度补齐:为 8 个缺失维度新增英文 prompt 组(沿用现有中文标签键 + 英文视觉描述值模式)
  2. 单次批量前向:新增 _classify_all,将所有 prompt 组(约 150 个文本)拼成一个 batch 一次推理,输出 logits 后按组切分分别 softmax 归一化
  3. 子类别等价合并:所有大类的子类别合并进同一次前向,大类确定后在其子类别组内取 top1——同组内相对分数不变,argmax 结果与当前两阶段方案数学等价,省掉第二次前向
  4. 适用性映射:用 DIMENSION_APPLICABILITY 表声明各维度适用的大类,不适用维度直接返回空字符串
  5. 副颜色逻辑:从颜色组 top-2 中取副色,第二置信度需达到阈值(建议为 top1 的 40% 或绝对值 0.15,取较低者更宽松)才输出,否则置空
flowchart LR
    A[图片上传] --> B[预处理: 仅透明图合成白底]
    B --> C[一次前向: 全部维度prompt拼batch]
    C --> D[按组softmax归一化]
    D --> E[大类 top1]
    E --> F[子类别: 大类组内 top1]
    E --> G[颜色 top1/top2 → 主色/副色]
    E --> H[其余维度 top1 或 top-N]
    H --> I[适用性映射: 不适用的置空]
    F --> J[响应字段对齐 model 命名]
    G --> J
    I --> J

新增 Prompt 组设计

  • THICKNESS_PROMPTS:厚/适中/薄
  • SLEEVE_TYPE_PROMPTS:无袖/短袖/中袖/长袖(仅上装、连衣裙、外套适用)
  • CLOTHES_TYPE_PROMPTS:短款/常规/中长/长款(上装、下装、连衣裙、外套适用)
  • NECKLINE_PROMPTS:圆领/V领/方领/高领/翻领/一字领/连帽(仅上装、连衣裙、外套适用)
  • FORMALITY_PROMPTS:5 档英文描述,返回 "1"~"5" 字符串 + 中文标签(如 休闲/日常/轻正式/商务/正式)
  • OCCASION_PROMPTS:日常通勤/运动健身/约会聚会/正式商务/居家休闲/度假旅游/户外活动,取置信度达标的 top-N 用逗号连接
  • VISUAL_IMPACT_PROMPTS:5 档英文描述,返回 "1"~"5" 字符串 + 中文标签(低调/平淡/适中/亮眼/高调)

响应结构(对齐 model)

{
  "category_main": "上装",
  "category_sub": "T恤",
  "style": "休闲风",
  "color_main": "黑色",
  "color_sub": "白色",
  "thickness": "适中",
  "version": "宽松",
  "material": "纯棉",
  "pattern": "纯色",
  "sleeve_type": "短袖",
  "clothes_type": "常规",
  "neckline_type": "圆领",
  "formality": "2",
  "occasions": "日常通勤,居家休闲",
  "visual_impact": "3",
  "details": { "…各维度 Top-5 明细,按新字段命名…" }
}

各维度附带 *_confidence 字段;details 保留 Top-5 明细便于调试与后续微调标签。

实现要点

  • 性能:前向次数 7 次 → 1 次(文本数约 150,CLIP 单 batch 可承受;CPU 场景收益最大);避免每组一次 processor 调用的重复 tokenize 开销
  • 等价性保证:批量方案下每组的 softmax 与逐组调用结果一致(组内归一化),子类别"组内 top1"与大类过滤后两阶段 argmax 完全一致
  • 健壮性:_classify_all 内部用 start/end 边界记录各组切片位置,防止顺序错乱;大类不在映射表中时安全回退(维度置空、子类别为空)
  • 兼容性:保留 /healthz 与整体接口形态;docstring 同步更新字段说明
  • 可维护性:prompt 组全部收敛为统一 dict 结构,新增维度只需加 dict 项 + 注册到批量分组,无需新增前向逻辑

目录结构

thirdparty/
└── classification_server/
    └── main.py   # [MODIFY] 唯一改动文件
                   # 1. 新增 7 组 prompt 定义 + 副颜色阈值常量 + 维度适用性映射表
                   # 2. 新增 _classify_all 批量单次前向函数(替代逐组 _classify_group 循环)
                   # 3. 重写 /classify 接口:调用批量前向、副颜色提取、适用性置空、响应字段对齐 model
                   # 4. 优化图片预处理:检测 alpha 通道后才合成白底