跳转到主要内容

外部构建

除了使用分区调优中的方法外,您还可以选择在其他机器或 GPU 上离线运行分区阶段,以缩短索引构建时间并降低内存消耗。

除了使用分区调优中的方法(以牺牲一定 QPS 和召回率为代价来缩短构建时间并降低内存消耗)之外,您还可以选择在其他机器或 GPU 上离线运行分区阶段。由于 vchordg 没有分区阶段,因此该特性不支持 vchordg。

假设表名为 t,待建索引的列名为 val。

CREATE TABLE t (val vector(3));

具体而言,您需要先对待建索引的列进行采样。

CREATE EXTENSION IF NOT EXISTS tsm_system_rows;
SELECT val FROM t TABLESAMPLE SYSTEM_ROWS(1000);

基于这些样本,您可以将向量空间划分为多个 Voronoi 单元(Voronoi cells)。完成划分后,创建一张表并将分区质心插入其中。

CREATE TABLE public.t_build (id INTEGER NOT NULL UNIQUE, parent INTEGER, vector vector NOT NULL);
INSERT INTO public.t_build (id, parent, vector) VALUES (0, NULL, '{0.1, 0.2, 0.3}');
INSERT INTO public.t_build (id, parent, vector) VALUES (1, 0, '{0.1, 0.2, 0.3}');
INSERT INTO public.t_build (id, parent, vector) VALUES (2, 0, '{0.4, 0.5, 0.6}');
INSERT INTO public.t_build (id, parent, vector) VALUES (3, 0, '{0.7, 0.8, 0.9}');

随后可以使用以下语法创建索引:

CREATE INDEX ON t USING vchordrq (embedding vector_l2_ops) WITH (options = $$
build.external.table = 'public.t_build'
$$);

表结构格式

存储分区信息的表必须严格遵循以下表结构(Schema):

  • 第一列必须为 id,类型为 integer,不可为 null(NOT NULL),且必须唯一(UNIQUE)。
  • 第二列必须为 parent,类型为 integer,允许为 null(根节点为 NULL)。
  • 第三列必须为 vector,类型为 vector,不可为 null(NOT NULL)。目前尚不支持 halfvec 或其他类型。

在逻辑上,这些数据构成了一棵树。从根节点到每个叶子节点的距离(深度)必须完全相同。

如果上述任何属性未得到满足,系统都会报错。

分区示例

为了帮助您快速上手,下面给出一个使用 faiss 执行向量空间分区的最小代码示例。

from typing import List
from faiss import Kmeans
import numpy

def partition(
    samples: List[numpy.Array[float]], lists: List[int]
) -> List[numpy.Array[float]]:
    dim = dataset.shape[1]
    results = []
    for i in range(len(lists) + 1):
        kmeans = Kmeans(
            dim,
            lists[len(lists) - 1 - i] if len(lists) - 1 - i >= 0 else 1,
            gpu=False,
            verbose=True,
            niter=10,
            seed=42,
            spherical=False,
        )
        kmeans.train(samples)
        results.push(kmeans.centroids)
        samples = kmeans.centroids
    return results

这段代码会计算出不同层级上所有 Voronoi 单元的生成元(质心)。树中的父子关系可通过计算最短距离来确定,此处省略具体细节。您可以使用任何能够生成多级 Voronoi 单元的算法,例如球面 K-means(spherical K-means)、平衡 K-means(balanced K-means)或 GPU K-means。