aliyun-knnプラグインは、Alibaba Cloud Elasticsearchチームによって開発されたベクトル検索エンジンです。Alibaba DAMO Academyによって設計されたベクトル検索エンジンであるProximaのベクトルライブラリを使用しています。このプラグインは、画像検索、ビデオフィンガープリント、顔認識と音声認識、商品レコメンデーションなど、さまざまなシナリオでのベクトル検索の要件を満たすことができます。このトピックでは、aliyun-knnプラグインの使用方法について説明します。
このトピックは参照用です。 aliyun-knnプラグインは、以前のバージョンの既存のElasticsearchクラスターで使用されます。
V8.15以降のElasticsearchクラスターを購入することをお勧めします。このようにして、エンジンカーネルによって提供されるネイティブのベクトル検索機能を直接使用して、新しいベクトル検索ビジネスを実装できます。
背景情報
ユースケース
Alibaba Cloud Elasticsearchのベクトル検索エンジンは、拍立淘、画像検索、優酷ビデオフィンガープリント、趣頭条ビデオフィンガープリント、淘宝商品レコメンデーション、カスタマイズ検索、クロスメディア検索など、Alibabaグループ内の多数の本番シナリオで使用されています。
原則
Alibaba Cloud Elasticsearchのベクトル検索機能は、aliyun-knnプラグインに基づいて実装されています。このプラグインは、オープンソースのElasticsearchのすべてのバージョンと互換性があります。したがって、追加の学習コストなしでプラグインを使用できます。リアルタイムの増分同期とニアリアルタイム(NRT)検索に加えて、ベクトルインデックスは、分散検索におけるオープンソースElasticsearchの他の機能もサポートしています。これらの機能には、複数のレプリカシャードと復元が含まれます。
説明aliyun-knnプラグインは、オブジェクトストレージサービス(OSS)のスナップショットまたはDataWorksを使用したデータ移行をサポートしていません。データを移行する場合は、Logstashを使用することをお勧めします。
アルゴリズム
aliyun-knnプラグインは、階層型ナビゲーション可能なスモールワールド(HNSW)アルゴリズムと線形検索アルゴリズムをサポートしています。これらのアルゴリズムは、メモリ内ストレージからの少量のデータを処理するのに適しています。次の説明では、アルゴリズムのパフォーマンスを比較します。
表 1. HNSWと線形検索のパフォーマンスの比較
次の表に、Alibaba Cloud Elasticsearch V6.7.0クラスターでの2つのアルゴリズムのパフォーマンスメトリックを示します。テスト環境の構成:
クラスター構成:2つのデータノード。各ノードは16 vCPU、64 GiBのメモリ、1つの100 GiB標準SSDを提供します。
データセット:SIFT 128次元浮動小数点型ベクトル
合計データレコード数:2,000万
インデックス設定:デフォルト設定
パフォーマンスメトリック
HNSW
線形検索
上位10件のリコール率
98.6%
100%
上位50件のリコール率
97.9%
100%
上位100件のリコール率
97.4%
100%
レイテンシ(p99)
0.093秒
0.934秒
レイテンシ(p90)
0.018秒
0.305秒
説明pはパーセンテージの略です。たとえば、レイテンシ(p99)は、99%のクエリに応答するために必要な秒数を示します。
前提条件
aliyun-knnプラグインがインストールされていること。このプラグインがデフォルトでインストールされるかどうかは、ElasticsearchクラスターのバージョンとElasticsearchクラスターのカーネルバージョンによって決まります。
クラスターバージョン
カーネルバージョン
説明
V6.7.0
V1.2.0より前
組み込みプラグインのインストールと削除に記載されている手順に従って、Elasticsearchコンソールの [プラグイン] ページで aliyun-knn プラグインを手動でインストールする必要があります。
aliyun-knnプラグインのスクリプトクエリとインデックスウォームアップ機能は使用できません。これらの機能を使用する場合は、AliESカーネルを搭載したElasticsearchクラスターを使用することをお勧めします。詳細については、AliESリリースノートをご参照ください。
ベクトルインデックスを作成する場合、
distance_methodパラメーターはデフォルト値のSquaredEuclideanにのみ設定できます。
V6.8 なし
aliyun-knnプラグインはデフォルトでインストールされています。
V7.4 なし
aliyun-knnプラグインはデフォルトでインストールされています。
V7.7 なし
aliyun-knnプラグインはデフォルトでインストールされています。
V6.7.0
V1.2.0以降
aliyun-knnプラグインは、デフォルトでインストールされているapackプラグインに統合されています。 aliyun-knnプラグインを削除または再インストールする場合は、apackプラグインで操作を実行する必要があります。詳細については、apackプラグインの物理レプリケーション機能の使用をご参照ください。
aliyun-knnプラグインのスクリプトクエリとインデックスウォームアップ機能、および拡張機能を使用できます。これらの機能を使用する前に、クラスターのカーネルバージョンがV1.3.0以降であることを確認してください。詳細については、クラスターのバージョンのアップグレードをご参照ください。
ベクトルインデックスの作成時にマッピング解析エラーが報告された場合は、クラスターのカーネルバージョンをV1.3.0以降にアップグレードして、再試行してください。
V7.10.0
V1.4.0以降
aliyun-knnプラグインは、デフォルトでインストールされているapackプラグインに統合されています。 aliyun-knnプラグインを削除または再インストールする場合は、apackプラグインで操作を実行する必要があります。詳細については、apackプラグインの物理レプリケーション機能の使用をご参照ください。
クラスターのカーネルバージョンがV1.4.0以降の場合、apackプラグインのバージョンは最新です。 GET _cat/plugins?v コマンドを実行して、apackプラグインのバージョンを取得できます。
その他のバージョン
なし
ベクトル検索機能はサポートされていません。
説明カーネルバージョンは、apackプラグインのバージョンとは異なります。 GET _cat/plugins?v コマンドを実行して、apackプラグインのバージョンを取得できます。
クラスターのインデックスが計画されていること。
アルゴリズム
ユースケース
メモリ内ストレージ
備考
HNSW
各ノードは少量のデータのみを格納します。
低い応答レイテンシが必要です。
高いリコール率が必要です。
はい
HNSWは貪欲検索アルゴリズムに基づいており、三角不等式に従います。三角不等式とは、AからBへのコストとBからCへのコストの合計は、AからCへのコストよりも大きい必要があるというものです。内積空間は三角不等式に従いません。この場合、HNSWアルゴリズムを使用する前に、ユークリッド空間または球面空間に変換する必要があります。
Alibaba Cloud Elasticsearchクラスターにデータを書き込んだ後、オフピーク時に定期的にforce merge APIを呼び出して、シャード内のセグメントをマージすることをお勧めします。これにより、応答レイテンシが短縮されます。
線形検索
総当たり検索を実行する必要があります。
100%のリコール率が必要です。
レイテンシは、処理が必要なデータ量とともに増加します。
効果比較が必要です。
はい
なし。
クラスターが計画されていること。
項目
説明
データノードの仕様(必須)
データノードの仕様は、16 vCPU および 64 GiB 以上のメモリである必要があります。
説明aliyun-knnプラグインを使用してインデックスを作成する場合、多くの計算リソースが必要になります。クラスターのデータノードの仕様が小さい場合、ボトルネックが簡単に発生する可能性があります。深刻な場合は、クラスターの安定性に影響を与える可能性があります。したがって、データノードの仕様が 16 vCPU および 64 GiB 以上のメモリであるクラスターを使用することをお勧めします。
ノードタイプ
クラスターには、独立した専用のマスターノードが含まれている必要があります。
オフヒープメモリのサイズ
クラスターのオフヒープメモリのサイズは、クラスター内のベクトルデータの合計サイズの2倍以上である必要があります。
たとえば、インデックスに 960 次元の浮動小数点型フィールドが 1 つだけ含まれているとします。インデックスには 400 のドキュメントが含まれており、浮動小数点型データは 4 バイトのメモリを占有します。この場合、インデックス内のベクトルデータは 1.5 MB のメモリを占有します。これは、次の式を使用して計算されます。960 × 400 × 4。したがって、クラスターのオフヒープメモリのサイズが 3 MB 以上であることを確認する必要があります。これは、次の式を使用して計算されます。1.5 × 2。
説明強制マージ中は、古いデータと新しいデータの両方がメモリを占有します。強制マージを実行する必要がある場合は、クラスターのオフヒープメモリのサイズが、クラスター内のベクトルデータの合計サイズの 4 倍以上であることを確認する必要があります。
メモリ仕様が 64 GiB 以上のクラスターの場合、クラスターのオフヒープメモリのサイズは、次の式の値とほぼ等しくなります。合計メモリサイズ - 32(GiB)。
書き込みスロットリング
ベクトルインデックス作成は CPU 集約型のジョブです。高い書き込みスループットを維持しないことをお勧めします。16 vCPU および 64 GiB のメモリを搭載したデータノードの場合、ピーク書き込みスループットは 5,000 トランザクション/秒(TPS)未満にすることをお勧めします。
システムがベクトルインデックスに対するクエリを処理する場合、すべてのインデックスをノードメモリにロードします。ノードのメモリが不足している場合、システムはシャードを再割り当てします。したがって、システムがクエリを処理しているときに、大量のデータをクラスターに書き込まないことをお勧めします。
説明上記の表には、推定項目のみが記載されています。ビジネス要件に基づいてクラスターを計画する必要があります。クラスターに十分なメモリを計画し、クラスターを使用する前にストレステストを実行することをお勧めします。
制限事項
aliyun-knnプラグインをインストールする前に、クラスター内のデータノードの仕様が16 vCPUおよび64 GiB以上のメモリであることを確認する必要があります。クラスター内のデータノードの仕様が要件を満たしていない場合は、データノードをアップグレードします。詳細については、クラスターの構成のアップグレードをご参照ください。
aliyun-knnプラグインを使用する場合、AliESカーネルによって提供される一部の高度な機能は使用できません。たとえば、物理レプリケーション機能を有効にしている場合は、aliyun-knnプラグインを使用する前にこの機能を無効にする必要があります。詳細については、apackプラグインの物理レプリケーション機能の使用をご参照ください。
aliyun-knnプラグインは、OSSのスナップショットまたはDataWorksを使用したデータ移行をサポートしていません。データを移行する場合は、Logstashを使用することをお勧めします。
ベクトルインデックスの作成
ElasticsearchクラスターのKibanaコンソールにログインし、プロンプトに従ってKibanaコンソールのホームページに移動します。
Kibanaコンソールへのログイン方法の詳細については、Kibanaコンソールへのログインをご参照ください。
説明この例では、Elasticsearch V6.7.0クラスターを使用しています。他のバージョンのクラスターでの操作は異なる場合があります。コンソールでの実際の操作が優先されます。
表示されるページの左側のナビゲーションペインで、[dev Tools] をクリックします。
表示されるページの [console] タブで、次のコマンドを実行してベクトルインデックスを作成します。
PUT test { "settings": { "index.codec": "proxima", "index.vector.algorithm": "hnsw" }, "mappings": { "_doc": { "properties": { "feature": { "type": "proxima_vector", "dim": 2, "vector_type": "float", "distance_method": "SquaredEuclidean" } // ベクトルフィールド feature を定義します。 } } } }説明Elasticsearchでサポートされている他のタイプのフィールドをベクトルインデックスに追加できます。
ベクトルインデックスの作成時に次のマッピング解析エラーが報告された場合は、クラスターのカーネルバージョンをアップグレードして、再試行してください:
"type": "mapper_parsing_exception", "reason": "Mapping definition for [feature] has unsupported parameters: [distance_method : SquaredEuclidean]。
パート
パラメーター
デフォルト値
説明
settings
index.codec
proxima
proximaベクトルインデックスを作成するかどうかを指定します。有効な値:
proxima:システムはproximaベクトルインデックスを作成します。このインデックスはベクトル検索をサポートしています。このパラメーターをproximaに設定することをお勧めします。
null:システムはproximaベクトルインデックスを作成せず、前方インデックスのみを作成します。この場合、proxima_vector タイプのフィールドは、HNSW または 線形検索 ベースのクエリをサポートしていません。これらのフィールドは、スクリプトクエリのみをサポートしています。
説明クラスターに大量のデータが格納されていて、クエリのレイテンシに高い要件がない場合は、パラメーターを削除するか、パラメーターを null に設定できます。この場合、スクリプトクエリ機能を使用して、ベクトルの k 近傍(k-NN)を検索できます。この機能は、apackプラグインが V1.2.1 以降の V6.7.0 クラスター、および apack プラグインが V1.4.0 以降の V7.10.0 クラスターでのみ使用できます。
index.vector.algorithm
hnsw
ベクトルを検索するために使用されるアルゴリズム。有効な値:
hnsw:HNSW
linear:線形検索
index.vector.general.builder.offline_mode
false
オフライン最適化モードを使用してベクトルインデックスを作成するかどうかを指定します。有効な値:
false:オフライン最適化モードは使用されません。
true:オフライン最適化モードが使用されます。この場合、ベクトルインデックスに書き込まれるセグメントの数が大幅に削減されます。これにより、書き込みスループットが向上します。
説明オフライン最適化モードは、apackプラグインが V1.2.1 以降の V6.7.0 クラスター、および apack プラグインが V1.4.0 以降の V7.10.0 クラスターでのみ使用できます。オフライン最適化モードを使用して作成されたインデックスに対してスクリプトクエリを実行することはできません。
すべてのデータを一度にクラスターに書き込む場合は、オフライン最適化モードを使用することをお勧めします。
mappings
type
proxima_vector
フィールドタイプ。たとえば、feature フィールドの type パラメーターを proxima_vector に設定すると、feature フィールドはベクトルタイプのフィールドになります。
dim
2
ベクトル次元の数。このパラメーターは必須です。有効な値:1〜2048。
vector_type
float
ベクトルのデータ型。有効な値:
float
short
binary
このパラメーターを binary に設定する場合、ベクトルインデックスに書き込むベクトルデータは uint32 データ型である必要があります。これは、ベクトルデータが符号なし 32 ビット 10 進数配列で表される必要があることを示します。さらに、dim パラメーターの値は 32 の倍数である必要があります。
たとえば、64 ビットのバイナリビジネスデータ 1000100100100101111000001001111101000011010010011010011010000100 をベクトルインデックスに書き込む場合は、vector [-1994006369, 1128900228] をインデックスに書き込みます。
説明上記の 3 つのデータ型はすべて、apack プラグインが V1.2.1 以降の V6.7.0 クラスター、および apack プラグインが V1.4.0 以降の V7.10.0 クラスターでのみサポートされています。他のクラスターは、float データ型のみをサポートしています。
distance_method
SquaredEuclidean
ベクトル間の距離を計算するために使用される関数。有効な値:
SquaredEuclidean:平方根抽出なしでユークリッド距離を計算します。
InnerProduct:内積を計算します。
Cosine:コサイン類似度を計算します。
Hamming:ハミング距離を計算します。この関数は、vector_type パラメーターを binary に設定した場合にのみ使用できます。
説明上記の 4 つの関数はすべて、apack プラグインが V1.2.1 以降の V6.7.0 クラスター、および apack プラグインが V1.4.0 以降の V7.10.0 クラスターでのみサポートされています。V6.8、V7.4、および V7.7 クラスターの場合、このパラメーターはデフォルト値の
SquaredEuclideanにのみ設定できます。上記の関数の詳細については、距離測定関数をご参照ください。
Hamming 関数の実装は特殊です。HNSW または線形検索アルゴリズムを使用する場合、インデックスは標準の k-NN 検索をサポートしていません。スクリプトクエリのみがサポートされており、スクリプトクエリの コマンドは script_score パラメーターと互換性があります。スクリプトクエリのコマンドでこのパラメーターを使用する場合は、最初にビジネスに基づいてコマンドの可用性をテストする必要があります。
説明GET /_cat/plugins?v コマンドを実行して、apackプラグインのバージョンを取得できます。apackプラグインのバージョンが要件を満たしていない場合は、submit a ticket して、Alibaba Cloudエンジニアにapackプラグインの更新を依頼できます。
aliyun-knnプラグインは、いくつかの高度な検索パラメーターもサポートしています。詳細については、高度なパラメーターをご参照ください。
次のコマンドを実行してドキュメントを追加します。
POST test/_doc { "feature": [1.0, 2.0] }説明ベクトルインデックスの作成時に vector_type パラメーターを binary に設定した場合、ベクトルインデックスに書き込むベクトルデータは uint32 データ型である必要があります。これは、ドキュメントを追加する前に、データを符号なし 32 ビット 10 進数配列に変換する必要があることを示します。さらに、dim パラメーターの値は 32 の倍数である必要があります。vector_type パラメーターを binary 以外の値に設定した場合、ベクトルデータの長さは、dim パラメーターに指定された値と同じである必要があります。
ベクトルの検索
標準検索
ベクトルの標準検索を実行するには、次のコマンドを実行します。
GET test/_search { "query": { "hnsw": { // 検索アルゴリズムを指定します。 "feature": { // 検索対象のベクトルフィールド名を指定します。 "vector": [1.5, 2.5], // クエリベクトルを指定します。 "size": 10 // 返すドキュメントの数を指定します。 } } } }次の表では、上記のコマンドのパラメーターについて説明します。
パラメーター
説明
hnsw
ベクトルを検索するために使用されるアルゴリズム。値は、インデックスの作成時に指定された algorithm パラメーターの値と同じである必要があります。
vector
検索するベクトル。ベクトルの配列の長さは、dim パラメーターの mappings パートで指定された値と同じである必要があります。
size
リコールされるドキュメントの数。
説明ベクトル検索コマンドの size パラメーターは、Elasticsearchによって提供される size パラメーターとは異なります。前者は aliyun-knn プラグインによってリコールされるドキュメントの数を制御しますが、後者は検索でリコールされるドキュメントの数を制御します。ベクトル検索を実行する場合、システムは関連するベクトル検索コマンドの size パラメーターの値に基づいて上位 N 個のドキュメントをリコールし、Elasticsearchによって提供される size パラメーターの値に基づいてすべての一致するドキュメントをリコールします。次に、システムは上位 N 個のドキュメントとすべての一致するドキュメントに基づいて結果を返します。
2 つの size パラメーターを同じ値に設定することをお勧めします。Elasticsearchによって提供される size パラメーターのデフォルト値は 10 です。
説明aliyun-knnプラグインは、いくつかの高度な検索パラメーターもサポートしています。詳細については、高度なパラメーターをご参照ください。
スクリプトクエリ
script_score パラメーターを使用してのみスクリプトクエリを実行できます。たとえば、script_score パラメーターを使用して、クエリ応答の各ドキュメントにスコアを付けることができます。スコアは、次の式を使用して計算されます。
1/(1+l2Squared(params.queryVector, doc['feature']))。次のコードは、スクリプトクエリの要求の例を示しています。GET test/_search { "query": { "match_all": {} // すべてドキュメントを対象とします。 }, "rescore": { // script_score を使用して再スコアリングします。 "query": { "rescore_query": { "function_score": { "functions": [{ "script_score": { "script": { "source": "1/(1+l2Squared(params.queryVector, doc['feature'])) ", // スクリプトを定義します。 "params": { // パラメーターを渡します。 "queryVector": [2.0, 2.0] // クエリベクトルを指定します。 } } } }] } } } } }Alibaba Cloud Elasticsearchのスクリプトクエリは、X-Packによって提供される関数をサポートしていません。次の表で説明されている関数のみがサポートされています。
関数
説明
l2Squared(float[] queryVector, DocValues docValues)ユークリッド距離に基づいてベクトルを検索するために使用される関数。
hamming(float[] queryVector, DocValues docValues)ハミング距離に基づいてベクトルを検索するために使用される関数。
cosineSimilarity(float[] queryVector, DocValues docValues)cosine(float[] queryVector, DocValues docValues)
コサイン類似度に基づいてベクトルを検索するために使用される関数。
説明V6.7クラスターには
cosineSimilarity(float[] queryVector, DocValues docValues)関数を使用し、V7.10クラスターにはcosine(float[] queryVector, DocValues docValues)関数を使用することをお勧めします。説明スクリプトクエリは、apackプラグインが V1.2.1 以降の V6.7.0 クラスター、および apack プラグインが V1.4.0 以降の V7.10.0 クラスターでのみ実行できます。 GET /_cat/plugins?v コマンドを実行して、apackプラグインのバージョンを取得できます。apackプラグインのバージョンが要件を満たしていない場合は、submit a ticket して、Alibaba Cloudエンジニアにapackプラグインの更新を依頼できます。
上記の関数の parameters:
float[] queryVector:クエリベクトル。このパラメーターは、仮パラメーターまたは実パラメーターに設定できます。
DocValues docValues:ドキュメントベクトル。
オフライン最適化モードを使用して作成されたインデックスに対しては、スクリプトクエリを実行できません。
インデックスのウォームアップ
検索は、メモリ内ストレージのベクトルインデックスに対して実行されます。ベクトルインデックスにデータを書き込んだ後、最初の検索のレイテンシが高くなります。これは、インデックスがまだメモリにロードされているためです。この問題に対処するために、aliyun-knnプラグインはインデックスウォームアップ機能を提供します。この機能を使用すると、aliyun-knnプラグインがベクトル検索サービスを提供する前に、ベクトルインデックスをウォームアップし、オンプレミスマシンのメモリにロードできます。これにより、ベクトル検索のレイテンシが大幅に短縮されます。
すべてのベクトルインデックスをウォームアップするには、次のコマンドを実行します。
POST _vector/warmup特定のベクトルインデックスをウォームアップするには、次のコマンドを実行します。
POST _vector/{indexName}/warmup
説明インデックスウォームアップ機能は、apackプラグインが V1.2.1 以降の V6.7.0 クラスター、および apack プラグインが V1.4.0 以降の V7.10.0 クラスターでのみ使用できます。 GET _cat/plugins?v コマンドを実行して、apackプラグインのバージョンを取得できます。apackプラグインのバージョンが要件を満たしていない場合は、submit a ticket して、Alibaba Cloudエンジニアにapackプラグインの更新を依頼できます。
クラスターに多数のベクトルインデックスが格納されていて、インデックスに大量のデータが格納されていて、特定のベクトルインデックスに対してのみベクトル検索が必要な場合は、検索パフォーマンスを向上させるために、特定のベクトルインデックスのみをウォームアップすることをお勧めします。
ベクトルスコアリング
ベクトル検索には、統一されたスコアリング式が用意されています。この式は、距離測定関数によって異なります。距離測定関数は、検索結果の並べ替えに影響します。
スコアリング式:
スコア = 1/(ベクトル距離 + 1)
デフォルトでは、スコアリングメカニズムは、平方根抽出なしでユークリッド距離を使用してスコアを計算します。
実際には、スコアに基づいて距離を計算できます。次に、距離に基づいてベクトルを最適化して、スコアを上げます。
距離測定関数
スコアリングメカニズムは、距離測定関数によって異なります。次の表に、aliyun-knnプラグインでサポートされている距離測定関数を示します。
距離測定関数 | 説明 | スコアリング式 | ユースケース | 例 |
SquaredEuclidean | この関数は、ベクトル間のユークリッド距離を計算するために使用されます。ユークリッド距離はユークリッドメトリックとも呼ばれ、m次元空間における点間の実際の距離またはベクトルの自然長を指します。ユークリッド距離は広く使用されています。2次元または3次元空間のユークリッド距離は、点間の実際の距離です。 | たとえば、2つのn次元ベクトル[A1、A2、...、An]と[B1、B2、...、Bn]が存在するとします。
説明 デフォルトでは、スコアリングメカニズムは、平方根抽出なしでユークリッド距離を使用してスコアを計算します。 | ユークリッド距離は、個々の数値の特性の絶対差を反映できます。したがって、ユークリッド距離は、さまざまな次元からの数値の差を分析するために広く使用されています。たとえば、ユーザー行動メトリックを使用して、ユーザー値の差や類似性を分析できます。 | 2次元ベクトル[0、0]と[1、2]の間の平方根抽出なしのユークリッド距離は5です。これは、次の式を使用して計算されます。(1-0)² +(2-0)²。 |
Cosine | この関数は、ベクトル間のコサイン類似度を計算するために使用されます。この関数は、ベクトル間の角度のコサインを計算して、ベクトル間のコサイン類似度を取得します。 | たとえば、2つのn次元ベクトル[A1、A2、...、An]と[B1、B2、...、Bn]が存在するとします。
| コサイン類似度は、方向からのベクトル間の差を反映します。コサイン類似度は、コンテンツをスコアリングして、ユーザーの関心の類似点または相違点を得るために使用されます。さらに、コサイン類似度は、ベクトル内の数値ではなく、ベクトルの方向の影響を受けます。したがって、コサイン類似度は、ユーザーが異なる測定基準を使用する可能性があるという問題に対処できます。 | 2次元ベクトル[1、1]と[1、0]のコサイン類似度は0.707です。 |
InnerProduct | この関数は、ベクトル間の内積を計算するために使用されます。内積はドット積とも呼ばれます。ドット積は、実数Rの2つのベクトルを取り、実数スカラーを返す2項演算です。実数 | たとえば、2つのn次元ベクトル[A1、A2、...、An]と[B1、B2、...、Bn]が存在するとします。
| 内積は、ベクトル間の角度と絶対長の両方を考慮します。ベクトルが正規化されると、内積の式はコサイン類似度の式と同じになります。 | 2次元ベクトル[1、1]と[1、5]の内積は6です。 |
Hamming(BINARYデータ型のベクトルでのみ使用可能) | 情報理論では、同じ長さの文字列間のハミング距離は、記号が異なる位置の数と等しくなります。d(x、y)は、文字列xとyの間のハミング距離を表すために使用されます。言い換えると、ハミング距離は、文字列xを文字列yに変更するために必要な最小の置換回数を測定します。 | たとえば、2つのnビットバイナリ文字列xとyが存在するとします。
| ハミング距離は、コンピューターネットワークを介してデータが送信されるときに発生するエラーを検出または修正するために使用されます。ハミング距離は、バイナリ文字列間の異なる文字の数を判断するためのエラー推定方法としても使用できます。 | 1011101と1001001のハミング距離は2です。 説明 aliyun-knnプラグインを使用する場合、ベクトルインデックスに書き込むベクトルデータはuint32データ型である必要があります。これは、ベクトルデータが符号なし32ビット10進数配列で表される必要があることを示します。さらに、 |
上記の4つの関数はすべて、apackプラグインがV1.2.1以降のV6.7.0クラスター、およびapackプラグインがV1.4.0以降のV7.10.0クラスターでのみサポートされています。 GET _cat/plugins?v コマンドを実行して、クラスターのapackプラグインのバージョンを取得できます。apackプラグインのバージョンが要件を満たしていない場合、クラスターはSquaredEuclidean関数のみをサポートします。他の関数を使用する場合は、submit a ticket して、Alibaba Cloudエンジニアにapackプラグインの更新を依頼できます。
mappings パートの distance_method パラメーターを構成して、ベクトルインデックスに使用される距離測定関数を指定できます。
サーキットブレーカーパラメーター
パラメーター | 説明 | デフォルト値 |
indices.breaker.vector.native.indexing.limit | オフヒープメモリの使用量がこのパラメーターで指定された値を超えると、書き込み操作は中断されます。システムがインデックスを作成してメモリを解放すると、書き込み操作が再開されます。サーキットブレーカーがトリガーされると、システムメモリの消費量が高くなります。この場合、書き込みスループットを調整することをお勧めします。 | 70% |
indices.breaker.vector.native.total.limit | ベクトルインデックスの作成に使用されるオフヒープメモリの最大割合。実際のオフヒープメモリの使用量がこのパラメーターで指定された値を超えると、システムはシャードを再割り当てする可能性があります。 | 80% |
上記のサーキットブレーカーパラメーターは、クラスターレベルのパラメーターです。 GET _cluster/settings コマンドを実行して、パラメーターの値を表示できます。パラメーターにはデフォルト値を保持することをお勧めします。
高度なパラメーター
表 2. HNSWのインデックス作成パラメーター
パラメーター | 説明 | デフォルト値 |
index.vector.hnsw.builder.max_scan_num | 最悪の場合にグラフが作成されるときにスキャンできる最近傍の最大数。 | 100000 |
index.vector.hnsw.builder.neighbor_cnt | レイヤー0で各ノードが持つことができる最近傍の最大数。このパラメーターを100に設定することをお勧めします。グラフの品質はこのパラメーターの値とともに増加します。ただし、非アクティブなインデックスはより多くのストレージリソースを消費します。 | 100 |
index.vector.hnsw.builder.upper_neighbor_cnt | レイヤー0以外のレイヤーで各ノードが持つことができる最近傍の最大数。このパラメーターを neighbor_cnt パラメーターに指定された値の50%に設定することをお勧めします。最大値:255。 | 50 |
index.vector.hnsw.builder.efconstruction | グラフの作成時にスキャンできる最近傍の数。グラフの品質はこのパラメーターの値とともに増加します。ただし、インデックスの作成にはより長い期間が必要です。このパラメーターを 400 に設定することをお勧めします。 | 400 |
index.vector.hnsw.builder.max_level | レイヤー0を含むレイヤーの総数。たとえば、1,000万個のドキュメントがあり、scaling_factor パラメーターが 30 に設定されている場合は、30 を基数として使用し、10,000,000 の対数を最も近い整数に切り上げます。結果は 5 です。 このパラメーターは、ベクトル検索に大きな影響を与えません。このパラメーターを 6 に設定することをお勧めします。 | 6 |
index.vector.hnsw.builder.scaling_factor | スケーリング係数。レイヤーのデータ量は、その上のレイヤーのデータ量にスケーリング係数を掛けたものに等しくなります。有効な値:10〜100。レイヤーの数は scaling_factor の値とともに減少します。このパラメーターを 50 に設定することをお勧めします。 | 50 |
index.vector.algorithm パラメーターを hnsw に設定した後でのみ、settings パートで上記のパラメーターを設定できます。
表 3. HNSWの検索パラメーター
パラメーター | 説明 | デフォルト値 |
ef | オンライン検索中にスキャンされる最近傍の数。値が大きいほどリコール率は高くなりますが、検索速度は遅くなります。有効な値:100〜1000。 | 100 |
次のコードは、検索リクエストの例を示しています。
GET test/_search
{
"query": {
"hnsw": {
"feature": {
"vector": [1.5, 2.5],
"size": 10,
"ef": 100 // ef パラメーターを設定します。
}
}
}
}FAQ
Q:ドキュメントのリコール率を評価するにはどうすればよいですか?
A:2つのインデックスを作成できます。1つはHNSWアルゴリズムを使用し、もう1つは線形検索アルゴリズムを使用します。2つのインデックスで他のインデックス設定を一致させてください。クライアントを使用して同じベクトルデータをインデックスに追加し、インデックスを更新します。次に、同じクエリベクトルを使用してインデックスに対してクエリを実行し、インデックスによって返されたドキュメントIDを比較し、両方のインデックスによって返されたドキュメントIDを見つけます。
説明両方のインデックスが返すドキュメントIDの数を、返されたドキュメントIDの総数で割って、ドキュメントのリコール率を計算します。
Q:クラスターにデータを書き込むと、システムから
circuitBreakingExceptionエラーが返されます。どうすればよいですか?A:このエラーは、オフヒープメモリの使用量が indices.breaker.vector.native.indexing.limit パラメーターで指定された割合を超えており、書き込み操作が中断されたことを示します。デフォルトの割合は 70% です。ほとんどの場合、システムがインデックスを作成してメモリを解放すると、書き込み操作は自動的に再開されます。クライアントのデータ書き込みスクリプトに再試行メカニズムを追加することをお勧めします。
Q:書き込み操作が中断された後もCPUが動作しているのはなぜですか?
A:システムは、更新プロセスとフラッシュプロセスの両方でベクトルインデックスを作成します。書き込み操作が中断されても、インデックス作成タスクがまだ実行されている可能性があります。計算リソースは、最後の更新が完了した後に解放されます。
Q:aliyun-knnプラグインを使用すると、次のエラーが報告されます:
class_cast_exception: class org.apache.lucene.index.SoftDeletesDirectoryReaderWrapper$SoftDeletesFilterCodecReader cannot be cast to class org.apache.lucene.index.SegmentReader (org.apache.lucene.index.SoftDeletesDirectoryReaderWrapper$SoftDeletesFilterCodecReader and org.apache.lucene.index.SegmentReader are in unnamed module of loader 'app')。どうすればよいですか?A:インデックスの物理レプリケーション機能を無効にします。詳細については、apackプラグインの物理レプリケーション機能の使用をご参照ください。
Q:aliyun-knnプラグインを使用してベクトル検索を実行すると、検索が遅い場合や、メモリ使用量が多いために検索が中断される場合があります。どうすればよいですか?
A:aliyun-knnプラグインをベクトル検索に使用する場合、メモリ内ベクトルが使用されます。これにより、大量のメモリリソースが消費されます。ベクトル検索中に、システムはインデックスデータをデータノードのメモリにロードします。データノードに大量のインデックスデータが格納されている場合、検索が遅くなったり中断されたりする可能性があります。この問題を回避するには、各データノードに格納されているデータ量が、データノードの合計メモリサイズの半分以下であることを確認する必要があります。クラスター内のデータノードのメモリサイズが小さすぎる場合は、データノードをアップグレードすることをお勧めします。詳細については、クラスターの構成のアップグレードをご参照ください。
Q:aliyun-knnプラグインのベストプラクティスは提供されていますか?
A:Alibaba Cloud開発者コミュニティは、aliyun-knnプラグインのビジネスシナリオとベストプラクティスを提供しています。
Q:
must_not existsを使用して、feature フィールドの値が空のドキュメントをフィルタリングできません。どうすればよいですか?A:ベクトルデータは特別な方法で保存されており、DSLクエリと互換性がない場合があります。次のスクリプトを使用してドキュメントをフィルタリングできます。
GET jx-similar-product-v1/_search { "query": { "bool": { "must": { // feature フィールドが存在しないドキュメントをフィルタリングします。 "script": { "script": { "source": "doc['feature'].empty", // feature フィールドが空かどうかをチェックするスクリプト。 "lang": "painless" } } } } } }
