Voyagerを始めよう:Spotifyの最近傍検索ライブラリ
Voyager: 高速最近傍探索のための新しいオープンソースライブラリ。VoyagerはHNSWアルゴリズムを使用し、以前のライブラリAnnoyを凌駕している。
今日のデータ駆動型の世界では、効率的な検索機能は多くのアプリケーションにとって重要である。この点で、最近傍探索(NNS)は重要な技術であり、音楽推薦や画像検索などのタスクをサポートしている。アプリケーションシステムは大量のデータを扱う必要があるため、与えられたクエリに関連する類似データを素早く見つける効率的なアルゴリズムを持つことが重要である。
最も一般的なアプローチの1つは、近似最近傍 (ANN)検索アルゴリズムを使用することです。Annoy (Approximate Nearest Neighbors, Oh Yeah) のようなライブラリは、これらのアルゴリズムを実装するために広く使われており、大規模で高次元のデータセットにおける高速な最近傍検索を可能にしている。しかし、データの大規模化に伴い、より高度で高速かつ高精度な手法が求められている。
この課題に対処するため、SpotifyはVoyager-最近傍探索を高速に実行するために2023年に設計された新しいオープンソースライブラリ-をリリースした。VoyagerはHNSW(Hierarchical Navigable Small Worlds)アルゴリズムを使用しており、以前のライブラリであるAnnoyよりも大きな進歩を示している。
Spotifyのエンジニアリング・チームによると、VoyagerはAnnoyと同程度の想起率を維持しながら、Annoyの最大10倍の速度を達成している。さらに、同程度の速度で最大50%高い精度を実現し、Annoyよりも最大4倍少ないメモリで済む。
Voyager-Spotifyの最近傍検索ライブラリ.png](https://assets.zilliz.com/Voyager_Spotify_s_Nearest_Neighbor_Search_Library_ac2ef1ac07.png)
Voyager:Spotifyの最近傍検索ライブラリ|出典
この記事では、マルチスレッドインデックスの作成とクエリ機能を含む、Voyagerの主な機能について説明する。さらに、Voyagerを最適化するためのベストプラクティスを取り上げ、Voyagerを使い始めるためのステップバイステップのガイドを提供します。
Voyagerの裏側:コア機能
Voyagerは、その前身であるAnnoyをベースに、大規模な高次元データセットへのスケーリングなど、最近傍探索における主要な課題に取り組んでいる。特に、最新のアプリケーションにおけるデータの規模と複雑さを管理するのに適している。Voyagerのコア機能とサポート機能を理解しよう。
スピードと精度の向上
Voyagerの際立った特徴のひとつは、インデックス作成とクエリ作成の速度が大幅に向上していることだ。Spotifyのエンジニアリングチーム報告によると、VoyagerはこれらのタスクにおいてAnnoyよりも約10倍高速だという。そのため、Voyagerは瞬時の検索を必要とするアプリケーションにとってより良い選択となる。
Voyagerは、Hierarchical Navigable Small Worlds(HNSW)アルゴリズムを使って検索プロセスを最適化する。これは、計算負荷を低く抑えながら、高次元空間をナビゲートして最近傍を見つけるのに役立つ。
Hierarchical Navigable Small Worlds (HNSW)アルゴリズムは、類似アイテムの検索方法を改善するのに役立ちます。複雑なデータ空間をナビゲートしやすくし、計算能力をあまり使わずに探しているものを素早く見つけることができる。
さらに、VoyagerはAnnoyよりも精度が最大50%向上している。精度の向上は、ユーザー・エクスペリエンスの向上を目指すレコメンデーション・エンジンにとって重要な、より質の高い検索結果を保証する。
メモリ使用量の削減
E4M38ビット浮動小数点表現を使用することで、VoyagerはAnnoyよりも最大4倍少ないメモリで、より大きなデータセットを効率的に扱うことができます。このため、高次元データを扱い、リソースの使用量を最適化したい組織にとって魅力的な選択肢となる。
マルチスレッドインデックスの作成とクエリ
Voyagerのもう一つの重要な特徴は、完全にマルチスレッド化されたインデックス作成とクエリをサポートしていることです。マルチスレッドにより、Voyager は複数の CPU コアを使用し、並列に計算を実行する機能を追加することで、大規模なデータセットをうまく処理することができます。これによりインデックス作成とクエリにかかる時間が短縮され、システム全体の効率が向上する。
マルチスレッディングは、Spotifyのような大規模なアプリケーションにとって重要である。これにより、システムは大量のクエリとインデックス作成に対応し、より良い、より効率的なユーザー体験を提供することができる。
言語サポート
Voyagerは、さまざまな生産環境において柔軟に対応できるように設計されている。HNSWlib](https://zilliz.com/learn/learn-hnswlib-graph-based-library-for-fast-anns)のような多くの最近傍ライブラリは主にPythonに焦点を当てていますが、VoyagerはPythonとJavaの両方をサポートしています。この2言語機能は、パフォーマンスクリティカルなシステムをデプロイするためにJavaやScalaのようなJVMベースの言語を好むバックエンドエンジニアや、機械学習のためにPythonで作業するデータサイエンティストをサポートします。
Voyagerのセットアップ:ステップバイステップガイド
このセクションでは、PythonでのVoyagerのセットアップ、インデックスの構築、検索の実行について説明する。JavaでVoyagerをセットアップするには、公式ドキュメントを参照してください。
インストールと前提条件
VoyagerのPythonバインディングを使用するには、まずVoyagerパッケージをインストールする必要がある。これはpipを使って行うことができる:
pip install voyager
ライブラリのインポート
必要なライブラリをインポートしよう。数値演算には numpy
、効率的で正確な最近傍探索には voyager
が必要だ。
numpy を np としてインポートする。
from voyager import インデックス, スペース
**データの準備
Voyagerはvector embeddingsで動作します。ここでは、GoogleのWord2Vecプロジェクトで学習済みの単語埋め込みを使用しています。
ベクトルデータをダウンロードする (
word2vec_10000_200d_tensors.bytes
)対応するラベルをダウンロードする (
word2vec_10000_200d_labels.tsv
).ベクトルをNumPyの配列(vectors)に、ラベルをリスト(labels)にロードする。
#ベクトルデータ
wget https://storage.googleapis.com/embedding-projector/data/word2vec_10000_200d_tensors.bytes
#ラベル
wget https://storage.googleapis.com/embedding-projector/data/word2vec_10000_200d_labels.tsv
ベクトルとラベルの準備ができたら、ベクトルをNumPyの配列に、ラベルをリストにロードします。
num_dimensions = 200
with open("word2vec_10000_200d_tensors.bytes", "rb") as f: vectors = np.fromfile(f, np.float32).reshape(-1, num_dimensions)
with open("word2vec_10000_200d_labels.tsv", "r") as f: labels = [line.split("\t")[0] for line in f.readlines()[1:]].
インデックスの構築
Voyager の Index クラスを使用して、ベクトルを保存および管理します。
# ベクトルを格納できるIndexオブジェクトを作成します:
index = Index(Space.Cosine, num_dimensions=200)
ここでは、類似度メトリック としてコサイン類似度の Space.Cosine
を使用しますが、ベクトルが 200 次元なので num_dimensions
を 200
に設定して Space.Euclidean
のような他の類似度メトリックを適用することもできます。
次に、add_items()メソッドを使用して、
vectors ` をインデックスに追加する。
index.add_items(vectors)
検索の実行
インデックスが構築されたら、最近傍検索を実行することができる。
query_vector = vectors[labels.index('dog')] #クエリベクトル
neighbors, distances = index.query(query_vector, k=10) # これは2つの配列を返します: neighbors (インデックス内の最近傍のインデックス) と distances (対応する距離).
for neighbor, distance in zip(neighbors, distances):
print(f"{ラベル[neighbor]!r}は'dog'から{距離:.2f}離れています")
**出力
'dog'はdogから0.00離れている
'dogs' は dog から 0.28 離れている
'cat' は犬から0.35離れている
'bird' は犬から0.38離れている
'breed' は犬から0.38離れている
'fish' は犬から0.41離れている
'pet' は犬から0.41離れている
'cats' は犬から0.41離れている
'cow' は犬から0.42離れている
'rat' は犬から0.42離れている
dog "という単語とそれ自身を比較した場合、両者は同一であるため、距離は0となる。複数形の "dogs "のような近縁の単語は距離が小さく、類似性が高いことを示す。cat "のように、多少関連はあるが概念的に異なる単語は距離が大きくなる。一方、"fish "のように "dog "との関連性が低い単語は、類似性が低いため、最も遠い位置にある。
こうだ!これは、Pythonで単語埋め込みを使った最近傍検索にVoyagerを使う基本的な例です。もちろん、マルチスレッドやインデックスの保存や読み込みなど、Voyagerのより高度な機能を探求することもできる。しかし、この例はVoyagerを使い始めるための強固な基礎となるはずです。
ベストプラクティスと最適化のヒント
以下のベストプラクティスと戦略に従って、Voyagerを最近傍検索タスクに最適化してください。
データの準備
正規化:*** ベクトルの平均がゼロ、分散が単位になるように正規化します。これは、特にユークリッド距離のような距離ベースのメトリクスの検索精度を向上させることができます。
次元削減:** 高次元のデータを扱うには、PCAやt-SNEのような次元削減テクニックの使用を検討してください。これらの手法は、重要な情報を保持したまま次元数を減らすことができ、最終的にインデックス作成と検索の効率を高めることができる。
インデックスの構築
空間選択:*** データとニーズに基づいて適切な類似空間パラメータを選択します。Voyager のオプションには、ユークリッド距離、内積、コサイン(余弦類似度)があります。
プロセスの高速化:** プロセスを高速化するために、特に大規模なデータセットの場合、インデックス構築中に複数のスレッドを使用します。お使いのシステムに最適な設定を見つけるために実験してください。
検索の最適化
k 値:** 検索する最近傍の数を表す適切な
k
値を選択します。十分な近傍探索の必要性と探索待ち時間への影響のバランスをとる。検索を並列化する:** 検索中に複数のスレッドを使用して処理を高速化する。
メモリー管理
大規模なデータセット:** データを小さな塊に分割し、大規模なデータセット用に個別のインデックスを構築することを検討してください。これにより、メモリ使用量を管理し、パフォーマンスを向上させることができます。
構築したインデックスは
index.save()
を使ってディスクに保存し、後でindex.load()
を使ってロードする。
Voyager と目的別ベクターデータベースの比較
Voyagerのようなベクトル検索ライブラリも、Milvusのような目的に特化したベクトルデータベースも、高次元ベクトルデータの類似性検索という課題に取り組んでいる。しかし、両者は異なるニーズとスケールに対応している。
ベクトル検索ライブラリ:効率重視
Voyager のようなライブラリは、効率的な最近傍探索を優先します。これらのライブラリは、類似ベクトルを見つけるための軽量で高速なソリューションを提供し、静的または中程度のサイズのデータセットを持つ小規模なシングルノード環境に最適です。しかし、一般的に動的データの管理、永続性の確保、分散システム間でのスケーリングなどの機能が欠けている。開発者は通常、データ管理、更新、スケーリングを手作業で行う必要がある。
目的別ベクターデータベース:包括的なソリューション
Milvus](https://zilliz.com/what-is-milvus)やZilliz Cloud (powered by Milvus)のような目的に特化したベクターデータベースは、ベクターデータを管理するためのより包括的なアプローチを提供します。これらのデータベースは、単純なベクトル検索を超えて、以下を提供します:
永続ストレージ: データの耐久性と可用性を確保する。
リアルタイム更新:** 動的データや頻繁な更新を効率的に処理する。
分散アーキテクチャとスケーラビリティ:**増大するデータセットとクエリワークロードを処理するための水平方向のスケーリング。
高度なクエリ機能:フィルタリング、メタデータ検索、ベクトル類似性検索を含む複雑なクエリをサポート。
これらの機能により、Milvusのようなベクトルデータベースは、スケーラビリティ、高可用性、複雑な検索機能を必要とするプロダクション環境に最適です。
結論
Voyagerは最近傍探索技術を進化させた。マルチスレッド機能により、メモリフットプリントを削減し、高次元データを効率的に扱うことができる。PythonとJavaの両方をサポートしているため、様々なアプリケーションに柔軟に対応できる。
しかし、VoyagerとMilvusのような専用に構築されたベクトルデータベースのどちらかを選択する際には、特定のニーズを考慮することが重要である。Voyagerは軽量で効率的な検索に適しているが、MilvusやZilliz Cloudのようなベクターデータベースは、永続性、リアルタイム更新、大規模な本番ワークロードを処理するための拡張性など、より包括的でエンタープライズレベルの機能を備えている。ベストプラクティスに従い、Voyagerの機能を使用することで、検索オペレーションを最適化し、アプリケーションのパフォーマンスを向上させることができます。
その他のリソース
階層型航行可能スモールワールド(HNSW)](https://zilliz.com/learn/hierarchical-navigable-small-worlds-HNSW)
近似最近傍オーイェー(ANNOY)](https://zilliz.com/learn/approximate-nearest-neighbor-oh-yeah-ANNOY)
ベクトルインデックスの基礎と反転ファイルインデックス](https://zilliz.com/learn/vector-index)
ベクトルデータベースとは](https://zilliz.com/learn/what-is-vector-database)
ベクターライブラリ対ベクターデータベース:どちらがあなたに適しているか](https://zilliz.com/learn/vector-library-versus-vector-database)
ベクターデータベース、ベクター検索ライブラリ、ベクター検索プラグインの比較](https://zilliz.com/learn/comparing-vector-database-vector-search-library-and-vector-search-plugin)
VectorDBBench: オープンソースベクターデータベースベンチマークツール](https://zilliz.com/learn/open-source-vector-database-benchmarking-your-way)
読み続けて

データの完全性を守る:ベクターデータベースにおけるバックアップとリカバリ
このブログでは、vectorDBにおけるデータのバックアップとリカバリ、その課題、様々な方法、そしてデータ資産のセキュリティを強化するための専用ツールについて説明します。

ベクトル・データベースにおけるデータの完全性の維持
データのライフサイクルを通じて、データが正しく、一貫性があり、信頼できることを保証することは、データ管理、特にベクターデータベースにおいて重要である。

ベクターデータベースの高可用性の確保
高可用性の確保は、特にダウンタイムが生産性と収益の損失に直結するアプリケーションにおいて、ベクトル・データベースの運用にとって極めて重要である。