Usa Vertex AI Matching Engine

En esta guía, se explica cómo configurar y usar Vertex AI Matching Engine para realizar búsquedas de similitud de vectores.

Configura una conexión de intercambio de tráfico entre redes de VPC

A fin de reducir la latencia de red para las consultas en línea de coincidencia de vectores, llama a los extremos del servicio de Vertex AI desde tu nube privada virtual (VPC) mediante el Acceso privado al servicio. Por cada proyecto de Google Cloud, solo una red de VPC puede intercambiar tráfico con Matching Engine. Si ya tienes una VPC con el acceso privado a servicios configurado, puedes usar esa VPC para intercambiar tráfico con Vertex AI Matching Engine.

Configurar una conexión de intercambio de tráfico entre redes de VPC es una tarea inicial que se requiere solo una vez por cada proyecto de Google Cloud. Después de realizar esta configuración, podrás hacer llamadas al índice de Matching Engine desde cualquier cliente que se ejecute dentro de tu VPC.

La conexión de intercambio de tráfico entre redes de VPC solo es necesaria para consultas en línea que coincidan con los vectores. Las llamadas a la API para crear, implementar y borrar índices no requieren una conexión de intercambio de tráfico entre redes de VPC.

El administrador del proyecto de Cloud o el administrador de red deben completar los siguientes pasos:

  1. Para configurar tus proyectos de Cloud, habilita la facturación y las API, y completa los siguientes pasos antes de comenzar.

  2. Para evitar conflictos de direcciones IP entre tu red de VPC y la red de nuestro productor de servicios, debes asignar un rango de direcciones IP para el servicio de Matching Engine en el que se implementen los índices de Matching Engine. Para obtener más información, consulta Asigna rangos de direcciones IP.

    # Note: `prefix-length=16` means a CIDR block with mask /16 is reserved for
    # use by Google services. Make sure to enable the Service Networking API.
    gcloud compute addresses create $PEERING_RANGE_NAME \
        --global \
        --prefix-length=16 \
        --description="peering range for Matching Engine service" \
        --network=$NETWORK_NAME \
        --purpose=VPC_PEERING \
        --project=$PROJECT_ID
    
    # Create the VPC connection.
    gcloud services vpc-peerings connect \
        --service=servicenetworking.googleapis.com \
        --network=$NETWORK_NAME \
        --ranges=$PEERING_RANGE_NAME \
        --project=$PROJECT_ID
    

Después de crear una conexión privada, puedes realizar llamadas en línea a un índice de Matching Engine desde cualquier instancia de máquina virtual (VM) que se ejecute dentro de la VPC de intercambio de tráfico.

Ejemplo de bloc de notas

Después de completar la configuración inicial de intercambio de tráfico entre redes de VPC, puedes crear una instancia de notebook administrada por el usuario dentro de esa VPC y emitir comandos desde el notebook.

Inicia el notebook de ejemplo en Vertex AI Workbench o visualiza el notebook en GitHub.

Control de acceso con IAM

Vertex AI usa Identity and Access Management (IAM) para administrar el acceso a los recursos. Para otorgar acceso a un recurso, asigna una o más funciones a un usuario, un grupo o una cuenta de servicio.

Si quieres usar Match Engineer, usa estas funciones predefinidas para otorgar diferentes niveles de acceso a los recursos a nivel de proyecto.

Formato y estructura de los datos de entrada

Para compilar un índice nuevo o actualizar un índice existente, proporciona vectores a Matching Engine con el formato y la estructura descritos en las siguientes secciones.

Almacenamiento de datos de entrada

Almacena los datos de entrada en un bucket de Cloud Storage en el proyecto de Cloud.

Estructura del directorio de entrada

Estructura tu directorio de datos de entrada de la siguiente manera:

  • Directorio raíz por lotes: Crea un directorio raíz para cada lote de archivos de datos de entrada. Usa un solo directorio de Cloud Storage como el directorio raíz. En el siguiente ejemplo, el directorio raíz se llama batch_root.
  • Nombres de archivos: Coloca los archivos de datos individuales directamente en batch_root y ponles un nombre con el sufijo .csv, .json o .avro, según el formato de archivo que uses.

    • Matching Engine interpreta cada archivo de datos como un conjunto de registros.

      El formato del registro se determina mediante el sufijo del nombre del archivo y se describe en una de las siguientes secciones.

    • Cada registro debe tener un ID y un vector de atributos, que puede tener campos adicionales, como restricciones y amontonamiento.

  • Borrar directorio: Puedes crear un subdirectorio delete en batch_root. Este directorio es opcional.

    • Cada archivo que se encuentra directamente en batch_root/delete es un archivo de texto de ID de registro, con un ID en cada línea. Cada ID debe ser una string UTF-8 válida.
  • Se ignorarán todos los demás directorios y archivos.

  • Todos los registros de todos los archivos de datos, incluidos los de delete, constan de un solo lote de entrada. El orden relativo de los registros dentro de un archivo de datos es inmaterial.

  • Un ID único puede aparecer solo una vez por lote.

    • Nota: Un ID no puede aparecer en un archivo de datos regulares y en un archivo de datos delete.
  • Todos los ID de un archivo de datos en delete se quitan de la próxima versión del índice. En la próxima versión, se incluirán los registros de archivos de datos regulares, y es posible que se reemplace un valor en una versión anterior del índice.

Formatos de archivo de datos

Los archivos de datos pueden estar en formato CSV, JSON o Avro.

CSV

  • Codifica el archivo mediante UTF-8.
  • Haz que cada línea sea un CSV válido para interpretarlo como un registro único.
  • Establece el primer valor como el id y el de id como una string UTF-8 válida.
  • Haz que los siguientes valores N sean la dimensión del vector de atributos, que se configura cuando se crea un índice. Haz que cada valor sea un literal de punto flotante tal como se define en las especificaciones del lenguaje Java.

JSON

  • Codifica el archivo mediante UTF-8.
  • Haz que cada línea sea un objeto JSON válido para que se interpreten como un registro.
  • En cada registro, incluye un campo llamado id que requiera una string UTF-8 válida que sea el ID del vector.
  • En cada registro, incluye un campo llamado embedding que requiera un array de números. Este es el vector de atributos.

