构建索引

一、向量嵌入

向量嵌入(Embedding)是一种将真实世界中复杂、高维的数据对象(如文本、图像、音频、视频等)转换为数学上易于处理的、低维、稠密的连续数值向量的技术。

想象一下,我们将每一个词、每一段话、每一张图片都放在一个巨大的多维空间里,并给它一个独一无二的坐标。这个坐标就是一个向量,它“嵌入”了原始数据的所有关键信息。这个过程,就是 Embedding。

  • 数据对象:任何信息,如文本“你好世界”,或一张猫的图片。
  • Embedding 模型:一个深度学习模型,负责接收数据对象并进行转换。
  • 输出向量:一个固定长度的一维数组,例如 [0.16, 0.29, -0.88, ...]。这个向量的维度(长度)通常在几百到几千之间。

在这里插入图片描述

Embedding 的真正威力在于,它产生的向量不是随机数值的堆砌,而是对数据语义的数学编码。

  • 核心原则:在 Embedding 构建的向量空间中,语义上相似的对象,其对应的向量在空间中的距离会更近;而语义上不相关的对象,它们的向量距离会更远。

  • 关键度量

    :我们通常使用以下数学方法来衡量向量间的“距离”或“相似度”:

    • 余弦相似度 (Cosine Similarity):计算两个向量夹角的余弦值。值越接近 1,代表方向越一致,语义越相似。这是最常用的度量方式。
    • 点积 (Dot Product):计算两个向量的乘积和。在向量归一化后,点积等价于余弦相似度。
    • 欧氏距离 (Euclidean Distance):计算两个向量在空间中的直线距离。距离越小,语义越相似。

二、多模态嵌入实战——Milvus介绍及多模态检索实践

该笔记是针对文章all-in-rag的第三章节实战的详细说明。若想看理论细节,请移步作者的文章。

向量数据库是专门用于存储和查询向量的数据库,这些向量来自对文本、语音、图像、视频等内容的向量化处理;与传统数据库相比,它不仅能完成添加、读取查询、更新、删除等基本操作,还能对向量数据进行更快速的相似性搜索。当前的大模型,无论是 NLP 领域的 GPT 系列还是 CV 领域的 ResNET 系列,都是经过预先训练的,存在明确的训练截止日,这使得它们对截止日之后发生的事情一无所知,而向量数据库的引入则能极大拓展大模型的应用边界 —— 其内部存储的最新信息向量可让大模型保持准实时性、提高适用性并实现动态调整,进而使大模型具备长期记忆。比如,一个 2021 年底完成训练的新闻摘要预训练模型,到 2023 年面对诸多新的新闻事件和趋势时,可借助向量数据库存储和查询 2023 年的新闻文章向量来处理新信息;在推荐系统中,预训练大模型可能无法识别新用户和新产品的特征,而通过向量数据库实时更新用户和产品的特征向量,能让大模型依据最新信息提供更精准的推荐;此外,向量数据库还支持实时监测和分析,像金融领域中,预训练的股票预测模型可能无法获取训练截止日后的股票价格信息,将最新股票价格向量存储在向量数据库中,大模型就能实时分析和预测未来股票价格走势,在客服领域,向量数据库也能让大模型追溯到对话的开始。

向量数据库自带多模态功能,这意味着它能够通过机器学习方法处理和理解来自不同源的多种模态信息,如文本、图像、音频和视频等,数据向量化过程使得这些不同模态数据的内部隐藏信息得以暴露,进而为多模态应用提供支持。

2.1 Milvus简介

Milvus 是一款云原生向量数据库,具备高可用、高性能、易拓展的特点,用于海量向量数据的实时召回。其官网地址为:Milvus。Milvus 基于 FAISS、Annoy、HNSW 等向量搜索库构建,核心目标是解决稠密向量相似度检索问题;在向量检索库的基础上,它支持数据分区分片、数据持久化、增量数据摄取、标量向量混合查询、time travel 等功能,同时大幅优化了向量检索性能,可满足各类向量检索场景的应用需求,通常建议用户采用 Kubernetes 部署 Milvus,以获得最佳的可用性和弹性。此外,Milvus 采用共享存储架构,实现存储与计算完全分离,计算节点支持横向扩展;从架构来看,它遵循数据流与控制流分离的原则,整体分为接入层(access layer)、协调服务(coordinator service)、执行节点(worker node)和存储层(storage)四个层次,各个层次相互独立,可实现独立扩展和容灾。

在这里插入图片描述

2.2 Collection(集合)

