MariaDB でのベクトルストレージ、インデックス付け、および検索

Generative AIアプリケーションを開発する際には、通常、インフラストラクチャに3つの追加コンポーネントを導入します:エンベッダー、LLM、およびベクトルデータベース。

ただし、MariaDBを使用している場合、独自のSQL方言やそれ以上に悪い独自のAPIを持つ追加のデータベースを導入する必要はありません。MariaDBバージョン11.7(およびMariaDB Enterprise Server 11.4)以降、埋め込み(またはベクトル)を単に任意のテーブルの任意の列に格納するだけで済みます。アプリケーションをデータベースのポリグロットにする必要はありません。

「MariaDB Serverでベクトル検索のプレビューを発表した後、ベクトル検索機能がMariaDB Community Server 11.7リリースに追加されました」と、MariaDBのProduct ManagerであるRalf Gebhardtは述べています。これには新しいデータ型(VECTOR)、ベクトルインデックス、およびベクトル操作用の一連の関数が含まれます。

生成AIアプリケーションでベクトルが必要な理由は何ですか?

ベクトルは、複雑な意味をコンパクトで固定長の数値配列(ベクトル)に埋め込むために生成AIアプリケーションで必要です。これは、リトリーバル拡張生成(またはRAG)のコンテキストではより明確です。この技術により、ソース(API、ファイル、データベース)から関連データを取得して、通常は事業に固有のデータを取得してAIモデルの入力を強化することができます。

データソースが広範囲であるため、現在のAIモデルには有限のコンテキストウィンドウがあるため、すべてのデータをプロンプトに単純に追加することはできません。データのチャンクを作成し、これらのデータのチャンクを特別なAIモデルである埋め込み器を通して実行することで、ベクトルを生成し、近接検索技術を使用してプロンプトに追加するための関連情報を見つけることができます。

たとえば、推薦チャットボットのユーザーからの次の入力を取り上げてみましょう。

Plain Text

 

AIモデルがオンラインストアの製品情報を含む正確なデータでトレーニングされていないため、ユーザーへのプロンプトを送信する前に最も関連のある製品とその情報を取得する必要があります。

そのため、ユーザーからの元の入力を埋め込み器に送信し、後で最も近い、たとえば10個の製品をユーザー入力に送信できるベクトルを取得します。この情報を取得した後(後でMariaDBでどのように行うかを見ていきます)、強化されたプロンプトをAIモデルに送信できます。

Plain Text

 

これにより、AI予測が自分のデータを使用するようになります。

ベクトルストレージ用のテーブルの作成

MariaDBでベクトルを保存するには、新しいVECTORデータ型を使用します。例:

MariaDB SQL

 

CREATE TABLE products (
    id INT PRIMARY KEY,
    name VARCHAR(100),
    description TEXT,
    embedding VECTOR(2048)
);

この例では、embedding列には2048次元のベクトルを保持できます。埋め込み機能で生成される次元数に一致させる必要があります。

ベクトルインデックスの作成

読み取りパフォーマンスを向上させるために、ベクトル列にインデックスを追加することが重要です。これにより類似検索が高速化されます。次のようにテーブル作成時にインデックスを定義できます:

MariaDB SQL

 

CREATE TABLE products (
    id INT PRIMARY KEY,
    name VARCHAR(100),
    description TEXT,
    embedding VECTOR(2048) NOT NULL,
    VECTOR INDEX (embedding)
);

より細かい制御をするために、データベースサーバーがインデックスを構築する際に使用する距離関数や、MariaDBが使用するM Hierarchical Navigable Small Worlds(HNSW)アルゴリズムを指定することもできます。例:

MariaDB SQL

 

CREATE TABLE products (
    id INT PRIMARY KEY,
    name VARCHAR(100),
    description TEXT,
    embedding VECTOR(2048) NOT NULL,
    VECTOR INDEX (embedding) M=8 DISTANCE=cosine
);

これらの構成に関する詳細については、ドキュメントを確認してください。

ベクトルの挿入

データ(テキスト、画像、音声)を埋め込み機能を通じて渡すと、ベクトルが取得されます。一般的に、これはJSON形式の配列内の数値の系列です。MariaDBテーブルにこのベクトルを挿入するには、VEC_FromText関数を使用できます。例:

MariaDB SQL

 

INSERT INTO products (name, embedding)
VALUES
  ("Alarm clock", VEC_FromText("[0.001, 0, ...]")),
  ("Cow figure", VEC_FromText("[1.0, 0.05, ...]")),
  ("Bicycle", VEC_FromText("[0.2, 0.156, ...]"));

挿入されるベクトルは、CREATE TABLEステートメントで定義された次元数と一致している必要があります。

類似性検索(ベクトルの比較)

RAGアプリケーションでは、ユーザー入力をエンベッダーに送信してベクトルを取得します。その後、そのベクトルに近いデータベース内のレコードをクエリできます。近いベクトルは意味的に類似したデータを表します。この記事執筆時点で、MariaDBには類似性や近接検索に使用できる2つの距離関数があります:

  • VEC_DISTANCE_EUCLIDEAN:2つのベクトル間の直線距離を計算します。生の非正規化データから派生したベクトルや、空間的な分離が類似性と直接関連するシナリオ(位置情報や数値特徴の比較など)に最適です。ただし、高次元または正規化されたエンベディングには効果が薄く、ベクトルの大きさの違いに敏感です。
  • VEC_DISTANCE_COSINE:ベクトル間の角度の違いを測定します。特にテキストや文書検索などの意味的アプリケーションにおいて、正規化されたエンベディングの比較に適しています。意味や文脈の類似性を捉えるのに優れています。

前述の関数を使用した類似性検索はあくまで近似であり、計算されたベクトルの品質、したがって使用されたエンベッダーの品質に大きく依存することを忘れないでください。

次の例では、与えられたベクトルに最も類似した上位10製品を見つけます($user_input_vectorは、ユーザー入力に対してエンベッダーから返された実際のベクトルに置き換える必要があります):

MariaDB SQL

 

SELECT id, name, description
FROM products
ORDER BY VEC_DISTANCE_COSINE(
  VEC_FromText($user_input_vector),
  embedding
)
LIMIT 10;

VEC_DISTANCE_COSINE および VEC_DISTANCE_EUCLIDEAN 関数は、2 つのベクトルを取ります。前述の例では、1 つのベクトルはユーザー入力に基づいて計算されたベクトルであり、もう 1 つは products テーブル内の各レコードに対応するベクトルです。

A Practical Example

Java を使用して AI フレームワークを使用せずに、MariaDB のベクトル検索機能を活用して生成的 AI アプリケーションを作成するプロセスを理解できるように、実践例を用意しました。コードは GitHub で見つけることができます。

Source:
https://dzone.com/articles/vector-storage-indexing-and-search-with-mariadb