AVRO

  • Usa un archivo Avro válido.
  • Haz registros que se ajusten al siguiente esquema:

    {
      "type": "record",
      "name": "FeatureVector",
      "fields": [
        {
          "name": "id",
          "type": "string"
        },
        {
          "name": "embedding",
          "type": {
            "type": "array",
            "items": "float"
          }
        },
        {
          "name": "restricts",
          "type": [
            "null",
            {
              "type": "array",
              "items": {
                "type": "record",
                "name": "Restrict",
                "fields": [
                  {
                    "name": "namespace",
                    "type": "string"
                  },
                  {
                    "name": "allow",
                    "type": [
                      "null",
                      {
                        "type": "array",
                        "items": "string"
                      }
                    ]
                  },
                  {
                    "name": "deny",
                    "type": [
                      "null",
                      {
                        "type": "array",
                        "items": "string"
                      }
                    ]
                  }
                ]
              }
            }
          ]
        },
        {
          "name": "crowding_tag",
          "type": [
            "null",
            "string"
          ]
        }
      ]
    }
    

Administra índices

En las siguientes secciones, se describe cómo crear, borrar o actualizar índices. Para obtener más información, consulta los documentos de la API sobre índices.

Archivo de metadatos de índice

Antes de crear un índice, debes configurar los parámetros para tu índice.

Por ejemplo, crea un archivo llamado index_metadata.json:

{
  "contentsDeltaUri": "gs://BUCKET_NAME/path",
  "config": {
    "dimensions": 100,
    "approximateNeighborsCount": 150,
    "distanceMeasureType": "DOT_PRODUCT_DISTANCE",
    "algorithm_config": {
      "treeAhConfig": {
        "leafNodeEmbeddingCount": 500,
        "leafNodesToSearchPercent": 7
      }
    }
  }
}

Puedes encontrar la definición de cada uno de estos campos en Configura índices o ver las definiciones en el siguiente esquema:

title: NearestNeighborSearch
type: object
properties:
  contentsDeltaUri:
    type: string
    description: >
      Allows inserting, updating  or deleting the contents of the Matching Engine Index.
      The string must be a valid Cloud Storage directory path. If this
      field is set when calling IndexService.UpdateIndex, then no other
      Index field can be also updated as part of the same call.
      The expected structure and format of the files this URI points to is
      described at https://cloud.google.com/vertex-ai/docs/matching-engine/using-matching-engine#input-data-format
    writeOnly: true
  isCompleteOverwrite:
    type: boolean
    description: >
      If this field is set together with contentsDeltaUri when calling IndexService.UpdateIndex,
      then existing content of the Index will be replaced by the data from the contentsDeltaUri.
    default: false
  config:
    type: object
    description: >
      The configuration of the Matching Engine Index.
    required:
    - dimensions
    - algorithmConfig
    properties:
      dimensions:
        type: integer
        format: int32
        description: >
          The number of dimensions of the input vectors.
      approximateNeighborsCount:
        type: integer
        format: int32
        description: >
          The default number of neighbors to find via approximate search before exact reordering is
          performed. Exact reordering is a procedure where results returned by an
          approximate search algorithm are reordered via a more expensive distance computation.
          Required if tree-AH algorithm is used.
      distanceMeasureType:
        description: >
          The distance measure used in nearest neighbor search.
        oneOf:
        - enum: [SQUARED_L2_DISTANCE]
          description: >
            Euclidean (L_2) Distance
        - enum: [L1_DISTANCE]
          description: >
            Manhattan (L_1) Distance
        - enum: [COSINE_DISTANCE]
          description: >
            Cosine Distance. Defined as 1 - cosine similarity.
        - enum: [DOT_PRODUCT_DISTANCE]
          description: >
            Dot Product Distance. Defined as a negative of the dot product
        default: DOT_PRODUCT_DISTANCE
      featureNormType:
        description: >
          Type of normalization to be carried out on each vector.
        oneOf:
        - enum: [UNIT_L2_NORM]
          description: >
            Unit L2 normalization type.
        - enum: [NONE]
          description: >
            No normalization type is specified.
        default: NONE
      algorithmConfig:
        description: >
          The configuration with regard to the algorithms used for efficient search.
        oneOf:
        - type: object
          description: >
             Configuration options for using the tree-AH algorithm (Shallow tree + Asymmetric Hashing).
             Please refer to this paper for more details: https://arxiv.org/abs/1908.10396
          properties:
            type:
              type: string
              enum: [treeAhConfig]
            leafNodeEmbeddingCount:
              type: integer
              format: int64
              description: >
                 Number of embeddings on each leaf node. The default value is 1000 if not set.
            leafNodesToSearchPercent:
              type: number
              format: int32
              description: >
                 The default percentage of leaf nodes that any query may be searched. Must be in
                 range 1-100, inclusive. The default value is 10 (means 10%) if not set.
        - type: object
          description: >
             Configuration options for using brute force search, which simply implements the
             standard linear search in the database for each query.
          properties:
            type:
              type: string
              enum: [bruteForceConfig]
        discriminator:
          propertyName: type

Este archivo de esquema de metadatos está disponible para descargar desde Cloud Storage.

Crea un índice

Para crear un índice, sigue estos pasos:

gcloud

  1. Define los metadatos de índices.
  2. Usa el comando gcloud ai indexes create:
gcloud ai indexes create \
  --metadata-file=LOCAL_PATH_TO_METADATA_FILE \
  --display-name=INDEX_NAME \
  --project=PROJECT_ID \
  --region=LOCATION

Reemplaza lo siguiente:

  • LOCAL_PATH_TO_METADATA_FILE: La ruta de acceso del archivo local al archivo de metadatos.
  • INDEX_NAME: El nombre visible del índice
  • PROJECT_ID: El ID del proyecto.
  • LOCATION: la región en la que usas Vertex AI.

LÍNEA DE REST Y CMD

Antes de usar cualquiera de los datos de solicitud a continuación, realiza los siguientes reemplazos:

  • LOCATION: Tu región.
  • PROJECT: ID del proyecto
  • INDEX_NAME: El nombre visible del índice
  • INPUT_DIR: Es la ruta de acceso del directorio de Cloud Storage del contenido del índice.
  • PROJECT_NUMBER: es el número de tu proyecto.

Método HTTP y URL:

POST https://LOCATION-aiplatform.googleapis.com/v1/projects/PROJECT/locations/LOCATION/indexes

Cuerpo JSON de la solicitud:

{
  "display_name": "INDEX_NAME",
  "metadata": {
    "contentsDeltaUri": "INPUT_DIR",
    "config": {
      "dimensions": 100,
      "approximateNeighborsCount": 150,
      "distanceMeasureType": "DOT_PRODUCT_DISTANCE",
      "algorithm_config": {
        "treeAhConfig": {
          "leafNodeEmbeddingCount": 500,
          "leafNodesToSearchPercent": 7
        }
      }
    }
  }
}

Para enviar tu solicitud, expande una de estas opciones:

Deberías recibir una respuesta JSON similar a la que se muestra a continuación:

{
  "name": "projects/PROJECT_NUMBER/locations/LOCATION/indexes/INDEX_ID/operations/OPERATION_ID",
  "metadata": {
    "@type": "type.googleapis.com/google.cloud.aiplatform.v1.CreateIndexOperationMetadata",
    "genericMetadata": {
      "createTime": "2022-01-08T01:21:10.147035Z",
      "updateTime": "2022-01-08T01:21:10.147035Z"
    }
  }
}
Puedes consultar el estado de la operación hasta que la respuesta incluya "done": true.

Mostrar lista de índices

gcloud

Usa el comando gcloud ai indexes list:

gcloud ai indexes list \
  --project=PROJECT_ID \
  --region=LOCATION

Reemplaza lo siguiente:

  • PROJECT_ID: El ID del proyecto.
  • LOCATION: la región en la que usas Vertex AI.

LÍNEA DE REST Y CMD

Antes de usar cualquiera de los datos de solicitud a continuación, realiza los siguientes reemplazos:

  • LOCATION: Tu región.
  • PROJECT: ID del proyecto
  • INDEX_NAME: El nombre visible del índice
  • PROJECT_NUMBER: es el número de tu proyecto.

Método HTTP y URL:

GET https://LOCATION-aiplatform.googleapis.com/v1/projects/PROJECT/locations/LOCATION/indexes

Para enviar tu solicitud, expande una de estas opciones:

Deberías recibir una respuesta JSON similar a la que se muestra a continuación:

{
  "indexes": [
    {
      "name": "projects/PROJECT_NUMBER/locations/LOCATION/indexes/INDEX_ID",
      "displayName": "INDEX_NAME",
      "metadataSchemaUri": "gs://google-cloud-aiplatform/schema/matchingengine/metadata/nearest_neighbor_search_1.0.0.yaml",
      "metadata": {
        "config": {
          "dimensions": 100,
          "approximateNeighborsCount": 150,
          "distanceMeasureType": "DOT_PRODUCT_DISTANCE",
          "featureNormType": "NONE",
          "algorithmConfig": {
            "treeAhConfig": {
              "maxLeavesToSearch": 50,
              "leafNodeCount": 10000
            }
          }
        }
      },
      "etag": "AMEw9yNU8YX5IvwuINeBkVv3yNa7VGKk11GBQ8GkfRoVvO7LgRUeOo0qobYWuU9DiEc=",
      "createTime": "2020-11-08T21:56:30.558449Z",
      "updateTime": "2020-11-08T22:39:25.048623Z"
    }
  ]
}

Actualiza el contenido del índice

Para actualizar el contenido de un Index existente, usa el método IndexService.UpdateIndex.

Para reemplazar el contenido existente de un Index, haz lo siguiente:

  • Configura Index.metadata.contentsDeltaUri como el URI de Cloud Storage que incluye los vectores que deseas actualizar.
  • Establecer isCompleteOverwrite como verdadero.

Ten en cuenta que si configuras el campo contentsDeltaUri cuando llamas a IndexService.UpdateIndex, entonces ningún otro campo de índice (como displayName, description o userLabels) puede también se actualizan como parte de la misma llamada.

gcloud

  1. Actualiza tu archivo de metadatos de índice.
  2. Usa el comando gcloud ai indexes update:
gcloud ai indexes update INDEX_ID \
  --metadata-file=LOCAL_PATH_TO_METADATA_FILE \
  --project=PROJECT_ID \
  --region=LOCATION

Reemplaza lo siguiente:

  • INDEX_ID: Es el ID del índice.
  • LOCAL_PATH_TO_METADATA_FILE: La ruta de acceso del archivo local al archivo de metadatos.
  • PROJECT_ID: El ID del proyecto.
  • LOCATION: la región en la que usas Vertex AI.

LÍNEA DE REST Y CMD

Antes de usar cualquiera de los datos de solicitud a continuación, realiza los siguientes reemplazos:

  • LOCATION: Tu región.
  • PROJECT: ID del proyecto
  • INPUT_DIR: Es la ruta de acceso del directorio de Cloud Storage del contenido del índice.
  • PROJECT_NUMBER: es el número de tu proyecto.

Método HTTP y URL:

PATCH https://LOCATION-aiplatform.googleapis.com/v1/projects/PROJECT/locations/LOCATION/indexes/INDEX_ID

Cuerpo JSON de la solicitud:

{
  "metadata": {
    "contentsDeltaUri": "INPUT_DIR",
    "isCompleteOverwrite": true
  }
}

Para enviar tu solicitud, expande una de estas opciones:

Deberías recibir una respuesta JSON similar a la que se muestra a continuación:

{
  "name": "projects/PROJECT_NUMBER/locations/LOCATION/indexes/INDEX_ID/operations/OPERATION_ID",
  "metadata": {
    "@type": "type.googleapis.com/google.cloud.aiplatform.v1.UpdateIndexOperationMetadata",
    "genericMetadata": {
      "createTime": "2022-01-12T23:56:14.480948Z",
      "updateTime": "2022-01-12T23:56:14.480948Z"
    }
  }
}
Puedes consultar el estado de la operación hasta que la respuesta incluya "done": true.

Si el Index tiene implementaciones asociadas (consulta el campo Index.deployed_indexes), cuando se realicen ciertos cambios en el Index original, DeployedIndex se actualizará automáticamente de forma asíncrona en segundo plano para reflejar estos cambios.

Para verificar si se propagó el cambio, compara la hora de finalización de la operación de actualización del índice y el valor DeployedIndex.index_sync_time.

Borra un índice

Ten en cuenta que no puedes borrar Index hasta que se anule la implementación de todos sus Index.deployed_indexes.

gcloud

Usa el comando gcloud ai indexes delete:

gcloud ai indexes delete INDEX_ID \
  --project=PROJECT_ID \
  --region=LOCATION