在 Milvus 中,Collection 是数据组织的基本逻辑单元,其功能等价于关系型数据库中的表(Table)。它作为向量数据及相关元数据的存储、管理与检索容器,所有操作(插入、删除、查询)均以 Collection 为操作对象。

可以用一个图书馆的比喻来理解 Collection:

  • Collection (集合): 相当于一个图书馆,是所有数据的顶层容器。一个 Collection 可以包含多个 Partition,每个 Partition 可以包含多个 Entity。
  • Partition (分区): 相当于图书馆里的不同区域(如“小说区”、“科技区”),将数据物理隔离,让检索更高效。
  • Schema (模式): 相当于图书馆的图书卡片规则,定义了每本书(数据)必须登记哪些信息(字段)。
  • Entity (实体): 相当于一本具体的书,是数据本身。
  • Alias (别名): 相当于一个动态的推荐书单(如“本周精选”),它可以指向某个具体的 Collection,方便应用层调用,实现数据更新时的无缝切换。

Collection 是 Milvus 中最基本的数据组织单位,类似于关系型数据库中的一张表 (Table)。是我们存储、管理和查询向量及相关元数据的容器。所有的数据操作,如插入、删除、查询等,都是围绕 Collection 展开的。

2.2.1 Schema(模式):数据结构规范

Collection 的创建需预定义其 Schema,该模式通过字段(Field)属性约束确保数据一致性与查询效率。Schema 包含三类核心字段:

  1. 主键字段(Primary Key Field)
    • 必备字段,全局唯一标识实体(Entity)。
    • 数据类型:INT64VARCHAR,值需满足唯一性约束。
  2. 向量字段(Vector Field)
    • 存储嵌入向量(Embedding Vector),支持单 Collection 多向量字段(如多模态场景)。
  3. 标量字段(Scalar Field)
    • 存储非向量元数据(字符串、数值、布尔值、JSON 等),用于查询过滤与结果聚合。

Schema 设计范式示例(新闻文章场景)
假设 Schema 包含:

  • 主键:article_id(唯一标识)
  • 标量字段:title (VARCHAR), author (VARCHAR), image_url (VARCHAR)
  • 向量字段:
    • image_embedding (密集向量,DENSE_FLOAT_VECTOR)
    • summary_embedding (密集向量)
    • summary_sparse_embedding (稀疏向量,SPARSE_FLOAT_VECTOR)
      此设计支持多模态混合检索,并通过标量字段实现元数据过滤。
2.2.2 Partition(分区):数据物理隔离机制

Partition 是 Collection 内部的逻辑数据分片,通过物理隔离优化查询性能与管理效率:

  • 初始状态:每个 Collection 含默认分区 _default
  • 容量限制:单 Collection 最多支持 1024 个分区

分区核心价值

  1. 查询性能提升
    限定搜索范围至特定分区(如 WHERE partition_name="AI_articles"),减少全量数据扫描。
  2. 数据生命周期管理
    • 支持分区级批量操作:加载/卸载内存、数据删除。
    • 示例:按时间分区(2024Q1, 2024Q2)可快速归档历史数据。
2.2.3 Alias

Alias (别名) 是为 Collection 提供的一个“昵称”。通过为一个 Collection 设置别名,我们可以在应用程序中使用这个别名来执行所有操作,而不是直接使用真实的 Collection 名称。

为什么使用别名?

  • 安全地更新数据:想象一下,你需要对一个在线服务的 Collection 进行大规模的数据更新或重建索引。直接在原 Collection 上操作风险很高。正确的做法是:
    1. 创建一个新的 Collection (collection_v2) 并导入、索引好所有新数据。
    2. 将指向旧 Collection (collection_v1) 的别名(例如 my_app_collection)原子性地切换到新 Collection (collection_v2) 上。
  • 代码解耦:整个切换过程对上层应用完全透明,无需修改任何代码或重启服务,实现了数据的平滑无缝升级。

2.3 Index

如果说 Collection 是 Milvus 的骨架,那么索引 (Index) 就是其加速检索的神经系统。从宏观上看,索引本身就是一种为了加速查询而设计的复杂数据结构。对向量数据创建索引后,Milvus 可以极大地提升向量相似性搜索的速度,代价是会占用额外的存储和内存资源。

在这里插入图片描述

索引建立由数据节点执行。为了避免频繁为数据更新建立索引,Milvus 将 Collections 进一步划分为多个分段,每个分段都有自己的索引。

Milvus 支持为每个向量场、标量场和主场建立索引。索引构建的输入和输出都与对象存储有关:数据节点将要建立索引的日志快照从段落(在对象存储中)加载到内存,反序列化相应的数据和元数据以建立索引,索引建立完成后序列化索引,并将其写回对象存储。

