Compila aplicaciones de IA generativa con AlloyDB AI

En esta sección, se describe cómo invocar predicciones y consultar y generar un índice de embeddings con la extensión pgvector. Estas funciones potenciadas por IA y aprendizaje automático están disponibles a través de AlloyDB AI, que es un conjunto de funciones de AlloyDB para PostgreSQL que te permiten aplicar el poder semántico y predictivo de los modelos de aprendizaje automático (AA) a tus datos.

Obtén más información sobre AlloyDB AI en https://cloud.google.com//alloydb/docs/ai.

Invoca predicciones

Para integrar Vertex AI con AlloyDB Omni y ejecutar predicciones en los modelos almacenados en Vertex AI, sigue estos pasos.

Antes de comenzar

  1. Habilita las predicciones en línea de Vertex AI en GDC.
  2. Ejecuta el siguiente comando para crear un secreto de Kubernetes basado en la clave de la cuenta de servicio que descargaste en los pasos anteriores. Asegúrate de crear el secreto de Kubernetes en el mismo espacio de nombres que tu recurso DBCluster.

    kubectl create secret generic SECRET_NAME \
    --from-file=PATH_TO_SERVICE_ACCOUNT_KEY/private-key.json \
    -n NAMESPACE

    Reemplaza lo siguiente:

    • SECRET_NAME: Es el nombre del secreto que se usa cuando creas un manifiesto de DBCluster para permitir que AlloyDB Omni acceda a las funciones de IA de Distributed Cloud. Por ejemplo, vertex-ai-key-alloydb.

    • PATH_TO_SERVICE_ACCOUNT_KEY: Es la ruta de acceso a la ubicación en la que descargaste la clave de la cuenta de servicio de private-key.json.

    • NAMESPACE: Es el espacio de nombres del clúster de la base de datos.

  3. Instala el operador de AlloyDB Omni siguiendo los pasos que se indican en Elige un tipo de motor de base de datos y crea un clúster de base de datos.

  4. Crea un clúster de base de datos con AlloyDB AI y configura vertexAIKeyRef en el campo googleMLExtension del manifiesto DBCluster como el secreto de Kubernetes creado en los pasos anteriores.

    apiVersion: v1
    kind: Secret
    metadata:
      name: db-pw-DBCLUSTER_NAME
      namespace: USER_PROJECT
    type: Opaque
    data:
      DBCLUSTER_NAME: "BASE64_PASSWORD"
    ---
    apiVersion: DBENGINE_NAME.dbadmin.gdc.goog/v1
    kind: DBCluster
    metadata:
      name: DBCLUSTER_NAME
      namespace: USER_PROJECT
    spec:
      primarySpec:
        adminUser:
          passwordRef:
            name: db-pw-DBCLUSTER_NAME
        features:
          googleMLExtension:
            config:
              vertexAIKeyRef: SECRET_NAME
        version: "DB_VERSION"
        resources:
          memory: DB_MEMORY
          cpu: DB_CPU
          disks:
          - name: DataDisk
            size: DB_DATA_DISK
    

    Reemplaza las siguientes variables:

    • DBCLUSTER_NAME: Es el nombre del clúster de la base de datos.
    • USER_PROJECT: Es el nombre del proyecto del usuario en el que se creará el clúster de la base de datos.
    • BASE64_PASSWORD: Es la codificación en Base64 de la contraseña del administrador de la base de datos.
    • DBENGINE_NAME: Es el nombre del motor de base de datos. Se establece en alloydbomni.
    • DB_VERSION: Es la versión del motor de base de datos.
    • DB_MEMORY: Es la cantidad de memoria asignada al clúster de la base de datos, por ejemplo, 5Gi.
    • DB_CPU: Es la cantidad de CPU asignadas al clúster de base de datos, por ejemplo, 2.
    • DB_DATA_DISK: Es la cantidad de espacio asignado al clúster de la base de datos, por ejemplo, 10 Gi.

    Aplica el manifiesto.

    kubectl apply -f DB_CLUSTER_YAML

    Reemplaza lo siguiente:

    • DB_CLUSTER_YAML: Es el nombre de este archivo de manifiesto del clúster de base de datos, por ejemplo, alloydb-omni-db-cluster.yaml.
  5. Instala la extensión de google_ml_integration.

    CREATE EXTENSION google_ml_integration CASCADE;
    

Invoca una predicción