Reemplaza lo siguiente:

  • INDEX_ID: Es el ID del índice.
  • PROJECT_ID: El ID del proyecto.
  • LOCATION: la región en la que usas Vertex AI.

LÍNEA DE REST Y CMD

Antes de usar cualquiera de los datos de solicitud a continuación, realiza los siguientes reemplazos:

  • LOCATION: Tu región.
  • PROJECT: ID del proyecto
  • INDEX_ID: Es el ID del índice.
  • PROJECT_NUMBER: es el número de tu proyecto.

Método HTTP y URL:

DELETE https://LOCATION-aiplatform.googleapis.com/v1/projects/PROJECT/locations/LOCATION/indexes/INDEX_ID

Para enviar tu solicitud, expande una de estas opciones:

Deberías recibir una respuesta JSON similar a la que se muestra a continuación:

{
  "name": "projects/PROJECT_NUMBER/locations/LOCATION/indexes/INDEX_ID/operations/OPERATION_ID",
  "metadata": {
    "@type": "type.googleapis.com/google.cloud.aiplatform.v1.DeleteOperationMetadata",
    "genericMetadata": {
      "createTime": "2022-01-08T02:35:56.364956Z",
      "updateTime": "2022-01-08T02:35:56.364956Z"
    }
  },
  "done": true,
  "response": {
    "@type": "type.googleapis.com/google.protobuf.Empty"
  }
}

Implementa y administra índices

La implementación de un índice incluye las siguientes tres tareas:

  1. Crea un IndexEndpoint, si es necesario, o reutiliza un IndexEndpoint existente.
  2. Obtén el ID de IndexEndpoint.
  3. Implementa el índice en IndexEndpoint.

Crea un IndexEndpoint dentro de tu red de VPC

Si implementas un Index en un IndexEndpoint existente, puedes omitir este paso.

Antes de usar un índice para entregar consultas de coincidencia de vectores en línea, debes IndexIndexEndpointimplementar dentro de tu red con intercambio de tráfico entre redes de VPC. El primer paso es crear un IndexEndpoint. Puedes implementar más de un índice en un IndexEndpoint que comparta la misma red de VPC.

gcloud

En el siguiente ejemplo, se usa el comando gcloud ai index-endpoints create:

gcloud ai index-endpoints create \
  --display-name=INDEX_ENDPOINT_NAME \
  --network=VPC_NETWORK_NAME \
  --project=PROJECT_ID \
  --region=LOCATION

Reemplaza lo siguiente:

  • INDEX_ENDPOINT_NAME: nombre visible del extremo del índice.
  • VPC_NETWORK_NAME: Es el nombre de la red de Google Compute Engine con el que se debe intercambiar el extremo del índice.
  • PROJECT_ID: El ID del proyecto.
  • LOCATION: la región en la que usas Vertex AI.

La herramienta Google Cloud CLI puede tardar unos minutos en crear el IndexEndpoint.

LÍNEA DE REST Y CMD

Antes de usar cualquiera de los datos de solicitud a continuación, realiza los siguientes reemplazos:

  • LOCATION: Tu región.
  • PROJECT: ID del proyecto
  • INDEX_ENDPOINT_NAME: nombre visible del extremo del índice.
  • VPC_NETWORK_NAME: Es el nombre de la red de Google Compute Engine con el que se debe intercambiar el extremo del índice.
  • PROJECT_NUMBER: es el número de tu proyecto.

Método HTTP y URL:

POST https://LOCATION-aiplatform.googleapis.com/v1/projects/PROJECT/locations/LOCATION/indexEndpoints

Cuerpo JSON de la solicitud:

{
  "display_name": "INDEX_ENDPOINT_NAME",
  "network": "VPC_NETWORK_NAME"
}

Para enviar tu solicitud, expande una de estas opciones:

Deberías recibir una respuesta JSON similar a la que se muestra a continuación:

{
  "name": "projects/PROJECT_NUMBER/locations/LOCATION/indexEndpoints/INDEX_ENDPOINT_ID/operations/OPERATION_ID",
  "metadata": {
    "@type": "type.googleapis.com/google.cloud.aiplatform.v1.CreateIndexEndpointOperationMetadata",
    "genericMetadata": {
      "createTime": "2022-01-13T04:09:56.641107Z",
      "updateTime": "2022-01-13T04:09:56.641107Z"
    }
  }
}
Puedes consultar el estado de la operación hasta que la respuesta incluya "done": true.

Implementa un índice

gcloud

En el siguiente ejemplo, se usa el comando gcloud ai index-endpoints deploy-index:

gcloud ai index-endpoints deploy-index INDEX_ENDPOINT_ID \
  --deployed-index-id=DEPLOYED_INDEX_ID \
  --display-name=DEPLOYED_INDEX_NAME \
  --index=INDEX_ID \
  --project=PROJECT_ID \
  --region=LOCATION

Reemplaza lo siguiente:

  • INDEX_ENDPOINT_ID: Es el ID del extremo del índice.
  • DEPLOYED_INDEX_ID: El ID del índice implementado.
  • DEPLOYED_INDEX_NAME: El nombre visible del índice implementado
  • INDEX_ID: Es el ID del índice.
  • PROJECT_ID: El ID del proyecto.
  • LOCATION: la región en la que usas Vertex AI.

LÍNEA DE REST Y CMD

Antes de usar cualquiera de los datos de solicitud a continuación, realiza los siguientes reemplazos:

  • LOCATION: la región en la que usas Vertex AI.
  • PROJECT: ID del proyecto
  • INDEX_ENDPOINT_ID: Es el ID del extremo del índice.
  • DEPLOYED_INDEX_ID: El ID del índice implementado.
  • DEPLOYED_INDEX_NAME: El nombre visible del índice implementado
  • INDEX_ID: Es el ID del índice.
  • PROJECT_NUMBER: es el número de tu proyecto.

Método HTTP y URL:

POST https://LOCATION-aiplatform.googleapis.com/v1/projects/PROJECT/locations/LOCATION/indexEndpoints/INDEX_ENDPOINT_ID:deployIndex

Cuerpo JSON de la solicitud:

{
  "deployedIndex": {
    "id": "DEPLOYED_INDEX_ID",
    "index": "projects/PROJECT/locations/LOCATION/indexes/INDEX_ID",
    "displayName": "DEPLOYED_INDEX_NAME"
  }
}

Para enviar tu solicitud, expande una de estas opciones:

Deberías recibir una respuesta JSON similar a la que se muestra a continuación:

{
  "name": "projects/PROJECT_ID/locations/LOCATION/indexEndpoints/INDEX_ENDPOINT_ID/operations/OPERATION_ID",
  "metadata": {
    "@type": "type.googleapis.com/google.cloud.aiplatform.v1.DeployIndexOperationMetadata",
    "genericMetadata": {
      "createTime": "2020-10-19T17:53:16.502088Z",
      "updateTime": "2020-10-19T17:53:16.502088Z"
    },
    "deployedIndexId": "DEPLOYED_INDEX_ID"
  }
}
Puedes consultar el estado de la operación hasta que la respuesta incluya "done": true.

Habilitar ajuste de escala automático

Matching Engine admite el ajuste de escala automático, que puede cambiar el tamaño de la cantidad de nodos de forma automática según las demandas de tus cargas de trabajo. Cuando la demanda es alta, se agregan nodos al grupo de nodos, y estos no superarán el tamaño máximo que designes. Cuando la demanda es baja, el grupo de nodos reduce su escala hasta el tamaño mínimo que designes. Puedes verificar los nodos reales en uso y los cambios si supervisas las réplicas actuales.

Para habilitar el ajuste de escala automático, especifica maxReplicaCount y minReplicaCount cuando implementes el índice:

gcloud

En el siguiente ejemplo, se usa el comando gcloud ai index-endpoints deploy-index:

gcloud ai index-endpoints deploy-index INDEX_ENDPOINT_ID \
  --deployed-index-id=DEPLOYED_INDEX_ID \
  --display-name=DEPLOYED_INDEX_NAME \
  --index=INDEX_ID \
  --min-replica-count=MIN_REPLICA_COUNT \
  --max-replica-count=MAX_REPLICA_COUNT \
  --project=PROJECT_ID \
  --region=LOCATION

Reemplaza lo siguiente:

  • INDEX_ENDPOINT_ID: Es el ID del extremo del índice.
  • DEPLOYED_INDEX_ID: El ID del índice implementado.
  • DEPLOYED_INDEX_NAME: El nombre visible del índice implementado
  • INDEX_ID: Es el ID del índice.
  • MIN_REPLICA_COUNT: la cantidad mínima de réplicas de máquinas en las que siempre se implementará el índice implementado. Si se especifica, el valor debe ser igual o mayor que 1.
  • MAX_REPLICA_COUNT: la cantidad máxima de réplicas de máquinas en las que se puede implementar el índice implementado.
  • PROJECT_ID: El ID del proyecto.
  • LOCATION: la región en la que usas Vertex AI.

LÍNEA DE REST Y CMD

Antes de usar cualquiera de los datos de solicitud a continuación, realiza los siguientes reemplazos:

  • LOCATION: la región en la que usas Vertex AI.
  • PROJECT: ID del proyecto
  • INDEX_ENDPOINT_ID: Es el ID del extremo del índice.
  • DEPLOYED_INDEX_ID: El ID del índice implementado.
  • DEPLOYED_INDEX_NAME: El nombre visible del índice implementado
  • INDEX_ID: Es el ID del índice.
  • MIN_REPLICA_COUNT: la cantidad mínima de réplicas de máquinas en las que siempre se implementará el índice implementado. Si se especifica, el valor debe ser igual o mayor que 1.
  • MAX_REPLICA_COUNT: la cantidad máxima de réplicas de máquinas en las que se puede implementar el índice implementado.
  • PROJECT_NUMBER: es el número de tu proyecto.

Método HTTP y URL:

POST https://LOCATION-aiplatform.googleapis.com/v1/projects/PROJECT/locations/LOCATION/indexEndpoints/INDEX_ENDPOINT_ID:deployIndex

Cuerpo JSON de la solicitud:

{
  "deployedIndex": {
    "id": "DEPLOYED_INDEX_ID",
    "index": "projects/PROJECT/locations/LOCATION/indexes/INDEX_ID",
    "displayName": "DEPLOYED_INDEX_NAME",
    "automaticResources": {
      "minReplicaCount": MIN_REPLICA_COUNT,
      "maxReplicaCount": MAX_REPLICA_COUNT
    }
  }
}

Para enviar tu solicitud, expande una de estas opciones:

Deberías recibir una respuesta JSON similar a la que se muestra a continuación:

{
  "name": "projects/PROJECT_ID/locations/LOCATION/indexEndpoints/INDEX_ENDPOINT_ID/operations/OPERATION_ID",
  "metadata": {
    "@type": "type.googleapis.com/google.cloud.aiplatform.v1.DeployIndexOperationMetadata",
    "genericMetadata": {
      "createTime": "2020-10-19T17:53:16.502088Z",
      "updateTime": "2020-10-19T17:53:16.502088Z"
    },
    "deployedIndexId": "DEPLOYED_INDEX_ID"
  }
}
Puedes consultar el estado de la operación hasta que la respuesta incluya "done": true.
  • Si minReplicaCount y maxReplicaCount no están configurados, se configuran como 2 de forma predeterminada.
  • Si solo se establece maxReplicaCount, minReplicaCount se establece en 2 de forma predeterminada.
  • Si solo se establece minReplicaCount, maxReplicaCount se configura como igual a minReplicaCount.

Muta un DeployedIndex

Puedes usar la API de MutateDeployedIndex para actualizar los recursos de implementación (por ejemplo, minReplicaCount y maxReplicaCount) de un índice ya implementado.

  • Los usuarios no pueden cambiar el machineType después de implementar el índice.
  • Si no se especifica maxReplicaCount en la solicitud, DeployedIndex seguirá usando el maxReplicaCount existente.

gcloud

En el siguiente ejemplo, se usa el comando gcloud ai index-endpoints mutate-deployed-index:

gcloud ai index-endpoints mutate-deployed-index INDEX_ENDPOINT_ID \
  --deployed-index-id=DEPLOYED_INDEX_ID \
  --min-replica-count=MIN_REPLICA_COUNT \
  --max-replica-count=MAX_REPLICA_COUNT \
  --project=PROJECT_ID \
  --region=LOCATION

Reemplaza lo siguiente:

  • INDEX_ENDPOINT_ID: Es el ID del extremo del índice.
  • DEPLOYED_INDEX_ID: El ID del índice implementado.
  • MIN_REPLICA_COUNT: la cantidad mínima de réplicas de máquinas en las que siempre se implementará el índice implementado. Si se especifica, el valor debe ser igual o mayor que 1.
  • MAX_REPLICA_COUNT: la cantidad máxima de réplicas de máquinas en las que se puede implementar el índice implementado.
  • PROJECT_ID: El ID del proyecto.
  • LOCATION: la región en la que usas Vertex AI.