索引构建主要涉及向量和矩阵操作,因此是计算和内存密集型操作。向量因其高维特性,无法用传统的树形索引高效地建立索引,但可以用这方面比较成熟的技术建立索引,如基于集群或图形的索引。无论其类型如何,建立索引都涉及大规模向量的大量迭代计算,如 Kmeans 或图遍历。

与标量数据的索引不同,建立向量索引必须充分利用 SIMD(单指令、多数据)加速。Milvus 天生支持 SIMD 指令集,例如 SSE、AVX2 和 AVX512。考虑到向量索引构建的 "打嗝 "和资源密集性质,弹性对 Milvus 的经济性而言变得至关重要。Milvus 未来的版本将进一步探索异构计算和无服务器计算,以降低相关成本。

此外,Milvus 还支持标量过滤和主字段查询。为了提高查询效率,Milvus 还内置了布鲁姆过滤索引、哈希索引、树型索引和反转索引等索引,并计划引入更多外部索引,如位图索引和粗糙索引。

具体细节可以查询Milvus帮助文档。

2.4 检索

有了数据容器(Collection)和检索引擎(Index)后,最后一步便是从海量数据中高效检索信息。

基础向量检索(ANN Search)是 Milvus 的核心功能之一,即近似最近邻(Approximate Nearest Neighbor, ANN)检索。与需计算全部数据的暴力检索(Brute-force Search)不同,ANN 检索借助预先构建的索引,能极速从海量数据中找到与查询向量最相似的 Top-K 个结果,是一种在速度和精度间实现极致平衡的策略。其主要参数包括:anns_field(指定检索的向量字段)、data(传入查询向量)、limit(或 top_k,指定返回最相似结果的数量)、search_params(指定检索参数,如距离计算方式 metric_type 和索引相关查询参数)。

在基础 ANN 检索之上,Milvus 还提供多种增强检索功能,以满足更复杂的业务需求。过滤检索(Filtered Search)将向量相似性检索与标量字段过滤结合,先根据过滤表达式(filter)筛选符合条件的实体,再在子集内执行 ANN 检索,大幅提升查询精准度,例如电商场景中 “检索与红色连衣裙相似且价格低于 500 元、有库存的商品”,或知识库中 “从‘技术’分类、2023 年后发布的文章里找与‘人工智能’相关的文档”。

范围检索(Range Search)聚焦于 “所有与查询向量相似度在特定范围内的结果”,通过定义距离(或相似度)阈值范围,返回所有距离落在该范围内的实体,应用于人脸识别中 “查找与目标人脸相似度超 0.9 的人脸” 进行身份验证,或异常检测中 “查找与正常样本向量距离过大的数据点” 以发现异常。

多向量混合检索是强大的高级模式,支持在一个请求中同时检索多个向量字段并智能融合结果:先针对不同向量字段(如文本语义密集向量、关键词匹配稀疏向量、图像内容多模态向量)并行发起 ANN 检索,再通过重排策略(如平衡各方结果的 RRFRanker、可为特定字段加权的 WeightedRanker)合并为统一高质量排序列表,例如多模态商品检索中,用户输入 “安静舒适的白色耳机”,系统同时检索商品文本描述和图片内容向量返回最匹配结果;增强型 RAG 中,结合密集向量(捕捉语义)和稀疏向量(精确匹配关键词)实现更精准的文档检索。

分组检索则解决了检索结果多样性不足的问题,允许指定字段(如 document_id)对结果分组,确保返回结果中每个组(每个 document_id)只出现一次(或指定次数),且为该组内与查询最相似的实体,例如视频检索 “可爱的猫咪” 时确保结果来自不同博主,文档检索 “数据库索引” 时确保结果来自不同书籍或来源。通过这些灵活的检索功能组合,开发者可构建满足各类复杂业务需求的向量检索应用。

2.5 部署安装

首先,我们需要下载一个docker。下载docker步骤如下:

1.安装wsl。首先,搜索“启用或关闭Windows功能”,可以直接在任务栏中搜索。勾选“虚拟机平台”与“适用于Linux的Windows子系统”。其中“虚拟机平台”可能并未被翻译,叫做“Virtual Machine Platform”

在这里插入图片描述

勾选完毕之后你的电脑会重启。重启之后你需要以管理员身份打开cmd。依次输入以下两串代码:

wsl --set-default-version 2
wsl --update --web-download

其中“–web-download”可以减少网络问题导致的wsl下载失败。

2.打开docker官方网址,选择amd64下载Docker Desktop Installer.exe文件。

在这里插入图片描述

