1. 向量数据库与 Qdrant 简介
向量的概念起源于数学和物理学,通常指那些不能用单个数字(标量)表达的量。一个向量可以被形象地理解为连接起始点 A 和终止点 B 的箭头,这个箭头不仅指示了方向,也代表了从 A 到 B 的距离。在机器学习和数据分析领域,高维向量被用来捕捉事物的复杂信息及其相互关系,如同对事物进行细致的描述,包含了多个不同的方面或特征。向量空间则是由这些向量组成的集合,它们之间可以进行加法和乘法运算,但需遵循特定的规则。理解向量的关键在于维度,维度描述了事物可以在多少个方向上被测量。例如,一条线是一维的,一个平面是二维的,而我们常见的物体如立方体、圆柱体或球体是三维的。高维向量可以拥有数百甚至数千个维度,从而能够捕捉极其复杂的特征。
向量数据库是一种专门用于存储、管理和索引高维向量数据的系统。与传统的以行和列存储数据的关系型数据库不同,向量数据库中的数据点由固定数量维度的向量表示,这些向量基于相似性进行聚类。这种设计使得向量数据库能够高效地处理非结构化数据,例如文本、图像、音频和视频等,这些数据的特征可以被提取并转化为高维向量嵌入。向量数据库的核心能力在于能够快速执行相似性搜索,即根据查询向量找到数据库中与之最接近的向量. 这种能力对于构建现代人工智能应用至关重要。虽然向量和向量数据库的概念并非新生事物,它们在地图绘制和数据分析等特定领域已有长期应用。近年来,随着人工智能和机器学习的飞速发展,向量嵌入和向量数据库在推荐系统、搜索引擎、个性化服务、异常检测等领域发挥着越来越重要的作用. 非结构化数据的爆炸式增长,使得传统基于关键词的搜索方法在理解用户意图和数据语义方面显得力不从心。向量搜索通过理解数据和查询的潜在含义,提供了更为强大的信息检索能力。
Qdrant 是一款领先的开源向量数据库和相似性搜索引擎。它专为处理高性能和大规模人工智能应用中的高维向量而设计。Qdrant 的关键特性包括卓越的性能,能够实现高速且高效的数据处理;良好的可扩展性,可以应对不断增长的数据量和查询负载;易于使用的 API,方便开发者进行集成;以及丰富的功能集,支持各种高级搜索和过滤操作。Qdrant 基于 Rust 语言开发,这赋予了它出色的安全性和可靠性,即使在重负载下也能保持稳定运行。Qdrant 在多种应用场景中表现出色,例如高级搜索、推荐系统、检索增强生成(RAG)、数据分析和异常检测以及构建智能代理。随着非结构化数据的持续增长,以及传统基于关键词的搜索在理解语义方面的局限性日益凸显,Qdrant 等向量数据库正成为构建智能应用的关键基础设施.
2. 向量搜索的理论基础
向量嵌入是数据的数值表示,将不同类型的数据(如文本、图像、音频等)转换成高维空间中的数字数组。这种转换过程旨在捕捉数据的本质特征和含义,使得在向量空间中,语义上相似的数据点在几何上也彼此靠近。向量的维度决定了能够捕获的特征的细致程度,维度越高,通常能表示越复杂的信息。与传统的稀疏数据表示方法(如 one-hot 编码)相比,向量嵌入是稠密的,并且能够通过向量之间的距离来衡量不同数据点之间的语义相似性。将数据对象转化为向量的过程称为向量化。有效的向量嵌入能够超越简单的关键词匹配或同义词搜索,真正理解用户的查询意图.
为了量化向量之间的相似性,需要使用距离度量或相似性度量。这些度量方法在数学上定义了向量空间中两个向量之间的“距离”或“接近程度”。常用的度量包括:
- 余弦相似度 (Cosine Similarity):衡量两个向量方向之间的夹角余弦值。余弦值为 1 表示方向完全相同,0 表示正交(无相似性),-1 表示方向完全相反。由于它关注的是向量的方向而非大小,因此特别适用于文本和文档相似性分析,在这些场景中,文档的长度差异可能很大,但语义方向的相似性更为重要.
- 欧氏距离 (Euclidean Distance):计算向量空间中两点之间的直线距离。距离越小,表示向量越相似。欧氏距离考虑了向量的大小和方向,因此适用于那些向量的整体差异需要被衡量的场景.
- 点积 (Dot Product / Inner Product):衡量两个向量在同一方向上的投影的乘积。点积的值与向量的长度和它们之间的角度有关,正值表示向量大致指向同一方向,负值表示相反方向,零值表示它们是正交的。点积常用于推荐系统中,衡量用户偏好与物品特征之间的“一致性”.
- 曼哈顿距离 (Manhattan Distance):计算在标准坐标系中两个点之间的轴对齐距离的总和。它类似于在城市街区中从一个点到另一个点所需要行走的总距离。
选择合适的相似性度量取决于数据的特性和应用的目标。不同的度量方法捕捉了不同的相似性概念,因此根据具体情况选择最能反映数据之间相关性的度量至关重要。
为了在大型数据集中高效地找到与查询向量相似的向量,需要使用索引技术。如果没有索引,搜索将需要将查询向量与数据库中的每一个向量进行比较,这在数据量很大时会非常耗时。索引技术通过组织向量数据,使得相似性搜索可以在一个较小的子集中进行,从而大大提高了搜索效率。常用的近似最近邻(Approximate Nearest Neighbor, ANN)搜索算法是向量数据库的核心。ANN 算法旨在快速找到查询向量的近似最近邻,而不是保证找到绝对精确的最近邻,这种近似换取了显著的搜索速度提升。常见的索引技术包括:
- 分层可导航小世界图 (Hierarchical Navigable Small World, HNSW):这是一种多层图结构,其中每个向量都是一个节点,相似的向量之间通过边连接。搜索从图的顶层开始,快速导航到可能包含最近邻的区域,然后在较低层进行更精细的搜索。HNSW 在搜索速度和准确性之间取得了良好的平衡,是 Qdrant 的默认索引方法.
- 倒排文件索引 (Inverted File Index, IVF):这种方法基于聚类,将向量空间划分为若干个簇。搜索时,首先确定查询向量属于哪个簇,然后只在该簇内进行搜索,从而缩小了搜索范围。
- 局部敏感哈希 (Locality Sensitive Hashing, LSH):LSH 是一种哈希技术,其目标是使相似的向量以高概率被哈希到相同的哈希桶中。搜索时,只需要检查与查询向量哈希到相同桶中的向量。LSH 特别适用于高维数据,并且可以提供快速的搜索速度,但召回率可能不如其他方法。
- 扁平索引 (Flat Indexing):这是一种暴力搜索方法,不进行任何索引构建,而是将查询向量与数据库中的所有其他向量进行比较。虽然可以保证找到最精确的最近邻,但对于大型数据集来说速度非常慢。
- 乘积量化 (Product Quantization, PQ):PQ 是一种压缩技术,通过将高维向量分解成若干个子向量,并对每个子向量进行量化来减少向量的内存占用。虽然可以显著降低内存使用,但也可能影响搜索的准确性。
不同的索引方法在准确性、搜索速度和内存使用方面各有优劣。选择哪种索引方法取决于具体的应用场景和对这些指标的不同侧重。
表 1:向量数据库索引技术比较
索引技术 | 准确性 | 速度 | 内存使用 | 适用场景 |
HNSW | 高 | 快 | 中等 | 通用,推荐系统,语义搜索 |
IVF | 中高 | 快 | 中等 | 大型数据集,可接受一定的准确性损失 |
LSH | 中低 | 非常快 | 低 | 非常高维数据,近重复项检测 |
扁平索引 | 高 | 慢 | 高 | 小型数据集,对准确性要求极高 |
乘积量化 | 中等 | 中等到快 | 低 | 内存受限环境,近似搜索 |
3. Qdrant 架构与核心概念
Qdrant 采用分布式架构,旨在提供高可扩展性和高可用性。一个 Qdrant 集群由多个服务器实例组成,这些实例被称为节点。每个节点都参与数据的存储和处理,共同构成一个提供向量数据库服务的统一整体。为了实现水平扩展,Qdrant 使用分片(Sharding)技术将一个集合(Collection)分割成更小的独立部分,称为分片。这些分片被分布到集群中的不同节点上,从而允许并行处理查询,显著提升了大型数据集的性能。为了确保数据的冗余和容错能力,Qdrant 还使用复制(Replication)技术为每个分片创建多个副本(Replicas),并将这些副本分布到不同的节点上。如果一个节点发生故障,数据仍然可以从其他节点上的副本中获取,保证了服务的高可用性和数据的持久性。Qdrant 使用 Raft 共识协议来维护集群拓扑和集合结构在所有节点上的一致性。虽然对于单个数据点的操作,Qdrant 优先考虑速度,但 Raft 协议确保了分布式系统的整体健康和数据一致性。在 Qdrant Hybrid Cloud 部署中,数据平面(存储和处理向量数据的地方)与控制平面(管理集群操作的地方)是分离的。这种架构允许用户将数据存储在他们自己的基础设施中(云端或本地),同时利用 Qdrant 的托管服务,为具有特定数据治理要求的组织提供了增强的数据主权、安全性和灵活性.
Qdrant 的核心概念包括:
- 集合 (Collections):集合是 Qdrant 中存储数据的主要组织单元,类似于关系型数据库中的表。一个集合包含多个数据点,所有数据点中的向量必须具有相同的维度,并且在集合内使用相同的距离度量进行相似性搜索.
- 点 (Points):点是 Qdrant 中存储的基本数据单元。每个点包含一个向量,一个唯一的 64 位无符号整数或 UUID 格式的 ID,以及一个可选的载荷(Payload),载荷是一个 JSON 对象,用于存储关于该向量的额外元数据.
- 向量 (Vectors):高维数值数组,用于表示数据的特征。向量是向量数据库中存储和查询的核心数据类型。
- 载荷 (Payload):一个与向量关联的可选 JSON 对象,用于存储关于该向量的额外信息或元数据。载荷可以用于过滤搜索结果,提供关于检索到的向量的更多上下文信息。
- 距离度量 (Distance Metrics):用于衡量向量之间相似性的方法,例如余弦相似度、欧氏距离和点积(已在第二章中介绍)。
- 索引 (Indexing):用于加速相似性搜索的技术,例如 HNSW、IVF 和 LSH(已在第二章中介绍)。
- 分片 (Shards) 和副本 (Replicas):用于实现水平扩展和容错(已在本章前面介绍)。
Qdrant 提供了多种存储选项以满足不同的性能和容量需求:
- 基于 RAM 的存储 (RAM-based Storage):默认情况下,Qdrant 可以将向量数据存储在服务器的随机存取内存(RAM)中。这种方式提供了最快的访问速度,适用于数据集大小不超过可用内存的情况.
- 内存映射存储 (Memmap Storage):对于大于可用 RAM 的数据集,Qdrant 提供了内存映射文件(Memmap)的选项。这允许操作系统将磁盘上的文件直接映射到进程的地址空间,在 RAM 足够的情况下,可以像访问 RAM 一样高效地访问数据.
- 磁盘向量存储 (On-disk Vector Storage):Qdrant 也支持将向量数据直接存储在磁盘上。这种方式可以显著降低 RAM 的使用,适用于非常大的数据集或内存资源有限的环境。然而,从磁盘访问数据通常比从 RAM 慢,这可能会影响搜索延迟。
值得注意的是,Qdrant 在存储向量之前会自动对其进行归一化处理。这确保了在使用某些距离度量(如余弦相似度)时,相似性是基于向量的方向而非大小来计算的,这在语义搜索等应用中非常重要。
4. Qdrant 入门
开始使用 Qdrant 有多种部署选项可供选择,以适应不同的开发和生产环境:
- Docker:对于本地开发和测试,推荐使用 Docker 部署 Qdrant。Docker 提供了一个容器化的环境,可以轻松地安装和运行 Qdrant,并且保证了环境的一致性。可以使用以下命令拉取最新的 Qdrant 镜像:BashBash
docker pull qdrant/qdrant
然后,可以使用以下命令运行 Qdrant 服务,并将主机端口 6333 和 6334 映射到容器的相应端口,同时将主机上的一个目录挂载到容器内的存储目录,以实现数据持久化:
docker run -p 6333:6333 -p 6334:6334 -v "$(pwd)/qdrant_storage:/qdrant/storage:z" qdrant/qdrant
其中,端口 6333 用于 REST API 访问,端口 6334 用于 gRPC API 访问。
- Qdrant Cloud:对于生产环境,Qdrant 提供了完全托管的云服务,支持在 AWS、GCP 和 Azure 上部署。Qdrant Cloud 简化了部署和管理过程,提供了自动化的扩展和维护,适合需要高可用性和可扩展性的应用.
- Hybrid Cloud:Qdrant Hybrid Cloud 允许在用户现有的基础设施中(无论是云端、本地还是边缘)部署托管的 Qdrant 集群。这种方式在提供 Qdrant 托管便利性的同时,也保障了数据的本地存储和主权。Hybrid Cloud 通常基于 Kubernetes 进行部署.
- Private Cloud (On-Premise):对于有严格安全和合规要求的组织,Qdrant 可以完全部署在企业自身的私有基础设施中。这种方式提供了最大的控制权,但需要企业自行管理所有的基础设施.
- Kubernetes:可以使用 Helm Chart 在 Kubernetes 集群中部署 Qdrant。Helm Chart 简化了在 Kubernetes 上部署和管理应用程序的过程。
- 二进制可执行文件:Qdrant 也提供了二进制可执行文件,可以直接在支持的操作系统上运行。
部署完成后,可以通过浏览器访问
http://localhost:6333/dashboard
来打开 Qdrant 的 Web UI(如果使用 Docker 部署在本地)。Web UI 提供了一个图形界面,可以方便地查看和管理集合,以及执行基本的查询操作.要使用 Python 与 Qdrant 进行交互,首先需要安装 Qdrant 的 Python 客户端库:
pip install qdrant-client
安装完成后,可以使用
QdrantClient
类来初始化客户端并连接到 Qdrant 实例。例如,连接到本地运行的 Qdrant 实例可以使用以下代码:from qdrant_client import QdrantClient, models client = QdrantClient(url="http://localhost:6333")
在连接到 Qdrant 实例后,可以创建一个新的集合来存储向量数据。创建集合需要指定集合的名称、向量的维度以及用于相似性比较的距离度量。以下是一个创建名为 "my_collection" 的集合的示例,该集合存储 128 维的向量,并使用余弦相似度作为距离度量:
client.create_collection( collection_name="my_collection", vectors_config=models.VectorParams(size=128, distance=models.Distance.COSINE) )
创建集合后,可以使用
upsert
方法向集合中插入数据点。每个数据点包含一个唯一的 ID、一个向量以及可选的载荷(元数据)。以下示例向 "my_collection" 插入 10 个随机生成的 128 维向量,并为每个向量添加一个包含索引的载荷:import numpy as np vectors = np.random.rand(10, 128).tolist() client.upsert( collection_name="my_collection", points=, wait=True )
插入数据后,可以执行基本的相似性搜索。
search
方法接受一个查询向量和返回结果的数量限制,并返回与查询向量最相似的向量及其相似度得分。以下示例查询与一个随机生成的 128 维向量最相似的 5 个向量:query_vector = np.random.rand(128).tolist() search_results = client.search( collection_name="my_collection", query_vector=query_vector, limit=5 ) print(search_results)
需要注意的是,Qdrant 默认使用 6333 端口作为 REST API 的服务端口,使用 6334 端口作为 gRPC API 的服务端口。在配置客户端连接或防火墙规则时,需要注意这些端口设置。
5. 生成和利用向量嵌入
向量嵌入是通过机器学习模型生成的,这些模型经过大量数据的训练,能够学习到数据的有意义的表示。在训练过程中,模型调整其内部参数,将输入的各种类型的数据(如文本、图像或音频)映射到稠密的、低维的向量空间中,这些向量能够捕捉不同数据点之间的语义关系。嵌入模型的质量和有效性高度依赖于模型的架构及其训练数据的质量和规模。不同的模型被设计用于捕捉不同类型的信息。
根据所表示的数据类型,可以使用不同类型的向量嵌入。词嵌入用于表示单个词语,句子嵌入用于表示整个句子,文档嵌入用于表示更长的文本,图像嵌入用于表示图像的视觉特征,音频嵌入用于表示音频信号的特性,等等。选择哪种类型的嵌入应与存储在向量数据库中并进行搜索的数据的粒度相匹配。
以下是一些常用的嵌入模型:
- 词嵌入模型 (Word Embedding Models):如 Word2Vec、GloVe 和 FastText。这些模型在自然语言处理(NLP)领域广泛使用,能够捕捉词语之间的语义和句法关系,将语义相似的词语在向量空间中放置得更近.
- 句子和文档嵌入模型 (Sentence and Document Embedding Models):如 BERT、Universal Sentence Encoder (USE) 和 Sentence Transformers。这些模型旨在为更大的文本单元生成嵌入,捕捉句子和文档的整体含义和上下文。它们对于语义搜索、文本分类和情感分析等任务至关重要。
- 图像嵌入模型 (Image Embedding Models):如卷积神经网络 (CNNs) 和预训练模型 ResNet、VGG 以及 CLIP。CNNs 擅长从图像中提取视觉特征,预训练模型则利用在大规模图像数据集上学习到的知识生成有效的图像表示。CLIP 模型则学习图像和文本的联合嵌入。
- 音频和其他数据类型的模型 (Models for Audio and Other Data Types):例如,Whisper 模型可以用于生成音频的嵌入。
值得一提的是,Transformer 架构,一种利用自注意力机制的神经网络架构,已经成为许多最先进的嵌入模型的基础。Transformer 模型能够有效地捕捉长距离依赖关系和上下文信息,从而生成高质量的嵌入.
在 Python 中,可以使用各种库来生成向量嵌入。例如,Sentence Transformers 库提供了一系列易于使用的预训练模型,可以为句子和文档生成高质量的嵌入。以下是一个使用 Sentence Transformers 库生成句子嵌入的示例:
from sentence_transformers import SentenceTransformer model = SentenceTransformer('all-MiniLM-L6-v2') sentences = ["这是第一个句子。", "这是第二个句子。"] embeddings = model.encode(sentences) print(embeddings.shape)
OpenAI API 也提供了强大的嵌入模型,可以使用
openai
库进行访问(以下是概念性示例):import openai openai.api_key = "YOUR_OPENAI_API_KEY" response = openai.Embedding.create( model="text-embedding-ada-002", input=["你的文本"], ) embedding = response['data']['embedding']
Hugging Face Transformers 库也提供了许多预训练模型,可以用于生成各种类型的嵌入(以下是概念性示例):
from transformers import AutoTokenizer, AutoModel import torch tokenizer = AutoTokenizer.from_pretrained('sentence-transformers/all-MiniLM-L6-v2') model = AutoModel.from_pretrained('sentence-transformers/all-MiniLM-L6-v2') inputs = tokenizer("你的文本", return_tensors="pt", padding=True, truncation=True, max_length=512) with torch.no_grad(): outputs = model(**inputs) embeddings = outputs.last_hidden_state.mean(dim=1).squeeze().numpy()
选择合适的嵌入模型需要在准确性、速度和资源使用之间进行权衡。模型的选择应基于具体的应用需求和数据的特点。
生成向量嵌入后,需要将其存储到 Qdrant 中以进行相似性搜索。在创建集合时,需要确保所使用的嵌入的维度与集合配置的向量大小相匹配。可以使用
upsert
方法将生成的嵌入连同原始数据或元数据(载荷)一起存储到 Qdrant 中。当通过搜索找到相似的嵌入时,可以使用返回的 ID 来检索原始数据(如果存储在其他地方)或使用存储在载荷中的元数据。Qdrant 充当了这些向量嵌入的专门索引,允许高效地检索语义上相似的数据。载荷提供了一种将原始数据或相关元数据与嵌入关联起来的方式。6. 在 Qdrant 中执行相似性搜索和查询
执行基本的相似性搜索是 Qdrant 的核心功能。可以使用
search
方法,提供一个查询向量和希望返回的结果数量限制。搜索结果会返回一个包含得分点的列表,每个得分点包含一个匹配向量的 ID 以及一个表示相似度得分的数值。得分的数值大小取决于在创建集合时选择的距离度量。之前在第四章中已经展示了基本的搜索示例。在许多实际应用中,仅仅基于语义相似性进行搜索可能不够,还需要根据与向量关联的元数据来进一步筛选搜索结果。Qdrant 允许使用载荷(Payload)来过滤搜索结果,从而根据特定的条件缩小搜索范围。可以使用
models.Filter
和 models.FieldCondition
来创建过滤器。一个过滤器可以包含多个条件,这些条件可以是不同类型的,例如精确匹配(match
)、范围查询(range
)、地理位置查询(geo
)、值计数查询(values count
)等等。多个条件可以使用 must
(逻辑与)、should
(逻辑或)和 must_not
(逻辑非)等子句进行组合。以下是一个在 Python 中使用载荷进行过滤的示例:from qdrant_client import models, QdrantClient import numpy as np client = QdrantClient(url="http://localhost:6333") query_vector = np.random.rand(128).tolist() search_results = client.search( collection_name="my_collection", query_vector=query_vector, limit=5, query_filter=models.Filter( must= ) ) print(search_results)
在这个例子中,搜索结果只包含那些载荷中 "index" 字段的值在 3 到 7 之间的向量。
混合搜索结合了语义理解和关键词匹配的优点。向量搜索擅长理解查询和文档的含义,而关键词搜索则可以精确地匹配特定的术语。Qdrant 支持混合查询,可以使用稀疏向量进行关键词检索,并结合稠密向量进行语义搜索。通过适当的技术(如分数融合),可以将来自不同搜索类型的结果组合起来,从而提高搜索的全面性和相关性.
除了基本的相似性搜索和过滤外,Qdrant 还提供了许多高级查询技术:
- 使用多个查询向量进行搜索。这对于比较多个项目或基于不同的方面细化搜索非常有用。
- 使用推荐 API。Qdrant 包含一个专门用于构建推荐系统的 API。
- 地理空间搜索功能。Qdrant 可以处理地理空间数据并执行相关的查询。
- 全文搜索集成。Qdrant 可以与全文搜索引擎集成或利用其内置的功能进行全文搜索。
这些高级查询功能使得 Qdrant 能够应对各种复杂的信息检索场景。
7. Qdrant 的高级特性:性能与可扩展性
向量量化是一种关键的压缩技术,用于优化向量数据库的性能和资源使用,尤其是在处理大规模数据集和高维向量时。通过压缩向量的表示,可以减少存储所需的内存,并且还可以加速距离计算,从而提高搜索速度. Qdrant 支持多种量化方法:
- 标量量化 (Scalar Quantization):将向量的每个分量从浮点数(通常为 32 位)转换为整数(通常为 8 位)。这可以将内存占用减少四倍,并且由于 Qdrant 可以使用优化的 SIMD 指令进行整数运算,因此还可以加快向量比较的速度. 标量量化在内存减少和准确性损失之间取得了良好的平衡,使其成为一种通用的技术.
- 二值量化 (Binary Quantization):是一种极端的标量量化形式,其中向量的每个分量都用单个比特(0 或 1)表示。与 32 位浮点数相比,这可以将内存使用量减少 32 倍,并提供最快的向量比较速度。然而,它可能导致更显著的准确性损失,并且最适合于特定类型的嵌入和应用.
- 乘积量化 (Product Quantization):将高维向量分成多个低维子向量,然后使用诸如 k-means 聚类之类的技术独立地量化每个子向量。这可以实现高压缩率,但也可能导致明显的准确性损失. 乘积量化适用于内存占用是绝对优先考虑的事项,即使搜索质量和速度相比标量量化有所下降也可以接受的场景。
可以使用
quantization_config
参数在创建或更新集合时配置 Qdrant 中的量化。例如,以下代码片段展示了如何在创建集合时启用标量量化:client.create_collection( collection_name="my_quantized_collection", vectors_config=models.VectorParams(size=128, distance=models.Distance.COSINE), quantization_config=models.QuantizationConfig( scalar=models.ScalarQuantization(type=models.ScalarType.INT8, always_ram=True) ) )
表 2:Qdrant 量化方法比较
量化方法 | 准确性影响 | 搜索速度 | 压缩率 | 推荐使用场景 |
标量量化 | 最小 | 最快可达 2 倍 | 4 倍 | 通用,大多数模型 |
二值量化 | 显著 | 最快可达 40 倍 | 32 倍 | 高维数据,经过测试的模型 |
乘积量化 | 中等到显著 | 比标量量化慢 | 最快可达 64 倍 | 内存受限环境 |
Qdrant 的分布式架构使其能够通过跨多个节点分发数据和处理来处理非常大的数据集和高查询负载。可以使用分片(Sharding)将一个集合分割成更小的部分,这些部分可以分布在集群中的不同节点上,从而实现水平扩展。复制(Replication)用于创建数据的多个副本,这些副本也分布在不同的节点上,以确保高可用性和数据持久性. 可以使用
shard_number
和 replication_factor
参数在创建集合时指定分片数和复制因子。Qdrant 支持自动分片和用户定义分片。在分布式环境中,负载均衡至关重要,可以确保查询被有效地分发到所有可用节点上。为了优化 Qdrant 的性能,可以采取多种最佳实践。对于大型数据集,可以考虑在批量导入数据时禁用 HNSW 索引,以减少内存使用。对载荷字段创建索引可以显著加快基于这些字段进行过滤的搜索。合理地使用内存管理技术,例如将向量存储在磁盘上(对于非常大的数据集),并结合向量量化技术,可以在内存使用和搜索速度之间取得平衡。调整查询参数,例如
hnsw_ef
,可以控制搜索的速度和准确性之间的权衡。此外,仔细设计过滤策略对于获得最佳性能也很重要。最后,监控 Qdrant 的性能指标对于分析瓶颈和进行进一步的优化至关重要.8. Qdrant 的实际用例和应用
Qdrant 在众多领域都有广泛的应用,尤其是在需要处理高维向量和执行相似性搜索的场景中。
在推荐系统中,向量嵌入可以用来表示用户和物品(如产品或内容)的特征。通过计算用户向量和物品向量之间的相似度,可以为用户推荐与其偏好相似的物品。例如,电子商务平台可以利用 Qdrant 来推荐用户可能感兴趣的商品,流媒体服务可以推荐用户可能喜欢的电影或音乐.
在语义搜索领域,向量嵌入可以捕捉文本查询和文档的含义和上下文。通过对文本嵌入执行相似性搜索,可以找到语义上相似的内容,即使它们不包含完全相同的关键词。这可以提高搜索引擎的准确性,改进问答系统,并优化文档检索.
异常检测是 Qdrant 的另一个重要应用领域。通过将正常行为和异常行为表示为向量,并使用相似性搜索找到与正常模式显著偏离的向量,可以识别出潜在的异常数据点或模式。这在欺诈检测、网络流量分析 和网络安全 等领域具有重要意义。
Qdrant 的其他应用还包括图像和视频检索、自然语言处理 (NLP) 任务(如文本分类和情感分析)、生物特征识别、基因组学和生物信息学、医疗保健和医学研究、自动驾驶汽车、个性化广告、聚类和分类 以及图分析 等。这些广泛的应用表明,向量数据库是一种多功能工具,可以在众多领域发挥关键作用。
9. Qdrant 企业级部署考虑因素
在企业环境中部署 Qdrant 需要考虑多个关键因素,以确保其能够满足企业的需求。
可扩展性和高可用性是首要考虑的因素。Qdrant 通过分片和复制实现水平扩展,可以处理不断增长的数据量和查询负载。通过数据冗余和容错机制确保高可用性,保证在发生硬件故障或其他问题时服务仍然可用。垂直扩展也是一个需要考虑的方面。Qdrant Cloud 提供的托管服务简化了可扩展性。混合云部署允许企业利用现有的基础设施来实现可扩展性.
安全性是企业部署中至关重要的一环。Qdrant 提供了多种身份验证和授权机制。需要考虑网络安全因素,如防火墙和访问限制。数据在存储和传输过程中都应进行加密。与企业现有的安全框架(如 RBAC)的集成也是一个重要的考虑因素.
与现有基础设施的集成对于顺利采用 Qdrant 至关重要。Qdrant 兼容各种嵌入和框架。需要考虑与现有数据管道和 ETL 流程的集成,以及与企业可能使用的其他数据库系统的连接。Qdrant 提供了多种编程语言的客户端库(如 Python、Java、Go、Rust、TypeScript、C#),并与 LangChain 和 LlamaIndex 等工具进行了集成.
成本效率也是企业需要考虑的关键因素。Qdrant 提供了多种存储选项和压缩技术来降低成本。选择合适的部署模型也对成本有影响。通过合理的配置和监控优化资源利用率可以进一步降低成本.
最后,备份和灾难恢复是确保数据持久性和业务连续性的重要方面。Qdrant 提供了快照功能。需要制定在分布式环境中进行数据备份和恢复的策略。Qdrant Cloud 也提供了备份和灾难恢复功能.
10. Qdrant Python 客户端:综合指南与示例
Qdrant 提供了功能强大的 Python 客户端库,允许开发者方便地与 Qdrant 实例进行交互。本节将提供详细的代码示例,涵盖使用 Python 客户端进行各种操作,从基本的集合管理到高级的查询和数据处理。
10.1 安装与初始化
首先,需要安装
qdrant-client
库 1:pip install qdrant-client
安装完成后,可以通过以下方式初始化客户端并连接到 Qdrant 实例。
连接到本地 Qdrant 实例 4:
from qdrant_client import QdrantClient client = QdrantClient(host="localhost", port=6333) # 或者使用 URL client = QdrantClient(url="http://localhost:6333")
连接到 Qdrant Cloud 实例 5:
from qdrant_client import QdrantClient client = QdrantClient( url="https://xxxxxx-xxxxx-xxxxx-xxxx-xxxxxxxxx.us-east.aws.cloud.qdrant.io:6333", api_key="<your-api-key>", )
使用 gRPC 连接 5:
from qdrant_client import QdrantClient client = QdrantClient(host="localhost", grpc_port=6334, prefer_grpc=True)
使用本地内存模式 (无需运行 Qdrant 服务器) 5:
from qdrant_client import QdrantClient client = QdrantClient(":memory:") # 或者将数据持久化到磁盘 client = QdrantClient(path="path/to/db")
10.2 集合管理
创建集合 4:
创建集合需要指定集合名称和向量配置(维度和距离度量)。
from qdrant_client.models import VectorParams, Distance client.create_collection( collection_name="my_collection", vectors_config=VectorParams(size=100, distance=Distance.COSINE), )
检查集合是否存在 7:
collection_exists = client.collection_exists("my_collection") print(f"集合是否存在: {collection_exists}")
获取集合信息 4:
collection_info = client.get_collection(collection_name="my_collection") print(collection_info)
删除集合:
client.delete_collection(collection_name="my_collection")
10.3 数据插入
可以使用
upsert
方法插入数据点。插入单个数据点 2:
from qdrant_client.models import PointStruct operation_info = client.upsert( collection_name="test_collection", wait=True, points=, payload={"city": "Berlin"}), ], ) print(operation_info)
批量插入数据点 7:
import numpy as np from qdrant_client.models import PointStruct vectors = np.random.rand(100, 100) points = operation_info = client.upsert(collection_name="my_collection", points=points, wait=True) print(operation_info)
10.4 基本搜索
使用
search
方法执行相似性搜索。import numpy as np query_vector = np.random.rand(100).tolist() search_results = client.search( collection_name="my_collection", query_vector=query_vector, limit=5 ) print(search_results)
10.5 使用过滤条件搜索 7:
可以使用
query_filter
参数根据载荷中的元数据进行过滤。from qdrant_client.models import Filter, FieldCondition, Range hits = client.search( collection_name="my_collection", query_vector=query_vector, query_filter=Filter( must= ), limit=5 ) print(hits)
10.6 命名向量
如果集合配置了多个命名向量字段,可以在插入和搜索时指定要使用的向量名称。
# 假设创建集合时配置了名为 "text" 和 "image" 的向量字段 client.upsert( collection_name="multi_vector_collection", points=, wait=True ) query_vector_text = np.random.rand(128).tolist() search_results_text = client.search( collection_name="multi_vector_collection", query_vector=("text", query_vector_text), limit=5 ) print(search_results_text) query_vector_image = np.random.rand(512).tolist() search_results_image = client.search( collection_name="multi_vector_collection", query_vector=("image", query_vector_image), limit=5 ) print(search_results_image)
10.7 混合搜索
Qdrant 支持使用稀疏向量进行关键词检索,并结合稠密向量进行语义搜索。
# 需要先创建包含稀疏向量配置的集合 # 示例代码(假设已创建包含名为 "sparse" 的稀疏向量字段的集合): # from qdrant_client.models import SparseVector # sparse_vector_data = {"indices": [1, 2, 3], "values": [0.8, 0.2, 0.5]} # client.upsert( # collection_name="hybrid_collection", # points=, values=sparse_vector_data["values"])}, # payload={"text": "example document"} # ), # ], # wait=True # ) # query_dense = np.random.rand(128).tolist() # query_sparse = {"indices": [4, 5, 6], "values": [0.9, 0.1, 0.4]} # search_results_hybrid = client.search( # collection_name="hybrid_collection", # query_vector=("dense", query_dense), # sparse_query=(("sparse", SparseVector(indices=query_sparse["indices"], values=query_sparse["values"]))), # limit=5 # ) # print(search_results_hybrid)
注意: 完整的混合搜索示例可能需要更复杂的设置,具体取决于稀疏向量的生成方式。
10.8 推荐 API
Qdrant 包含一个用于构建推荐系统的 API。
# 假设已有一些数据点 # recommendation_result = client.recommend( # collection_name="my_collection", # positive=[1, 4], # 正例 ID # negative=[7], # 负例 ID # limit=5 # ) # print(recommendation_result)
注意: 推荐 API 的使用需要根据具体的数据和推荐策略进行调整。
10.9 高级集合管理
更新集合配置 (例如,添加量化) 3:
from qdrant_client.models import QuantizationConfig, ScalarQuantization, ScalarType client.update_collection( collection_name="my_collection", quantization_config=QuantizationConfig( scalar=ScalarQuantization(type=ScalarType.INT8, always_ram=True) ) )
创建载荷索引 6:
from qdrant_client.models import PayloadSchemaType client.create_payload_index( collection_name="my_collection", field_name="city", field_schema=PayloadSchemaType.KEYWORD )
10.10 快照管理
创建快照 12:
snapshot_info = client.create_snapshot(collection_name="my_collection") print(snapshot_info)
恢复快照 12:
client.recover_snapshot(collection_name="my_collection", snapshot_name="<snapshot_name>")
10.11 批量上传 12:
对于大型数据集,可以使用
upload_points
或 upload_collection
进行批量上传,这些方法会自动处理数据分批。# 示例(假设有 ids, vectors, payloads 列表) # operation_info = client.upload_collection( # collection_name="large_collection", # ids=ids, # vectors=vectors, # payload=payloads, # batch_size=100 # 可选的批处理大小 # wait=True # ) # print(operation_info)
10.12 异步操作 7:
qdrant-client
也支持异步操作。需要使用 AsyncQdrantClient
并使用 async
和 await
关键字。import asyncio import numpy as np from qdrant_client import AsyncQdrantClient, models async def main(): client = AsyncQdrantClient(url="http://localhost:6333") if not await client.collection_exists("async_collection"): await client.create_collection( collection_name="async_collection", vectors_config=models.VectorParams(size=10, distance=models.Distance.COSINE), ) await client.upsert( collection_name="async_collection", points=, wait=True ) search_results = await client.search( collection_name="async_collection", query_vector=np.random.rand(10).tolist(), limit=5 ) print(search_results) if __name__ == "__main__": asyncio.run(main())
这些示例展示了 Qdrant Python 客户端的一些基本和高级功能。更详细的信息和更多示例,请参考 Qdrant 官方文档和相关的教程 1.
11. Qdrant 社区与资源
Qdrant 拥有一个活跃的社区,提供了丰富的学习和支持资源。官方文档是学习 Qdrant 的主要资源,涵盖了从入门到高级特性的所有方面。文档网站包含了快速入门指南、核心概念解释、详细的操作指南、API 参考以及各种教程。
Qdrant 社区论坛和渠道包括 Discord 社区 和 GitHub Discussions。这些平台是与其他 Qdrant 用户和开发团队交流、提问和分享经验的绝佳场所。Qdrant 还有一个社区博客,定期发布关于 Qdrant 和向量数据库领域的最新信息和技术文章。此外,Qdrant 还组织 Vector Space Talks,邀请用户和行业专家进行技术分享。
Qdrant Stars 计划 旨在表彰社区中的优秀贡献者和推广者。参与该计划可以获得培训、认可、旅行基金以及参与 Beta 测试的机会.
Qdrant 在 GitHub 上维护了一个示例代码仓库,其中包含了各种用例的代码示例,展示了如何将 Qdrant 与 LangChain、LlamaIndex 等框架集成。社区中也有许多用户贡献的教程和文章,提供了不同角度的学习资源。
对于 Qdrant Cloud 的付费用户,可以获得官方的支持服务。免费用户可以通过社区渠道寻求帮助。Qdrant 官方文档中也提供了常见问题解答和故障排除指南.
总而言之,Qdrant 社区为用户提供了全面的学习、支持和协作平台。
结论
Qdrant 作为一个高性能、可扩展且易于使用的开源向量数据库,为各种人工智能应用提供了强大的支持。从理论基础到实践案例,无论是简单的入门应用还是复杂的企业级部署,Qdrant 都展现了其强大的功能和灵活性。通过深入理解向量数据库的原理、Qdrant 的架构和核心概念,以及掌握其基本操作和高级特性,开发者可以有效地利用 Qdrant 构建各种创新的应用,例如智能搜索、个性化推荐和异常检测等。Qdrant 活跃的社区和丰富的学习资源也为用户提供了持续学习和解决问题的支持。随着人工智能技术的不断发展,向量数据库将在未来的数据处理和智能应用中扮演越来越重要的角色,而 Qdrant 无疑是这一领域中值得关注的领先者之一。
引用资料
- onebridge.techHow Vector Embeddings Enable Semantic Searching in AI - OnebridgeOpens in a new window