Mithilfe von partitionierter DML Bulk-Vektoreinbettungen für Textdaten generieren

In diesem Dokument wird erläutert, wie Sie Vektoreinbettungen in großen Mengen für Textdaten (STRING oder JSON), die in Spanner gespeichert sind, mithilfe von SQL und den Gemini Enterprise Agent Platform-Modellen zur Texteinbettung generieren und nachfüllen.

Vorbereitung

Sie benötigen eine Tabelle in Ihrer Spanner-Datenbank, die Textdaten (STRING oder JSON) enthält. Weitere Informationen zum Importieren von Daten finden Sie in der Spanner-Übersicht zum Importieren und Exportieren.

Anwendungsbeispiel

Angenommen, Sie haben eine Tabelle in Spanner mit dem folgenden Schema. Diese Tabelle enthält Millionen von Datensätzen.

GoogleSQL

CREATE TABLE Products (
  product_id INT64 NOT NULL,
  name STRING(MAX),
  description STRING(MAX)
) PRIMARY KEY(product_id);

PostgreSQL

CREATE TABLE Products (
  product_id INT8 NOT NULL,
  name TEXT,
  description TEXT,
  PRIMARY KEY(product_id)
);

Ihr Ziel ist es, Vektoreinbettungen für die description Spalte in dieser Tabelle zu generieren, um ähnliche Artikel zu finden, die Kunden empfohlen werden können, um das Einkaufs erlebnis mithilfe der Vektorsuche zu verbessern.

Einbettungsmodell registrieren

GoogleSQL

Registrieren Sie ein Texteinbettungsmodell mit dem Agent Platform-Modellendpunkt in Ihrer Spanner-Datenbank:

CREATE MODEL MODEL_NAME
INPUT(
  content STRING(MAX)
)
OUTPUT(
  embeddings STRUCT<values ARRAY<FLOAT32>>
)
REMOTE OPTIONS(
    endpoint = '//aiplatform.googleapis.com/projects/PROJECT/locations/LOCATION/publishers/google/models/$MODEL_NAME',
  default_batch_size = 5
)

Ersetzen Sie Folgendes:

  • MODEL_NAME: der Name des Agent Platform-Modells zur Texteinbettung
  • PROJECT: das Projekt, in dem der Agent Platform-Endpunkt gehostet wird
  • LOCATION: der Standort des Agent Platform-Endpunkts

PostgreSQL

Im PostgreSQL-Dialekt ist es nicht erforderlich, das Modell zu registrieren. Sie übergeben den Endpunktnamen direkt an den Funktionsaufruf spanner.ML_PREDICT_ROW.

Beachten Sie die folgenden Best Practices:

  • Um die Isolation von Kontingenten aufrechtzuerhalten, verwenden Sie einen Endpunkt in einem anderen Projekt, um Einbettungen zu generieren und nachzufüllen, als den Produktionsendpunkt. Reservieren Sie den Produktionsendpunkt für den Produktions-Traffic.
  • Achten Sie darauf, dass der Modellendpunkt den Wert von default_batch_size unterstützt. Sie können default_batch_size mit dem Abfragehinweis @{remote_udf_max_rows_per_rpc=NEW_NUMBER} überschreiben. Informationen zum default_batch_size Limit für jede Region finden Sie unter Texteinbettungen für einen Textausschnitt abrufen.
  • Definieren Sie den Endpunkt mit einer bestimmten Modellversion (z.B. @003) anstelle von @latest. Das liegt daran, dass sich die für denselben Text generierten Einbettungsvektoren je nach verwendeter Modellversion unterscheiden können. Daher sollten Sie nicht verschiedene Modellversionen verwenden, um Einbettungen im selben Dataset zu generieren. Außerdem werden durch das Aktualisieren der Modellversion in der Anweisung zur Modelldefinition die Einbettungen, die bereits mit diesem Modell generiert wurden, nicht aktualisiert. Eine Möglichkeit, die Modellversion für Einbettungen zu verwalten, besteht darin, der Tabelle eine zusätzliche Spalte hinzuzufügen, in der die Modellversion gespeichert wird.
  • Benutzerdefinierte Texteinbettungsmodelle werden mit den GoogleSQL-Funktionen ML.PREDICT und PostgreSQL-Funktionen spanner.ML_PREDICT_ROW nicht unterstützt.