你可以直接安装,如果你想要指定docker的安装目录,你可以将exe文件拖到cmd默认目录下,然后输入下面这段代码:

start /w "" "Docker Desktop Installer.exe" install --installation-dir=地址

3.下载Milvus配置文件

首先移动到你代码所在的目录下,注意这里要使用powershell

cd "code 地址"

接着,使用以下命令下载官方的 docker-compose.yml 文件。这个文件定义了 Milvus Standalone 及其运行所需的两个核心依赖服务:etcd 用于存储元数据,MinIO 用于对象存储(更多架构细节请参考官方文档)。

# Windows (使用 PowerShell)
Invoke-WebRequest -Uri "https://github.com/milvus-io/milvus/releases/download/v2.5.14/milvus-standalone-docker-compose.yml" -OutFile "docker-compose.yml"

下载完毕之后,你的文件夹中会有一个名为“docker-compose.yml”的文件。

docker-compose.yml 文件所在的目录中,运行以下命令以后台模式启动 Milvus:

docker compose up -d

Docker 将会自动拉取所需的镜像并启动三个容器:milvus-standalone, milvus-minio, 和 milvus-etcd。这个过程可能需要几分钟,具体取决于你的网络状况。流程截图如下:

在这里插入图片描述

可以通过以下方式验证 Milvus 是否成功启动:

  • 查看 Docker 容器: 打开 Docker Desktop 的仪表盘 (Windows/macOS) 或在终端运行 docker ps 命令 (Linux),确认三个 Milvus 相关容器(milvus-standalone, milvus-minio, milvus-etcd)都处于 runningup 状态。
  • 检查服务端口: Milvus Standalone 默认通过 19530 端口提供服务,这是后续代码连接时需要用到的地址。

在这里插入图片描述

并且你的文件夹会变成这样:

在这里插入图片描述

2.6 运行代码

完整代码如下:

