Heroku Postgres での pgvector
最終更新日 2024年05月08日(水)
Table of Contents
Heroku Postgres の pgvector
拡張機能により、ベクトルデータタイプのサポートが追加されます。これにより、最近傍探索やコサイン距離などのベクトルを操作するための関数が追加されます。ベクトルは大規模言語モデルやその他の機械学習アプリケーションを使用する場合に重要となります。これらのモデルが生成する埋め込みは、ベクトル形式で出力されることが多いためです。
ユースケース
pgvector
を使用すると、次のことが可能になります。
- Retrieval Augmented Generation (RAG: 検索拡張生成) を実行する: 特定分野の最新の商品ドキュメントなど、インデックス付けされたドキュメントの意味的な性質を表すベクトル (埋め込み) をデータベースに取り込むことができます。クエリを渡すと、RAG は最も関連性の高い埋め込みとそれに対応するドキュメントを取得します。その後、これらを使用して、生成 AI のプロンプトの文脈を拡張します。これにより、AI は正確で文脈に関連する応答を生成できます。
- 商品をお勧めする: さまざまな属性を含むベクトルデータベースを使用すると、検索条件に基づいて代替品を簡単に検索できます。たとえば、ドレスやシャツなど、類似商品に基づいてお勧めしたり、スタイルと色をマッチングしてパンツや靴を提案したりできます。協調フィルタリングを使用してこれをさらに拡張できます。協調フィルタリングでは類似した好みを持つ他の買い物客の情報によりレコメンデーションの性能が向上します。
- Salesforce データを検索する: Heroku Connect を使用して Salesforce データを Heroku に同期します。Heroku Connect はベクトルデータタイプを同期できないため、埋め込みを使用してテーブルを作成します。たとえば、Service Cloud ケースの埋め込みを使用して類似のサポートケースを検索できます。
- マルチメディアを検索する: 画像、オーディオ、動画などのマルチメディアコンテンツを検索します。コンテンツを直接埋め込むことも、トランスクリプトやその他の属性を使用して検索を実行することもできます。たとえば、テンポ、気分、ジャンル、歌詞などの埋め込まれた特徴に基づいて類似する曲を検索して音楽プレイリストを生成できます。
- データを分類、セグメント化する: 医療や製造業などの業種では、データのセグメンテーションと分類はデータ分析を成功させる鍵となります。たとえば、患者の記録、診断データ、ゲノム配列をベクトルに変換することで、類似した症例を特定したり、希少疾患の診断や患者それぞれに合った治療のレコメンデーションに役立てたりできます。
- 異常の検出: 通常のパターンに当てはまらないベクトルを比較して、データ内の異常を検出します。この比較は、ネットワークトラフィックデータ、産業用センサーデータ、トランザクションデータ、オンライン動作などの領域で、問題のあるパターンや疑わしいパターンを分析したり、検出したりするのに役立ちます。
- 類似性検索を実行する: 入力クエリベクトルに基づいて、単純なベクトル類似性検索 (VSS) を実行します。通常、クエリ埋め込みはデータベースにロードされた埋め込みに対する検索に使用されますが、任意のベクトルデータも使用できます。
前提条件
- PostgreSQL 14 以降を実行している Essential-0、Essential-1、Essential-2 データベース、または PostgreSQL 15 以降を実行している Standard 層以上のデータベース がある。
- そのデータベースに Heroku ストリーミングデータコネクターが設定されていない。ベクトルデータタイプは同期されません。
プロビジョニング
pgvector
をインストールするには、データベースの psql
セッションで CREATE EXTENSION vector;
を実行します。
$ heroku pg:psql DATABASE_URL -a example-app
--> Connecting to postgresql-octagonal-12345
psql (13.2, server 11.12 (Ubuntu 11.12-1.pgdg16.04+1))
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.
example-app::DATABASE=> CREATE EXTENSION vector;
CREATE EXTENSION
example-app::DATABASE=>
インストールされているバージョンを確認するには、psql
で次のクエリを実行します。
=> SELECT extversion FROM pg_extension WHERE extname = 'vector';
extversion
------------
0.5.0
(1 row)
pgvector を使用する
ベクトル列を持つテーブルを作成できます。
CREATE TABLE animals(id serial PRIMARY KEY, name VARCHAR(100), embedding VECTOR(100));
この例では、embedding
ベクトル列を持つ animals
テーブルを作成しました。
テーブルを作成したら、ベクトルを挿入できます。
INSERT INTO animals(name, embedding) VALUES ('llama', '[-0.15647223591804504,
…
-0.7506130933761597, 0.1427040845155716]');
この例では、llama
を embedding
ベクトル列に挿入しました。
既存のテーブルにベクトル列を追加することもできます。
ALTER TABLE fruit ADD COLUMN embedding VECTOR(100);
この例では、ベクトル列を既存の fruit
テーブルに追加しました。
ベクトルクエリを実行する
以下の一般的なクエリ演算子を使用して、ベクトルデータに対してさまざまな操作を実行できます。
<->: ユークリッド距離
ユークリッド距離 (L2 距離) では、演算子はベクトル内の 2 つのポイント間の直線距離を測定します。この演算子は、クエリに代替アイテムまたは最も類似したアイテムを検索するのに最適です。
この例では、ユークリッド距離検索を使用して、animals
テーブル内のサメに似た動物を検索しています。
=> SELECT name FROM animals WHERE name != 'shark' ORDER BY embedding <-> (SELECT embedding FROM animals WHERE name = 'shark') LIMIT 5;
name
-----------
crocodile
dolphin
whale
turtle
alligator
(5 rows)
<#>: 負の内積
負の内積演算子は直交射影を測定します。これは、ベクトルが向いている方向が同じか逆か、およびベクトルの大きさを示します。内積が大きいほど、2 つのベクトル間の類似性が高いことを意味します。この演算子は、トピックが類似し、ベクトルの長さも類似するアイテムを検索するのに最適です。たとえば、画像識別では、サメの画像はサメの埋め込みに対して最も大きい内積を生成します。
<=>: コサイン距離
コサイン距離演算子は、2 つのベクトル間の角度のコサインを測定します。値の範囲は -1 から 1 で、1 に近いほどベクトル間の類似性が高いことを表します。この演算子は、大きさを省略したほうがよい類似性検索に最適です。たとえば、頻度が重要でない異常検出や、段落全体とドキュメントのセマンティクスに対するテキストベースの検索です。
パフォーマンス
ベクトルデータをデータベースに追加すればするほど、パフォーマンスの問題やクエリの実行速度の低下が発生する可能性があります。ベクトルデータは Postgres の他の列と同様にインデックス付けできます。pgvector
は、インデックス付けする方法をいくつか提供しています。以下に注意してください。
- インデックスを追加すると、
pgvector
は正確な最近傍探索ではなく近似最近傍探索を使用するように切り替わり、クエリ結果に違いが生じる可能性があります。 - インデックス付け関数は距離計算に基づいています。アプリケーションで最も使用しようとしている計算に基づいて関数を作成してください。
パフォーマンスを最適化するために、次のように設定できます。
max_parallel_workers_per_gather
は、インデックスを作成せずにクエリを高速化します。
SET max_parallel_workers_per_gather = 4;
max_parallel_maintenance_workers
は、並列ワーカーの数を増やすことで、大きなテーブルでのインデックス作成を高速化します。
SET max_parallel_maintenance_workers = 7;
現在の設定を確認するには、SHOW
コマンドを使用します。
=> SHOW max_parallel_workers_per_gather;
max_parallel_workers_per_gather
---------------------------------
1
(1 row)
ベクトルデータタイプのインデックス作成とパフォーマンス最適化に関するガイダンスについては、pgvector
のドキュメントを参照してください。
インデックス
pgvector
は、HNSW (Hierarchical Navigable Small Worlds) と IVFFlat (Inverted File with Flat Compression index) の 2 つのインデックスタイプをサポートしています。選択したインデックスタイプに応じて、速度、再現率、クエリ結果の品質、ビルド時間、リソース消費などの一般的なトレードオフが存在します。
pgvector
は正確な最近傍探索用に構成されているため、デフォルトのインデックスタイプはインデックスなしです。このデフォルト設定により、速度を犠牲にして完全な再現率を可能にします。HNSW または IVFFlat インデックスを追加すると、近似最近傍 (ANN) 探索を実行できます。
HNSW
HNSW は、ほとんどのユースケースで IVFFlat よりもパフォーマンスが優れており、ANN 探索に推奨されるインデックスタイプです。ただし、HNSW インデックスはビルドに時間がかかり、メモリを多く消費します。このアルゴリズムは、検索結果を高速で取得できるようにする多層グラフを構築します。インデックスはテーブルにデータを挿入するのと同時に作成されるため、データがなくてもインデックスを作成できます。
IVFFlat
IVFFlat インデックスを使用すると、高次元埋め込みに対する検索を含む ANN 探索のパフォーマンスを向上させることができます。IVFFlat は既存のベクトルに依存するため、再現率を向上させるには、テーブルにデータを追加した後にインデックスを作成するのが最適です。データ分布が大幅に変化した場合は、インデックスを再作成します。IVFFlat インデックスは HNSW よりもビルド時間が短く、メモリ使用量も少なくなりますが、クエリのパフォーマンスは低くなります。