Skip to content

Repository files navigation

VectorGallery 多模态图片向量检索系统

TestsLicenseVersionLanguage

VectorGallery 是一个可本地部署的多模态图片向量检索系统,基于 cn_clip、FastAPI、Flask 和 Qdrant,支持以文搜图、以图搜图、图文融合检索,以及结合 CoverGroup.cfg 的尺寸匹配重排。

Note

README 主要面向开发者:如果你要运行、部署、调试或二次开发这个项目,建议先从 Docker Compose 流程开始。

目录

功能特性

  • 以文搜图:输入文本描述,检索语义相近的图片。
  • 以图搜图:上传或传入参考图片,检索视觉相似图片。
  • 图文融合搜图:文本和图片分别检索,再通过 rrfweighted 晚融合合并结果。
  • 尺寸匹配重排:索引时读取 CoverGroup.cfg 的 bbox 信息,搜索时可按目标宽高过滤并重排。
  • Web + CLI 双入口:既可以通过浏览器使用,也可以通过命令行索引和搜索。
  • 容器化部署docker-compose.yml 编排 Qdrant、模型服务和 Flask Web 应用。

架构概览

graph TD
    A[Web UI 或 CLI] --> B[client 业务层]
    B --> C[FastAPI cn_clip 模型服务]
    B --> D[Qdrant 向量数据库]
    C --> B
    D --> B
Loading

运行链路:

Flask Web UI / CLI
  -> client 业务层
  -> FastAPI cn_clip 模型服务
  -> Qdrant 向量数据库

主要目录:

路径 说明
client/app/ CLI 入口、Flask Web 应用和 Web 启动脚本
client/core/ ImageIndexerSearchEngine 等索引/检索核心流程
client/adapters/ Qdrant 与模型服务 HTTP 客户端
client/processing/ 图片扫描、格式校验、CoverGroup.cfg 解析
client/templates/ Flask Web 页面模板
server/ FastAPI + cn_clip 模型推理服务
docker-compose.yml Qdrant、模型服务、Web 应用一键编排

快速开始:Docker Compose

Compose 会启动三个服务:

服务 作用 对外端口
qdrant 向量数据库,存储图片向量和 metadata payload 6333, 6334
model-server FastAPI + cn_clip embedding 服务 8000
client-web Flask Web 搜索界面 5000

1. 准备图片目录

默认情况下,Compose 会把仓库内的 ./images 挂载到容器内 /data/images

如果要使用本机其他图片目录,新建 .env

VECTORGALLERY_IMAGE_DIR=<YOUR_IMAGE_DIRECTORY>

Windows 示例:

VECTORGALLERY_IMAGE_DIR=E:/TEST

Linux/macOS 示例:

VECTORGALLERY_IMAGE_DIR=/home/me/images

2. 启动服务

docker compose up -d --build

首次启动 model-server 可能需要下载或缓存 cn_clip 模型,耗时会比较久。查看状态和日志:

docker compose ps
docker compose logs -f

Web 访问地址:

http://localhost:5000

3. 建立图片索引

docker compose exec client-web python -m client.app.main index --directory /data/images

如果需要显式指定 CoverGroup.cfg,请先把该文件所在目录挂载到容器中,再传入容器内路径:

docker compose exec client-web python -m client.app.main index \
  --directory /data/images \
  --covergroup-cfg /data/CoverGroup.cfg

4. 停止服务

# 停止容器,保留 Qdrant 数据、模型缓存和缩略图缓存
docker compose down

# 停止并删除持久化 volume;索引数据和模型缓存会被清理,慎用
docker compose down -v

本地 Python 运行

展开本地 Python 启动步骤

1. 安装依赖

建议先创建虚拟环境,然后在仓库根目录执行:

pip install -r client/requirements.txt
pip install -r server/requirements.txt
pip install -r requirements-dev.txt

2. 启动 Qdrant

docker run -p 6333:6333 -p 6334:6334 qdrant/qdrant:v1.12.5

3. 启动模型服务

请从 server/ 目录启动,避免 uvicorn server:app 解析到错误模块:

cd server
uvicorn server:app --host 0.0.0.0 --port 8000

Windows 可使用:

cd server
run.bat

模型服务健康检查:

http://127.0.0.1:8000/health

4. 启动 Web 应用

回到仓库根目录执行:

python -m client.app.run_web

访问:

http://localhost:5000