Invoca una predicción en línea a través de un extremo del modelo de Vertex AI ejecutando la siguiente función de SQL ml_predict_row():

  SELECT ml_predict_row('PREDICTION_ENDPOINT/PROJECT_NAMESPACE/ORGANIZATION/ZONE/DNS/DNS_SUFFIX', '{ "instances": [ INSTANCES ], "parameters":
  PARAMETERS');

Reemplaza lo siguiente:

  • PREDICTION_ENDPOINT: Es el nombre calificado del extremo de Vertex AI.

  • PROJECT_NAMESPACE: Es el espacio de nombres en el que se implementa el extremo de Vertex AI.

  • ORGANIZATION: Es el nombre de la organización en la que se implementa el extremo de Vertex AI.

  • ZONE: Es la zona en la que se implementa tu extremo de Vertex AI.

  • DNS: El DNS de tu organización

  • DNS_SUFFIX: Es el sufijo del objeto DNS.

  • INSTANCES: las entradas de la llamada de predicción, en formato JSON

  • PARAMETERS: los parámetros de la llamada de predicción, en formato JSON

Consulta embeddings y un índice mediante pgvector

La extensión pgvector de PostgreSQL te permite usar operadores y funciones específicos de vectores cuando almacenas, indexas y consultas embeddings de texto en tu base de datos. AlloyDB proporciona optimizaciones para trabajar con pgvector, lo que te permite crear índices que pueden acelerar ciertas consultas que involucran embeddings.

Obtén más información para usar AlloyDB como un LLM y generar y almacenar embeddings de vectores basados en un LLM en https://cloud.google.com/alloydb/docs/ai/work-with-embeddings#index.

Crea índices y vectores de consulta con ScaNN

En esta sección, se muestra cómo usar los embeddings almacenados para generar índices y consultar embeddings. Puedes crear índices ScaNN con AlloyDB.

Antes de comenzar

Antes de comenzar a crear índices, debes completar los siguientes requisitos previos.

  • Los vectores de incorporación se agregan a una tabla en tu base de datos de AlloyDB.

  • Se instaló la versión 0.5.0 o posterior de la extensión vector basada en pgvector, que Google extendió para AlloyDB.

    CREATE EXTENSION IF NOT EXISTS vector;
    
  • Para generar índices ScaNN, instala la extensión postgres_ann además de la extensión vector.

    CREATE EXTENSION IF NOT EXISTS postgres_ann;
    

Crea un índice de ScaNN

Puedes crear un índice ScaNN para las tablas de tu base de datos.

AlloyDB postgres_ann, una extensión de PostgreSQL desarrollada por Google que implementa un índice de vecinos más cercanos altamente eficiente potenciado por el algoritmo ScaNN.

El índice ScaNN es un índice de cuantificación basado en un árbol para la búsqueda de vecinos más cercanos aproximados. Proporciona un tiempo de compilación de índice bajo y un uso de memoria pequeño. Además, proporciona QPS rápidas según la carga de trabajo.

Índice de árbol ScaNN de dos niveles

Para aplicar un índice de árbol de dos niveles con el algoritmo ScaNN a una columna que contiene embeddings de vectores almacenadas, ejecuta la siguiente consulta DDL:

CREATE INDEX INDEX_NAME ON TABLE
  USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION)
  WITH (num_leaves=NUM_LEAVES_VALUE);

Reemplaza lo siguiente:

  • INDEX_NAME: El nombre del índice que deseas crear, por ejemplo, my-scann-index. Los nombres de los índices se comparten en toda la base de datos. Asegúrate de que cada nombre de índice sea único para cada tabla de tu base de datos.

  • TABLE: Es la tabla a la que se agregará el índice.

  • EMBEDDING_COLUMN: Es una columna que almacena datos vector.

  • DISTANCE_FUNCTION: Es la función de distancia que se usará con este índice. Elige una de estas opciones:

    • Distancia de L2: l2

    • Producto escalar: dot_product

    • Distancia de coseno: cosine

  • NUM_LEAVES_VALUE: Es la cantidad de particiones que se aplicarán a este índice. Se puede establecer en cualquier valor entre 1 y 1048576.

Índice de árbol ScaNN de tres niveles

Para crear un índice de árbol de tres niveles con el algoritmo de ScaNN en una columna que contiene embeddings de vectores almacenados, ejecuta la siguiente consulta en DDL:

