大規模なテーブルの自動ベクトル エンベディングを生成および管理する

テーブル列全体のベクトル エンベディングを生成および管理できるため、大規模なベクトル エンベディングの作成に対応したスケーラブルなソリューションが実現します。このソリューションは、次のようなテキスト コンテンツに対するセマンティック検索と検索拡張生成(RAG)を容易にする場合に特に役立ちます。

  • 新しいテーブルの初期ベクトル エンベディングを作成する
  • 大規模なデータ インポート後にエンベディングを生成する
  • 大幅なデータ変更後にエンベディングを更新する
  • エンベディングを増分的にメンテナンスする

自動ベクトル エンベディングについて

AlloyDB の自動ベクトル エンベディングは、データのベクトル エンベディングの生成とメンテナンスを自動化するスケーラブルな方法を提供します。自動ベクトル エンベディングを構成することで、新しいテキストや更新されたテキストごとにエンベディングを手動で生成する必要がなくなり、そのようなプロセスが自動化されます。これは、セマンティック検索、検索拡張生成(RAG)、その他の AI 搭載機能で最新のエンベディングを使用するアプリケーションで特に役立ちます。

自動ベクトル エンベディングを使用すると、次のことが可能になります。

  • テーブル全体のエンベディングを初期化する: 単一のコマンドで、テーブル列内の既存のすべてのデータのエンベディングを生成できます。
  • エンベディングの同期を維持する: ソースデータが変更されたときにエンベディングを自動的に更新し、AI アプリケーションが常に最新の情報を使用できるようにします。
  • エンベディングを大規模に生成する: 数百万行に及ぶ大規模なテーブルのエンベディングを効率的に作成できます。
  • 各エンベディング列の管理機能を呼び出して、同じテーブル内の複数の列のエンベディングを構成して管理できます。

この機能により、ベクトル エンベディングの作成とメンテナンスの複雑さが抽象化され、AI アプリケーションの開発とメンテナンスが簡素化されます。

始める前に

大規模なテーブルのベクトル エンベディングを生成して管理する前に、次の操作を行います。

  • psql または AlloyDB for PostgreSQL Studio を使用して postgres ユーザーとしてデータベースに接続します。
  • google_ml_integration 拡張機能がインストールされていることを確認します
  • google_ml_integration.enable_model_support フラグが on に設定されていることを確認します。
  • google_ml_integration 拡張機能のバージョンが 1.5.2 以降であり、google_ml_integration.enable_faster_embedding_generation フラグが on に設定されていることを確認します。

    拡張機能のバージョンを確認するには、次のコマンドを使用します。

    SELECT extversion FROM pg_extension WHERE extname = 'google_ml_integration';
    

    拡張機能を更新する必要がある場合は、ALTER EXTENSION google_ml_integration UPDATE; コマンドを使用します。

  • AlloyDB データベースからエンベディングを生成するには、Vertex AI と連携するように AlloyDB を構成する必要があります。詳細については、データベースを Vertex AI と統合するをご覧ください。

  • 自動エンベディング生成を管理およびモニタリングするために、ユーザーはデフォルトで google_ml.embed_gen_progress テーブルと google_ml.embed_gen_settings テーブルに対する Select アクセス権を持っています。

    ユーザーが自動エンベディング生成を管理できるようにするには、google_ml.embed_gen_progress テーブルと google_ml.embed_gen_settings テーブルに対する INSERTUPDATEDELETE の各権限を付与します。

    GRANT INSERT, UPDATE, DELETE ON google_ml.embed_gen_progress TO 'USER_NAME';
    

    次のように置き換えます。

    • USER_NAME: 権限が付与されるユーザーの名前。
  • 使用する PostgreSQL クライアントで AUTOCOMMITON に設定されていることを確認します。

  • 使用するエンベディング モデルに自動ベクトル エンベディングに対して十分な割り当てがあることを確認します。割り当てが不足していると、自動エンベディング オペレーションが遅くなったり、失敗したりする可能性があります。たとえば、Vertex AI エンベディング モデルの上限は次のとおりです。

    • テキスト エンベディングの上限: 各リクエストには、最大 250 個の入力テキスト(入力テキストごとに 1 つのエンベディングを生成)と、リクエストごとに 20,000 個のトークンを指定できます。エンベディングの計算には、各入力テキストの最初の 2,048 トークンのみが使用されます。
    • 1 分あたりのリクエスト数:

      • base_model : text-embedding : 1500
      • base_model : gemini-embedding : 100000
    • Gemini エンベディング モデルのトークン上限: 他のエンベディング モデルは主に RPM 割り当てによって制限されていましたが、Gemini エンベディング モデル シリーズは、プロジェクトごとに 1 分あたり 5,000,000 個のトークンに制限されています。

テーブルのエンベディングを初期化する

自動ベクトル エンベディングを管理する関数は、ai スキーマで使用できます。このスキーマは、AlloyDB の最新の AI 機能のインターフェースを提供します。

