ベクトル量子化(Vector Quantization)は、高次元ベクトルのデータを圧縮し、メモリ使用量を削減しながら重要な情報を保持する技術です。例えば、OpenAIのembeddingモデルが生成する1536次元のベクトル1つは6KBのメモリを消費し、100万ベクトルで約6GBになります。データセットが数百万ベクトルに達すると、メモリと処理要求が大幅に増加します。量子化はベクトルを圧縮することで、より効率的なストレージと高速な検索を可能にします。
HNSWインデックスの課題
HNSW(Hierarchical Navigable Small World)インデックスは、階層的なグラフ構造でベクトルを近傍に接続します。新しいベクトルを追加する際、システムはその位置をグラフ内で決定する必要があり、これには検索と同様の複雑な操作が必要です。このプロセスはランダムな読み取りとシーケンシャルなトラバーサルを多く含み、特に高次元ベクトルが多数ある場合に計算コストが高くなります。量子化はベクトルを圧縮することで、このコストを削減します。
スカラー量子化
Qdrantでは、各次元はデフォルトでfloat32(4バイト)で表現されます。スカラー量子化は、ベクトル値をint8(1バイト、256値を表現)にマッピングし、75%のメモリ削減を実現します。例えば、-1.0から1.0の範囲の値はint8の-128から127に線形変換されます。設定時にはquantization_configにscalarを指定し、quantileパラメータ(例:0.99)で外れ値を除外して精度を調整できます。スカラー量子化は精度損失が最小限で、ほとんどのアプリケーションに適したデフォルトの選択肢です。
バイナリ量子化
バイナリ量子化は、ベクトルをバイナリ(0または1)に変換します。値が0より大きければ1、それ以下なら0です。1536次元のベクトルは6KBから192バイトに削減され、32倍の圧縮率で、検索速度は最大40倍向上します。Qdrantはインデックス作成時に自動的にバイナリ量子化を適用します。この手法はXORやPopcountなどの最適化されたCPU命令を活用し、高速な距離計算を可能にします。互換性のあるモデル(OpenAI text-embedding-ada-002やCohere embed-english-v2.0)では精度損失が少なく、少なくとも1024次元のモデルが推奨されます。精度を維持するために、オーバーサンプリングと再スコアリングが推奨されます。
プロダクト量子化
プロダクト量子化は、高次元ベクトルをサブベクトルに分割し、各サブベクトルに対してコードブックを作成します。コードブックのセントロイドはK-meansクラスタリング(K=256)で決定されます。1024次元のベクトルは4096バイトから128バイト(128個のインデックス、各1バイト)に圧縮され、最大64倍の圧縮が可能です。設定時にはcompression(例:x32)を指定します。ただし、高圧縮率は精度低下を招く可能性があるため、メモリ節約が最優先で精度がある程度許容される場合に適しています。
再スコアリング、オーバーサンプリング、再ランキング
量子化による精度低下を補うため、Qdrantはオーバーサンプリングと再スコアリングをサポートしています。まず量子化ベクトルで初期検索を行い、オーバーサンプリング(例:limit=4の場合、oversampling=2で8候補を取得)で候補を拡大します。その後、元のベクトルを使用して候補を再スコアリングし、より正確な類似度を計算します。最後に再ランキングで最終的なtop-K結果を決定します。これらの手法により、速度を維持しながら精度を向上できます。
ディスクとメモリのリソース配分
デフォルトでは、元のベクトルと量子化ベクトルは両方ともRAMに保存されます。メモリを節約するには、元のベクトルをディスクに移動し(on_disk=True)、量子化ベクトルのみRAMに保持します。例えば、バイナリ量子化を有効にし、元のベクトルをディスクに設定することで、RAM使用量を大幅に削減できます。明示的にon_disk=Trueを設定しない限り、RAMの節約は得られないので注意が必要です。
io_uringによる再スコアリングの高速化
Linuxベースのシステムでは、io_uringにより複数のディスク操作を並列処理でき、特に再スコアリング時のI/Oオーバーヘッドを削減します。Qdrantではstorage設定でasync_scorer: trueを有効にすることでio_uringを利用できます。これにより、ディスク上の大規模データセットでの検索パフォーマンスが向上します。
量子化データと非量子化データのパフォーマンス比較
Qdrantはデフォルトで量子化ベクトルを使用します。量子化の影響を評価するには、クエリにignore: trueを設定して一時的に無効化し、結果を比較できます。また、量子化方式はいつでも変更・削除可能で、元のベクトルには影響しません。例えば、スカラー量子化からバイナリ量子化に切り替えたり、量子化を完全に無効にしたりできます。
まとめ
3つの量子化手法にはそれぞれ長所と短所があります。バイナリ量子化は最速で最もメモリ効率が良いですが、互換性のあるモデルが必要です。スカラー量子化は精度損失が最小で、安全なデフォルトです。プロダクト量子化は最大の圧縮率を提供しますが、精度とインデックス速度のトレードオフがあります。オーバーサンプリング、再スコアリング、io_uringなどの技術を組み合わせることで、速度、精度、コストのバランスを最適化できます。