HNSW_SQ

HNSW_SQはHNSW(Hierarchical Navigable Small World)グラフとSQ(Scalar Quantization)を組み合わせたもので、サイズと精度のトレードオフを制御できる高度なベクトルインデックス作成手法である。標準的なHNSWと比較して、このインデックスタイプは高いクエリ処理速度を維持する一方で、インデックス構築時間は若干増加する。

概要

HNSW_SQは2つのインデックス作成技術を組み合わせたものである:HNSWはグラフベースの高速ナビゲーションを行い、SQは効率的なベクトル圧縮を行う。

HNSW

HNSWは、各ノードがデータセット内のベクトルに対応する多層グラフを構築する。このグラフでは、ノードは類似性に基づいて接続され、データ空間を高速にトラバースできる。階層構造により、検索アルゴリズムは近傍候補を絞り込むことができ、高次元空間での検索プロセスが大幅に高速化される。

詳細はHNSWを参照。

SQ

SQは、より少ないビット数でベクトルを表現して圧縮する手法である。例えば

  • SQ8は8ビットを使用し、値を256段階にマッピングする。 詳細はIVF_SQ8を参照。

  • SQ6 は各浮動小数点値を表すのに 6 ビットを使用し、64 個の離散レベルになります。

Hnsw Sq Hnsw Sq

この精度の低下により、メモリ・フットプリントが劇的に減少し、データの本質的な構造を保持したまま計算が高速化されます。

SQ4UCompatible with Milvus 2.6.8+

Milvusは、極限のクエリー速度と最小限のメモリー使用量を要求するシナリオのために、SQ4U 、4ビット統一スカラー量子化を導入しています。これは、各次元の浮動小数点値を4ビットの符号なし整数に圧縮する、積極的なスカラー量子化です。

SQ4Uの "U "はUniformの略です。通常、各次元ごとに最小値と最大値を個別に計算する(Per-Dimension Quantization)非均一なスカラー量子化とは異なり、SQ4UではGlobal Uniform Quantizationストラテジーを強制します:

  1. グローバル統計:グローバル統計:システムは、ベクトルのすべての次元(またはベクトルセグメント全体)に適用される単一の最小値vmin単一の値域vdiff を計算します。

  2. 一様マッピング:グローバルな値域は、16 の等しい区間に分割されます。ベクトル内のすべての浮動小数点値は、どの次元に属するかに関係なく、これらの共有パラメータを使用して 4 ビット整数(0 ~ 15)にマッピングされます。

パフォーマンスの利点

  • 8倍の圧縮率: FP32 と比較して8倍、SQ8 と比較して2倍のサイズ縮小を実現し、ベクトル探索のボトルネックとなりがちなメモリ帯域幅の圧迫を大幅に軽減します。

  • SIMD最適化:コンパクトな構造により、最新のCPU(AVX2/AVX-512)は1サイクルあたりより多くの次元を処理することができます。特に、グローバルパラメータを使用することで、距離計算中にスケール/オフセット値を変化させてロードする必要がなくなり、命令パイプラインを完全に飽和させることができます。

  • キャッシュ効率:ベクターサイズが小さいほど、より多くのデータがCPUキャッシュに収まるため、メモリアクセスによるレイテンシが減少します。

グローバルなパラメータ共有により、SQ4Uは正規化されたデータ、または次元間で一貫した値分布を持つデータセットで最高のパフォーマンスを発揮します。

HNSW + SQ

