Questo documento spiega come generare e eseguire il backfill degli incorporamenti vettoriali collettivamente per i dati di testo (STRING
o JSON
) archiviati in Spanner utilizzando SQL e il modello textembedding-gecko
di Vertex AI.
Prerequisiti
Nel database Spanner deve essere presente una tabella contenente
dati di testo (STRING
o JSON
). Per ulteriori informazioni sull'importazione dei dati,
consulta la panoramica dell'importazione e dell'esportazione di Spanner.
Caso d'uso di esempio
Supponiamo di avere 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 embedding di vettori per la colonna description
in questa tabella per trovare articoli simili da consigliare ai clienti al fine di migliorare la loro esperienza di acquisto utilizzando la ricerca di vettori.
Registra un modello di embedding
GoogleSQL
Registra un modello di embedding con l'endpoint textembedding-gecko
di Vertex AI nel tuo 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/textembedding-gecko$MODEL_VERSION',
default_batch_size = 5
)
Sostituisci quanto segue:
MODEL_NAME
: il nome del modello di embeddingPROJECT
: il progetto che ospita l'endpoint Vertex AILOCATION
: la posizione dell'endpoint Vertex AIMODEL_VERSION
: la versione del modello di embeddingtextembedding-gecko
PostgreSQL
Nel dialetto PostgreSQL non è necessario registrare il modello.
Devi passare il nome dell'endpoint direttamente alla chiamata della 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 e 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
default_batch_size
. Puoi sostituiredefault_batch_size
con l'indicazione di query@{remote_udf_max_rows_per_rpc=NEW_NUMBER}
. Per informazioni sul limite didefault_batch_size
per ogni regione, consulta Ottenere gli embedding di testo per uno snippet di testo. - Definisci l'endpoint con una versione del modello specifica (ad es.
@003
) anziché@latest
. Questo perché i vettori di embedding generati per lo stesso testo potrebbero variare a seconda della versione del modello utilizzata. Per questo motivo, è consigliabile 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 un'altra colonna nella tabella che memorizzi la versione del modello. - I modelli
textembedding-gecko
ottimizzati personalizzati non sono supportati con la funzioneML.PREDICT
di GoogleSQL espanner.ML_PREDICT_ROW
di PostgreSQL.
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 seguente query:
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 embedding
PostgreSQL
SELECT spanner.ML_PREDICT_ROW(
'projects/PROJECT/locations/LOCATION/publishers/google/models/textembedding-gecko$MODEL_VERSION',
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 Vertex AILOCATION
: la posizione dell'endpoint Vertex AIMODEL_VERSION
: la versione del modello di embeddingtextembedding-gecko
Aggiorna la tabella di origine in modo da includere colonne aggiuntive per archiviare gli embedding
Aggiorna lo schema della tabella di origine in modo da includere un'altra colonna del
tipo di dati ARRAY<FLOAT32>
per memorizzare 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 origineEMBEDDING_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 origineEMBEDDING_COLUMN_NAME
: il nome della colonna in cui vuoi aggiungere gli embedding generati
Ad esempio, utilizzando l'esempio di 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;
Aumentare la quota per Vertex AI
Potresti dover aumentare la quota dell'API Vertex AI per
textembedding-gecko
nella regione che utilizza il modello. Per richiedere un aumento, consulta la pagina Aumenti di quota di Vertex AI.
Per ulteriori informazioni, consulta Quote e limiti di Vertex AI.
Incorporamenti di backfill
Infine, esegui la seguente istruzione UPDATE
utilizzando la DML partizionata per generare gli embedding per la colonna di dati di testo e memorizzarli nel database. Puoi memorizzare la versione del modello insieme agli embedding. Ti consigliamo di eseguire questa query durante un periodo 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 testoEMBEDDING_COLUMN_NAME
: il nome della colonna in cui vuoi aggiungere gli embedding generatiDATA_COLUMN_NAME
: il nome della colonna con i dati di testoMODEL_NAME
: il nome del modello di embeddingMAX_ROWS
: il numero massimo di righe per RPCEMBEDDING_VERSION_COLUMN
: la colonna che gestisce la versione del modello di embeddingtextembedding-gecko
utilizzato per il backfill degli embeddingMODEL_VERSION
: la versione del modello di embeddingtextembedding-gecko
FILTER_CONDITION
: una condizione di filtro partizionabile da applicare
L'utilizzo di SAFE.ML.PREDICT
restituisce NULL
per le richieste non riuscite. Puoi anche utilizzare
SAFE.ML.PREDICT
in combinazione con un
WHERE embedding_column IS NULL
filtro per eseguire nuovamente la query senza calcolare gli embedding per i campi
che sono già stati calcolati.
PostgreSQL
UPDATE TABLE_NAME
SET
EMBEDDING_COLUMN_NAME = spanner.FLOAT32_ARRAY(spanner.ML_PREDICT_ROW(
'projects/PROJECT/locations/LOCATION/publishers/google/models/textembedding-gecko$MODEL_VERSION',
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 testoEMBEDDING_COLUMN_NAME
: il nome della colonna in cui vuoi aggiungere gli embedding generatiDATA_COLUMN_NAME
: il nome della colonna con i dati di testoPROJECT
: il progetto che ospita l'endpoint Vertex AILOCATION
: la posizione dell'endpoint Vertex AIMODEL_VERSION
: la versione del modello di embeddingtextembedding-gecko
MAX_ROWS
: il numero massimo di righe per RPCEMBEDDING_VERSION_COLUMN
: la colonna che gestisce la versione del modello di embeddingtextembedding-gecko
utilizzato per il backfill degli embeddingFILTER_CONDITION
: una condizione di filtro partizionabile da applicare
Un esempio di query di backfill per la tabella products
:
GoogleSQL
UPDATE products
SET
products.desc_embed = (
SELECT embeddings.values
FROM SAFE.ML.PREDICT(
MODEL gecko_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/textembedding-gecko@003',
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 incorporamenti di cui esegui il backfill, potresti dover aumentare questo timeout per assicurarti che la DML partizionata
UPDATE
abbia tempo sufficiente per essere completata. Per ulteriori informazioni, consulta Configurare i timeout e le riavviate personalizzati.
Prestazioni e altre considerazioni
Tieni presente quanto segue per ottimizzare il rendimento durante il backfill dei dati di incorporamento.
Numero di nodi
La DML partizionata esegue l'istruzione DML specificata su partizioni diverse in parallelo. Per le istanze con un numero elevato di nodi, potresti notare errori di quota durante l'esecuzione di DML partizionato. Se le richieste dell'API Vertex AI vengono limitate a causa dei limiti di quota dell'API Vertex AI, Spanner riprova questi errori nella modalità di transazione DML partizionata per un massimo di 20 volte. Se noti un tasso elevato di errori di quota in Vertex AI, aumenta la quota per Vertex AI.
Puoi anche ottimizzare il parallelismo utilizzando l'opzione di suggerimento a livello di dichiarazione
@{pdml_max_parallelism=DESIRED_NUMBER}
durante l'utilizzo di GoogleSql. Nell'esempio seguente il parallelismo viene impostato su "5":
GoogleSQL
@{pdml_max_parallelism=5} UPDATE products
SET products.desc_embed =(
SELECT embeddings.values
FROM SAFE.ML.PREDICT(MODEL gecko_model, (
SELECT products.value AS CONTENT
)
)
@{remote_udf_max_rows_per_rpc=200}
),
products.desc_embed_model_version = 003
WHERE products.desc_embed IS NULL;
Dimensioni del testo nella colonna di dati
Il modello di embedding di Vertex AI ha limiti sul numero massimo di token per ogni input di testo. Le versioni dei modelli hanno limiti di token diversi. Ogni richiesta Vertex AI può avere più campi di testo di input, ma è previsto un limite al numero massimo di token presenti in una singola richiesta. Per i database GoogleSQL, se riscontri un erroreINVALID_ARGUMENT
con il messaggio "La richiesta è troppo grande", prova a ridurre le dimensioni del batch per evitare l'errore. A tale scopo, puoi configurare default_batch_size
o utilizzare l'opzione di suggerimento di query @{remote_udf_max_outstanding_rpcs}
durante la registrazione del modello.
Numero di richieste API inviate a Vertex AI
Puoi utilizzare l'indicazione di query @{remote_udf_max_outstanding_rpcs}
per aumentare o diminuire il numero di richieste inviate a Vertex AI da Spanner. Tieni presente che l'aumento di questo limite può aumentare l'utilizzo della CPU e della memoria dell'istanza Spanner. Per i database Google SQL, l'utilizzo di questo suggerimento di query sostituisce il valore default_batch_size
configurato per il modello.
Monitorare l'avanzamento del backfill
Puoi monitorare il numero di richieste, la latenza e i byte di rete inviati a Vertex AI da Spanner utilizzando la dashboard di approfondimenti sul sistema.
Passaggi successivi
- Scopri come eseguire una ricerca vettoriale di similarità trovando i K vicini più prossimi.
- Scopri di più sul machine learning e sugli embedding nel nostro corso introduttivo sugli embedding.