Cosmos DB(Azure和Fabric)提供高效的矢量索引和搜索。 此功能旨在处理多模式、高维向量,从而在任何规模上实现高效准确的矢量搜索。 现在可以直接将矢量与数据一起存储在文档中。 数据库中的每个文档不仅可以包含传统的无架构数据,还可以包含多模式高维向量作为文档的其他属性。 这种数据和矢量的并置可以实现高效的索引和搜索,因为矢量与它们所代表的数据存储在同一个逻辑单元中。 将矢量和数据放在一起简化了数据管理、AI 应用程序体系结构以及基于矢量的操作效率。
Cosmos DB 提供选择矢量索引方法时提供的灵活性:
对于较小、集中的矢量搜索,“扁平”或 k 最近邻精确搜索(有时也称为暴力搜索)可以提供 100% 的检索召回率。 尤其是与查询筛选器和分区键结合使用时。
一种量化扁平索引,使用基于 DiskANN 的量化方法压缩矢量,以提高 kNN 搜索的效率。
DiskANN 是一套由 Microsoft Research 开发的最先进的矢量索引算法,可在任何规模上实现高效、高精度的多模式矢量搜索。
Cosmos DB 中的矢量搜索可以使用 WHERE 子句与所有其他支持的NoSQL查询筛选器和索引结合使用。 这种组合使矢量搜索成为应用程序最相关的数据。
此功能增强了 Cosmos DB 的核心功能,使其更适用于处理 AI 应用程序中的矢量数据和搜索要求。
什么是矢量存储?
矢量存储或向量数据库是一个旨在存储和管理矢量嵌入的数据库,它是高维空间中数据的数学表示形式。 在此空间中,每个维度对应于数据的一个特征,数万个维度可用于表示复杂的数据。 矢量在此空间中的位置表示其特征。 字词、短语或整个文档、图像、音频和其他类型的数据都可以矢量化。
矢量存储的工作原理是什么?
在矢量存储中,矢量搜索算法用于查询嵌入项以及为其编制索引。 一些已知的矢量搜索算法包括分层导航小型世界 (HNSW)、倒置文件(IVF)、DiskANN 等。借助矢量搜索,可根据数据特征而不是属性字段上的精确匹配项来查找相似的项。 这种方法在搜索相似文本、查找相关图像、提出建议甚至是检测异常等应用中很有用。 它用于通过嵌入 API 查询你使用机器学习模型创建的数据的向量嵌入。 嵌入 API 的示例包括 Azure OpenAI Embeddings 或 Hugging Face on Azure。 矢量搜索测量数据矢量与查询矢量之间的距离。 与查询矢量最接近的这些矢量是在语义上被发现最相似的。
在 Cosmos DB 中的集成向量数据库中,可以存储、索引和查询嵌入内容以及原始数据。 此方法避免了在单独的纯矢量数据库中复制数据产生的额外成本。 此外,此体系结构可将矢量嵌入和原始数据保存在一起,从而更好地促进多模式数据操作,并且可以实现更高的数据一致性、缩放和性能。
容器向量策略
使用 Cosmos DB 执行矢量搜索需要为容器定义向量策略。 此策略为数据库引擎提供重要信息,用于对容器文档中找到的矢量进行高效的相似性搜索。 如果选择此选项,此配置还会通知向量索引策略所需的信息。 包含的矢量策略中包含以下信息:
path:包含向量(必需)的属性。datatype:矢量属性的数据类型。 支持的类型为float32(默认值),int8和uint8。dimensions:路径中每个向量的维度或长度。 路径中的所有矢量应具有相同的维度数。 (默认值1536)。distanceFunction:用于计算距离/相似性的指标。 支持的指标包括:cosine,其值从 $-1$ (最低相似) 到 $+1$ (最相似)。dot product,其值从 $-\infty$ (最不相似) 到 $+\infty$ (最相似)。euclidean,其值从 $0$ (最相似) 到 $+\infty$ (最不相似)。
注释
每个唯一路径最多可以有一个策略。 但是,如果多个策略都以不同的路径为目标,则可以指定这些策略。
容器矢量策略可描述为 JSON 对象。 下面是有效容器矢量策略的两个示例:
具有单个向量路径的策略
此示例展示了使用单个向量路径的向量嵌入策略配置,显示了用于存储具有余弦相似性的 1536 维 float32 向量的基本设置。 此配置演示了:
-
/[0]:使用具有余弦相似性的 float32 数据类型,适用于 1536 维向量(常用于 OpenAI 嵌入)
{
"vectorEmbeddings": [
{
"path": "/vector1",
"dataType": "float32",
"distanceFunction": "cosine",
"dimensions": 1536
}
]
}
具有两个向量路径的策略
此示例演示如何使用两个不同的矢量嵌入路径(每个路径具有不同的数据类型、距离函数和维度)配置矢量索引策略。 此配置演示了:
-
/[0]:使用具有余弦相似性的 float32 数据类型,适用于 1536 维向量(常用于 OpenAI 嵌入) -
/[1]:将 int8 数据类型与 100 维矢量的点积距离配合使用(对于较小的嵌入,内存效率更高)
{
"vectorEmbeddings": [
{
"path": "/vector1",
"dataType": "float32",
"distanceFunction": "cosine",
"dimensions": 1536
},
{
"path": "/vector2",
"dataType": "int8",
"distanceFunction": "dotproduct",
"dimensions": 100
}
]
}
有关容器向量策略设置的详细信息和示例,请参阅 矢量索引策略示例。
矢量索引策略
矢量索引可在使用 系统函数执行矢量搜索时提高效率VectorDistance。 使用矢量索引时,矢量搜索的延迟降低、吞吐量变高、RU 消耗量降低。 可以指定以下类型的矢量索引策略:
| Description | 最大维度 | |
|---|---|---|
flat |
将矢量存储在与其他已索引属性相同的索引上。 | 505 |
quantizedFlat |
在索引上存储之前,量化(压缩)矢量。 该策略可以通过牺牲少许准确性来提高延迟和吞吐量。 | 4096 |
diskANN |
基于 DiskANN 创建索引,实现快速高效的近似搜索。 | 4096 |
请注意以下几点:
索引类型
flat和quantizedFlat在矢量搜索期间使用 Cosmos DB 的索引来存储和读取每个向量。flat索引中的矢量搜索是暴力搜索,其准确度或召回率为 100%。 也就是说,可以保证在数据集中找到最相似的向量。 但是,平面索引上的向量存在505维度限制。quantizedFlat索引在该索引上存储量化(压缩)矢量。 使用quantizedFlat索引的矢量搜索也是暴力搜索,但由于矢量在添加到索引之前进行了量化,因此其准确度可能略低于 100%。 但相较于quantized flat索引上的矢量搜索,使用flat的矢量搜索应会具有更低的延迟、更高的吞吐量和更低的 RU 成本。 对于较小的方案,或使用查询筛选器将矢量搜索缩小到相对较小的矢量集的方案,此索引是一个不错的选择。 当每个物理分区中要编制索引的矢量数约为 50,000 或更少时,建议使用quantizedFlat。 但是,此建议只是一般准则,应测试实际性能,因为每个方案可能有所不同。diskANN索引是一个单独的索引,专用于使用 DiskANN(Microsoft Research 开发的高性能矢量索引算法套件)。 DiskANN 索引可提供一些延迟最低、吞吐量最高且 RU 成本最低的查询,同时仍保持较高的准确度。 通常,如果每个物理分区的矢量数超过 50,000 个,DiskANN 通常是所有索引类型中性能最佳的选择。quantizedFlat和diskANN索引通过vectorIndexes属性支持对象中的quantizerType两个量化方法:product和spherical。
下面是有效矢量索引策略的示例:
{
"indexingMode": "consistent",
"automatic": true,
"includedPaths": [
{
"path": "/*"
}
],
"excludedPaths": [
{
"path": "/_etag/?"
},
{
"path": "/vector1/*"
}
],
"vectorIndexes": [
{
"path": "/vector1",
"type": "diskANN"
}
]
}
{
"indexingMode": "consistent",
"automatic": true,
"includedPaths": [
{
"path": "/*"
}
],
"excludedPaths": [
{
"path": "/_etag/?"
},
{
"path": "/vector1/*",
},
{
"path": "/vector2/*",
}
],
"vectorIndexes": [
{
"path": "/vector1",
"type": "quantizedFlat"
},
{
"path": "/vector2",
"type": "diskANN"
}
]
}
量化方法
此外,还可以直接在对象中 vectorIndexes 指定量化方法。 Cosmos DB 支持两种量化方法: product默认方法和 spherical (在公共预览版中),该方法可能会表现出更好的性能特征,包括更快的索引时间和更高的召回率。 可以使用对象中的quantizerType属性指定vectorIndexes量化方法,如下所示:
{
"vectorIndexes": [
{
"path": "/vector1",
"type": "diskANN",
"quantizerType": "spherical"
}
]
}
重要
矢量策略或向量索引目前不支持通配符(*, [])。
使用查询进行矢量搜索 VECTORDISTANCE
创建具有所需向量策略的容器,并将矢量数据插入到容器中后,可以使用查询中的 内置 VECTORDISTANCE 函数 执行矢量搜索。 一个NoSQL查询示例,将相似性分数作为别名score进行投影,并按相似程度从高到低排序:
SELECT TOP 10
c.title,
VECTORDISTANCE(c.contentVector, [1,2,3]) AS score
FROM
container c
ORDER BY
VECTORDISTANCE(c.contentVector, [1,2,3])
重要
始终在查询的 TOP N 语句中使用 SELECT 子句。 否则,矢量搜索会尝试返回更多结果,导致查询花费的请求单位数(RU)多,延迟比必要时间高。