通过


矢量数据库

矢量数据库以矢量的形式来存储和管理数据,这些矢量是数据点的数值阵列。

使用矢量可以进行复杂的查询和分析,因为可以使用高级技术(如矢量相似性搜索、量化和聚类分析)来比较和分析矢量。 传统数据库不适合处理在数据分析中越来越常见的高维数据。 但是,矢量数据库可以通过将高维数据(如文本、图像和音频)表示为矢量来处理这些数据。 矢量数据库适用于机器学习、自然语言处理、图像识别等任务,其目标是识别大型数据集中的模式或相似度。

本文提供有关矢量数据库的一些背景,并在概念上介绍了如何在 Microsoft Fabric 的实时智能中将 Eventhouse 用作矢量数据库。 有关实际示例,请参阅教程:使用 Eventhouse 作为矢量数据库

关键概念

矢量数据库使用了以下关键概念:

向量相似性

矢量相似度是衡量两个或更多矢量的不同程度(或相似程度)的度量值。 矢量相似度搜索是一种用于在数据集中查找相似矢量的技术。 通过使用距离指标(如 Euclidean 距离余弦相似性)来比较矢量。 两个矢量越接近,它们就越相似。

嵌入

嵌入是一种以矢量格式表示数据的常见方法,适用于矢量数据库。 嵌入是一段数据(例如字词、文本文档或图像)的数学表示形式,旨在捕获其语义含义。 使用分析数据的算法创建嵌入内容,并生成一组表示其关键特征的数值。 例如,字词的嵌入可能表示其含义、上下文以及与其他字词的关系。 创建嵌入的过程非常简单。 虽然可以使用标准 Python 包(例如 spaCy、sent2vec、Gensim)创建它们,但大型语言模型(LLM)为语义文本搜索生成质量最高的嵌入内容。 例如,可以将文本发送到 Azure OpenAI 中的嵌入模型,并生成可存储用于分析的向量表示形式。 有关详细信息,请参阅了解 Azure OpenAI 服务中的嵌入

常规工作流

如何嵌入、存储、查询作为矢量存储的文本的示意图。

使用矢量数据库的常规工作流如下所示:

  1. 嵌入数据:使用嵌入模型,将数据转换为矢量格式。 例如,可以使用 OpenAI 模型来嵌入文本数据。
  2. 存储矢量:将嵌入的矢量存储在矢量数据库中。 可将嵌入的数据发送到 Eventhouse 以便存储和管理矢量。
  3. 嵌入查询:使用用于嵌入存储数据的相同嵌入模型,将查询数据转换为矢量格式。
  4. 查询矢量:使用矢量相似度搜索,查找数据库中与查询相似的条目。

Eventhouse 作为矢量数据库

矢量相似性搜索的核心是存储、索引和查询向量数据。 Eventhouse 提供了一种用于处理和分析大量数据(特别是在需要实时分析和探索的场景中)的解决方案。 此功能使 Eventhouse 成为存储和搜索向量的绝佳选择。

Eventhouse 的以下组件使你能够将其用作向量数据库:

  • 动态数据类型,可以存储数组和属性包等非结构化数据。 使用此数据类型来存储向量值。 通过将与原始对象相关的元数据存储为表中的单独列,可以进一步增强矢量值。
  • 用于以 16 位精度存储浮点数矢量的 编码 类型 Vector16 。 此编码使用 Bfloat16 而不是默认的 64 位。 使用此编码来存储 ML 矢量嵌入,因为它将存储需求减少四倍,并按数量级顺序加速矢量处理函数,例如series_dot_product()series_cosine_similarity()。
  • series_cosine_similarity函数,可用于在存储在 Eventhouse 中的向量基础上执行向量相似性搜索。

针对扩展性进行优化

有关优化矢量相似性搜索的详细信息,请参阅 博客

若要最大程度地提高性能和生成的搜索时间,请执行以下步骤:

  1. 将嵌入列的编码设置为 Vector16,该编码是矢量系数的 16 位编码(而不是默认的 64 位)。
  2. 将嵌入向量表存储在每个处理器至少有一个分片的所有群集节点上。 若要实现此目标,请执行以下步骤:
    1. 通过更改分片策略ShardEngineMaxRowCount 来限制每个分片的嵌入矢量数。 分片策略平衡每个节点具有多个盘区的所有节点上的数据,以便搜索可以使用所有可用的处理器。
    2. 更改 合并策略RowCountUpperBoundForMerge。 需要合并策略才能在引入后抑制合并数据范围。

示例优化步骤

在以下示例中,定义用于存储 1M 矢量的静态向量表。 将嵌入策略定义为 Vector16,并设置分片和合并策略以针对矢量相似性搜索优化表。 对于此示例,假设群集有 20 个节点,每个节点有 16 个处理器。 表的分片应最多包含 1,000,000/(20*16)=3,125 行。

  1. 逐个运行以下 KQL 命令来创建空表并设置所需的策略和编码:

    .create table embedding_vectors(vector_id:long, vector:dynamic)                                  //  This is a sample selection of columns, you can add more columns
    
    .alter column embedding_vectors.vector policy encoding type = 'Vector16'                         // Store the coefficients in 16 bits instead of 64 bits accelerating calculation of dot product, suppress redundant indexing
    
    .alter-merge table embedding_vectors policy sharding '{ "ShardEngineMaxRowCount" : 3125 }'       // Balanced data on all nodes and, multiple extents per node so the search can use all processors 
    
    .alter-merge table embedding_vectors policy merge '{ "RowCountUpperBoundForMerge" : 3125 }'      // Suppress merging extents after ingestion
    
  2. 将数据引入到在上一步创建和定义的表。

下一步