Web 使用方式

  1. 启动服务并完成索引。

  2. 打开浏览器访问:

    http://localhost:5000
    
  3. 在页面中选择搜索方式:

    • 输入文本:以文搜图。
    • 上传图片:以图搜图。
    • 同时输入文本并上传图片:图文融合搜图。
  4. 如需要尺寸匹配,填写目标宽高和相关权重参数。

Web 端主要接口:

方法 路径 说明
GET / Web 首页
POST /search 搜索接口;支持 JSON 文本搜索和 form-data 图片/图文搜索
GET /thumbnail?picid=... 返回缩略图或原图
GET /image/<path> 返回本地图片文件
GET /health Web 应用健康检查

Warning

/image/<path> 会按路径返回本地存在且扩展名允许的图片文件。若要把 Flask 服务暴露到不可信网络,请先增加路径白名单或访问控制。

CLI 使用方式

Important

python -m client.app.main 会先检查 Qdrant 和模型 API,再解析命令。因此即使只是查看帮助,也可能因为 127.0.0.1:6333127.0.0.1:8000 不可用而失败。

常用命令:

# 查看系统信息
python -m client.app.main info

# 索引默认图片目录
python -m client.app.main index

# 推荐:显式指定图片目录
python -m client.app.main index --directory /path/to/images

# 显式指定 CoverGroup.cfg
python -m client.app.main index --directory /path/to/images --covergroup-cfg /path/to/CoverGroup.cfg

# 文本搜索
python -m client.app.main search-text "猫咪"

# 图片搜索
python -m client.app.main search-image /path/to/query/image.jpg

# 图文融合搜索
python -m client.app.main search-multimodal --image /path/to/query/image.jpg --query "红色跑车"

# 自定义返回数量和阈值
python -m client.app.main search-text "风景" --top-k 20 --threshold 0.4

CLI 参数概览:

命令 关键参数 说明
index --directory, --covergroup-cfg 扫描目录、生成图片向量并写入 Qdrant
search-text query, --top-k, --threshold 文本搜图
search-image image, --top-k, --threshold 图片搜图
search-multimodal --image, --query, --fusion-method, --rrf-k 图文融合搜图
info 查看集合状态、向量维度、默认搜索配置
test 运行项目自定义测试/诊断路径,不等同于完整 pytest 套件

Python API 参考

SearchEngine

from client.core.search_engine import SearchEngine

search_engine = SearchEngine()

# 文本搜索
results = search_engine.search_by_text("猫咪", top_k=10, score_threshold=0.4)

# 图片搜索
results = search_engine.search_by_image_path("/path/to/query.jpg", top_k=10)

# 图文融合搜索
results = search_engine.search_multimodal_late_fusion(
    query_text="红色跑车",
    image_path="/path/to/query.jpg",
    top_k=20,
    fusion_method="rrf",
)

常用方法:

方法 说明
search_by_text(...) 根据文本检索图片
search_by_image_path(...) 根据图片路径检索图片
search_by_image_data(...) 根据图片字节数据检索图片
search_multimodal_late_fusion(...) 图文晚融合检索,支持 rrfweighted
advanced_search(...) 根据传入参数自动选择文本、图片或图文搜索
get_database_stats() 获取 Qdrant 集合与搜索配置摘要

ImageIndexer

from client.core.indexer import ImageIndexer

indexer = ImageIndexer()
success_count, error_count = indexer.index_images(
    image_dir="/path/to/images",
    covergroup_cfg_path="/path/to/CoverGroup.cfg",
)

常用方法:

方法 说明
index_images(image_dir=None, batch_size=50, covergroup_cfg_path=None) 批量索引图片目录
index_single_image(image_path) 索引单张图片
reindex_all_images(image_dir=None, covergroup_cfg_path=None) 清空集合后重新索引
get_indexing_progress() 获取当前索引统计信息

配置项

主要运行配置来自 client/config.py,多数可通过环境变量覆盖。