import os
from tqdm import tqdm
from glob import glob
import torch
from visual_bge.visual_bge.modeling import Visualized_BGE
from pymilvus import MilvusClient, FieldSchema, CollectionSchema, DataType
import numpy as np
import cv2
from PIL import Image# 1. 初始化设置
MODEL_NAME = "BAAI/bge-base-en-v1.5"  # 使用的预训练模型名称
MODEL_PATH = r"all-in-rag\models\bge\Visualized_base_en_v1.5.pth"  # 模型权重路径
DATA_DIR = r"all-in-rag\data\C3"  # 数据集目录
COLLECTION_NAME = "multimodal_demo"  # Milvus集合名称
MILVUS_URI = "http://localhost:19530"  # Milvus服务器地址# 2. 定义工具 (编码器和可视化函数)
class Encoder:"""编码器类,用于将图像和文本编码为向量。"""def __init__(self, model_name: str, model_path: str):# 初始化多模态模型self.model = Visualized_BGE(model_name_bge=model_name, model_weight=model_path)self.model.eval()  # 设置为评估模式def encode_query(self, image_path: str, text: str) -> list[float]:# 使用图像和文本生成多模态嵌入with torch.no_grad():  # 禁用梯度计算query_emb = self.model.encode(image=image_path, text=text)return query_emb.tolist()[0]  # 转换为Python列表def encode_image(self, image_path: str) -> list[float]:# 仅使用图像生成嵌入with torch.no_grad():query_emb = self.model.encode(image=image_path)return query_emb.tolist()[0]def visualize_results(query_image_path: str, retrieved_images: list, img_height: int = 300, img_width: int = 300, row_count: int = 3) -> np.ndarray:"""从检索到的图像列表创建一个全景图用于可视化。"""# 创建空白画布panoramic_width = img_width * row_countpanoramic_height = img_height * row_countpanoramic_image = np.full((panoramic_height, panoramic_width, 3), 255, dtype=np.uint8)  # 白色背景query_display_area = np.full((panoramic_height, img_width, 3), 255, dtype=np.uint8)  # 查询图像区域# 处理查询图像query_pil = Image.open(query_image_path).convert("RGB")query_cv = np.array(query_pil)[:, :, ::-1]  # PIL转OpenCV格式(RGB->BGR)resized_query = cv2.resize(query_cv, (img_width, img_height))bordered_query = cv2.copyMakeBorder(resized_query, 10, 10, 10, 10, cv2.BORDER_CONSTANT, value=(255, 0, 0))  # 添加蓝色边框# 将查询图像放置在右侧区域底部query_display_area[img_height * (row_count - 1):, :] = cv2.resize(bordered_query, (img_width, img_height))# 添加"Query"标签cv2.putText(query_display_area, "Query", (10, panoramic_height - 20), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2)# 处理检索到的图像for i, img_path in enumerate(retrieved_images):row, col = i // row_count, i % row_count  # 计算网格位置start_row, start_col = row * img_height, col * img_width  # 计算起始坐标retrieved_pil = Image.open(img_path).convert("RGB")retrieved_cv = np.array(retrieved_pil)[:, :, ::-1]  # 转换格式resized_retrieved = cv2.resize(retrieved_cv, (img_width - 4, img_height - 4))  # 调整大小bordered_retrieved = cv2.copyMakeBorder(resized_retrieved, 2, 2, 2, 2, cv2.BORDER_CONSTANT, value=(0, 0, 0))  # 添加黑色边框panoramic_image[start_row:start_row + img_height, start_col:start_col + img_width] = bordered_retrieved  # 放置到画布# 添加索引号cv2.putText(panoramic_image, str(i), (start_col + 10, start_row + 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)# 拼接查询区域和结果区域return np.hstack([query_display_area, panoramic_image])# 3. 初始化客户端
print("--> 正在初始化编码器和Milvus客户端...")
encoder = Encoder(MODEL_NAME, MODEL_PATH)  # 创建编码器实例
milvus_client = MilvusClient(uri=MILVUS_URI)  # 连接Milvus服务器# 4. 创建 Milvus Collection
print(f"\n--> 正在创建 Collection '{COLLECTION_NAME}'")
# 检查并删除已存在的集合
if milvus_client.has_collection(COLLECTION_NAME):milvus_client.drop_collection(COLLECTION_NAME)print(f"已删除已存在的 Collection: '{COLLECTION_NAME}'")# 获取数据集中的图像文件
image_list = glob(os.path.join(DATA_DIR, "dragon", "*.png"))
if not image_list:raise FileNotFoundError(f"在 {DATA_DIR}/dragon/ 中未找到任何 .png 图像。")# 获取嵌入维度(使用第一张图像)
dim = len(encoder.encode_image(image_list[0]))# 定义集合字段
fields = [FieldSchema(name="id", dtype=DataType.INT64, is_primary=True, auto_id=True),  # 主键IDFieldSchema(name="vector", dtype=DataType.FLOAT_VECTOR, dim=dim),  # 向量字段FieldSchema(name="image_path", dtype=DataType.VARCHAR, max_length=512),  # 图像路径
]# 创建集合
schema = CollectionSchema(fields, description="多模态图文检索")
milvus_client.create_collection(collection_name=COLLECTION_NAME, schema=schema)
print(f"成功创建 Collection: '{COLLECTION_NAME}'")
print("Collection 结构:")
print(milvus_client.describe_collection(collection_name=COLLECTION_NAME))# 5. 准备并插入数据
print(f"\n--> 正在向 '{COLLECTION_NAME}' 插入数据")
data_to_insert = []
# 遍历所有图像并生成嵌入向量
for image_path in tqdm(image_list, desc="生成图像嵌入"):vector = encoder.encode_image(image_path)  # 编码图像data_to_insert.append({"vector": vector, "image_path": image_path})  # 准备数据# 批量插入数据
if data_to_insert:result = milvus_client.insert(collection_name=COLLECTION_NAME, data=data_to_insert)print(f"成功插入 {result['insert_count']} 条数据。")# 6. 创建索引
print(f"\n--> 正在为 '{COLLECTION_NAME}' 创建索引")
# 配置HNSW索引参数
index_params = milvus_client.prepare_index_params()
index_params.add_index(field_name="vector",index_type="HNSW",  # 分层可导航小世界图算法metric_type="COSINE",  # 余弦相似度params={"M": 16, "efConstruction": 256}  # HNSW参数
)
# 创建索引
milvus_client.create_index(collection_name=COLLECTION_NAME, index_params=index_params)
# 加载集合到内存
milvus_client.load_collection(collection_name=COLLECTION_NAME)
print("已加载 Collection 到内存中。")# 7. 执行多模态检索
print(f"\n--> 正在 '{COLLECTION_NAME}' 中执行检索")
# 定义查询图像和文本
query_image_path = os.path.join(DATA_DIR, "dragon", "query.png")
query_text = "一条龙"
# 生成多模态查询向量
query_vector = encoder.encode_query(image_path=query_image_path, text=query_text)# 执行相似度搜索
search_results = milvus_client.search(collection_name=COLLECTION_NAME,data=[query_vector],  # 查询向量output_fields=["image_path"],  # 返回的字段limit=5,  # 返回前5个结果search_params={"metric_type": "COSINE", "params": {"ef": 128}}  # 搜索参数
)[0]  # 获取第一个查询结果# 处理检索结果
retrieved_images = []
print("检索结果:")
for i, hit in enumerate(search_results):print(f"  Top {i+1}: ID={hit['id']}, 距离={hit['distance']:.4f}, 路径='{hit['entity']['image_path']}'")retrieved_images.append(hit['entity']['image_path'])  # 收集图像路径# 8. 可视化与清理
print(f"\n--> 正在可视化结果并清理资源")
if not retrieved_images:print("没有检索到任何图像。")
else:panoramic_image = visualize_results(query_image_path, retrieved_images)combined_image_path = os.path.join(DATA_DIR, "search_result.png")cv2.imwrite(combined_image_path, panoramic_image)print(f"结果图像已保存到: {combined_image_path}")Image.open(combined_image_path).show()milvus_client.release_collection(collection_name=COLLECTION_NAME)
print(f"已从内存中释放 Collection: '{COLLECTION_NAME}'")
milvus_client.drop_collection(COLLECTION_NAME)
print(f"已删除 Collection: '{COLLECTION_NAME}'")