CREATE INDEX INDEX_NAME ON TABLE
  USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION)
  WITH (num_leaves=NUM_LEAVES_VALUE, max_num_levels = MAX_NUM_LEVELS);

Reemplaza lo siguiente:

  • MAX_NUM_LEVELS: Es la cantidad máxima de niveles del árbol de agrupamiento de K-means. Se establece en 1(predeterminado) para la cuantificación basada en árboles de dos niveles y en 2 para la cuantificación basada en árboles de tres niveles.

Después de crear el índice, puedes ejecutar consultas de búsqueda de vecinos más cercanos que lo utilicen siguiendo las instrucciones en Realiza una consulta de vecino más cercano con texto determinado.

Los parámetros del índice deben establecerse para lograr un equilibrio adecuado entre las QPS y la recuperación.

Para crear este índice en una columna de embedding que use el tipo de datos real[] en lugar de vector, convierte la columna en el tipo de datos vector:

CREATE INDEX INDEX_NAME ON TABLE
  USING scann (CAST(EMBEDDING_COLUMN AS vector(DIMENSIONS)) DISTANCE_FUNCTION)
  WITH (num_leaves=NUM_LEAVES_VALUE, max_num_levels = MAX_NUM_LEVELS);

Reemplaza DIMENSIONS por el ancho dimensional de la columna de embedding.

Para ver el progreso de la indexación, usa la vista pg_stat_progress_create_index:

SELECT * FROM pg_stat_progress_create_index;

La columna phase muestra el estado actual de la creación del índice, y la fase building index: tree training desaparece después de que se crea el índice.

Ejecuta una consulta

Una vez que hayas almacenado y, también, indexado las embeddings en tu base de datos, puedes comenzar a realizar consultas con la funcionalidad de consulta de pgvector. No puedes ejecutar búsquedas masivas con la extensión postgres_ann.

Para encontrar los vecinos semánticos más cercanos a un vector de embedding, puedes ejecutar la siguiente consulta de ejemplo, en la que estableces la misma función de distancia que usaste durante la creación del índice.

  SELECT * FROM TABLE
    ORDER BY EMBEDDING_COLUMN DISTANCE_FUNCTION_QUERY ['EMBEDDING']
    LIMIT ROW_COUNT

Reemplaza lo siguiente:

  • TABLE: la tabla que contiene la embedding con la que se compara el texto.

  • INDEX_NAME: Es el nombre del índice que deseas usar, por ejemplo, my-scann-index.

  • EMBEDDING_COLUMN: la columna que contiene las incorporaciones almacenadas.

  • DISTANCE_FUNCTION_QUERY: Es la función de distancia que se usará con esta consulta. Elige una de las siguientes opciones según la función de distancia que se usó para crear el índice:

    • Distancia de L2: <->

    • Producto interno: <#>

    • Distancia de coseno: <=>

  • EMBEDDING: Es el vector de incorporación del que deseas encontrar los vecinos semánticos almacenados más cercanos.

  • ROW_COUNT: cantidad de filas que se mostrarán.

    Especifica 1 si solo deseas la mejor coincidencia.

También puedes usar la función embedding() para traducir el texto a un vector. Aplicas el vector a uno de los operadores de vecino más cercano pgvector, <-> para la distancia L2, para encontrar las filas de la base de datos con las embeddings semánticamente más similares. Ten en cuenta que primero debes registrar el modelo de Gecko de incorporación de texto para usar esta función.

Debido a que embedding() devuelve un array real, debes convertir de forma explícita la llamada embedding() en vector para usar estos valores con operadores pgvector.

  CREATE EXTENSION google_ml_integration;
  CREATE EXTENSION IF NOT EXISTS vector;

  SELECT * FROM TABLE
    ORDER BY EMBEDDING_COLUMN::vector
    <-> embedding('MODEL_IDVERSION_TAG', 'TEXT')
    LIMIT ROW_COUNT

Reemplaza lo siguiente:

  • MODEL_ID: el ID del modelo que se consultará.

    Si usas Vertex AI Model Garden, especifica textembedding-gecko@003 como el ID del modelo. Estos son los modelos basados en la nube que Distributed Cloud puede usar para las embeddings de texto.

  • Opcional: VERSION_TAG: Es la etiqueta de la versión del modelo que se consultará. Agrega @ a la etiqueta.

    Si usas uno de los modelos en inglés textembedding-gecko con Vertex AI, especifica una de las etiquetas de versión, por ejemplo, textembedding-gecko@003.

    Google recomienda enfáticamente que siempre especifiques la etiqueta de versión. Si no especificas la etiqueta de versión, AlloyDB siempre usará la versión del modelo más reciente, lo que podría generar resultados inesperados.

  • TEXT: es el texto que se traducirá en una embedding de vector.