配置键 默认值 说明
QDRANT_HOST 127.0.0.1 Qdrant host
QDRANT_PORT 6333 Qdrant port
COLLECTION_NAME image_search Qdrant collection 名称
VECTOR_SIZE 512 cn_clip 向量维度
MULTIMODAL_SERVER_URL http://127.0.0.1:8000 模型服务地址
IMAGE_DIR E:\TEST 默认图片目录
DEFAULT_TOP_K 20 默认返回数量
SIMILARITY_THRESHOLD 0.4 默认相似度阈值
SEARCH_FUSION_METHOD rrf 默认图文融合策略
SEARCH_RRF_K 60 RRF 参数
SEARCH_TEXT_WEIGHT 0.5 文本分支权重
SEARCH_IMAGE_WEIGHT 0.5 图片分支权重
SEARCH_CANDIDATE_MULTIPLIER 5 候选池倍数
SEARCH_MIN_CANDIDATE_K 100 最小候选数

Compose 中 client-web 会覆盖部分配置:

QDRANT_HOST=qdrant
QDRANT_PORT=6333
COLLECTION_NAME=image_search
MULTIMODAL_SERVER_URL=http://model-server:8000
IMAGE_DIR=/data/images

CoverGroup.cfg 与尺寸匹配

CoverGroup.cfg 用于提供图片或 cover group 的 bbox 宽高信息。索引时,ImageIndexer 会解析它并把 bbox metadata 写入 Qdrant payload;搜索时,SearchEngine 可按 target_width / target_height 进行强过滤,并结合语义分和尺寸分重排。

索引入口的路径规则:

  1. 显式传入 --covergroup-cfg / covergroup_cfg_path 时,使用该路径。
  2. 未显式传入时,使用 图片目录的父目录/CoverGroup.cfg
  3. 只有底层路径解析没有显式 cfg 且没有图片目录时,才使用 Config.COVERGROUP_CFG_PATH

如果解析失败,索引会记录警告并继续执行;对应图片的 bbox metadata 为空或为 0。

尺寸匹配配置:

配置键 默认值 说明
SIZE_TOLERANCE 50.0 宽高强约束容差,单位为像素
SEARCH_SEMANTIC_WEIGHT 0.7 语义分权重
SEARCH_SIZE_WEIGHT 0.3 尺寸分权重
SIZE_SCORE_ALPHA 2.0 面积差异衰减系数
SIZE_SCORE_BETA 3.0 宽高比差异衰减系数

测试与代码检查

运行默认测试:

python -m pytest

运行单个测试:

python -m pytest client/tests/test_size_filter.py
python -m pytest client/tests/test_size_filter.py::TestCoverGroupParser::test_parse_cfg_structure
python -m unittest client.tests.test_size_filter.TestCoverGroupParser.test_parse_cfg_structure

兼容 unittest discovery:

python -m unittest discover -s client/tests -p "test*.py"

显式 opt-in 的集成测试需要设置环境变量:

VECTORGALLERY_RUN_INDEX_INTEGRATION=1
VECTORGALLERY_INTEGRATION_PROJECT_DIR=<YOUR_PROJECT_DIR>
VECTORGALLERY_INDEX_IMAGE_DIR=<YOUR_IMAGE_DIR>

代码检查和格式化:

python -m ruff check .
python -m ruff format .

安全与运行产物

不应提交的运行时或工具缓存:

  • client/thumbnails/
  • __pycache__/
  • .pyc
  • .pytest_cache/
  • .ruff_cache/
  • *.pt 模型权重
  • Qdrant volume 数据

Caution

模型权重和向量数据库数据可能较大,不建议直接纳入普通 Git 管理。如果确实需要版本化模型资产,请先设计 Git LFS 或外部制品管理方案。

路线图

  • 文本搜图
  • 图片搜图
  • 图文晚融合检索
  • Docker Compose 编排
  • CoverGroup.cfg 尺寸匹配
  • 索引去重策略
  • Web 文件访问路径白名单
  • 更完整的模型资产管理方案

贡献

欢迎提交 issue 或 pull request。建议遵循以下约定:

  1. 功能改动前先确认影响范围,尤其是索引、搜索和 Web 文件访问逻辑。

  2. 提交前运行:

    python -m pytest
    python -m ruff check .
  3. README 示例应与 client/config.pydocker-compose.yml 和 CLI 参数保持一致。

  4. 不要把运行缓存、缩略图、模型权重或 Qdrant 数据提交到仓库。

许可证

本项目使用 MIT License。详见 LICENSE

About

VectorGallery 是一个可本地部署的多模态图片向量检索系统,基于 cn_clip、FastAPI、Flask 和 Qdrant,支持以文搜图、以图搜图、图文融合检索,以及结合 CoverGroup.cfg 的尺寸匹配重排。

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages