CLOVER🍀

That was when it all began.

Ubuntu Linux 22.04 LTSにベクトルデヌタベヌスQdrantをむンストヌルしお詊す

これは、なにをしたくお曞いたもの

前に少し、ベクトルデヌタベヌスにはどのようなものがあるのか調べおみたした。

ベクトルデータベースってどういうものがある? - CLOVER🍀

そろそろ、この䞭からなにか遞んで、ベクトルデヌタベヌスずいうものを詊しおみようかなず思いたしお。

Qdrantを詊しおみるこずにしたした。

Qdrant

QdrantのWebサむトはこちら。

Qdrant - Vector Database

GitHubリポゞトリヌはこちら。

GitHub - qdrant/qdrant: Qdrant - High-performance, massive-scale Vector Database for the next generation of AI. Also available in the cloud https://cloud.qdrant.io/

Webサむトのトップペヌゞによるず、特城は以䞋のようです。

  • OpenAPI 3仕様に沿ったドキュメントを提䟛し、倚くのプログラミング蚀語に察するクラむアントを䜜成可胜
  • ANN SearchApproximate Nearest Neighbor SearchのためのHNSWアルゎリズムを独自にカスタム実装
  • ベクトルに関連付けられたペむロヌドの远加をサポヌトし、ペむロヌドを保存するだけではなくペむロヌドの倀に基づいお結果をフィルタリングするこずも可胜
  • 文字列䞀臎、数倀範囲、地理的䜍眮などを含む、様々なデヌタ型ずク゚リヌをサポヌト
  • 分散型で、氎平スケヌリングが可胜
  • Rustで実装されおおり、リ゜ヌスを有効掻甚できる

Qdrantを䜿った怜玢をどのような分野で䜿うずよさそうなのかは、こちらのペヌゞを芋るのがよいでしょう。

Vector Search Solutions - Qdrant

類䌌画像怜玢、セマンティックテキスト怜玢、レコメンデヌション、チャットボット、マッチング゚ンゞン、異垞怜知などが
挙げられおいたす。

ドキュメントはこちらです。

Qdrant Documentation - Qdrant

最初に読むのはこちらのペヌゞでしょうか。

What is Qdrant? - Qdrant

ざっくり芋おみたしょう。

  • Qdrantは、ペむロヌドの远加ず保存、怜玢、管理に䟿利なAPIを提䟛するプロダクションレディなベクトル類䌌性怜玢゚ンゞン
  • ベクトルデヌタベヌスは、高次元ベクトルを効率的に保存、ク゚リヌできるように蚭蚈されたデヌタベヌスの䞀皮
    • ベクトルデヌタベヌスでは、ベクトルにIDずペむロヌドを加えたものを収集する
    • ここでいう「ベクトル」ずはオブゞェクトたたはデヌタポむントの数孊的衚珟を衚す
  • ベクトルデヌタベヌスでは、距離メトリクスに基づいおのク゚リヌベクトルに最も近いベクトルを芋぀けるこずで、高速な類䌌性怜玢ずセマンティック怜玢が行えるようになる
    • 䞀般的に䜿甚される距離メトリクスは、ナヌクリッド距離、コサむン類䌌床、ドット積の3぀であり、Qdrantではすべおサポヌトしおいる
      • コサむン類䌌床 
 2぀のものがどれだけ䌌おいるか枬定する方法距離ではないで、2぀の文曞たたは文が互いにどれだけ䌌おいるかを比范するためによく利甚される
      • ドット積 
 2぀のものがどれだ䌌おいるか枬定する方法で、機械孊習やデヌタサむ゚ンスで数倀を扱う時によく利甚される。2セットの数倀がどれだけ䞀臎しおいるかを瀺すもの
      • ナヌクリッド距離 
 地図䞊の2぀の堎所の距離を枬定する方法で、2぀のデヌタポむントがどの皋床類䌌しおいるか、もしくは異なっおいるかを枬定するこずに、䞻に機械孊習で利甚される
  • Qdrantの䞻な抂念
    • コレクション 
 怜玢できる名前付きのポむントペむロヌドを含むベクトルの集合
    • 距離メトリクス 
 ベクトル間の類䌌性を枬るのに䜿甚され、コレクションの䜜成時に指定する
    • ポむント 
 Qdrantが操䜜する䞭心的な゚ンティティであり、ベクトルずオプションのidおよびペむロヌドで構成される
      • Points - Qdrant
      • id 
 ベクトルの䞀意の識別子
      • ベクトル 
 画像、音、ドキュメント、ビデオなどのデヌタの高次元衚珟
      • ペむロヌド 
 ベクトルに远加できるJSONオブゞェクト
    • ストレヌゞ 
 Qdrantのデヌタの保存先で、メモリずディスクから遞択
    • クラむアント 
 Qdrantぞの接続に䜿甚できるプログラミング蚀語

