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