运行结果如下所示:

E:\anaconda\envs\all-in-rag\Lib\site-packages\timm\models\layers\__init__.py:48: 
--> 正在初始化编码器和Milvus客户端...--> 正在创建 Collection 'multimodal_demo'
Schema 结构:
{'auto_id': True, 'description': '多模态图文检索', 'fields': [{'name': 'id', 'description': '', 'type': <DataType.INT64: 5>, 'is_primary': True, 'auto_id': True}, {'name': 'vector', 'description': '', 'type': <DataType.FLOAT_VECTOR: 101>, 'params': {'dim': 768}}, {'name': 'image_path', 'description': '', 'type': <DataType.VARCHAR: 21>, 'params': {'max_length': 512}}], 'enable_dynamic_field': False}
成功创建 Collection: 'multimodal_demo'
Collection 结构:
{'collection_name': 'multimodal_demo', 'auto_id': True, 'num_shards': 1, 'description': '多模态图文检索', 'fields': [{'field_id': 100, 'name': 'id', 'description': '', 'type': <DataType.INT64: 5>, 'params': {}, 'auto_id': True, 'is_primary': True}, {'field_id': 101, 'name': 'vector', 'description': '', 'type': <DataType.FLOAT_VECTOR: 101>, 'params': {'dim': 768}}, {'field_id': 102, 'name': 'image_path', 'description': '', 'type': <DataType.VARCHAR: 21>, 'params': {'max_length': 512}}], 'functions': [], 'aliases': [], 'collection_id': 460171652961143814, 'consistency_level': 2, 'properties': {}, 'num_partitions': 1, 'enable_dynamic_field': False, 'created_timestamp': 460171813451988996, 'update_timestamp': 460171813451988996} --> 正在向 'multimodal_demo' 插入数据
生成图像嵌入: 100%|█████████████████████████████████████████████████████████████████████████████████████████████████| 7/7 [00:01<00:00,  4.45it/s] 
成功插入 7 条数据。--> 正在为 'multimodal_demo' 创建索引
成功为向量字段创建 HNSW 索引。
索引详情:
{'M': '16', 'efConstruction': '256', 'metric_type': 'COSINE', 'index_type': 'HNSW', 'field_name': 'vector', 'index_name': 'vector', 'total_rows': 0, 'indexed_rows': 0, 'pending_index_rows': 0, 'state': 'Finished'}
已加载 Collection 到内存中。--> 正在 'multimodal_demo' 中执行检索
检索结果:Top 1: ID=460171652961143835, 距离=0.9466, 路径='all-in-rag\data\C3\dragon\query.png'Top 2: ID=460171652961143829, 距离=0.7443, 路径='all-in-rag\data\C3\dragon\dragon02.png'Top 3: ID=460171652961143833, 距离=0.6851, 路径='all-in-rag\data\C3\dragon\dragon06.png'Top 4: ID=460171652961143830, 距离=0.6049, 路径='all-in-rag\data\C3\dragon\dragon03.png'Top 5: ID=460171652961143832, 距离=0.5360, 路径='all-in-rag\data\C3\dragon\dragon05.png'--> 正在可视化结果并清理资源
结果图像已保存到: all-in-rag\data\C3\search_result.png
已从内存中释放 Collection: 'multimodal_demo'
已删除 Collection: 'multimodal_demo'

在这里插入图片描述

