👗 Fashion Search — 服装以图搜图系统
上传一张服装图片即可入库,随后用任意服装图检索出视觉最相似的单品;可选叠加 AI 语义描述做视觉 + 文本融合检索。
向量底座为 ZVec(进程内嵌入式向量数据库,内置 FAISS / DiskANN 引擎),按数据量自动选型(Flat → IVF+PQ → DiskANN);推理设备(NVIDIA / AMD / Intel / Apple / CPU)自动探测。
目录
🎯 特性
- 服装检测与分割:YOLOv8-seg 实例分割,掩码抠图 + 白底预处理
- 视觉特征编码:MODA 微调 ViT-B-16-SigLIP,输出 768 维归一化向量(GPU 半精度加速)
- 以图搜图:内积相似度检索,
top_k/min_similarity双重过滤 - AI 语义增强:OpenAI 兼容多模态接口生成结构化服装描述,视觉 + 文本加权融合
- 批量入库 / 批量检索:检测、编码、检索全链路 batch 推理 + AI 并发描述
- 图片去重:xxh3 精确哈希 + 64 位感知哈希模糊去重(同图不同编码也能识别)
- ZVec 嵌入式向量库:进程内零网络开销、WAL 持久化,数据量跨阈值自动迁移索引
- 跨品牌 GPU 支持:NVIDIA CUDA / AMD ROCm / Intel XPU / Apple MPS 自动探测,无 GPU 自动回退 CPU
📦 安装
需要 Python 3.10+(推荐 3.12)。
# pip
pip install fashion-image-search
# uv
uv add fashion-image-search
PyPI 发行名为
fashion-image-search,导入名为fashion_search,命令行命令为fashion-search。
包内不含模型权重(YOLO 分割模型约 50 MB、视觉编码器约 177 MB,超出 PyPI 单文件 100 MB 限制)。首次运行会自动下载到本地模型目录,之后完全离线复用。想提前拉好可执行
fashion-search download-models。
依赖中包含 PyTorch。若需要 GPU 加速,建议先按 PyTorch 官方指引 安装对应 CUDA / ROCm 版本的 torch 与 torchvision,再安装本包:
pip install torch==2.3.1 torchvision==0.18.1 --index-url https://download.pytorch.org/whl/cu118
pip install fashion-image-search
🚀 快速开始
1. 自检环境(可选)
fashion-search doctor
检查依赖、运行目录、配置与模型权重是否就绪,不会下载也不会加载模型。
2. 启动服务
fashion-search serve --host 0.0.0.0 --port 8000
# 交互式接口文档: http://localhost:8000/docs
首次启动会自动下载缺失的模型权重。
3. 入库与检索
# 批量入库一个目录
fashion-search import ./my_garments
# 以图搜图
fashion-search search ./query.jpg --top-k 10
命令行输出示例:
1. score=1.0000 id=06aca010-5ff4-7086-8000-7665c707c370 path=/home/me/.fashion-search/data/garments/06aca010-....jpg
2. score=0.7793 id=06aca010-f680-77e5-8000-70fcedc4111e path=/home/me/.fashion-search/data/garments/06aca010-....jpg
也可以直接用 HTTP 接口:
curl -X POST http://localhost:8000/wardrobe/add \
-F "file=@./my_garments/shirt.webp" \
-F "enable_ai=false"
curl -X POST http://localhost:8000/wardrobe/search \
-F "file=@./my_garments/shirt.webp" \
-F "top_k=10" \
-F "min_similarity=0.5"
🛠️ 命令行工具
fashion-search --help
| 子命令 | 用途 |
|---|---|
serve |
启动 HTTP 服务(--host / --port / --config) |
download-models |
预下载全部模型权重(--no-text 跳过文本编码器,省约 90 MB) |
doctor |
依赖、目录、配置、模型权重自检 |
stats |
数据库记录数与索引规模、当前算法 |
add <图片> |
入库单张图片(--metadata '{...}' 附加元数据) |
search <图片> |
以图搜图(--top-k / --min-similarity / --no-ai) |
import <目录> |
批量入库整个目录(--reset 先清空,--query 指定验证图) |
smoke <目录> |
端到端冒烟测试:检测 → 编码 → 入库 → 检索 |
api-smoke <目录> |
对运行中的服务做 HTTP 接口测试 |
reset |
清空数据库、原图与索引(--yes 跳过确认) |
config |
输出当前生效配置;--write <路径> 写出默认配置模板 |
等价入口:python -m fashion_search <子命令>。
🌐 HTTP 接口
服务默认监听 http://localhost:8000,交互式文档在 /docs。
POST /wardrobe/add — 入库一张服装图片
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
file |
UploadFile | ✅ | 服装图片 |
enable_ai |
bool | 否 | 是否启用 AI 描述(默认 true) |
metadata |
str | 否 | 可选图片元数据,JSON 字符串 |
响应 200:
{
"id": "06a9e86f-e264-74ef-8000-a62ed2fbb5d5",
"message": "success",
"ai_enabled": false,
"metadata": null
}
重复图片不会重复入库,返回 {"skipped": true, "reason": "重复图片", "existing_id": "..."}。
POST /wardrobe/search — 以图搜图
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
file |
UploadFile | ✅ | 查询图片 |
enable_ai |
bool | 否 | 是否启用 AI 文本融合(默认 false) |
top_k |
int | 否 | 返回数量,1~100(默认取配置 search.default_top_k) |
min_similarity |
float | 否 | 相似度下限,0~1(默认取配置 search.min_similarity) |
响应为数组,按相似度降序:
[
{
"id": "06a9e86f-e264-74ef-8000-a62ed2fbb5d5",
"score": 1.0,
"image_path": "data/garments/06a9e86f-e264-74ef-8000-a62ed2fbb5d5.jpg",
"ai_description": null,
"metadata": null
}
]
POST /wardrobe/add_batch — 批量入库
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
files |
List[UploadFile] | ✅ | 多张服装图片 |
enable_ai |
bool | 否 | 是否启用 AI 描述(默认 true) |
curl -X POST http://localhost:8000/wardrobe/add_batch \
-F "files=@./my_garments/a.webp" \
-F "files=@./my_garments/b.webp"
POST /wardrobe/search_batch — 批量检索
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
files |
List[UploadFile] | ✅ | 多张查询图片 |
enable_ai |
bool | 否 | 是否启用 AI 文本融合(默认 false) |
top_k |
int | 否 | 每张图返回数量(默认 20) |
min_similarity |
float | 否 | 相似度下限(默认取配置) |
返回与上传顺序一致的数组,每项结构同 /wardrobe/search。
GET /wardrobe/{garment_id} — 服装详情
返回该服装的元数据与 AI 描述;不存在返回 404。
GET /image/{garment_id} — 服装原图
直接返回入库时保存的原图(JPEG 流),可直接作为 <img> 的 src;不存在或文件缺失返回 404。
GET /health — 健康检查
{
"status": "ok",
"version": "0.1.1",
"garments": 128,
"vision_index": 128,
"text_index": 96,
"algorithm": "flat",
"ai_enabled": true,
"index_dir": "/home/me/.fashion-search/data/vector_index"
}
⚙️ 配置
首次启动会在运行根目录生成 config.yaml(完整注释版)。运行根目录按以下顺序确定:
- 环境变量
FASHION_SEARCH_HOME - 当前工作目录(若其中存在
config.yaml或pyproject.toml) ~/.fashion-search
目录结构:
<运行根目录>/
├── config.yaml # 配置(首次启动自动生成)
├── data/
│ ├── wardrobe.db # SQLite 元数据(ID / 图片路径 / AI 描述 / 去重指纹)
│ ├── garments/ # 入库原图
│ └── vector_index/ # 向量集合(vision/ 与 text/,WAL 自动持久化)
└── models/ # 模型权重
主要配置段:
| 配置段 | 关键项 | 说明 |
|---|---|---|
models |
detector / vision_encoder / text_encoder |
模型路径与名称 |
search |
default_top_k / min_similarity / alpha / enable_ai_enhance |
检索行为 |
vector_db |
algorithm / flat_threshold / ivf_threshold / device / index_dir |
向量库与选型 |
ai |
api_key / platform / model / api_base / concurrency |
外部 AI 描述 |
system |
image_max_size / garments_dir / dedup_images / garment_id_prefix |
系统参数 |
相关环境变量
| 变量 | 说明 |
|---|---|
FASHION_SEARCH_HOME |
运行根目录(数据、模型、配置) |
FASHION_SEARCH_CONFIG |
指定配置文件路径 |
FASHION_SEARCH_MODELS_DIR |
单独指定模型目录 |
FASHION_SEARCH_DATA_DIR |
单独指定数据目录 |
FASHION_SEARCH_HF_ENDPOINT |
HuggingFace 端点(默认 https://hf-mirror.com;设为 https://huggingface.co 走官方) |
FASHION_SEARCH_GH_PROXY |
GitHub 加速前缀(默认 https://ghfast.top/,置空则直连) |
HF_HUB_OFFLINE=1 |
完全离线,只用本地已有权重(缺失则明确报错) |
FASHION_SEARCH__<段>__<键> |
覆盖任意配置项,如 FASHION_SEARCH__VECTOR_DB__DEVICE=cpu |
AI 语义增强
在 ai 段配置 api_key(OpenAI 兼容接口)后,入库时会生成结构化服装描述并建立文本向量,检索时按 search.alpha 做视觉/文本加权融合:
search:
alpha: 0.4 # 1.0=纯视觉;越小文本权重越高
enable_ai_enhance: true
ai:
api_key: "" # 留空则纯视觉模式
api_base: "https://api.openai.com/v1"
model: "gpt-4o-mini"
image_input_size: 384 # AI 输入图最长边(越大越慢)
concurrency: 4 # 并发识别数,建议 2~8
max_retries: 3 # 指数退避重试次数
生产环境请用环境变量注入密钥,不要写入配置文件:
export FASHION_SEARCH__AI__API_KEY=sk-xxx
AI 未配置或调用失败时系统自动降级为纯视觉检索,接口不报错(结果中带 ai_failed: true)。
🤖 模型权重
| 模型 | 用途 | 体积 | 来源 |
|---|---|---|---|
yolov8m-seg.pt |
服装检测与分割 | ~50 MB | ultralytics assets |
moda-fashion-vision-fp16 |
视觉特征编码(768 维) | ~177 MB | HopitAI/moda-fashion-vision-fp16 |
all-MiniLM-L6-v2 |
文本编码(384 维,AI 增强用) | ~90 MB | sentence-transformers |
权重不随包分发,首次使用时自动下载到运行根目录的 models/(文本编码器落在 HuggingFace 缓存),之后离线复用。可提前预下载:
fashion-search download-models # 全部
fashion-search download-models --no-text # 不用 AI 增强时跳过文本编码器
网络受限时可指定镜像:
export FASHION_SEARCH_HF_ENDPOINT=https://huggingface.co # 走官方
export FASHION_SEARCH_GH_PROXY= # GitHub 直连
也可以手动放置权重:把 yolov8m-seg.pt 和 moda-fashion-vision-fp16/vision_encoder.safetensors 放进 <运行根目录>/models/,或用 config.yaml 的 models 段指向自定义路径。
🧠 工作原理
查询图 ──► YOLOv8-seg 分割抠图(白底)──► ViT-B-16-SigLIP 编码(768 维归一化)
│
┌─────────────────────────┴─────────────────────────┐
▼ ▼
视觉向量检索(ZVec,内积) AI 描述 ──► 文本编码(384 维)
│ │
└────────────► alpha 加权融合 ◄─────────────────────┘
│
▼
top_k + min_similarity 过滤 ──► 结果(含原图路径)
- 入库:图片去重 → 检测抠图 → 视觉编码入库 → (可选)AI 描述 + 文本编码入库 → 元数据写 SQLite → 索引落盘
- 检索:检测抠图 → 视觉编码 → 视觉检索(必须)→ (可选)AI 文本融合 → 阈值过滤
- 结果:每条含
id/score/image_path/ai_description/metadata,原图可由GET /image/{id}获取
📐 向量引擎自动选型
vector_db.algorithm: auto(默认)时按数据量选择算法,并在平台不支持时优雅回退:
| 数据量 | 算法 | 特点 |
|---|---|---|
| < 100 万 | FAISS Flat | 100% 精确,硬件成本低 |
| 100 万 ~ 5000 万 | FAISS IVF + PQ | 内存/速度平衡(INT8 量化) |
| > 5000 万 | DiskANN | SSD 换内存,海量数据 |
- 阈值由
flat_threshold/ivf_threshold控制 - 数据增长跨过阈值时自动重建索引(如 Flat → IVF+PQ),已有数据不丢失
- DiskANN 在 Windows 上不受支持,自动回退到 IVF+PQ
- 也可显式指定
algorithm: flat | ivf_pq | diskann
🎛️ 推理设备自动适配
vector_db.device: auto(默认)按 NVIDIA CUDA → AMD ROCm/HIP → Intel XPU → Apple MPS → CPU 顺序探测,检测器与视觉编码器共用同一结果:
- 无 GPU 时自动回退 CPU(全链路端到端可用,仅速度较慢)
- 强制指定:
device: gpu(无 GPU 时回退 CPU)或device: cpu - ZVec 索引本身是进程内 CPU 索引(SIMD/AVX 自动调度),天然适配各平台
🤔 常见问题
Q:安装后第一次运行很慢?
A:首次运行要下载约 240 MB 模型权重。建议先执行 fashion-search download-models,之后再运行就完全离线。
Q:pip install 报依赖解析失败或想装 GPU 版 PyTorch?
A:本包依赖 torch>=2.3.1,<2.4。若要 CUDA/ROCm 版本,先按 PyTorch 官方指引安装对应 torch / torchvision,再安装本包,或使用 pip install fashion-image-search --no-deps 后自行补齐依赖。
Q:没有 GPU 能跑吗?
A:能。device 默认 auto,无 GPU 自动回退 CPU。中小数据量(< 100 万)下 CPU + FAISS Flat 已足够。
Q:检索结果为空?
A:检查 min_similarity(默认 0.7,偏高)——调低或设为 0 再看;确认目标图片已入库(GET /health 看 vision_index)。
Q:AI 增强检索没有返回 AI 结果?
A:AI 未配置或调用失败时会降级为纯视觉(结果带 ai_failed: true)。检查 ai.api_key 是否有效、search.enable_ai_enhance 是否为 true;ai.concurrency 过大可能触发接口限流(建议 2~8)。
Q:索引和原图存在哪?
A:默认在 ~/.fashion-search/data/ 下:wardrobe.db(元数据)、garments/(原图)、vector_index/(向量集合,由 WAL 自动持久化)。检索结果里的 image_path 即原图路径,也可用 GET /image/{id} 获取。
Q:服务重启后数据还在吗? A:在。元数据在 SQLite,向量由 ZVec WAL 落盘。即使索引文件丢失,启动时会根据数据库记录与已存原图自动重建索引。
Metadata
Release files for fashion-image-search 0.1.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| fashion_image_search-0.1.2.tar.gz | 51.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| fashion_image_search-0.1.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 112.7 kB
Release files / fashion_image_search-0.1.2.tar.gz
| Download URL | fashion_image_search-0.1.2.tar.gz |
|---|---|
| Size | 51.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f896e14fee50511b5805247029b874a0fc83867d34d332e14dd7e2fa96823484
|
|
BLAKE2b-256 checksum How to use checksums |
f8401f07c4edaae7e6f3f6238a937504b9e4ebccbf952f6ed37eb5cf72ad9161
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.8.23
|
Release files / fashion_image_search-0.1.2-py3-none-any.whl
| Download URL | fashion_image_search-0.1.2-py3-none-any.whl |
|---|---|
| Size | 61.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
aa80533dc3410762b3268309817e68ca7447620880ff620220e068b89894842b
|
|
BLAKE2b-256 checksum How to use checksums |
cb8be69c9f7a8d3aed5b3361176997e7b9763f5614b0b50fa0ffdb2c79dbb953
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.8.23
|