シュッと Spotify さんとこの voyager を使ってみる

ちゃっす(/・ω・)/



Spotify さんで使われてる Vector Database である VOYAGER がリリースされた模様なのでシュッと戯れてみるぞ☆
(他との比較、検証はしないぞ☆)

Voyager is a library for performing fast approximate nearest-neighbor searches on an in-memory collection of vectors.

Voyager features bindings to both Python and Java, with feature parity and index compatibility between both languages. It uses the HNSW algorithm, based on the open-source hnswlib package, with numerous features added for convenience and speed. Voyager is used extensively in production at Spotify, and is queried hundreds of millions of times per day to power numerous user-facing features.

Think of Voyager like Sparkey, but for vector/embedding data; or like Annoy, but with much higher recall. It got its name because it searches through (embedding) space(s), much like the Voyager interstellar probes launched by NASA in 1977.

https://github.com/spotify/voyager

翻訳をしまぁ~す

Voyagerは、インメモリのベクトルコレクションに対して近似最近傍探索を高速に実行するためのライブラリである。

VoyagerはPythonとJavaの両方にバインディングされており、両言語間で機能パリティとインデックスの互換性がある。オープンソースのhnswlibパッケージをベースとしたHNSWアルゴリズムを使用し、利便性と速度のために多くの機能が追加されている。Voyagerは、Spotifyのプロダクションで広範囲に使用されており、1日に何億回もクエリされ、ユーザー向けの数多くの機能をパワーアップしている。

VoyagerはSparkeyのようなものだが、ベクター/エンベッディングデータ用である。1977年にNASAが打ち上げた恒星間探査機ボイジャーのように、空間を(埋め込んで)探索することからこの名前がついた。

DeepL さん

この文章から特徴を抽出しまぁ~す

"Voyager"の新規性や特徴を考察するにあたり、提供された情報に基づいて以下の点が挙げられます。

1. **多言語バインディング**: VoyagerはPythonとJavaの両方にバインディングを提供しています。このような多言語対応は、開発者が異なる環境やプラットフォームでの統一された経験を持つことができるため価値があります。特に、PythonとJavaは、データサイエンスとエンタープライズレベルのアプリケーション開発において主要な言語であるため、この2つの言語に対応することは大きなメリットとなるでしょう。

2. **HNSWアルゴリズムの利用**: HNSW(Hierarchical Navigable Small World)アルゴリズムは、近似最近傍検索において高い性能を持つアルゴリズムとして知られています。Voyagerがhnswlibを基にしていることは、高速で効率的な検索が可能であることを示唆しています。

3. **Spotifyでの本番環境での利用**: VoyagerはSpotifyで大規模に利用されているとのこと。これは、Voyagerがスケーラビリティや信頼性の面での実証がなされていることを意味します。

4. **既存のツールとの比較**: SparkeyやAnnoyといった既存のツールとの比較が触れられています。Sparkeyに比べてベクトルや埋め込みデータに特化しており、Annoyと比較してはるかに高いリコールを持つとのこと。これにより、Voyagerが特定のユースケースにおいて優れた性能を持つことが示唆されます。

5. **名前の背景**: Voyagerの名前がNASAの1977年のボイジャー探査機に由来することは、その機能や目的に対する愛情や熱意を感じさせるエピソードとして興味深いです。

以上の特徴から、Voyagerは高速かつ効率的なベクトルの近似最近傍検索を提供するライブラリとして、新規性や利点を持つと考えられます。

By ChatGPT 4

では使ってみまぁ~す


ドキュメントは言語ごとに用意されていて Python はこちら(/・ω・)/



いざコード書きかき、、、とその前に(/・ω・)/



DB なのでぶち込むデータを用意しないといけませんな☆



っちゅーことで、先ほどの Python 用のドキュメントから QA を Calude ちゃんに作ってもらった☆



みたいな感じ


ではコードを書いていきまぁ~す



Google Colab でシュッとやるわよ(/・ω・)/


まずは data.json として作った QA をファイルとして保存する(大体100件くらいになった)