整体流程总结:

  1. 初始化设置:配置模型、路径和Milvus连接参数
  2. 定义工具
    • Encoder类:处理图像/文本到向量的转换
    • visualize_results函数:创建查询结果的可视化视图
  3. Milvus集合管理
    • 创建包含向量和图像路径的集合
    • 删除已存在的同名集合
  4. 数据处理
    • 加载并编码所有图像
    • 将向量和元数据插入Milvus
  5. 索引创建:为向量字段创建HNSW索引
  6. 多模态检索
    • 结合图像和文本生成查询向量
    • 在Milvus中执行相似度搜索
  7. 结果展示
    • 打印检索结果
    • 可视化查询图像和结果图像
  8. 资源清理:释放并删除Milvus集合

参考文章

[1] https://blog.csdn.net/lsb2002/article/details/132222947

[2] https://datawhalechina.github.io/all-in-rag/#/chapter3/09_milvus

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/919190.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/919190.shtml
英文地址,请注明出处:http://en.pswp.cn/news/919190.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

亚马逊店铺绩效巡检_影刀RPA源码解读

一、项目简介 本项目是一个基于RPA开发的店铺绩效巡店机器人。该机器人能够自动化地登录卖家后台&#xff0c;遍历多个店铺和站点&#xff0c;收集并分析各类绩效数据&#xff0c;包括政策合规性、客户服务绩效、配送绩效等关键指标&#xff0c;并将数据整理到Excel报告中&…

跨越南北的养老对话:为培养“银发中国”人才注入新动能

2025年8月16日&#xff0c;北京养老行业协会常务副会长陈楫宝一行到访广州市白云区粤荣职业培训学校&#xff0c;受到颐年集团副总李娜的热情接待。此次访问不仅是京穗两地养老行业的一次深度交流&#xff0c;更为推动全国智慧养老体系建设、提升养老服务专业化水平注入了新动能…

Spring IOC 学习笔记

1. 概述Spring IOC&#xff08;Inversion of Control&#xff0c;控制反转&#xff09;是一种设计思想&#xff0c;通过依赖注入&#xff08;Dependency Injection&#xff0c;DI&#xff09;实现。它的核心思想是将对象的创建和依赖关系的管理交给Spring容器&#xff0c;从而降…

揭开Android Vulkan渲染封印:帧率暴增的底层指令

ps&#xff1a;本文内容较干&#xff0c;建议收藏后反复边跟进源码边思考设计思想。壹渲染管线的基础架构为什么叫渲染管线&#xff1f;这里是因为整个渲染的过程涉及多道工序&#xff0c;像管道里的流水线一样&#xff0c;一道一道的处理数据的过程&#xff0c;所以使用渲染管…

HTTP 请求转发与重定向详解及其应用(含 Java 示例)

在 Web 开发中&#xff0c;我们经常需要在不同页面之间跳转&#xff0c;比如登录成功后跳到首页、提交表单后跳到结果页面。这时&#xff0c;常见的两种跳转方式就是 请求转发&#xff08;Request Forward&#xff09; 和 重定向&#xff08;Redirect&#xff09;。虽然它们都能…

如何将 MCP Server (FastMCP) 配置为公网访问(监听 0.0.0.0)

如何将 MCP Server &#xff08;FastMCP&#xff09; 配置为公网访问&#xff08;监听 0.0.0.0&#xff09;引言常见错误尝试根本原因&#xff1a;从源码解析正确的解决方案总结引言 在使用 Model Context Protocol(MCP) 框架开发自定义工具服务器时&#xff0c;我们经常使用 …

The Network Link Layer: 无线传感器中Delay Tolerant Networks – DTNs 延迟容忍网络

Delay Tolerant Networks – DTNs 延迟容忍网络架构归属Delay Tolerant Networks – DTNs 延迟容忍网络应用实例例子 1&#xff1a;瑞典北部的萨米人 (Saami reindeer herders)例子 2&#xff1a;太平洋中的动物传感网络DTNs路由方式——存储&转发DTNs移动模型Random walk …

计算机视觉(opencv)实战二——图像边界扩展cv2.copyMakeBorder()

OpenCV copyMakeBorder() 图像边界扩展详解与实战在图像处理和计算机视觉中&#xff0c;有时需要在原始图像的四周增加边界&#xff08;Padding&#xff09;。这种操作在很多场景中都有应用&#xff0c;比如&#xff1a;卷积神经网络&#xff08;CNN&#xff09;中的图像预处理…

ansible管理变量和事实

ansible管理变量和事实与实施任务控制 在 Ansible 中&#xff0c;变量和事实&#xff08;Facts&#xff09;就像给剧本&#xff08;Playbook&#xff09;配备的 “信息工具箱”&#xff0c;让你的自动化配置管理更灵活、更智能。 变量&#xff1a;提前准备的 “预设信息” 变…