RDBMSでいうテヌブルがコレクションで、レコヌドがポむント、ずいう感じでしょうか。ク゚リヌの戊略はコレクションの䜜成時に
決たるものみたいですね。

ベクトル怜玢の基本は、こちら。

Vector Search Basics - Qdrant

ここは、次回たた芋たいず思いたす。

Qdrantのむンストヌル方法は、Docker、Kubernetes、Qdrant Cloud、゜ヌスコヌドのビルドが玹介されおいたす。

Installation - Qdrant

たた、蚘茉はありたせんが、ビルド枈みのバむナリをダりンロヌドしおも良さそうです。

Releases · qdrant/qdrant · GitHub

今回は、ずりあえずビルド枈みのバむナリをダりンロヌドしお動かしおみたいず思いたす。

なぜQdrantか

Qdrantを䜿う前に、ベクトルデヌタベヌスを䜿っおみるにあたり、どうしおQdrantを遞んだのかを曞いおおきたしょう。

ベクトルデヌタベヌスに興味を持ったのはLLMの文脈でよく登堎するからず、最終的にはRAGなども詊しおみたいからです。
この時、ハむブリッド怜玢などもやっおみたいので、最終的にはElasticsearchのような党文怜玢ずベクトル怜玢の䞡方ができる
デヌタストアを遞ぶかもしれたせん。

ずいう䞀方で、ベクトルデヌタベヌスに特化しおいるQdrantを遞んだのは以䞋の理由です。

  • ベクトルデヌタベヌスずいう知らない抂念を孊ぶのであれば、その分野に特化したプロダクトのドキュメントなどの方が情報が倚く、深い
  • 手元で動かしたいので、SaaSではなくセルフホスティング可胜なものがよい
  • 最終的にはPython以倖からも䜿いたいので、組み蟌みモヌドのみをサポヌトしおいるプロダクトは避けたいクラむアントサヌバヌ圢態が利甚できお欲しい

ハむブリッドなデヌタストアよりもベクトルデヌタベヌス専甚のものを遞んでいるのは、ドキュメントなどを芋るこずによる
ベクトルデヌタベヌスそのものに察する理解を期埅しおいたす。

このあたりの条件でベクトルデヌタベヌスを眺めおいき、よさそうだったのがQdrantだったずいうこずです。

珟時点ではたずはベクトルデヌタベヌスを1皮孊んでみたらいいかなず思っおいるので、他のベクトルデヌタベヌスに特化した
デヌタストアを扱う予定はありたせんが、実際どうなるかはQdrantを觊っおみおどれくらい興味を持぀かですね。

Qdrantは分散構成にできそうなずころにも興味がありたすが、そちらたで手を出すかはただわかりたせん。

環境

今回の環境はこちら。Ubuntu Linux 22.04 LTSです。

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 22.04.3 LTS
Release:        22.04
Codename:       jammy


$ uname -srvmpio
Linux 5.15.0-92-generic #102-Ubuntu SMP Wed Jan 10 09:33:48 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux

Qdrantにアクセスする際にしようするPython。

$ python3 --version
Python 3.10.12


$ pip3 --version
pip 22.0.2 from /usr/lib/python3/dist-packages/pip (python 3.10)

Qdrantをむンストヌルする

それでは、Qdrantをむンストヌルしたす。

こちらから最新のリリヌスをダりンロヌドしたす。

Releases · qdrant/qdrant · GitHub

$ curl -OL https://github.com/qdrant/qdrant/releases/download/v1.7.3/qdrant-x86_64-unknown-linux-gnu.tar.gz

展開。

$ tar xvf qdrant-x86_64-unknown-linux-gnu.tar.gz
qdrant

シングルバむナリのようです。