Métricas del índice vectorial

En esta sección, se enumeran las métricas relacionadas con los índices de vectores que generas en AlloyDB. Puedes ver estas métricas con la vista pg_stat_ann_indexes que está disponible cuando instalas la extensión postgres_ann.

Métricas de usabilidad

Las métricas de usabilidad incluyen métricas que te ayudan a comprender el estado de la utilización del índice con métricas como la configuración del índice y la cantidad de análisis del índice.

Nombre de la métrica Tipo de datos Descripción
relid OID Es el identificador único de la tabla que contiene el índice de vectores.
indexrelid OID Es el identificador único del índice de vectores.
schemaname NAME Nombre del esquema al que pertenece el índice.
relname NAME Es el nombre de la tabla que contiene el índice.
indexrelname NAME Es el nombre del índice.
indextype NAME Es el tipo de índice. Este valor siempre se establece en postgres_ann.
indexconfig TEXT[] Es la configuración, como el recuento de hojas y el cuantificador, que se definió para el índice cuando se creó.
indexsize TEXT Es el tamaño del índice.
indexscan BIGINT Cantidad de análisis de índices iniciados en el índice.

Métricas de ajuste

Las métricas de ajuste proporcionan estadísticas sobre la optimización actual del índice, lo que te permite aplicar recomendaciones para mejorar el rendimiento de las consultas.

Nombre de la métrica Tipo de datos Descripción
insertcount BIGINT Cantidad de operaciones de inserción en el índice. Esta métrica también incluye cualquier cantidad de filas que existían antes de que se creara el índice.
updatecount BIGINT Cantidad de operaciones de actualización en el índice. Esta métrica no tiene en cuenta las actualizaciones de HOT.
deletecount BIGINT Cantidad de operaciones de eliminación en el índice.
distribution JSONB Son las distribuciones de vectores en todas las particiones del índice.

En los siguientes campos, se muestra la distribución:
  • maximum (INT8): Es la cantidad máxima de vectores en todas las particiones.
  • minimum (INT8): Es la cantidad mínima de vectores en todas las particiones.
  • average (FLOAT) : Es la cantidad promedio de vectores en todas las particiones.
  • outliers (INT8[]): Valores atípicos principales en todas las particiones. Este valor muestra los 20 valores atípicos principales.

Nota: Debido a las características inherentes del algoritmo de agrupamiento K-means, siempre habrá cierto grado de varianza en la distribución de los vectores en las particiones, incluso cuando se cree el índice inicialmente.

Ajuste de la recomendación según las métricas

Mutación
Las métricas insertcount, updatecount y deletecount juntas muestran los cambios o las mutaciones en el vector del índice.
El índice se crea con una cantidad específica de vectores y particiones. Cuando se realizan operaciones como insertar, actualizar o borrar en el índice de vectores, solo se ven afectadas las particiones iniciales en las que residen los vectores. Por lo tanto, la cantidad de vectores en cada partición fluctúa con el tiempo, lo que puede afectar la recuperación, las QPS o ambas.
Si, con el tiempo, tienes problemas de lentitud o precisión, como un QPS bajo o una recuperación deficiente, en tus búsquedas de ANN, considera revisar estas métricas. Una gran cantidad de mutaciones en relación con la cantidad total de vectores podría indicar la necesidad de volver a indexar.
Distribución
La métrica distribution muestra las distribuciones de vectores en todas las particiones.
Cuando creas un índice, este se crea con una cantidad específica de vectores y particiones fijas. El proceso de partición y la distribución posterior se realizan en función de esta consideración. Si se agregan vectores adicionales, se particionan entre las particiones existentes, lo que genera una distribución diferente en comparación con la distribución cuando se creó el índice. Dado que la distribución final no considera todos los vectores de forma simultánea, es posible que se vean afectados el recall, las QPS o ambos.
Si observas una disminución gradual en el rendimiento de tus búsquedas de ANN, como tiempos de respuesta más lentos o menor precisión en los resultados (medidos por QPS o recuperación), considera revisar esta métrica y volver a indexar.