End-to-End-Integration des Einbettungsmodells testen

Sie können eine Abfrage ausführen, um zu testen, ob das Einbettungsmodell erfolgreich konfiguriert wurde und Einbettungen abgerufen werden. Führen Sie beispielsweise die folgende Abfrage aus:

GoogleSQL

SELECT embeddings.values
FROM SAFE.ML.PREDICT(
  MODEL MODEL_NAME,
  (SELECT description AS content FROM products LIMIT 10)
);

Ersetzen Sie Folgendes:

  • MODEL_NAME: der Name des Agent Platform-Modells zur Texteinbettung

PostgreSQL

SELECT spanner.ML_PREDICT_ROW(
    'projects/PROJECT/locations/LOCATION/publishers/google/models/$MODEL_NAME',
    JSONB_BUILD_OBJECT('instances', JSONB_BUILD_ARRAY(JSONB_BUILD_OBJECT('content', description))))
FROM Products
LIMIT 10;

Ersetzen Sie Folgendes:

  • PROJECT: das Projekt, in dem der Agent Platform-Endpunkt gehostet wird
  • LOCATION: der Standort des Agent Platform-Endpunkts
  • MODEL_NAME: der Name des Agent Platform-Modells zur Texteinbettung

Quelltabelle aktualisieren, um zusätzliche Spalten zum Speichern der Einbettungen einzufügen

Aktualisieren Sie als Nächstes das Quelltabellenschema, um eine zusätzliche Spalte des Datentyps ARRAY<FLOAT32> zum Speichern der generierten Einbettungen einzufügen:

GoogleSQL

ALTER TABLE TABLE_NAME
ADD COLUMN EMBEDDING_COLUMN_NAME ARRAY<FLOAT32>;

Ersetzen Sie Folgendes:

  • TABLE_NAME: der Name der Quelltabelle
  • EMBEDDING_COLUMN_NAME: der Name der Spalte, in der Sie generierte Einbettungen hinzufügen möchten

PostgreSQL

ALTER TABLE TABLE_NAME
ADD COLUMN EMBEDDING_COLUMN_NAME real[];

Ersetzen Sie Folgendes:

  • TABLE_NAME: der Name der Quelltabelle
  • EMBEDDING_COLUMN_NAME: der Name der Spalte, in der Sie generierte Einbettungen hinzufügen möchten

Führen Sie beispielsweise mit der Tabelle products Folgendes aus:

GoogleSQL

ALTER TABLE Products
ADD COLUMN desc_embed ARRAY<FLOAT32>;

PostgreSQL

ALTER TABLE Products
ADD COLUMN desc_embed real[];

Sie können eine weitere Spalte hinzufügen, um die Version des Einbettungsmodells zu verwalten.

GoogleSQL

ALTER TABLE Products
ADD COLUMN desc_embed_model_version INT64;

PostgreSQL

ALTER TABLE Products
ADD COLUMN desc_embed_model_version INT8;

Kontingent für Agent Platform erhöhen

Möglicherweise müssen Sie das Agent Platform API-Kontingent für die Region erhöhen, in der das Texteinbettungsmodell verwendet wird. Informationen zum Anfordern einer Erhöhung finden Sie unter Kontingenterhöhungen für Agent Platform .

Einbettungen nachfüllen

Führen Sie schließlich die folgende UPDATE Anweisung mit partitionierter DML aus, um Einbettungen für die Textdatenspalte zu generieren und die Einbettungen in Ihrer Datenbank zu speichern. Sie können die Modellversion zusammen mit den Einbettungen speichern. Wir empfehlen, diese Abfrage während eines Zeitraums mit wenig Traffic in Ihrer Datenbank auszuführen.

GoogleSQL

