Generare in blocco gli embedding di vettori per i dati di testo utilizzando la DML partizionata

Questo documento spiega come generare ed eseguire il backfill di vector embedding in blocco per i dati di testo (STRING o JSON) archiviati in Spanner utilizzando SQL e i modelli di text embedding di Gemini Enterprise Agent Platform.

Prerequisiti

Devi avere una tabella nel database Spanner che contenga dati di testo (STRING o JSON). Per saperne di più sull'importazione dei dati, consulta la panoramica sull'importazione e l'esportazione di Spanner.

Caso d'uso di esempio

Supponiamo che tu abbia una tabella in Spanner con lo schema seguente. Questa tabella contiene milioni di record.

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)
);

Il tuo obiettivo è generare vector embedding per la colonna description in questa tabella per trovare elementi simili da consigliare ai clienti per migliorare la loro esperienza di acquisto utilizzando la ricerca vettoriale.

Registra un modello di embedding

GoogleSQL

Registra un modello di text embedding con l' endpoint del modello Agent Platform nel database Spanner:

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
)

Sostituisci quanto segue:

  • MODEL_NAME: il nome del modello di text embedding di Agent Platform
  • PROJECT: il progetto che ospita l'endpoint di Agent Platform
  • LOCATION: la località dell'endpoint di Agent Platform

PostgreSQL

Nel dialetto PostgreSQL non è necessario registrare il modello. Passa il nome dell'endpoint direttamente alla chiamata di funzione spanner.ML_PREDICT_ROW.

Per le best practice, tieni presente quanto segue:

  • Per mantenere l'isolamento delle quote, utilizza un endpoint in un progetto diverso per generare ed eseguire il backfill degli embedding rispetto all'endpoint di produzione. Riserva l'endpoint di produzione per gestire il traffico di produzione.
  • Assicurati che l'endpoint del modello supporti il valore di default_batch_size. Puoi sostituire default_batch_size con il suggerimento di query @{remote_udf_max_rows_per_rpc=NEW_NUMBER}. Per informazioni sul default_batch_size limite per ogni regione, consulta Ottieni text embedding per uno snippet di testo.
  • Definisci l'endpoint con una versione specifica del modello (ad es. @003) anziché @latest. Questo perché i vettori di embedding generati per lo stesso testo potrebbero variare a seconda della versione del modello che utilizzi; per questo motivo, devi evitare di utilizzare versioni diverse del modello per generare embedding nello stesso set di dati. Inoltre, l'aggiornamento della versione del modello nell'istruzione di definizione del modello non aggiorna gli embedding già generati con questo modello. Un modo per gestire la versione del modello per gli embedding è creare una colonna aggiuntiva nella tabella che memorizza la versione del modello.
  • I modelli di text embedding personalizzati non sono supportati con le funzioni GoogleSQL ML.PREDICT e PostgreSQL spanner.ML_PREDICT_ROW.

Testa l'integrazione end-to-end del modello di embedding

Puoi eseguire una query per verificare che il modello di embedding sia configurato correttamente e che gli embedding vengano recuperati. Ad esempio, esegui la query seguente:

GoogleSQL

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

Sostituisci quanto segue:

  • MODEL_NAME: il nome del modello di text embedding di Agent Platform

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;

Sostituisci quanto segue:

  • PROJECT: il progetto che ospita l'endpoint di Agent Platform
  • LOCATION: la località dell'endpoint di Agent Platform
  • MODEL_NAME: il nome del modello di text embedding di Agent Platform

Aggiorna la tabella di origine in modo da includere colonne aggiuntive per archiviare gli embedding

Poi, aggiorna lo schema della tabella di origine in modo da includere una colonna aggiuntiva del tipo di dati ARRAY<FLOAT32> per archiviare gli embedding generati:

GoogleSQL

ALTER TABLE TABLE_NAME
ADD COLUMN EMBEDDING_COLUMN_NAME ARRAY<FLOAT32>;

Sostituisci quanto segue:

  • TABLE_NAME: il nome della tabella di origine
  • EMBEDDING_COLUMN_NAME: il nome della colonna in cui vuoi aggiungere gli embedding generati

PostgreSQL

ALTER TABLE TABLE_NAME
ADD COLUMN EMBEDDING_COLUMN_NAME real[];

Sostituisci quanto segue:

  • TABLE_NAME: il nome della tabella di origine
  • EMBEDDING_COLUMN_NAME: il nome della colonna in cui vuoi aggiungere gli embedding generati

Ad esempio, utilizzando la tabella products, esegui:

GoogleSQL

ALTER TABLE Products
ADD COLUMN desc_embed ARRAY<FLOAT32>;

PostgreSQL

ALTER TABLE Products
ADD COLUMN desc_embed real[];

Puoi aggiungere un'altra colonna per gestire la versione del modello di embedding.

GoogleSQL

ALTER TABLE Products
ADD COLUMN desc_embed_model_version INT64;

PostgreSQL

ALTER TABLE Products
ADD COLUMN desc_embed_model_version INT8;

Aumenta la quota per Agent Platform

