近似最近傍(ANN)を検索してベクトル エンベディングをクエリする

このページでは、ANN 距離関数を使用して近似最近傍(ANN)を検索し、ベクトル エンベディングをクエリする方法について説明します。

データセットが小さい場合は、k 近傍法(KNN)を使用して、正確な k 近傍ベクトルを検索できます。ただし、データセットのサイズが大きくなるにつれて、KNN 検索のレイテンシとコストも増加します。ANN を使用すると、レイテンシと費用を大幅に削減しながら、近似 k 最近傍を検索できます。

ANN 検索では、近似距離が計算され、データセット内のすべてのベクトルが検査されない可能性があるため、返される k 個のベクトルは真の上位 k 近傍ではありません。上位 k 近傍にないベクトルが返されることがあります。これは「再現損失」と呼ばれます。許容できる再現損失の量はユースケースによって異なりますが、ほとんどの場合、データベースのパフォーマンスを改善するために再現率を多少犠牲にすることは許容されるトレードオフです。

Spanner でサポートされている近似距離関数の詳細については、次の GoogleSQL リファレンス ページをご覧ください。

ベクトル エンベディングのクエリ

Spanner は、ベクトル インデックスを使用して近似最近傍(ANN)ベクトル検索を高速化します。ベクトル インデックスを使用して、ベクトル エンベディングをクエリできます。ベクトル エンベディングをクエリするには、まずベクトル インデックスを作成する必要があります。次に、3 つの近似距離関数のいずれかを使用して ANN を見つけることができます。

近似距離関数を使用する際の制限事項は次のとおりです。

  • 近似距離関数は、エンベディング列と定数式(パラメータやリテラルなど)間の距離を計算する必要があります。
  • 近似距離関数の出力を ORDER BY 句で唯一の並べ替えキーとして使用し、ORDER BY の後に LIMIT を指定する必要があります。
  • クエリで、インデックスに登録されていない行を明示的に除外する必要があります。ほとんどの場合、テーブル定義で列がすでに NOT NULL としてマークされている場合を除き、クエリにベクトル インデックス定義に一致する WHERE <column_name> IS NOT NULL 句を含める必要があります。

制限事項の詳細なリストについては、近似距離関数のリファレンス ページをご覧ください。

DocContents バイト列の事前計算されたテキスト エンベディングの DocEmbedding 列と、null になる可能性のある他のソースから入力された NullableDocEmbedding 列を含む Documents テーブルについて考えてみます。

CREATE TABLE Documents (
UserId       INT64 NOT NULL,
DocId        INT64 NOT NULL,
Author       STRING(1024),
DocContents  BYTES(MAX),
DocEmbedding ARRAY<FLOAT32> NOT NULL,
NullableDocEmbedding ARRAY<FLOAT32>,
WordCount    INT64
) PRIMARY KEY (UserId, DocId);

[1.0, 2.0, 3.0] に最も近い 100 個のベクトルを検索するには:

SELECT DocId
FROM Documents
WHERE WordCount > 1000
ORDER BY APPROX_EUCLIDEAN_DISTANCE(
  ARRAY<FLOAT32>[1.0, 2.0, 3.0], DocEmbedding,
  options => JSON '{"num_leaves_to_search": 10}')
LIMIT 100

エンベディング列が null 値を許容する場合:

SELECT DocId
FROM Documents
WHERE NullableDocEmbedding IS NOT NULL AND WordCount > 1000
ORDER BY APPROX_EUCLIDEAN_DISTANCE(
  ARRAY<FLOAT32>[1.0, 2.0, 3.0], NullableDocEmbedding,
  options => JSON '{"num_leaves_to_search": 10}')
LIMIT 100

次のステップ