テーブルのコンテンツ列のエンベディングを生成するには、ai.initialize_embeddings() SQL 関数を使用します。これはブロッキング呼び出しです。

  • 関数が成功を返すと、ベクトル エンベディングの作成が完了します。
  • この関数は、モデルの割り当てエラーなどの一時的な問題から自動的に復元を試みます。復元を試みても失敗した場合にのみ、エラーが返されます。batch_size の構成ミスによってリクエストがサイズ上限を超えるような永続的な問題が発生した場合や、オペレーションが手動でキャンセルされた場合は、呼び出しを手動で再発行する必要があります。

この関数は、Google が提供するモデル(Vertex AI の text-embedding-005 など)と、登録済みのスタムモデルをサポートします。

エンベディングを生成する前に、テーブルに content_embeddings 列を作成します。この列は通常は vector(DIMENSION) 型で、DEFAULT NULL 値を持ちます。

ALTER TABLE user_reviews ADD COLUMN IF NOT EXISTS content_embeddings vector(768) DEFAULT NULL;

バッチ生成を実行する

デフォルトでは、AlloyDB はバッチ処理を使用し、複数のテキスト入力に対して 1 つのリクエストでエンベディングを生成することで、効率を向上させます。バッチサイズを明示的に指定しない場合、AlloyDB は自動的に決定されたデフォルト値を適用します。

ヒントのバッチサイズ

ai.initialize_embeddingsbatch_size パラメータを使用すると、直接サポートされているモデルに対して推奨されるバッチサイズを提案することで、AlloyDB のクエリ オプティマイザーを誘導できます。AlloyDB は、モデルの上限または割り当てに基づいてこのサイズを動的に削減する場合がありますが、ヒントはクエリ実行プランに影響します。

CALL ai.initialize_embeddings(
    model_id => 'text-embedding-005',
    table_name => 'user_reviews',
    content_column => 'content',
    embedding_column => 'content_embeddings',
    batch_size => 50
);

バッチ処理をサポートするカスタム エンベディング モデルを使用する

バッチ処理をサポートするカスタムモデルまたは外部でサポートされているモデルを使用する場合は、バッチ変換関数を定義し、モデルの作成時に model_batch_in_transform_fn および model_batch_out_transform_fn として指定します。また、initialize_embeddings 呼び出しで batch_size を指定することもできます。バッチ処理をサポートするモデルでは、パフォーマンスを向上させるために batch_size を 1 より大きい値にすることをおすすめします。

  1. カスタムモデルの入力関数、出力関数、バッチ変換関数を定義します。

    -- Scalar input transform functions
    CREATE OR REPLACE FUNCTION acme_text_input_transform(model_id TEXT, input TEXT) RETURNS JSON;
    CREATE OR REPLACE FUNCTION acme_text_output_transform(model_id TEXT, model_output JSON) RETURNS real[];
    CREATE OR REPLACE FUNCTION acme_generate_headers(model_id TEXT, input TEXT) RETURNS JSON;
    -- Batch input transform functions
    CREATE OR REPLACE FUNCTION acme_text_batch_input_transform(model_id TEXT, input TEXT[]) RETURNS JSON;
    CREATE OR REPLACE FUNCTION acme_text_batch_output_transform(model_id TEXT, model_output JSON) RETURNS real[][];
    
  2. モデルを作成するには、バッチ変換関数を指定します。

    CALL
      ai.create_model(
        model_id => 'custom-embedding-model',
        model_request_url => 'https://acme.com/models/text/embeddings/v1',
        model_type => 'text_embedding',
        model_in_transform_fn => 'acme_text_input_transform',
        model_out_transform_fn => 'acme_text_output_transform',
        generate_headers_fn => 'acme_generate_headers',
        model_batch_in_transform_fn => 'acme_text_batch_input_transform',
        model_batch_out_transform_fn => 'acme_text_batch_output_transform'
      );
    
  3. カスタムモデルを使用してベクトル エンベディングを生成します。

    CALL
      ai.initialize_embeddings(
        model_id => 'custom-embedding-model',
        table_name => 'user_reviews',
        content_column => 'content',
        embedding_column => 'content_embeddings',
        batch_size => 10
    );
    

バッチ処理をネイティブでサポートしていないカスタムモデルでも、自動エンベディング機能を使用できます。そのためには、バッチ変換関数 model_batch_in_transform_fnmodel_batch_out_transform_fn を定義する必要があります。バッチ処理をサポートしていないモデルの場合は、入力配列から一度に 1 つの入力を処理するように、これらの関数を定義します。このモデルに対して ai.initialize_embeddings を呼び出す場合は、batch_size1 に設定します。

エンベディングを増分更新する

エンベディングを更新すると、入力コンテンツ列の最新の値に基づいて再生成されます。