Potresti dover aumentare la quota dell'API Agent Platform per la regione che utilizza il modello di text embedding. Per richiedere un aumento, consulta Aumenti della quota di Agent Platform.

Esegui il backfill degli embedding

Infine, esegui l'istruzione UPDATE seguente utilizzando DML partizionato per generare embedding per la colonna dei dati di testo e archiviarli nel database. Puoi archiviare la versione del modello insieme agli embedding. Ti consigliamo di eseguire questa query durante una finestra di traffico ridotto nel database.

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;

Sostituisci quanto segue:

  • TABLE_NAME: il nome della tabella con i dati di testo
  • EMBEDDING_COLUMN_NAME: il nome della colonna in cui vuoi aggiungere gli embedding generati
  • DATA_COLUMN_NAME: il nome della colonna con i dati di testo
  • MODEL_NAME: il nome del modello di embedding di Agent Platform
  • MAX_ROWS: il numero massimo di righe per RPC
  • EMBEDDING_VERSION_COLUMN: la colonna che gestisce la versione del modello di embedding utilizzato per eseguire il backfill degli embedding
  • MODEL_VERSION: la versione del modello di text embedding
  • FILTER_CONDITION: una condizione di filtro partizionabile che vuoi applicare

L'utilizzo di SAFE.ML.PREDICT restituisce NULL per le richieste non riuscite. Puoi anche utilizzare SAFE.ML.PREDICT in combinazione con un filtro WHERE embedding_column IS NULL per eseguire di nuovo la query senza calcolare gli embedding per i campi già calcolati.

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;

Sostituisci quanto segue:

  • TABLE_NAME: il nome della tabella con i dati di testo
  • EMBEDDING_COLUMN_NAME: il nome della colonna in cui vuoi aggiungere gli embedding generati
  • DATA_COLUMN_NAME: il nome della colonna con i dati di testo
  • PROJECT: il progetto che ospita l'endpoint di Agent Platform
  • LOCATION: la località dell'endpoint di Agent Platform
  • MODEL_NAME: il nome del modello di embedding di Agent Platform
  • MODEL_VERSION: la versione del modello di embedding di Agent Platform
  • MAX_ROWS: il numero massimo di righe per RPC
  • EMBEDDING_VERSION_COLUMN: la colonna che gestisce la versione del modello di text embedding utilizzato per eseguire il backfill degli embedding
  • FILTER_CONDITION: una condizione di filtro partizionabile che vuoi applicare

Esempio di query di backfill per la tabella 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;

Per le best practice, tieni presente quanto segue:

  • Il timeout gRPC predefinito per l'API Spanner è di un'ora. A seconda della quantità di embedding di cui stai eseguendo il backfill, potresti dover aumentare questo timeout per assicurarti che il DML partizionato UPDATE abbia tempo sufficiente per completare l'operazione. Per saperne di più, consulta Configurare timeout e tentativi personalizzati.

Rendimento e altre considerazioni

Tieni presente quanto segue per ottimizzare il rendimento durante il backfill dei dati di embedding.

Numero di nodi

Il DML partizionato esegue l'istruzione DML specificata su partizioni diverse in parallelo. Per le istanze con un numero elevato di nodi, potresti riscontrare errori di quota durante l'esecuzione del DML partizionato. Se le richieste dell'API Agent Platform vengono limitate a causa dei limiti di quota dell'API Agent Platform, Spanner ritenta questi errori in modalità di transazione DML partizionata per un massimo di 20 volte. Se riscontri una percentuale elevata di errori di quota in Agent Platform, allora aumenta la quota per Agent Platform. Puoi anche ottimizzare il parallelismo utilizzando il suggerimento a livello di istruzione @{pdml_max_parallelism=DESIRED_NUMBER} durante l'utilizzo di GoogleSQL. L'esempio seguente imposta il parallelismo su "5":

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;

Dimensioni del testo nella colonna dei dati

Il modello di embedding di Agent Platform ha limiti sul numero massimo di token per ogni input di testo. Le diverse versioni del modello hanno limiti di token diversi. Ogni richiesta di Agent Platform può avere più campi di testo di input, ma esiste un limite al numero massimo di token presenti in una singola richiesta. Per i database GoogleSQL, se riscontri un errore INVALID_ARGUMENT con il messaggio "Request is too large", prova a ridurre le dimensioni del batch per evitare l'errore. Per farlo, puoi configurare default_batch_size o utilizzare il suggerimento di query @{remote_udf_max_outstanding_rpcs} durante la registrazione del modello.

Numero di richieste API inviate ad Agent Platform

Puoi utilizzare il suggerimento di query @{remote_udf_max_outstanding_rpcs} per aumentare o diminuire il numero di richieste inviate ad Agent Platform da Spanner. Tieni presente che l'aumento di questo limite può aumentare l'utilizzo di CPU e memoria dell'istanza Spanner. Per i database GoogleSQL, l'utilizzo di questo suggerimento di query sostituisce default_batch_size configurato per il modello.

Monitora l'avanzamento del backfill

Puoi monitorare il numero di richieste, la latenza e i byte di rete inviati ad Agent Platform da Spanner utilizzando la dashboard Approfondimenti di sistema.

Passaggi successivi