HNSW_SQはHNSWとSQの長所を組み合わせ、効率的な近似最近傍探索を可能にします。その仕組みは以下の通りである:

  1. データ圧縮:SQはsq_type (例えばSQ6やSQ8)を使用してベクトルを圧縮し、メモリ使用量を削減します。この圧縮は精度を低下させる可能性があるが、システムがより大きなデータセットを扱うことを可能にする。

  2. グラフの構築:圧縮されたベクトルはHNSWグラフの構築に使用される。データが圧縮されているため、結果として得られるグラフはより小さく、より高速に検索できる。

  3. 候補の検索:クエリーベクトルが提供されると、アルゴリズムは圧縮されたデータを使用して、HNSWグラフから近隣候補のプールを素早く特定します。

  4. (オプション)結果の絞り込み:最初の候補結果は、以下のパラメータに基づいて、より精度を高めるために改良することができる:

    • refine:この絞り込みステップを有効にするかどうかを制御します。true に設定すると、システムはより高精度または非圧縮表現を使用して距離を再計算します。

    • refine_type:精密化時に使用するデータの精度レベルを指定します(SQ6、SQ8、BF16 など)。FP32 のような高精度の選択は、より正確な結果をもたらしますが、より多くのメモリを必要とします。これは、元の圧縮データセットの精度をsq_type だけ上回る必要があります。

    • refine_k:倍率として機能する。例えば、トップkが100でrefine_k が2の場合、システムはトップ200の候補を再ランク付けし、ベスト100を返し、全体的な精度を向上させる。

パラメータの完全なリストと有効な値については、Index params を参照してください。

インデックスの構築

MilvusでベクトルフィールドにHNSW_SQ インデックスを構築するには、add_index() メソッドを使用し、index_typemetric_type 、インデックス用の追加パラメータを指定します。

from pymilvus import MilvusClient

# Prepare index building params
index_params = MilvusClient.prepare_index_params()

index_params.add_index(
    field_name="your_vector_field_name", # Name of the vector field to be indexed
    index_type="HNSW_SQ", # Type of the index to create
    index_name="vector_index", # Name of the index to create
    metric_type="L2", # Metric type used to measure similarity
    params={
        "M": 64, # Maximum number of neighbors each node can connect to in the graph
        "efConstruction": 100, # Number of candidate neighbors considered for connection during index construction
        "sq_type": "SQ6", # Scalar quantizer type
        "refine": true, # Whether to enable the refinement step
        "refine_type": "SQ8" # Precision level of data used for refinement
    } # Index building params
)

この設定では

  • index_type:構築するインデックスのタイプ。この例ではHNSW_SQ とします。

  • metric_type:ベクトル間の距離の計算方法。サポートされている値には、COSINEL2IP があります。詳細については、メトリック・タイプを参照してください。

  • params:インデックスを構築するための追加設定オプション。詳細は「インデックス構築パラメータ」を参照。

インデックス・パラメータを構成したら、create_index() メソッドを直接使用するか、create_collection メソッドでインデックス・パラメータを渡してインデックスを作成できます。詳細は、コレクションの作成 を参照してください。

インデックスでの検索

インデックスが構築され、エンティティが挿入されると、インデックス上で類似検索を実行できます。

search_params = {
    "params": {
        "ef": 10, # Parameter controlling query time/accuracy trade-off
        "refine_k": 1 # The magnification factor
    }
}

res = MilvusClient.search(
    collection_name="your_collection_name", # Collection name
    anns_field="vector_field",  # Vector field name
    data=[[0.1, 0.2, 0.3, 0.4, 0.5]],  # Query vector
    limit=3,  # TopK results to return
    search_params=search_params
)

この構成では

インデックスパラメータ

このセクションでは、インデックスを構築し、インデックス上で検索を実行するために使用されるパラメータの概要を説明します。

インデックス構築パラメータ

以下の表に、paramsインデックスを構築する際に設定できるパラメータを列挙します。

パラメータ

説明

値の範囲

チューニングの提案

HNSW

M

各ノードがグラフ内で持つことのできる接続(またはエッジ)の最大数。

このパラメータはインデックスの構築と検索の両方に直接影響する。

:整数