[
{
"question": "voyagerモジュールとは?",
"answer": "ベクトルデータの近似最近傍検索インデックスを構築するためのクラスと関数を提供するPythonモジュールです。"
},
{
"question": "Indexクラスのコンストラクタにはどのようなパラメータがありますか?",
"answer": "主なパラメータはspace、num_dimensions、M、ef_constructionなどがあります。spaceはベクトル間の距離計算方法を、num_dimensionsはベクトルの次元数を表します。"
},
...
]


読み込みんぐ

import pandas as pd

df = pd.read_json("./data.json")
df.head()


なんとなく QA を結合した文字列をベクトル化したいと思ったので

for i in range(len(df)):
    df['qa'][i] = df['question'][i] + " " + df['answer'][i]

df.head()
こんな感じ



よっしゃこのデータをぶち込むぜぇ、、、ひゃっは~~~(/・ω・)/



と、その前に


voyager 氏に保存できるのはベクトル化された情報のみなので作ったデータをまずはベクトル化せんとあきまへん(/・ω・)/


っちゅーことで


intfloat/multilingual-e5-base を使ってベクトル化するぞい(/・ω・)/


必要な物いれる

!pip install sentence_transformers



モデル読みこみ

model_name = "intfloat/multilingual-e5-base"

from sentence_transformers import SentenceTransformer
model = SentenceTransformer(model_name)



んでベクトル化しちゃう

df["vector"] = df["qa"].apply(model.encode)
df.head()


上手に焼けました!


では本丸の voyager さんをシュッと試すぞ☆

!pip install voyager


index に追加できる型が np.float32 だったのでシュッと変換してぶち込む

import numpy as np
from voyager import Index, Space

vectors = np.stack(df["vector"].to_numpy())
vector_float32 = vectors.astype(np.float32)

# Create an empty Index object that can store vectors:
index = Index(Space.Euclidean, num_dimensions=768)
index.add_items(vector_float32)



質問を作ってみる

query = model.encode("voyager とはどういったものですか?")


質問も同様に変換して近しいデータの上位五件を取得してみるぞ☆

query_float32 = query.astype(np.float32)
neighbors, distances = index.query(query_float32, k=5)
print(neighbors)
print(distances)
for i in neighbors:
    print(df["answer"][i])
上位五件の id: [ 0 45 11 85 25]
上位五件の 距離: [0.27051553 0.3788426  0.38504416 0.38671505 0.39111543]

事前作成した QA の Answer 部分を表示

ベクトルデータの近似最近傍検索インデックスを構築するためのクラスと関数を提供するPythonモジュールです。
空間分割索引構造を利用した近似最邻探索アルゴリズムが使用されています。
ベクトル間の距離計算方法を表す列挙型です。EuclideanInnerProductCosineなどが定義されています。
近傍探索なので分類アルゴリズムとは目的が異なりますが、近傍ラベルを利用することで準分類は可能です。
プロプライエタリなバイナリ形式です。拡張子は.voyが推奨されています。


うむ。ちゃんと答えられて偉い偉い(/・ω・)/


質問を変えてみる

query = model.encode("voyager でアイテムを追加するにはどうすればよいですか?")
単純にadd_item()やadd_items()メソッドで追加可能です。必要に応じて事前にresize()すると良いでしょう。
直接はできません。各ベクトルに重みを乗算したデータを追加することで実現できます。
add_item()またはadd_items()メソッドを使用します。
各ベクトルに重みを乗算したうえでIndexに追加することで、重み付けが実現できます。クエリ時も同じ重みを適用する必要があります。
構築アルゴリズムがランダム化されているので、明示的なシャッフルは必要ありません。


うむうむ(/・ω・)/


まぁいいのではないだろうかしら(/・ω・)/


んじゃ、ファイルに書き出すぞ☆


# Save the index to disk to reload later (or in Java!)
index.save("./output_file.voy")


っちゅーことで、シュッと触っただけなので特に他との比較、評価はしとらんですが、満足したのでおしまい。

この記事が気に入ったらサポートをしてみませんか?