En este instructivo, se muestra cómo compilar una aplicación de IA generativa con Spanner y Vertex AI.
Esta aplicación te permite realizar búsquedas de similitud semántica, lo que te permite encontrar productos que coincidan con una consulta en lenguaje natural. Para ello, utiliza embeddings, que son representaciones numéricas del texto que capturan el significado y el contexto de las palabras. Usarás un modelo de Vertex AI para generar estos embeddings y, luego, los almacenarás y buscarás en Spanner. Este enfoque es particularmente útil para casos de uso como la búsqueda de productos, en los que los usuarios pueden describir lo que quieren en lenguaje natural en lugar de usar palabras clave específicas.
Los siguientes temas te ayudarán a aprender a hacer lo siguiente:
- Crea un Google Cloud proyecto
- Crea una instancia de Spanner
- Cómo crear una base de datos
- Crea un modelo de embedding
- Carga datos en Spanner
- Genera embeddings para los datos
- Realiza una búsqueda de similitud de vectores con KNN
- Cómo escalar la búsqueda de vectores con un índice de vectores
- Limpia los recursos
Para obtener información sobre los precios de Spanner, consulta Precios de Spanner.
Para probar un codelab, consulta Cómo comenzar a usar la búsqueda vectorial de Spanner.
Antes de comenzar
Debes crear un proyecto Google Cloud que esté conectado a una cuenta de facturación.
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Verify that billing is enabled for your Google Cloud project.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Verify that billing is enabled for your Google Cloud project.
- La API de Spanner debería habilitarse automáticamente. Si no es así, habilítala de forma manual: Habilita la API de Spanner
- La API de Vertex AI debería habilitarse automáticamente. Si no es así, habilítala de forma manual: Habilitar la API de Vertex AI
-
Para obtener los permisos que necesitas para crear instancias y bases de datos, pídele a tu administrador que te otorgue el rol de IAM de administrador de Cloud Spanner (
roles/spanner.admin
) en tu proyecto. -
Para obtener los permisos que necesitas para consultar gráficos de Spanner si no se te otorgó el rol de administrador de Cloud Spanner, pídele a tu administrador que te otorgue el rol de IAM de lector de bases de datos de Cloud Spanner (
roles/spanner.databaseReader
) en tu proyecto. En la consola de Google Cloud , ve a la página Spanner.
Selecciona o crea un Google Cloud proyecto si aún no lo hiciste.
Realiza una de las siguientes acciones:
- Si nunca creaste una instancia de Spanner, en la página Welcome to Spanner, haz clic en Create a provisioned instance.
- Si creaste una instancia de Spanner, en la página Instancias, haz clic en Crear instancia.
En la página Selecciona una edición, elige Enterprise Plus o Enterprise.
La búsqueda vectorial de Spanner solo está disponible en las ediciones Enterprise o Enterprise Plus. Para comparar las diferentes ediciones, haz clic en Comparar ediciones. Para obtener más información, consulta la Descripción general de las ediciones de Spanner.
Haz clic en Continuar.
En Nombre de la instancia, ingresa un nombre de instancia, por ejemplo,
test-instance
.En ID de instancia, mantén o cambia el ID de instancia. El ID de instancia se establece de forma predeterminada en el nombre de la instancia, pero puedes cambiarlo. El nombre y el ID de la instancia pueden ser iguales o diferentes.
Haz clic en Continuar.
En Elige una configuración, haz lo siguiente:
- Mantén seleccionada la opción Regional.
- En Selecciona una configuración, elige una región. La región que selecciones es donde se almacenan y replican tus instancias.
- Haz clic en Continuar.
En Configurar la capacidad de procesamiento, haz lo siguiente:
- En Seleccionar unidad, selecciona Unidades de procesamiento (PU).
- En Elige un modo de ajuste de escala, mantén seleccionada la opción Asignación manual y, en Cantidad, mantén 1,000 unidades de procesamiento.
Haz clic en Crear. La consola de Google Cloud muestra la página Descripción general de la instancia que creaste.
En la consola de Google Cloud , ve a la página Instancias de Spanner.
Haz clic en la instancia que creaste, por ejemplo,
test-instance
.En Descripción general, debajo del nombre de tu instancia, haz clic en Crear base de datos.
En Nombre de la base de datos, ingresa un nombre para la base de datos. Por ejemplo,
example-db
En Selecciona el dialecto de la base de datos, elige SQL estándar de Google.
La búsqueda de vectores de Spanner no está disponible en el dialecto de PostgreSQL.
Copia y pega el siguiente esquema en la pestaña del editor DDL Templates. El esquema define una tabla
Products
.CREATE TABLE products ( categoryId INT64 NOT NULL, productId INT64 NOT NULL, productName STRING(MAX) NOT NULL, productDescription STRING(MAX) NOT NULL, productDescriptionEmbedding ARRAY<FLOAT32>, createTime TIMESTAMP NOT NULL OPTIONS ( allow_commit_timestamp = true ), inventoryCount INT64 NOT NULL, priceInCents INT64, ) PRIMARY KEY(categoryId, productId);
No realices ningún cambio en Mostrar opciones de encriptación.
Haz clic en Crear. Google Cloud La consola muestra la página Descripción general de la base de datos que creaste.
- En la página Overview de la base de datos, haz clic en Spanner Studio.
- En la página Spanner Studio, haz clic en Pestaña nueva o usa la pestaña del editor vacía.
Escribe lo siguiente:
CREATE MODEL EmbeddingsModel INPUT( content STRING(MAX), ) OUTPUT( embeddings STRUCT<values ARRAY<FLOAT32>>, ) REMOTE OPTIONS ( endpoint = '//aiplatform.googleapis.com/projects/PROJECT_ID/locations/us-central1/publishers/google/models/TEXT_EMBEDDING_MODEL' );
Reemplaza lo siguiente:
- PROJECT_ID: Es un identificador permanente que es único para tu proyecto deGoogle Cloud .
- TEXT_EMBEDDING_MODEL: Es el nombre del modelo de incorporación de texto. Para obtener una lista de los modelos de incorporación de texto de Vertex AI, consulta Modelos compatibles.
Haz clic en Ejecutar para crear el modelo.
Después de que se agregue el modelo correctamente, lo verás en el panel Explorador.
En una pestaña nueva de Spanner Studio, copia y pega la siguiente instrucción de inserción:
INSERT INTO products (categoryId, productId, productName, productDescription, createTime, inventoryCount, priceInCents) VALUES (1, 1, "Cymbal Helios Helmet", "Safety meets style with the Cymbal children's bike helmet. Its lightweight design, superior ventilation, and adjustable fit ensure comfort and protection on every ride. Stay bright and keep your child safe under the sun with Cymbal Helios!", PENDING_COMMIT_TIMESTAMP(), 100, 10999), (1, 2, "Cymbal Sprout", "Let their cycling journey begin with the Cymbal Sprout, the ideal balance bike for beginning riders ages 2-4 years. Its lightweight frame, low seat height, and puncture-proof tires promote stability and confidence as little ones learn to balance and steer. Watch them sprout into cycling enthusiasts with Cymbal Sprout!", PENDING_COMMIT_TIMESTAMP(), 10, 13999), (1, 3, "Cymbal Spark Jr.", "Light, vibrant, and ready for adventure, the Spark Jr. is the perfect first bike for young riders (ages 5-8). Its sturdy frame, easy-to-use brakes, and puncture-resistant tires inspire confidence and endless playtime. Let the spark of cycling ignite with Cymbal!", PENDING_COMMIT_TIMESTAMP(), 34, 13900), (1, 4, "Cymbal Summit", "Conquering trails is a breeze with the Summit mountain bike. Its lightweight aluminum frame, responsive suspension, and powerful disc brakes provide exceptional control and comfort for experienced bikers navigating rocky climbs or shredding downhill. Reach new heights with Cymbal Summit!", PENDING_COMMIT_TIMESTAMP(), 0, 79999), (1, 5, "Cymbal Breeze", "Cruise in style and embrace effortless pedaling with the Breeze electric bike. Its whisper-quiet motor and long-lasting battery let you conquer hills and distances with ease. Enjoy scenic rides, commutes, or errands with a boost of confidence from Cymbal Breeze!", PENDING_COMMIT_TIMESTAMP(), 72, 129999), (1, 6, "Cymbal Trailblazer Backpack", "Carry all your essentials in style with the Trailblazer backpack. Its water-resistant material, multiple compartments, and comfortable straps keep your gear organized and accessible, allowing you to focus on the adventure. Blaze new trails with Cymbal Trailblazer!", PENDING_COMMIT_TIMESTAMP(), 24, 7999), (1, 7, "Cymbal Phoenix Lights", "See and be seen with the Phoenix bike lights. Powerful LEDs and multiple light modes ensure superior visibility, enhancing your safety and enjoyment during day or night rides. Light up your journey with Cymbal Phoenix!", PENDING_COMMIT_TIMESTAMP(), 87, 3999), (1, 8, "Cymbal Windstar Pump", "Flat tires are no match for the Windstar pump. Its compact design, lightweight construction, and high-pressure capacity make inflating tires quick and effortless. Get back on the road in no time with Cymbal Windstar!", PENDING_COMMIT_TIMESTAMP(), 36, 24999), (1, 9,"Cymbal Odyssey Multi-Tool","Be prepared for anything with the Odyssey multi-tool. This handy gadget features essential tools like screwdrivers, hex wrenches, and tire levers, keeping you ready for minor repairs and adjustments on the go. Conquer your journey with Cymbal Odyssey!", PENDING_COMMIT_TIMESTAMP(), 52, 999), (1, 10,"Cymbal Nomad Water Bottle","Stay hydrated on every ride with the Nomad water bottle. Its sleek design, BPA-free construction, and secure lock lid make it the perfect companion for staying refreshed and motivated throughout your adventures. Hydrate and explore with Cymbal Nomad!", PENDING_COMMIT_TIMESTAMP(), 42, 1299);
Haz clic en Ejecutar para insertar los datos.
En una pestaña nueva de Spanner Studio, copia y pega la siguiente instrucción de actualización:
UPDATE products p1 SET productDescriptionEmbedding = (SELECT embeddings.values FROM ML.PREDICT(MODEL EmbeddingsModel, (SELECT p1.productDescription as content) ) ) WHERE categoryId=1;
Haz clic en Ejecutar para generar las incorporaciones.
- Usa
ML.PREDICT
para generar un embedding para la búsqueda determinada ("Quiero comprar una bicicleta para principiantes para mi hijo de 3 años"). - Calcula el
COSINE_DISTANCE
entre la incorporación de esta búsqueda y elproductDescriptionEmbedding
de cada producto en la tabla de productos para encontrar resultados similares en tu tienda de Cymbal. - Filtra los resultados para incluir solo los productos con un
inventoryCount
mayor que 0. - Ordena los resultados según la distancia calculada y devuelve las cinco coincidencias más cercanas, junto con
productName
,productDescription
yinventoryCount
. En una pestaña nueva de Spanner Studio, copia y pega la siguiente consulta:
SELECT productName, productDescription, inventoryCount, COSINE_DISTANCE( productDescriptionEmbedding, ( SELECT embeddings.values FROM ML.PREDICT( MODEL EmbeddingsModel, (SELECT "I'd like to buy a starter bike for my 3 year old child" AS content)) )) AS distance FROM products WHERE inventoryCount > 0 ORDER BY distance LIMIT 5;
Haz clic en Ejecutar para mostrar los productos que mejor coincidan con tu texto de búsqueda.
Resultado de ejemplo:
/*-----------------+--------------------+----------------+--------------------* | productName | productDescription | inventoryCount | distance | +------------------+--------------------+----------------+--------------------+ | Cymbal Sprout | Let their cycling | 10 | 0.3094387191860244 | | | journey begin with | | | | | the Cymbal Sprout, | | | | | the ideal balance | | | | | bike for beginning | | | | | riders ages 2-4 | | | | | years... | | | | Cymbal Spark Jr | Light, vibrant, | 34 | 0.3412342902117166 | | | and ready for | | | | | adventure, the | | | | | Spark Jr. is the | | | | | perfect first bike | | | | | for young riders | | | | | (ages 5-8)... | | | | Cymbal Helios | Safety meets style | 100 | 0.4197863319656684 | | Helmet | with the Cymbal | | | | | children's bike | | | | | helmet... | | | | Cymbal Breeze | Cruise in style and| 72 | 0.485231776523978 | | | embrace effortless | | | | | pedaling with the | | | | | Breeze electric | | | | | bike... | | | | Cymbal Phoenix | See and be seen | 87 | 0.525101413779242 | | Lights | with the Phoenix | | | | | bike lights... | | | *------------------+--------------------+----------------+--------------------*/
En una pestaña nueva de Spanner Studio, copia y pega la siguiente declaración de DDL para volver a crear la columna
productDescriptionEmbedding
:ALTER TABLE products DROP COLUMN productDescriptionEmbedding; ALTER TABLE products ADD COLUMN productDescriptionEmbedding ARRAY<FLOAT32>(vector_length=>VECTOR_LENGTH_VALUE);
Reemplaza
VECTOR_LENGTH_VALUE
por las dimensiones máximas de salida del modelo de incorporación que elegiste.Haz clic en Ejecutar.
Copia y pega la siguiente instrucción de inserción para volver a generar las incorporaciones de vectores:
UPDATE products p1 SET productDescriptionEmbedding = (SELECT embeddings.values from ML.PREDICT(MODEL EmbeddingsModel, (SELECT p1.productDescription as content))) WHERE categoryId=1;
Haz clic en Ejecutar.
Copia y pega la siguiente instrucción DDL para crear el índice vectorial:
CREATE VECTOR INDEX ProductDescriptionEmbeddingIndex ON products(productDescriptionEmbedding) WHERE productDescriptionEmbedding IS NOT NULL OPTIONS ( distance_type = 'COSINE' );
Haz clic en Ejecutar.
- Genera la incorporación de la instrucción por separado, en lugar de hacerlo dentro de la consulta en SQL.
- Copia los resultados de las incorporaciones en la búsqueda.
- Usa la sugerencia
FORCE_INDEX
para hacer referencia al nuevo índice de vectores:@{force_index=ProductDescriptionEmbeddingIndex}
- Usa la función de distancia de vectores
APPROX_COSINE_DISTANCE
en lugar deCOSINE_DISTANCE
. La opciónJSON '{"num_leaves_to_search": num_leaves}'
es obligatoria. En una pestaña nueva de Spanner Studio, copia y pega la siguiente consulta para generar la incorporación de la instrucción:
-- Generate the prompt embedding SELECT embeddings.values FROM ML.PREDICT( MODEL EmbeddingsModel, (SELECT "I'd like to buy a starter bike for my 3 year old child" as content) );
Haz clic en Ejecutar.
Copia el resultado de
embeddings.values
.Reemplaza
embedding
en la siguiente consulta por el resultado de la incorporación que copiaste en el paso anterior.-- Update embedding query using the vector index SELECT productName, productDescription, inventoryCount, (APPROX_COSINE_DISTANCE(productDescriptionEmbedding, array<float32>[embedding], options => JSON '{\"num_leaves_to_search\": 10}')) as distance FROM products @{force_index=ProductDescriptionEmbeddingIndex} WHERE productDescriptionEmbedding IS NOT NULL AND inventoryCount > 0 ORDER BY distance LIMIT 5;
La nueva consulta en SQL es similar a la siguiente:
SELECT productName, productDescription, count, (APPROX_COSINE_DISTANCE(productDescriptionEmbedding, array<float32>[-0.00457216799,-0.0771846101,-0.0319350846,0.0352052487,-0.0457422845,0.0183265656...], options => JSON '{\"num_leaves_to_search\": 10}')) as distance FROM products @{force_index=ProductDescriptionEmbeddingIndex} WHERE productDescriptionEmbedding IS NOT NULL AND inventoryCount > 0 ORDER BY distance LIMIT 5;
Resultado de ejemplo:
/*-----------------+--------------------+----------------+--------------------* | productName | productDescription | inventoryCount | distance | +------------------+--------------------+----------------+--------------------+ | Cymbal Sprout | Let their cycling | 10 | 0.30935457151661594| | | journey begin with | | | | | the Cymbal Sprout, | | | | | the ideal balance | | | | | bike for beginning | | | | | riders ages 2-4 | | | | | years... | | | | Cymbal Spark Jr | Light, vibrant, | 34 | 0.34116496551593656| | | and ready for | | | | | adventure, the | | | | | Spark Jr. is the | | | | | perfect first bike | | | | | for young riders | | | | | (ages 5-8)... | | | | Cymbal Helios | Safety meets style | 100 | 0.4198014303921187 | | Helmet | with the Cymbal | | | | | children's bike | | | | | helmet... | | | | Cymbal Breeze | Cruise in style and| 72 | 0.4850674854267337 | | | embrace effortless | | | | | pedaling with the | | | | | Breeze electric | | | | | bike... | | | | Cymbal Phoenix | See and be seen | 87 | 0.525101413779242 | | Lights | with the Phoenix | | | | | bike lights... | | | *------------------+--------------------+----------------+--------------------*/
El Cymbal Sprout, con su
APPROX_COSINE_DISTANCE
de 0.30935457151661594, tiene el mayor grado de similitud con la búsqueda original.Para obtener más información sobre cómo interpretar la relación entre las funciones de vectores y la similitud, consulta Elige entre las funciones de distancia de vectores para medir la similitud de los embeddings de vectores.
En la consola de Google Cloud , ve a la página Instancias de Spanner.
Haz clic en el nombre de la instancia que tiene la base de datos que deseas borrar, por ejemplo, test-instance.
Haz clic en el nombre de la base de datos que deseas borrar, por ejemplo, example-db.
En la página Descripción general de la base de datos, haz clic en Borrar Borrar base de datos.
Para confirmar que deseas borrar la base de datos, ingresa su nombre y haz clic en Borrar.
En la consola de Google Cloud , ve a la página Instancias de Spanner.
Haz clic en el nombre de la instancia que deseas borrar, por ejemplo, test-instance.
Haz clic en Borrar instancia.
Ingresa el nombre de la instancia y haz clic en Borrar para confirmar que quieres borrarla.
- Obtén más información sobre la función de k-vecino más cercano (KNN) de Spanner.
- Obtén más información sobre la función de búsqueda de vecinos más cercanos aproximados (ANN) de Spanner.
- Obtén más información para realizar predicciones en línea con SQL usando Vertex AI.
Crea una instancia
Cuando uses Spanner por primera vez, deberás crear una instancia, que es una asignación de recursos que usan las bases de datos de Spanner. En esta sección, se muestra cómo crear una instancia con la consola de Google Cloud .
Crea una base de datos
Después de que se ejecute la instancia, podrás crear tu base de datos. Defines tu esquema en la base de datos .
Crea un modelo de incorporación
Cuando usas la sentencia DDL CREATE MODEL
en Spanner, registras una referencia al extremo del modelo de Vertex AI desde tu base de datos. Después de registrar el modelo, puedes usar la función ML.PREDICT
para acceder a él en tus consultas.
En el siguiente ejemplo, se muestra cómo registrar un modelo de incorporación de texto de Vertex AI, que luego se usa para realizar una búsqueda de similitud y encontrar productos similares en una base de datos.
Cargar datos
Para cargar los datos de muestra de Cymbal en la tabla products
, haz lo siguiente:
Genera embeddings de vectores
Después de registrar un modelo y cargar datos en Spanner, puedes generar embeddings de vectores con las descripciones de los productos de tus datos. Los embeddings de vectores transforman los datos de texto en un valor numérico que captura el significado y el contexto de las palabras. Esta transformación es fundamental para realizar una búsqueda semántica.
En este paso, propagarás la columna productDescriptionEmbedding
generando embeddings a partir de la columna productDescription
con ML.PREDICT
. Esto te permite realizar una búsqueda de similitud de vectores en el siguiente paso.
Realiza una búsqueda de similitud de vectores
En el siguiente ejemplo, proporcionarás una solicitud de búsqueda en lenguaje natural con una consulta en SQL. La consulta en SQL realiza una búsqueda de similitud de vectores con los embeddings de vectores que generaste anteriormente. La consulta realiza la búsqueda de la siguiente manera:
Cómo escalar la búsqueda vectorial para usar vecinos más cercanos aproximados
En el ejemplo anterior de búsqueda vectorial, se usa la búsqueda vectorial de K-vecinos más cercanos (KNN) exacta. Las funciones de distancia vectorial de KNN (distancia del coseno, distancia euclidiana y producto escalar) son útiles cuando puedes consultar un subconjunto específico de tus datos de Spanner. Dado que la búsqueda de KNN calcula la distancia exacta entre un vector de búsqueda y todos los vectores de la base de datos, es eficiente cuando puedes particionar los datos. Si tu búsqueda necesita comparar el vector de búsqueda con todos los vectores de tu base de datos sin filtros específicos y no puedes dividir la búsqueda en subbúsquedas independientes, es posible que experimentes cuellos de botella en el rendimiento si usas KNN. La búsqueda vectorial de vecinos aproximados más cercanos (ANN) resulta útil en estas situaciones. Para obtener más información, consulta Cómo encontrar vecinos más cercanos aproximados.
Si tus cargas de trabajo no se pueden particionar y tienes una gran cantidad de datos, puedes usar la búsqueda de vectores con ANN para aumentar el rendimiento de las consultas en conjuntos de datos más grandes.
Para escalar y usar la búsqueda de vectores con ANN en Spanner, haz lo siguiente:
Crea un índice vectorial
Spanner acelera las búsquedas de vectores de ANN con un índice de vectores especializado que aprovecha el vecino más cercano escalable (ScaNN) de Google Research.
Para crear un índice vectorial en tu conjunto de datos, debes modificar la columna productDescriptionEmbeddings
para definir una anotación vector_length
.
La anotación vector_length
indica la dimensión de cada vector. Las siguientes instrucciones DDL descartan la columna productDescriptionEmbedding
y la vuelven a crear con vector_length
. La longitud máxima (dimensión) del vector varía según el modelo de incorporación que elijas.
Usa la función de distancia del vector de ANN
Para usar la búsqueda de vectores con ANN en Spanner, modifica lo siguiente en tu consulta en SQL:
Limpia
En esta sección, se muestra cómo usar la consola de Google Cloud para limpiar tus recursos. Para evitar que se apliquen cargos adicionales a tu cuenta de facturación de Cloud, borra la base de datos y la instancia que creaste durante la configuración. Si borras una instancia, se borrarán todas las bases de datos creadas en ella.