範囲:[2, 2048[2, 2048]

デフォルト値:30 (ノードあたり最大 30 の送信エッジと 30 の受信エッジ)

M を大きくすると一般的に精度が高くなるが、メモリ・オーバーヘッドが増加し、インデックス構築と検索の両方が遅くなる

高次元のデータセットや高い再現性が重要な場合は、M を増やすことを検討する。

メモリ使用量と検索速度を重視する場合は、M を減らすことを検討する。

ほとんどの場合、この範囲内の値を設定することを推奨する:[5, 100].

efConstruction

インデックス構築時に接続を考慮する近隣候補の数。

各新要素に対してより多くの候補が評価されますが、 実際に確立される接続の最大数はM によって制限されます。

:整数

範囲: [1, int_max]:[1,int_max] です。

デフォルト値360

efConstruction を大きくすると、より多くの潜在的なコネクションが探索されるため、通常より正確なインデックスが作成される。しかし、これはインデックス作成時間の延長と、作成中のメモリ使用量の増加にもつながります。

特にインデックス作成時間がそれほど重要でないシナリオでは、精度を向上させるためにefConstruction を増加させることを検討してください。

リ ソ ース制約が懸念 さ れ る 場合には、efConstruction を減らして イ ンデ ッ ク ス作成を高速化す る こ と を検討 し て く だ さ い。

ほとんどの場合、この範囲内の値を設定することを推奨します:[50, 500].

SQ

sq_type

ベクトルを圧縮するスカラー量子化法を指定します。各オプションは、圧縮率と精度のバランスが異なります:

  • SQ4U:4ビット均一量子化を使用してベクトルをエンコードします。このモードは最も高速で圧縮率が高い。

  • SQ6:6ビット整数を使用してベクトルをエンコードします。

  • SQ8:8ビット整数を用いてベクトルをエンコードする。

  • BF16:Bfloat16フォーマットを使用。

  • FP16:標準的な16ビット浮動小数点フォーマットを使用。

:文字列

範囲:[SQ4U,SQ6,SQ8,BF16,FP16 ]。

デフォルト値SQ8

sq_type の選択は、特定のアプリケーションのニーズに依存する。SQ4U は、最大速度とメモリ効率のために選択される。SQ6 またはSQ8 は、バランスの取れたパフォーマンスに適しているかもしれない。一方、精度が最優先される場合は、BF16 またはFP16 が好まれるかもしれない。

refine

検索中に絞り込みステップを適用するかどうかを制御するブーリアン・フラグ。refinementは、クエリベクタと候補の間の正確な距離を計算することによって、最初の結果を再ランク付けすることを含む。

型はブール値

範囲:[true,false]。

デフォルト値false

高精度が必須で、検索時間が多少遅くても許容できる場合は、true に設定する。スピードを優先し、精度の多少の妥協が許容できる場合はfalse を使用します。

refine_type

精緻化に使用するデータの精度を決定します。

この精度は(sq_type で設定された)圧縮ベクトルの精度よりも高くなければならず、再ランク付けされたベクトルの精度とメモリフットプリントの両方に影響します。

:文字列

範囲:[ SQ6, SQ8, BF16, FP16, FP32 ]。

デフォルト値:なし

より高いメモリコストで最大の精度を得るにはFP32 を使用し、より良い圧縮を得るにはSQ6/SQ8 を使用する。BF16FP16 はバランスの取れた代替を提供する。

インデックス固有の検索パラメータ

次の表は、インデックスを検索する際にsearch_params.params で設定可能なパラメータの一覧です。

パラメータ

説明

値の範囲

チューニングの提案

HNSW

ef

最近傍検索時の検索の幅を制御します。どれだけのノードが最近傍候補として訪問され、評価されるかを決定します。

このパラメータは検索プロセスのみに影響し、グラフの最下層にのみ適用される。

型を指定します:整数

範囲: [1, int_max[1,int_max]

デフォルト値:limit(TopK nearest neighbors to return)

ef を大きくすると、より多くの近傍候補が考慮されるため、一般的に検索精度が高くなります。しかし、これは検索時間を増加させます

高い想起率を達成することが重要であり、検索速度があまり気にならない場合は、ef を増やすことを検討してください。

特に精度が多少低下しても構わないようなシナリオでは、ef を減らして、より高速な検索を優先させることを検討してください。

ほとんどの場合、この範囲内の値を設定することをお勧めします:[K, 10K]。

SQ

refine_k

要求された上位K個の結果に対して、絞り込み段階でどれだけの余分な候補を調べるかを制御する倍率。

タイプFloat

範囲:[1,float_max)

デフォルト値: 1

refine_k の値を大きくすると、再現率と精度が向上するが、検索時間とリソースの使用量も増加する。1の値は、絞り込み処理が最初の上位K個の結果のみを考慮することを意味する。