UPDATE TABLE_NAME
SET
  TABLE_NAME.EMBEDDING_COLUMN_NAME = (
    SELECT embeddings.values
    FROM SAFE.ML.PREDICT(
      MODEL MODEL_NAME,
      (SELECT TABLE_NAME.DATA_COLUMN_NAME AS content)
    ) @{remote_udf_max_rows_per_rpc=MAX_ROWS}
  ),
  TABLE_NAME.EMBEDDING_VERSION_COLUMN = MODEL_VERSION
WHERE FILTER_CONDITION;

Ersetzen Sie Folgendes:

  • TABLE_NAME: der Name der Tabelle mit den Textdaten
  • EMBEDDING_COLUMN_NAME: der Name der Spalte, in der Sie generierte Einbettungen hinzufügen möchten
  • DATA_COLUMN_NAME: der Name der Spalte mit den Textdaten
  • MODEL_NAME: der Name des Agent Platform-Einbettungsmodells
  • MAX_ROWS: die maximale Anzahl der Zeilen pro RPC
  • EMBEDDING_VERSION_COLUMN: die Spalte, in der die Version des Einbettungsmodells verwaltet wird, das zum Nachfüllen Ihrer Einbettungen verwendet wird
  • MODEL_VERSION: die Version des Texteinbettungsmodells
  • FILTER_CONDITION: eine partitionierbare Filterbedingung, die Sie anwenden möchten

Bei Verwendung von SAFE.ML.PREDICT wird für fehlgeschlagene Anfragen NULL zurückgegeben. Sie können SAFE.ML.PREDICT auch in Kombination mit einem WHERE embedding_column IS NULL-Filter verwenden, um die Abfrage noch einmal auszuführen, ohne die Einbettungen für die bereits berechneten Felder zu berechnen.

PostgreSQL

UPDATE TABLE_NAME
SET
  EMBEDDING_COLUMN_NAME = spanner.FLOAT32_ARRAY(spanner.ML_PREDICT_ROW(
    'projects/PROJECT/locations/LOCATION/publishers/google/models/$MODEL_NAME',
    JSONB_BUILD_OBJECT('instances', JSONB_BUILD_ARRAY(JSONB_BUILD_OBJECT('content', DATA_COLUMN_NAME)))
  ) /*@ remote_udf_max_rows_per_rpc=MAX_ROWS */ ->'predictions'->0->'embeddings'->'values'),
  EMBEDDING_VERSION_COLUMN = MODEL_VERSION
WHERE FILTER_CONDITION;

Ersetzen Sie Folgendes:

  • TABLE_NAME: der Name der Tabelle mit den Textdaten
  • EMBEDDING_COLUMN_NAME: der Name der Spalte, in der Sie generierte Einbettungen hinzufügen möchten
  • DATA_COLUMN_NAME: der Name der Spalte mit den Textdaten
  • PROJECT: das Projekt, in dem der Agent Platform-Endpunkt gehostet wird
  • LOCATION: der Standort des Agent Platform-Endpunkts
  • MODEL_NAME: der Name des Agent Platform-Einbettungsmodells
  • MODEL_VERSION: die Version des Agent Platform-Einbettungsmodells
  • MAX_ROWS: die maximale Anzahl der Zeilen pro RPC
  • EMBEDDING_VERSION_COLUMN: die Spalte, in der die Version des Texteinbettungsmodells verwaltet wird, das zum Nachfüllen Ihrer Einbettungen verwendet wird
  • FILTER_CONDITION: eine partitionierbare Filterbedingung, die Sie anwenden möchten

Beispiel für eine Backfill-Abfrage für die Tabelle products:

GoogleSQL

UPDATE products
SET
  products.desc_embed = (
    SELECT embeddings.values
    FROM SAFE.ML.PREDICT(
      MODEL embedding_model,
      (SELECT products.description AS content)
    ) @{remote_udf_max_rows_per_rpc=200}
  ),
  products.desc_embed_model_version = 3
WHERE products.desc_embed IS NULL;

PostgreSQL