LÍNEA DE REST Y CMD

Antes de usar cualquiera de los datos de solicitud a continuación, realiza los siguientes reemplazos:

  • LOCATION: la región en la que usas Vertex AI.
  • PROJECT: ID del proyecto
  • INDEX_ENDPOINT_ID: Es el ID del extremo del índice.
  • DEPLOYED_INDEX_ID: El ID del índice implementado.
  • MIN_REPLICA_COUNT: la cantidad mínima de réplicas de máquinas en las que siempre se implementará el índice implementado. Si se especifica, el valor debe ser igual o mayor que 1.
  • MAX_REPLICA_COUNT: la cantidad máxima de réplicas de máquinas en las que se puede implementar el índice implementado.
  • PROJECT_NUMBER: es el número de tu proyecto.

Método HTTP y URL:

POST https://LOCATION-aiplatform.googleapis.com/v1/projects/PROJECT/locations/LOCATION/indexEndpoints/INDEX_ENDPOINT_ID:mutateDeployedIndex

Cuerpo JSON de la solicitud:

{
  "id": "DEPLOYED_INDEX_ID",
  "automaticResources": {
    "minReplicaCount": MIN_REPLICA_COUNT,
    "maxReplicaCount": MAX_REPLICA_COUNT
  }
}

Para enviar tu solicitud, expande una de estas opciones:

Deberías recibir una respuesta JSON similar a la que se muestra a continuación:

{
  "name": "projects/PROJECT_ID/locations/LOCATION/indexEndpoints/INDEX_ENDPOINT_ID/operations/OPERATION_ID",
  "metadata": {
    "@type": "type.googleapis.com/google.cloud.aiplatform.v1.MutateDeployedIndexOperationMetadata",
    "genericMetadata": {
      "createTime": "2022-01-24T20:36:37.902782Z",
      "updateTime": "2022-01-24T20:36:37.902782Z"
    },
    "deployedIndexId": "gcloud_deployed_index_2"
  }
}
Puedes consultar el estado de la operación hasta que la respuesta incluya "done": true.

Enumera IndexEndpoints

Para ver una lista de tus recursos IndexEndpoint y ver la información de las instancias DeployedIndex asociadas, ejecuta el siguiente código:

gcloud

En el siguiente ejemplo, se usa el comando gcloud ai index-endpoints list:

gcloud ai index-endpoints list \
  --project=PROJECT_ID \
  --region=LOCATION

Reemplaza lo siguiente:

  • PROJECT_ID: El ID del proyecto.
  • LOCATION: la región en la que usas Vertex AI.

LÍNEA DE REST Y CMD

Antes de usar cualquiera de los datos de solicitud a continuación, realiza los siguientes reemplazos:

  • LOCATION: Tu región.
  • PROJECT: ID del proyecto
  • PROJECT_NUMBER: es el número de tu proyecto.

Método HTTP y URL:

GET https://LOCATION-aiplatform.googleapis.com/v1/projects/PROJECT/locations/LOCATION/indexEndpoints

Para enviar tu solicitud, expande una de estas opciones:

Deberías recibir una respuesta JSON similar a la que se muestra a continuación:

{
  "indexEndpoints": [
    {
      "name": "projects/PROJECT_NUMBER/locations/LOCATION/indexEndpoints/INDEX_ENDPOINT_ID",
      "displayName": "INDEX_ENDPOINT_NAME",
      "deployedIndexes": [
        {
          "id": "DEPLOYED_INDEX_ID",
          "index": "projects/PROJECT_NUMBER/locations/LOCATION/indexes/INDEX_ID",
          "displayName": "DEPLOYED_INDEX_ID",
          "createTime": "2021-06-04T02:23:40.178286Z",
          "privateEndpoints": {
            "matchGrpcAddress": "GRPC_ADDRESS"
          },
          "indexSyncTime": "2022-01-13T04:22:00.151916Z",
          "automaticResources": {
            "minReplicaCount": 2,
            "maxReplicaCount": 10
          }
        }
      ],
      "etag": "AMEw9yP367UitPkLo-khZ1OQvqIK8Q0vLAzZVF7QjdZ5O3l7Zow-mzBo2l6xmiuuMljV",
      "createTime": "2021-03-17T04:47:28.460373Z",
      "updateTime": "2021-06-04T02:23:40.930513Z",
      "network": "VPC_NETWORK_NAME"
    }
  ]
}

Para obtener más información, consulta la documentación de referencia de IndexEndpoint.

Anula la implementación de un índice

Para anular la implementación de un índice, ejecuta el siguiente código:

gcloud

En el siguiente ejemplo, se usa el comando gcloud ai index-endpoints undeploy-index:

gcloud ai index-endpoints undeploy-index INDEX_ENDPOINT_ID \
  --deployed-index-id=DEPLOYED_INDEX_ID \
  --project=PROJECT_ID \
  --region=LOCATION

Reemplaza lo siguiente:

  • INDEX_ENDPOINT_ID: Es el ID del extremo del índice.
  • DEPLOYED_INDEX_ID: El ID del índice implementado.
  • PROJECT_ID: El ID del proyecto.
  • LOCATION: la región en la que usas Vertex AI.

LÍNEA DE REST Y CMD

Antes de usar cualquiera de los datos de solicitud a continuación, realiza los siguientes reemplazos:

  • LOCATION: Tu región.
  • PROJECT: ID del proyecto
  • INDEX_ENDPOINT_ID: Es el ID del extremo del índice.
  • DEPLOYED_INDEX_ID: El ID del índice implementado.
  • PROJECT_NUMBER: es el número de tu proyecto.

Método HTTP y URL:

POST https://LOCATION-aiplatform.googleapis.com/v1/projects/PROJECT/locations/LOCATION/indexEndpoints/INDEX_ENDPOINT_ID:undeployIndex

Cuerpo JSON de la solicitud:

{
  "deployed_index_id": "DEPLOYED_INDEX_ID"
}

Para enviar tu solicitud, expande una de estas opciones:

Deberías recibir una respuesta JSON similar a la que se muestra a continuación:

{
  "name": "projects/PROJECT_NUMBER/locations/LOCATION/indexEndpoints/INDEX_ENDPOINT_ID/operations/OPERATION_ID",
  "metadata": {
    "@type": "type.googleapis.com/google.cloud.aiplatform.v1.UndeployIndexOperationMetadata",
    "genericMetadata": {
      "createTime": "2022-01-13T04:09:56.641107Z",
      "updateTime": "2022-01-13T04:09:56.641107Z"
    }
  }
}

Borra un IndexEndpoint

Antes de borrar un IndexEndpoint, debes anular la implementación de todos los índices asociados.

gcloud

En el siguiente ejemplo, se usa el comando gcloud ai index-endpoints delete:

gcloud ai index-endpoints delete INDEX_ENDPOINT_ID \
  --project=PROJECT_ID \
  --region=LOCATION

Reemplaza lo siguiente:

  • INDEX_ENDPOINT_ID: Es el ID del extremo del índice.
  • PROJECT_ID: El ID del proyecto.
  • LOCATION: la región en la que usas Vertex AI.

LÍNEA DE REST Y CMD

Antes de usar cualquiera de los datos de solicitud a continuación, realiza los siguientes reemplazos:

  • LOCATION: Tu región.
  • PROJECT: ID del proyecto
  • INDEX_ENDPOINT_ID: Es el ID del extremo del índice.
  • PROJECT_NUMBER: es el número de tu proyecto.

Método HTTP y URL:

DELETE https://LOCATION-aiplatform.googleapis.com/v1/projects/PROJECT/locations/LOCATION/indexEndpoints/INDEX_ENDPOINT_ID

Para enviar tu solicitud, expande una de estas opciones:

Deberías recibir una respuesta JSON similar a la que se muestra a continuación:

{
  "name": "projects/PROJECT_NUMBER/locations/LOCATION/indexEndpoints/INDEX_ENDPOINT_ID/operations/OPERATION_ID",
  "metadata": {
    "@type": "type.googleapis.com/google.cloud.aiplatform.v1.DeleteOperationMetadata",
    "genericMetadata": {
      "createTime": "2022-01-13T04:36:19.142203Z",
      "updateTime": "2022-01-13T04:36:19.142203Z"
    }
  },
  "done": true,
  "response": {
    "@type": "type.googleapis.com/google.protobuf.Empty"
  }
}

Consulta índices para obtener los vecinos más cercanos

Cada DeployedIndex tiene un DEPLOYED_INDEX_SERVER_IP que puedes recuperar si enumeras IndexEndpoints. Para consultar un DeployedIndex, conéctate a su DEPLOYED_INDEX_SERVER_IP en el puerto 10000 y llama a los métodos Match o BatchMatch.

En los siguientes ejemplos, se usa la herramienta de código abierto grpc_cli para enviar solicitudes de grpc al servidor de índice implementado. En el primer ejemplo, envías una sola consulta con el método Match.

./grpc_cli call ${DEPLOYED_INDEX_SERVER_IP}:10000 google.cloud.aiplatform.container.v1.MatchService.Match '{deployed_index_id: "${DEPLOYED_INDEX_ID}", float_val: [-0.1,..]}'

En el segundo ejemplo, combina dos consultas separadas en la misma solicitud BatchMatch.

./grpc_cli call ${DEPLOYED_INDEX_SERVER_IP}:10000 google.cloud.aiplatform.container.v1.MatchService.BatchMatch 'requests: [{deployed_index_id: "${DEPLOYED_INDEX_ID}", requests: [{deployed_index_id: "${DEPLOYED_INDEX_ID}", float_val: [-0.1,..]}, {deployed_index_id: "${DEPLOYED_INDEX_ID}", float_val: [-0.2,..]}]}]'

Debes realizar llamadas a estas API desde un cliente que se ejecute en la misma VPC con la que el servicio intercambia tráfico.

Si deseas obtener más información sobre cómo crear las consultas, inicia un notebook de muestra y ejecútalo en Vertex AI Workbench.

Ajusta el índice

El ajuste del índice requiere establecer los parámetros de configuración que afectan el rendimiento de los índices implementados, en especial la recuperación y la latencia. Estos parámetros se configuran cuando se crea el índice. Puedes usar los índices de fuerza bruta para medir la recuperación.

Parámetros de configuración que afectan la recuperación y la latencia

  1. distanceMeasureType

    Se admiten los siguientes valores:

    • SQUARED_L2_DISTANCE: Distancia euclidiana L2
    • L1_DISTANCE: Distancia de Manhattan L1
    • COSINE_DISTANCE: Distancia de coseno definida como "1: similitud de coseno"
    • DOT_PRODUCT_DISTANCE: Distancia del producto de vDot, definida como un valor negativo del producto de VDot. Este es el valor predeterminado.

    En la mayoría de los casos, los vectores de incorporación que se usan para la coincidencia de similitud se calculan mediante modelos de aprendizaje de métricas (también llamados redes siamesas o modelos de dos torres). Estos modelos usan una métrica de distancias para calcular la función de pérdida contrastada. Lo ideal es que el valor del parámetro distanceMeasureType del índice coincidente coincida con la medida de distancia que usa el modelo que produjo los vectores de incorporación.

  2. approximateNeighborsCount

    La cantidad predeterminada de vecinos que se deben encontrar mediante la búsqueda aproximada antes de que se realice el reordenamiento exacto. El reordenamiento exacto es un procedimiento en el que los resultados que muestra un algoritmo de búsqueda aproximada se ordenan a través de un cálculo de distancias más costoso. Aumentar este valor aumenta la recuperación, lo que puede crear un aumento proporcional de la latencia.

  3. treeAhConfig.leafNodesToSearchPercent

    El porcentaje de hojas que se deben buscar para cada consulta. Aumentar este valor aumenta la recuperación, lo que también puede crear un aumento proporcional de la latencia. El valor predeterminado es 10 o el 10% de las hojas.

  4. treeAhConfig.leafNodeEmbeddingCount

    La cantidad de incorporaciones para cada nodo hoja. De forma predeterminada, este número se establece en 1000.

    Este parámetro no tiene una correlación lineal que se debe recuperar. Aumentar o disminuir el valor del parámetro treeAhConfig.leafNodeEmbeddingCount no siempre aumenta o disminuye la recuperación. Experimenta para encontrar el valor óptimo. Por lo general, cambiar el valor del parámetro treeAhConfig.leafNodeEmbeddingCount tiene menos efecto que cambiar el valor de los otros parámetros.