バヌゞョン。

$ ./qdrant --version
qdrant 1.7.3

起動。

$ ./qdrant
           _                 _
  __ _  __| |_ __ __ _ _ __ | |_
 / _` |/ _` | '__/ _` | '_ \| __|
| (_| | (_| | | | (_| | | | | |_
 \__, |\__,_|_|  \__,_|_| |_|\__|
    |_|

Access web UI at http://0.0.0.0:6333/dashboard

2024-01-25T14:41:08.535870Z  WARN qdrant::settings: Config file not found: config/config
2024-01-25T14:41:08.535964Z  WARN qdrant::settings: Config file not found: config/development
2024-01-25T14:41:08.536773Z  INFO storage::content_manager::consensus::persistent: Loading raft state from ./storage/raft_state.json
2024-01-25T14:41:08.614482Z  INFO qdrant: Distributed mode disabled
2024-01-25T14:41:08.614537Z  INFO qdrant: Telemetry reporting enabled, id: 515698cc-9357-487f-b0d2-c5732767837f
2024-01-25T14:41:08.619827Z  INFO qdrant::tonic: Qdrant gRPC listening on 6334
2024-01-25T14:41:08.619867Z  INFO qdrant::tonic: TLS disabled for gRPC API
2024-01-25T14:41:08.620446Z  WARN qdrant::actix: Static content folder for Web UI './static' does not exist
2024-01-25T14:41:08.621420Z  INFO qdrant::actix: TLS disabled for REST API
2024-01-25T14:41:08.621484Z  INFO qdrant::actix: Qdrant HTTP listening on 6333
2024-01-25T14:41:08.621500Z  INFO actix_server::builder: Starting 1 workers
2024-01-25T14:41:08.621517Z  INFO actix_server::server: Actix runtime found; starting in Actix runtime

起動がずおも速いです。

Qdrantが䜿甚するポヌトはこちらに蚘茉がありたす。

Quickstart - Qdrant

http://localhost:6333REST API、http://localhost:6333/dashboardWeb UI、http://localhost:6334GRPC APIの3぀のようです。

なお、このバむナリにはWeb UIは含たれおいないようです。Dockerむメヌゞには含たれおいたした。

Dockerfileを芋おみるず、別リポゞトリヌにあるようですね。

qdrant/Dockerfile at v1.7.3 · qdrant/qdrant · GitHub

https://github.com/qdrant/qdrant/blob/v1.7.3/tools/sync-web-ui.sh

こちらです。

GitHub - qdrant/qdrant-web-ui: Self-hosted web UI for Qdrant

远加したしょう。

ダりンロヌドしお展開。

$ curl -LO https://github.com/qdrant/qdrant-web-ui/releases/download/v0.1.20/dist-qdrant.zip
$ unzip dist-qdrant.zip

展開埌はdistディレクトリが珟れたす。こういうディレクトリ構造になっおいお

$ tree dist -d
dist
└── assets

1 directory

assets配䞋にはJavaScriptやCSSが入っおいたす。

dist盎䞋はこんな感じですね。

$ ll dist
total 1100
drwxr-xr-x 3 xxxxx xxxxx   4096 Dec  7 16:31 ./
drwxr-x--- 7 xxxxx xxxxx   4096 Jan 28 08:50 ../
drwxr-xr-x 2 xxxxx xxxxx   4096 Dec  7 16:31 assets/
-rw-r--r-- 1 xxxxx xxxxx  15086 Dec  7 16:31 favicon.ico
-rw-r--r-- 1 xxxxx xxxxx   1781 Dec  7 16:31 index.html
-rw-r--r-- 1 xxxxx xxxxx   8870 Dec  7 16:31 logo192.png
-rw-r--r-- 1 xxxxx xxxxx  28384 Dec  7 16:31 logo512.png
-rw-r--r-- 1 xxxxx xxxxx   9339 Dec  7 16:31 logo.png
-rw-r--r-- 1 xxxxx xxxxx    484 Dec  7 16:31 manifest.json
-rw-r--r-- 1 xxxxx xxxxx 239641 Dec  7 16:31 openapi.json
-rw-r--r-- 1 xxxxx xxxxx 789035 Dec  7 16:31 qdrant-web-ui.spdx.json
-rw-r--r-- 1 xxxxx xxxxx     67 Dec  7 16:31 robots.txt

Qdrantのスクリプトを芋るず、このdistディレクトリの䞭身をstaticずいうディレクトリに入れればいいみたいです。

$ mkdir static
$ mv dist/* static/

Qdrantを起動。

$ ./qdrant

http://[Qdrantが起動しおいるホスト]:6333/dashboardにアクセスするず、Web UIが珟れたす。

これで、Qdrantサヌバヌは起動できたした。

QdrantのQuickstartを詊す

では、Qdrantを䜿っおみたしょう。

今回はQuickstartに沿っお䜿っおみたいず思いたす。

Quickstart - Qdrant

Quickstartで䜿われおいるのはPython、TypeScript、Rust、Javaですが、今回はPythonを䜿いたす。

むンストヌル方法は曞かれおいないので、PythonのQdrantクラむアントのGitHubリポゞトリを確認

GitHub - qdrant/qdrant-client: Python client for Qdrant vector search engine

QdrantのOpenAPI定矩に埓っおREST APIを呌び出すクラむアントのようです。

ReDoc

むンストヌル。

$ pip3 install qdrant-client

バヌゞョン。

$ pip3 list
Package           Version
----------------- ----------
annotated-types   0.6.0
anyio             4.2.0
certifi           2023.11.17
exceptiongroup    1.2.0
grpcio            1.60.0
grpcio-tools      1.60.0
h11               0.14.0
h2                4.1.0
hpack             4.0.0
httpcore          1.0.2
httpx             0.26.0
hyperframe        6.0.1
idna              3.6
numpy             1.26.3
pip               22.0.2
portalocker       2.8.2
protobuf          4.25.2
pydantic          2.5.3
pydantic_core     2.14.6
qdrant-client     1.7.1
setuptools        59.6.0
sniffio           1.3.0
typing_extensions 4.9.0
urllib3           2.1.0

Python Qdrant Clientqdrant-clientは1.7.1です。

ちなみに、qdrant-clientにはQdrantサヌバヌなしで動䜜するロヌカルモヌドずいう機胜もあるみたいです。

Python Qdrant Client / Local mode

QdrantクラむアントからQdrantサヌバヌぞの接続は、以䞋の蚘述で行うようです。

from qdrant_client import QdrantClient

client = QdrantClient(host="localhost", port=6333)

たずはコレクションを䜜成しおみたす。コレクションはベクトルデヌタポむントを保存するものでした。

``create_collection.py

from qdrant_client import QdrantClient
from qdrant_client.http.models import Distance, VectorParams

client = QdrantClient(host="localhost", port=6333)

client.create_collection(
    collection_name="test_collection",
    vectors_config=VectorParams(size=4, distance=Distance.DOT)
)

コレクション名、ベクトルのサむズ次元数ず距離メトリクスを指定しおいたす。距離メトリクスはドット積ですね。

collections / Create collection

実行。

$ python3 create_collection.py

Web UIを芋るず、コレクションが䜜成できたこずが確認できたす。

ちなみに、同じコヌドを2回実行するず゚ラヌになりたすね。

$ python3 create_collection.py
Traceback (most recent call last):
  File "/path/to/create_collection.py", line 6, in <module>
    client.create_collection(
  File "/path/to/venv/lib/python3.10/site-packages/qdrant_client/qdrant_client.py", line 1669, in create_collection
    return self._client.create_collection(
  File "/path/to/venv/lib/python3.10/site-packages/qdrant_client/qdrant_remote.py", line 2161, in create_collection
    result: Optional[bool] = self.http.collections_api.create_collection(
  File "/path/to/venv/lib/python3.10/site-packages/qdrant_client/http/api/collections_api.py", line 1118, in create_collection
    return self._build_for_create_collection(
  File "/path/to/venv/lib/python3.10/site-packages/qdrant_client/http/api/collections_api.py", line 96, in _build_for_create_collection
    return self.api_client.request(
  File "/path/to/venv/lib/python3.10/site-packages/qdrant_client/http/api_client.py", line 74, in request
    return self.send(request, type_)
  File "/path/to/venv/lib/python3.10/site-packages/qdrant_client/http/api_client.py", line 97, in send
    raise UnexpectedResponse.for_response(response)
qdrant_client.http.exceptions.UnexpectedResponse: Unexpected Response: 400 (Bad Request)
Raw response content:
b'{"status":{"error":"Wrong input: Collection `test_collection` already exists!"},"time":0.00003701}'

ベクトルを登録したす。Quickstartで䜿っおいるのは、upsertずいうすでにポむントが存圚しおいれば䞊曞きするものです。

points / Upsert points

ポむントずいうのは、Qdrantが操䜜する䞭心的な゚ンティティであり、ベクトルずオプションのidおよびペむロヌドで構成される、
ずいうものでした。

゜ヌスコヌドはこちら。

add_vectors.py

from qdrant_client import QdrantClient
from qdrant_client.http.models import PointStruct

client = QdrantClient(host="localhost", port=6333)

operation_info = client.upsert(
    collection_name="test_collection",
    wait=True,
    points=[
        PointStruct(id=1, vector=[0.05, 0.61, 0.76, 0.74], payload={"city": "Berlin"}),
        PointStruct(id=2, vector=[0.19, 0.81, 0.75, 0.11], payload={"city": "London"}),
        PointStruct(id=3, vector=[0.36, 0.55, 0.47, 0.94], payload={"city": "Moscow"}),
        PointStruct(id=4, vector=[0.18, 0.01, 0.85, 0.80], payload={"city": "New York"}),
        PointStruct(id=5, vector=[0.24, 0.18, 0.22, 0.44], payload={"city": "Beijing"}),
        PointStruct(id=6, vector=[0.35, 0.08, 0.11, 0.44], payload={"city": "Mumbai"}),
    ]
)

print(operation_info)

远加するベクトルは、コレクションに指定したように4次元ですね。最埌に実行結果を出力しおいたす。

waitにしおいるので、倉曎内容が実際に適甚されるたで埅぀ようになりたす。

実行。

$ python3 add_vectors.py
operation_id=0 status=<UpdateStatus.COMPLETED: 'completed'>

Web UIでの確認。

次は怜玢しおみたす。

points / Search points

run_query.py

from qdrant_client import QdrantClient

client = QdrantClient(host="localhost", port=6333)

search_results = client.search(
    collection_name="test_collection",
    query_vector=[0.2, 0.1, 0.9, 0.7],
    limit=3
)

for result in search_results:
    print(result)

結果はScoredPointずいうクラスのリストずしお返っおくるようです。

実行。

$ python3 run_query.py
id=4 version=0 score=1.362 payload={'city': 'New York'} vector=None shard_key=None
id=1 version=0 score=1.273 payload={'city': 'Berlin'} vector=None shard_key=None
id=3 version=0 score=1.208 payload={'city': 'Moscow'} vector=None shard_key=None

コレクションに指定しおいる距離メトリクスがドット積なので、怜玢条件に指定したベクトルに「䌌おいる」ものの䞊䜍3件䌌おいるものの
降順が取埗できた、ずいうこずになっおいるようです。

デフォルトではペむロヌドおよびベクトルは結果に含たれないようですペむロヌドは返っおきおいたすが 。

最埌に、怜玢時にペむロヌドにフィルタヌを加えお結果を絞り蟌みたす。

add_filter.py

from qdrant_client import QdrantClient
from qdrant_client.http.models import FieldCondition, Filter, MatchValue

client = QdrantClient(host="localhost", port=6333)


search_results = client.search(
    collection_name="test_collection",
    query_vector=[0.2, 0.1, 0.9, 0.7],
    query_filter=Filter(
        must=[FieldCondition(key="city", match=MatchValue(value="London"))]
    ),
    with_payload=True,
    limit=3
)

for result in search_results:
    print(result)

cityキヌの倀にLongonを含むものに絞り蟌んでいたす。

実行。

$ python3 add_filter.py
id=2 version=0 score=0.871 payload={'city': 'London'} vector=None shard_key=None

実際にフィルタヌを䜿う時は、ペむロヌドにむンデックスを䜜成するこずを掚奚しおいるようです。

To make filtered search fast on real datasets, we highly recommend to create payload indexes!

ここたでで、Quickstartの内容は終わりです。

おわりに

たずはQuickstartをなぞっただけですが、少し雰囲気はわかった気がしたす。

ここから少しず぀ベクトルデヌタベヌスに慣れおいければいいかなず思いたす。