UPDATE products
SET
  desc_embed = spanner.FLOAT32_ARRAY(spanner.ML_PREDICT_ROW(
    'projects/PROJECT/locations/LOCATION/publishers/google/models/$MODEL_NAME',
    JSONB_BUILD_OBJECT('instances', JSONB_BUILD_ARRAY(JSONB_BUILD_OBJECT('content', description)))
  ) /*@ remote_udf_max_rows_per_rpc=200 */ ->'predictions'->0->'embeddings'->'values'),
  desc_embed_model_version = 3
WHERE desc_embed IS NULL;

Beachten Sie die folgenden Best Practices:

  • Das Standard-gRPC-Zeitlimit für die Spanner API beträgt eine Stunde. Je nach Anzahl der Einbettungen, die Sie nachfüllen, müssen Sie dieses Zeitlimit möglicherweise erhöhen, damit die partitionierte DML-Anweisung UPDATE ausreichend Zeit hat, um abgeschlossen zu werden. Weitere Informationen finden Sie unter Benutzerdefinierte Zeitlimits und Wiederholungen konfigurieren.

Leistung und andere Überlegungen

Beachten Sie Folgendes, um die Leistung beim Nachfüllen von Einbettungsdaten zu optimieren.

Anzahl der Knoten

Bei der partitionierten DML wird die angegebene DML-Anweisung parallel für verschiedene Partitionen ausgeführt. Bei Instanzen mit einer hohen Anzahl von Knoten können während der Ausführung der partitionierten DML Kontingentfehler auftreten. Wenn die Agent Platform API-Anfragen aufgrund von Kontingentlimits für die Agent Platform API gedrosselt werden, wiederholt Spanner diese Fehler im partitionierten DML-Transaktionsmodus maximal 20 Mal. Wenn Sie eine hohe Anzahl von Kontingentfehlern in Agent Platform feststellen, dann erhöhen Sie das Kontingent für Agent Platform. Sie können die Parallelität auch mit dem Hinweis auf Anweisungsebene @{pdml_max_parallelism=DESIRED_NUMBER} anpassen, wenn Sie GoogleSQL verwenden. Im folgenden Beispiel wird die Parallelität auf „5“ festgelegt:

GoogleSQL

@{pdml_max_parallelism=5} UPDATE products
SET products.desc_embed =(
  SELECT embeddings.values
  FROM SAFE.ML.PREDICT(MODEL embedding_model, (
        SELECT products.value AS CONTENT
        )
  )
      @{remote_udf_max_rows_per_rpc=200}
),
products.desc_embed_model_version = MODEL_VERSION
WHERE products.desc_embed IS NULL;

Größe des Texts in der Datenspalte

Für das Agent Platform-Einbettungsmodell gelten Limits für die maximale Anzahl von Tokens für jede Texteingabe. Verschiedene Modellversionen haben unterschiedliche Tokenlimits. Jede Agent Platform-Anfrage kann mehrere Eingabetextfelder haben, aber es gibt ein Limit für die maximale Anzahl von Tokens in einer einzelnen Anfrage. Wenn in GoogleSQL-Datenbanken ein INVALID_ARGUMENT-Fehler mit der Meldung „Request is too large“ (Anfrage zu groß) auftritt, versuchen Sie, die Batchgröße zu verringern, um den Fehler zu vermeiden. Dazu können Sie default_batch_size konfigurieren oder den Abfragehinweis @{remote_udf_max_outstanding_rpcs} verwenden, wenn Sie das Modell registrieren.

Anzahl der an Agent Platform gesendeten API-Anfragen

Mit dem Abfragehinweis @{remote_udf_max_outstanding_rpcs} können Sie die Anzahl der Anfragen erhöhen oder verringern, die von Spanner an Agent Platform gesendet werden. Beachten Sie, dass durch das Erhöhen dieses Limits die CPU- und Arbeitsspeichernutzung der Spanner-Instanz steigen kann. Bei GoogleSQL-Datenbanken überschreibt dieser Abfragehinweis die für Ihr Modell konfigurierte default_batch_size.

Backfill-Fortschritt überwachen

Im Dashboard für Systemstatistiken können Sie die Anzahl der Anfragen, die Latenz und die Anzahl der Netzwerkbytes überwachen, die von Spanner an Agent Platform gesendet werden.

Nächste Schritte