Cómo usar un índice de fuerza bruta para medir la recuperación

Para obtener los vecinos más cercanos exactos, usa índices con el algoritmo de fuerza bruta. El algoritmo de fuerza bruta proporciona una recuperación del 100% a expensas de una latencia más alta. El uso de un índice de fuerza bruta a fin de medir la recuperación no suele ser una buena opción para la entrega de producción, pero puede resultarte útil a fin de evaluar la recuperación de varias opciones de indexación sin conexión.

Para crear un índice con el algoritmo de fuerza bruta, especifica brute_force_config en los metadatos del índice:

curl -X POST -H "Content-Type: application/json" \
-H "Authorization: Bearer `gcloud auth print-access-token`" \
https://us-central1-aiplatform.googleapis.com/v1/projects/${PROJECT_ID}/locations/us-central1/indexes \
-d '{
    displayName: "'${DISPLAY_NAME}'",
    description: "'${DESCRIPTION}'",
    metadata: {
       contentsDeltaUri: "'${INPUT_DIR}'",
       config: {
          dimensions: 100,
          approximateNeighborsCount: 150,
          distanceMeasureType: "DOT_PRODUCT_DISTANCE",
          featureNormType: "UNIT_L2_NORM",
          algorithmConfig: {
             bruteForceConfig: {}
          }
       },
    },
}'

En el notebook de ejemplo, se muestra cómo usar un índice de fuerza bruta para medir la recuperación.

Supervisa IndexEndpoint

Google proporciona dos métricas para supervisar IndexEndpoint:

  • aiplatform.googleapis.com/matching_engine/current_shards

    La cantidad de fragmentos del DeployedIndex. A medida que se agregan y borran datos, el motor de coincidencias vuelve a fragmentar de forma automática el índice para lograr un rendimiento óptimo. Esta métrica indica la cantidad actual de fragmentos del índice implementado.

  • aiplatform.googleapis.com/matching_engine/current_replicas

    La cantidad total de servidores de réplica activos que usa DeployedIndex. Para que el volumen de consultas coincida, el motor de coincidencias activa o reduce automáticamente los servidores de réplica según la configuración de réplica mínima y máxima especificada cuando se implementa el índice.

    Si el índice tiene varios fragmentos, cada fragmento se puede entregar mediante una cantidad diferente de servidores de réplica. Esta métrica es la cantidad total de servidores de réplica en todos los fragmentos del índice determinado.

Obtén más información sobre cómo seleccionar, consultar y mostrar estas métricas en el Explorador de métricas.

Cuotas

Obtén más información sobre las cuotas de Vertex AI Matching Engine y cómo solicitar aumentos de cuotas.

Preguntas frecuentes

¿Cuántas direcciones IP debo reservar?

Si no hay restricciones en el rango de IP que puedes asignar, te recomendamos que reserves un rango de IP grande como /16 para evitar un problema futuro de agotamiento de IP.

Si no deseas asignar en exceso los rangos de IP, puedes realizar una estimación aproximada en función del tamaño de tus datos y del tráfico. Cada fragmento puede alojar alrededor de 20 GB de datos en formato Avro, y cada réplica puede entregar entre 800 y 1,000 consultas por segundo (QPS). La cantidad de QPS precisa que puede entregar cada réplica depende, por ejemplo, del tamaño de la incorporación, las dimensiones y las configuraciones de algoritmos. Te recomendamos que realices una prueba de carga para determinar un número preciso.

La cantidad total de nodos de índice implementados es (la cantidad de fragmentos * la cantidad de réplicas por fragmento). Por ejemplo, si tu tamaño de datos es de 30 GB y las QPS son 1,200, necesitas al menos 2 fragmentos y 2 réplicas por fragmento, lo que da un total de 4 nodos de índice implementados.

Después de estimar el total de nodos de índice implementados, puedes elegir el prefijo de rango de IP según la siguiente tabla:

Total de nodos de índice implementados Prefijo de IP reservada recomendado
1 - 10 /21
11 - 25 /20
26 - 50 /19
51 - 120 /18

¿Cómo resuelvo un error de IP agotada?

Para resolver un error de IP agotada, sigue estos pasos:

  1. Verifica si hay DeployedIndexes sin usar y anúlalos para liberar algunos espacios de IP.

  2. Expande los rangos de IP reservados existentes o asigna más rangos de IP.

Para obtener más información, consulta Agotamiento del rango de direcciones IP.

¿Por qué no puedo volver a usar el ID de índice implementado cuando se anula la implementación del anterior DeployedIndex?

La limpieza de UndeployIndex requiere entre 10 y 20 minutos como mínimo para completarse, incluso después de recibir una confirmación de operación correcta. Te recomendamos que esperes entre 10 y 20 minutos antes de volver a usar el mismo ID, o usa uno diferente.

Obtén asistencia

Si tienes un problema cuando usas Matching Engine, hay dos formas de obtener asistencia. En cualquier caso, incluye los siguientes detalles en la comunicación:

  • El comando o código que ejecutaste y que produjo el problema.
  • El entorno en el que ejecutaste el comando o el código. Por ejemplo, ¿lo ejecutaste en una instancia de Compute Engine o en una computadora local?
  • El comportamiento que observaste y cómo difiere de lo que esperabas.

Crea un ticket de Atención al cliente de Cloud

Si tienes un paquete de Atención al cliente, puedes enviar un ticket de asistencia. Para obtener información sobre cómo obtener un paquete de Atención al cliente de Cloud, consulta Atención al cliente.

  1. En Google Cloud Console, navega a la página Casos.

    Ir a Casos

  2. Haz clic en Crear caso.

    • En el campo Título, escribe Matching Engine serving.
    • En el campo Categoría, selecciona Aprendizaje automático.
    • En el campo Componente, selecciona Vertex AI Match Engine.
    • En el campo Descripción, proporciona la información solicitada y responde las preguntas. Asegúrate de incluir detalles relevantes, como el ID del proyecto, el índice, la operación, los mensajes de error, etcétera.
    • Haga clic en Submit.

Pregunta en la comunidad

También puedes obtener asistencia mediante uno de los siguientes canales públicos.

  • Para preguntas relacionadas con el SDK cliente, informa un problema en GitHub.
  • Si tienes otras preguntas de asistencia, publícalas en la etiqueta google-cloud-vertex-ai en Stack Overflow.

¿Qué sigue?