Milvus Liteのクイックスタート
ニューラルネットワークモデルの出力データフォーマットであるベクトルは、情報を効果的にエンコードすることができ、知識ベース、セマンティック検索、RAG(Retrieval Augmented Generation)などのAIアプリケーションで重要な役割を果たします。
Milvusはオープンソースのベクトルデータベースであり、Jupyterノートブックでのデモチャットボットの実行から、何十億ものユーザーにサービスを提供するウェブスケール検索の構築まで、あらゆる規模のAIアプリケーションに適している。このガイドでは、Milvusを数分でローカルにセットアップし、Pythonクライアント・ライブラリを使用してベクトルを生成、保存、検索する方法を説明します。
Milvusのインストール
このガイドでは、クライアントアプリケーションに組み込むことができるpymilvus
に含まれるPythonライブラリであるMilvus Liteを使用します。MilvusはDockerや Kubernetesへのデプロイもサポートしており、本番環境での利用も可能です。
始める前に、ローカル環境でPython 3.8+が利用可能であることを確認してください。pythonクライアントライブラリとMilvus Liteの両方を含むpymilvus
:
$ pip install -U pymilvus
Google Colabを使用している場合、インストールした依存関係を有効にするために、ランタイムを再起動する必要があるかもしれません。(画面上部の "Runtime "メニューをクリックし、ドロップダウンメニューから "Restart session "を選択してください)。
ベクターデータベースのセットアップ
ローカルにMilvusベクトルデータベースを作成するには、"milvus_demo.db "のように全てのデータを保存するファイル名を指定してMilvusClient
。
from pymilvus import MilvusClient
client = MilvusClient("milvus_demo.db")
コレクションの作成
Milvusでは、ベクターとそれに関連するメタデータを保存するコレクションが必要です。これは従来のSQLデータベースでいうテーブルのようなものです。コレクションを作成する際、スキーマとインデックスのパラメータを定義して、次元数、インデックスタイプ、遠隔メトリックなどのベクター仕様を設定することができます。また、ベクトル検索のパフォーマンスのためにインデックスを最適化する複雑な概念もあります。とりあえず、基本的なことに絞って、可能な限りデフォルトを使用することにしましょう。最低限必要なのは、コレクション名とコレクションのベクトル・フィールドの次元だけです。
if client.has_collection(collection_name="demo_collection"):
client.drop_collection(collection_name="demo_collection")
client.create_collection(
collection_name="demo_collection",
dimension=768, # The vectors we will use in this demo has 768 dimensions
)
上記の設定では
- プライマリ・キーとベクトル・フィールドは、デフォルト名("id" と "vector")を使用する。
- メトリックタイプ(ベクトル距離定義)は、デフォルト値(COSINE)に設定される。
- プライマリ・キー・フィールドは整数を受け入れ、自動的にインクリメントしない(つまり、自動id機能を使用しない)。 または、この命令に従って、コレクションのスキーマを正式に定義できます。
データの準備
このガイドでは、テキストに対してセマンティック検索を実行するためにベクトルを使用します。埋め込みモデルをダウンロードして、テキストのベクトルを生成する必要があります。これは、pymilvus[model]
ライブラリのユーティリティ関数を使えば簡単にできる。
ベクトルでテキストを表現する
まず、モデルライブラリをインストールする。このパッケージにはPyTorchのようなMLに不可欠なツールが含まれています。PyTorchがインストールされていない環境では、ダウンロードに時間がかかるかもしれません。
$ pip install "pymilvus[model]"
デフォルトモデルでベクトル埋め込みを生成します。Milvusはデータが辞書のリストとして挿入されることを想定しており、各辞書はentityと呼ばれるデータレコードを表す。
from pymilvus import model
# If connection to https://huggingface.co/ failed, uncomment the following path
# import os
# os.environ['HF_ENDPOINT'] = 'https://hf-mirror.com'
# This will download a small embedding model "paraphrase-albert-small-v2" (~50MB).
embedding_fn = model.DefaultEmbeddingFunction()
# Text strings to search from.
docs = [
"Artificial intelligence was founded as an academic discipline in 1956.",
"Alan Turing was the first person to conduct substantial research in AI.",
"Born in Maida Vale, London, Turing was raised in southern England.",
]
vectors = embedding_fn.encode_documents(docs)
# The output vector has 768 dimensions, matching the collection that we just created.
print("Dim:", embedding_fn.dim, vectors[0].shape) # Dim: 768 (768,)
# Each entity has id, vector representation, raw text, and a subject label that we use
# to demo metadata filtering later.
data = [
{"id": i, "vector": vectors[i], "text": docs[i], "subject": "history"}
for i in range(len(vectors))
]
print("Data has", len(data), "entities, each with fields: ", data[0].keys())
print("Vector dim:", len(data[0]["vector"]))
Dim: 768 (768,)
Data has 3 entities, each with fields: dict_keys(['id', 'vector', 'text', 'subject'])
Vector dim: 768
[代替] ランダムなベクトルによる偽の表現を使用する。
ネットワークの問題でモデルをダウンロードできなかった場合、ウォークアラウンドとして、ランダムなベクトルを使ってテキストを表現することができます。ただ、そのベクトルは偽物なので、検索結果に意味的類似性が反映されないことに注意してください。
import random
# Text strings to search from.
docs = [
"Artificial intelligence was founded as an academic discipline in 1956.",
"Alan Turing was the first person to conduct substantial research in AI.",
"Born in Maida Vale, London, Turing was raised in southern England.",
]
# Use fake representation with random vectors (768 dimension).
vectors = [[random.uniform(-1, 1) for _ in range(768)] for _ in docs]
data = [
{"id": i, "vector": vectors[i], "text": docs[i], "subject": "history"}
for i in range(len(vectors))
]
print("Data has", len(data), "entities, each with fields: ", data[0].keys())
print("Vector dim:", len(data[0]["vector"]))
Data has 3 entities, each with fields: dict_keys(['id', 'vector', 'text', 'subject'])
Vector dim: 768
データの挿入
データをコレクションに挿入してみましょう:
res = client.insert(collection_name="demo_collection", data=data)
print(res)
{'insert_count': 3, 'ids': [0, 1, 2], 'cost': 0}
セマンティック検索
検索クエリテキストをベクトルで表現し、milvus上でベクトルの類似性検索を行うことで、セマンティック検索を行うことができる。
ベクトル検索
Milvusは1つまたは複数のベクトル検索リクエストを同時に受け付ける。query_vectors変数の値はベクトルのリストであり、各ベクトルは浮動小数点数の配列である。
query_vectors = embedding_fn.encode_queries(["Who is Alan Turing?"])
# If you don't have the embedding function you can use a fake vector to finish the demo:
# query_vectors = [ [ random.uniform(-1, 1) for _ in range(768) ] ]
res = client.search(
collection_name="demo_collection", # target collection
data=query_vectors, # query vectors
limit=2, # number of returned entities
output_fields=["text", "subject"], # specifies fields to be returned
)
print(res)
data: ["[{'id': 2, 'distance': 0.5859944820404053, 'entity': {'text': 'Born in Maida Vale, London, Turing was raised in southern England.', 'subject': 'history'}}, {'id': 1, 'distance': 0.5118255615234375, 'entity': {'text': 'Alan Turing was the first person to conduct substantial research in AI.', 'subject': 'history'}}]"] , extra_info: {'cost': 0}
出力は結果のリストで、それぞれがベクトル検索クエリに対応します。各クエリには結果のリストが含まれ、各結果には、エンティティの主キー、クエリ・ベクタまでの距離、指定されたoutput_fields
を含むエンティティの詳細が含まれます。
メタデータフィルタリングによるベクトル検索
メタデータの値(Milvusでは "スカラー "フィールドと呼ばれ、スカラーはベクトル以外のデータを指す)を考慮しながらベクトル検索を行うこともできます。これは特定の条件を指定したフィルタ式で行います。次の例でsubject
フィールドを使った検索とフィルタの方法を見てみよう。
# Insert more docs in another subject.
docs = [
"Machine learning has been used for drug design.",
"Computational synthesis with AI algorithms predicts molecular properties.",
"DDR1 is involved in cancers and fibrosis.",
]
vectors = embedding_fn.encode_documents(docs)
data = [
{"id": 3 + i, "vector": vectors[i], "text": docs[i], "subject": "biology"}
for i in range(len(vectors))
]
client.insert(collection_name="demo_collection", data=data)
# This will exclude any text in "history" subject despite close to the query vector.
res = client.search(
collection_name="demo_collection",
data=embedding_fn.encode_queries(["tell me AI related information"]),
filter="subject == 'biology'",
limit=2,
output_fields=["text", "subject"],
)
print(res)
data: ["[{'id': 4, 'distance': 0.27030569314956665, 'entity': {'text': 'Computational synthesis with AI algorithms predicts molecular properties.', 'subject': 'biology'}}, {'id': 3, 'distance': 0.16425910592079163, 'entity': {'text': 'Machine learning has been used for drug design.', 'subject': 'biology'}}]"] , extra_info: {'cost': 0}
デフォルトでは、スカラー・フィールドはインデックスされません。大規模なデータセットでメタデータ・フィルター検索を行う必要がある場合は、固定スキーマの使用を検討し、検索パフォーマンスを向上させるためにインデックスをオンにすることもできる。
ベクトル検索に加えて、他のタイプの検索を実行することもできます:
クエリー
query()は、フィルタ式やいくつかのIDに一致するなどの条件に一致するすべてのエンティティを検索する操作です。
たとえば、スカラ・フィールドが特定の値を持つすべてのエンティティを検索します:
res = client.query(
collection_name="demo_collection",
filter="subject == 'history'",
output_fields=["text", "subject"],
)
主キーによるエンティティの直接取得:
res = client.query(
collection_name="demo_collection",
ids=[0, 2],
output_fields=["vector", "text", "subject"],
)
エンティティの削除
データを消去したい場合は、主キーを指定してエンティティを削除したり、特定のフィルタ式に一致するエンティティをすべて削除したりできます。
# Delete entities by primary key
res = client.delete(collection_name="demo_collection", ids=[0, 2])
print(res)
# Delete entities by a filter expression
res = client.delete(
collection_name="demo_collection",
filter="subject == 'biology'",
)
print(res)
[0, 2]
[3, 4, 5]
既存データの読み込み
Milvus Liteの全データはローカルファイルに保存されているため、プログラム終了後でも、既存のファイルでMilvusClient
、全データをメモリにロードすることができます。例えば、"milvus_demo.db "ファイルからコレクションを復元し、引き続きデータを書き込むことができます。
from pymilvus import MilvusClient
client = MilvusClient("milvus_demo.db")
コレクションの削除
コレクション内のすべてのデータを削除したい場合、以下の方法でコレクションを削除できます。
# Drop collection
client.drop_collection(collection_name="demo_collection")
詳細
Milvus LiteはローカルのPythonプログラムで始めるには最適です。大規模なデータをお持ちの場合や、Milvusを本番環境で使用したい場合は、Dockerや Kubernetes上でのMilvusのデプロイについて学ぶことができます。Milvusのすべてのデプロイメントモードは同じAPIを共有しているため、他のデプロイメントモードに移行する場合でもクライアント側のコードを大きく変更する必要はありません。どこにでもデプロイされたMilvusサーバのURIとTokenを指定するだけです:
client = MilvusClient(uri="http://localhost:19530", token="root:Milvus")
MilvusはRESTとgRPC APIを提供し、Python、Java、Go、C#、Node.jsなどの言語でクライアントライブラリを提供しています。