STM32--寄存器与标准库函数--基本定时器

目录 前言 基本定时器概念 定时时间 定时器时钟确定 倍频锁相环被正确配置为168MHz 定时器的库函数操作 代码 定时器的寄存器操作 代码 寄存器 后言 前言 使用平台:STM32F407ZET6 使用数据手册&#xff1a;STM32F407数据手册.pdf 使用参考手册&…

PCA 实现多向量压缩:首个主成分的深层意义

PCA 实现多向量压缩 第一个主成分(components_[0])正是数据协方差矩阵中最大特征值对应的特征向量。 ,layer_attention_vector[layer] 被赋值为 pca.components_[0],这确实是一个特征向量,具体来说是 PCA 分解得到的第一个主成分(主特征向量)。 关于它的维度: 假设 c…

网络常识-DNS如何解析

DNS&#xff08;Domain Name System&#xff0c;域名系统&#xff09;是互联网的“地址簿”&#xff0c;负责将人类易记的域名&#xff08;如www.example.com&#xff09;转换为计算机可识别的IP地址&#xff08;如192.168.1.1&#xff09;。其工作流程可以简单理解为“从域名到…

Java中 23 种设计模式介绍,附带示例

文章目录设计模式六大原则设计模式分类1、创建型模式&#xff08;Creational Patterns&#xff09;2、结构型模式&#xff08;Structural Patterns&#xff09;3、行为型模式&#xff08;Behavioral Patterns&#xff09;一、创建型模式&#xff08;Creational Patterns&#x…

嵌入式开发入门——电子元器件~电磁继电器、蜂鸣器

文章目录电磁继电器定义关键参数实物蜂鸣器实物内部结构分类关键参数电磁继电器 定义 概述&#xff1a;电磁继电器是利用电磁感应原理职称的一种电磁开关&#xff0c;他能通过&#xff1a;低电压、低电流的电路&#xff0c;来控制高电压、高电流的电路。 关键参数 线圈电压…

ROS2基础

1.helloworld案例1.创建功能包&#xff08;C&#xff09;终端下&#xff0c;进入ws00_helloworld/src目录&#xff0c;使用如下指令创建一个C 功能包:ros2 pkg create pkg01_helloworld_cpp --build-type ament_cmake --dependencies rclcpp --node-name helloworld执行完毕&a…

Python爬虫实战:研究pygalmesh,构建Thingiverse平台三维网格数据处理系统

1. 引言 1.1 研究背景 在数字化浪潮席卷全球的当下,三维建模技术已成为连接虚拟与现实的核心纽带,广泛渗透于工程设计、地理信息系统(GIS)、虚拟现实(VR)、增强现实(AR)、医学影像等关键领域。例如,在建筑工程中,BIM(建筑信息模型)技术依赖高精度三维网格实现施工…

开发者说 | EmbodiedGen:为具身智能打造可交互3D世界生成引擎

概述 具身智能的发展离不开高质量、多样化的可交互3D仿真环境。为突破传统构建方式的瓶颈&#xff0c;我们提出了EmbodiedGen&#xff0c;一个基于生成式AI技术的自动化3D世界生成引擎&#xff0c;助力低成本、高效率地创建真实且可交互的3D场景。用户仅需输入任务定义或场景图…

GitHub Copilot:AI编程助手的架构演进与真实世界影响

本文由「大千AI助手」原创发布&#xff0c;专注用真话讲AI&#xff0c;回归技术本质。拒绝神话或妖魔化。搜索「大千AI助手」关注我&#xff0c;一起撕掉过度包装&#xff0c;学习真实的AI技术&#xff01; 1. 技术背景与核心架构 GitHub Copilot 是由 GitHub 与 OpenAI 联合开…

PDF OCR + 大模型:让文档理解不止停留在识字

在企业数字化的实际场景中&#xff0c;PDF OCR 已经很普遍了&#xff1a;从扫描件提取文本、表格到生成可搜索 PDF。但这类技术往往停留在"把图片变成文字"&#xff0c;对文档背后的语义、逻辑、业务价值理解不足。 而当 OCR 遇上大语言模型&#xff08;LLM&#xff…

半敏捷卫星观测调度系统的设计与实现

半敏捷卫星观测调度系统的设计与实现 摘要 本文详细阐述了一个基于Python的半敏捷卫星观测调度系统的设计与实现过程。系统针对半敏捷卫星特有的机动能力限制&#xff0c;综合考虑了地面目标观测需求、卫星资源约束、能源管理等多重因素&#xff0c;提出了一种混合启发式算法解…