整合性とパフォーマンスを制御できるように、AlloyDB は増分のエンベディング更新について、複数のモードをサポートしています。モードは、ai.initialize_embeddings()incremental_refresh_mode 列挙型引数を使用して選択できます。使用できるモードは次のとおりです。

  • transactional: コンテンツ列を更新するトランザクションの一環として、エンベディングが更新されます。このプロセスでは、多くの場合、コンテンツ列の更新時にデータベース トリガーに似たメカニズムを使用してエンベディングを自動的に生成しますが、このプロセスではオーバーヘッドが発生するため、更新オペレーションに時間がかかる可能性があります。このオーバーヘッドは、トランザクション セマンティクスを維持し、エンベディングとコンテンツの同期を確保するためのトレードオフです。このモードはモデルのスカラー変換関数に依存するため、モデルの作成時に model_in_transform_fnmodel_out_transform_fn を定義する必要があります。transactional モードを使用するには、テーブルに対するオーナーロールが必要です。

    CALL
      ai.initialize_embeddings(
        model_id => 'text-embedding-005',
        table_name => 'user_reviews',
        content_column => 'content',
        embedding_column => 'content_embeddings',
        batch_size => 10,
        incremental_refresh_mode => 'transactional'
    );
    
  • none: これがデフォルト モードです。このモードでは、AlloyDB はエンベディングを自動的に更新しません。増分変更のトラッキングはないため、ai.refresh_embeddings() 関数を呼び出すと、テーブル全体のエンベディングが再生成されます。このモードでは完全な制御が可能です。

テーブルのすべてのエンベディングを更新する

テーブルに対して ai.initialize_embeddings() を正常に実行したら、ai.refresh_embeddings() 関数を使用してエンベディングを再生成できます。更新オペレーションを使用すると、最初の initialize_embeddings 呼び出し時に同時に変更された行のエンベディングを更新したり、定期的な完全更新を実行したりできます。

refresh 関数は最初の呼び出しの設定を再利用するため、テーブルとエンベディング列のみを指定する必要があります。オプションで batch_size を指定して、デフォルト値をオーバーライドすることもできます。

CALL ai.refresh_embeddings(
    table_name => 'user_reviews',
    embedding_column => 'content_embeddings',
    batch_size => 50  -- Optional override
);

ベクトル エンベディングの作成時にテーブルデータを操作する

ai.initialize_embeddings() は、実行されているセッションに対してはブロッキング呼び出しとなりますが、他の接続は引き続きテーブルを操作できます。自動ベクトル エンベディング プロセスでは、標準の行レベルのロックが使用され、行がバッチで更新されます。つまり、UPDATEDELETE などの同時実行 DML オペレーションは、エンベディング プロセスが更新している同じ行を変更しようとした場合にのみ、短時間ブロックされます。他の接続からのクエリはブロックされません。initialize_embeddings は、同時に変更される行をスキップすることに注意してください。incremental_refresh_modenone の場合、これらの変更された行のエンベディングは、後続の更新が呼び出されるまで更新されません。

-- connection1 (starts embedding generation)
SELECT
  ai.initialize_embeddings(
    model_id => 'text-embedding-005',
    table_name => 'user_reviews',
    content_column => 'content',
    embedding_column => 'content_embeddings'
  );

-- connection2 (performs DMLs/queries without blocking)
INSERT INTO user_reviews(id, review_time, is_edited, content)
VALUES (48290, now(), false, 'I really liked the product functionality, but wish it came in orange color');

UPDATE user_reviews
SET is_edited = TRUE, content = 'Changing to 5 star. My issue is resolved by the support'
WHERE id = 700;

pg_cancel を使用して initialize_embeddings をキャンセルした場合、または内部エラーが原因で initialize_embeddings が失敗した場合は、失敗を示すステータスが返されます。正常に作成されたベクトル エンベディングはロールバックされません。障害から復元してベクトル エンベディングの作成を完了するには、まず ai.drop_embedding_config() 関数を使用して構成をクリーンアップしてから、ai.initialize_embeddings() 呼び出しを再発行する必要があります。

同時に変更された行のエンベディングを更新するには、ai.initialize_embeddings 呼び出しの完了後に ai.refresh_embeddings を呼び出します。この更新呼び出しにより、テーブル全体のエンベディングが再生成されます。

自動ベクトル エンベディングの設定を削除する

特定のテーブルとエンベディング列の組み合わせの自動ベクトル エンベディング構成を削除する必要がある場合は、ai.drop_embedding_config() 関数を使用します。この関数は、クリーンアップや、列のエンベディング管理を再構成する場合に便利です。

CALL
  ai.drop_embedding_config(
    table_name => 'user_reviews',
    embedding_column => 'content_embeddings');

自動でエンベディングを生成する例

このセクションでは、登録済みのモデル エンドポイントを使用して自動でエンベディングを生成する例を示します。

OpenAI のエンベディング モデル

OpenAI が提供する登録済みの text-embedding-3-small モデル エンドポイントを使用してエンベディングを生成するには、次のステートメントを実行します。

CALL ai.initialize_embeddings(
    model_id => 'text-embedding-3-small',
    table_name => 'user_reviews',
    chunk_column => 'content',
    embedding_column => 'content_embeddings'
);

カスタムのエンベディング モデル

独自モデルまたは外部でサポートされているモデルの場合は、入出力変換関数を定義して ai.create_model に登録する必要があります。自動エンベディング機能を使用する場合は、スカラー変換関数(acme_text_input_transformacme_text_output_transform など)とバッチ変換関数(acme_text_batch_input_transformacme_text_batch_output_transform など)の両方を指定する必要があります。

次のステップ