Formato y estructura de los datos de entrada

Para crear un índice o actualizar uno que ya tengas, proporciona vectores a la búsqueda vectorial con el formato y la estructura que se describen en las secciones siguientes.

Requisitos previos

Almacena los datos de entrada en un segmento de Cloud Storage de tu proyecto Google Cloud .

Los archivos de datos de entrada deben organizarse de la siguiente manera:

  • Cada lote de archivos de datos de entrada debe estar en un solo directorio de Cloud Storage.
  • Los archivos de datos deben colocarse directamente en batch_root y nombrarse con los siguientes sufijos: .csv, .json y .avro.
  • El directorio raíz del lote tiene un límite de 5000 objetos (archivos).
  • Cada archivo de datos se interpreta como un conjunto de registros. El formato del registro viene determinado por el sufijo del nombre de archivo y se describen los requisitos de formato. Consulte Formatos de archivo de datos.
  • Cada registro debe tener un id, un vector de características y los campos opcionales que admita Vertex AI Feature Store, como restricciones y saturación.
  • Puede haber un subdirectorio llamado delete. Cada archivo que se encuentre directamente en batch_root/delete se considerará un archivo de texto de registros id con un id en cada línea.
  • No se permiten otros subdirectorios.
  • No se admite la transcodificación de archivos comprimidos con gzip como datos de entrada.

Procesamiento de datos de entrada

  • Todos los registros de todos los archivos de datos, incluidos los de delete, constan de un único lote de entrada.
  • El orden relativo de los registros de un archivo de datos no es importante.
  • Un ID solo debe aparecer una vez en un lote. Si hay un duplicado con el mismo ID, se muestra como un recuento de vectores.
  • Un ID no puede aparecer tanto en un archivo de datos normal como en un archivo de datos de eliminación.
  • Si se eliminan todos los IDs de un archivo de datos, se quitará de la siguiente versión del índice.
  • Los registros de los archivos de datos normales se incluyen en la siguiente versión, sobrescribiendo un valor de una versión anterior del índice.

Estos son algunos ejemplos de embeddings densos, dispersos e híbridos:

  • Incrustaciones densas:

    {"id": "1", "embedding": [1,1,1]}
    {"id": "2", "embedding": [2,2,2]}
    
  • Incrustaciones dispersas:

    {"id": "3", "sparse_embedding": {"values": [0.1, 0.2], "dimensions": [1, 4]}}
    {"id": "4", "sparse_embedding": {"values": [-0.4, 0.2, -1.3], "dimensions": [10, 20, 20]}}
    
  • Inserciones híbridas:

    {"id": "5", "embedding": [5, 5, -5], "sparse_embedding": {"values": [0.1], "dimensions": [500]}}
    {"id": "6", "embedding": [6, 7, -8.1], "sparse_embedding": {"values": [0.1, -0.2], "dimensions": [40, 901]}}
    

A continuación, se muestra un ejemplo de organización válida de un archivo de datos de entrada:

batch_root/
  feature_file_1.csv
  feature_file_2.csv
  delete/
    delete_file.txt

Los archivos feature_file_1.csv y feature_file_2.csv contienen registros en formato CSV. El archivo delete_file.txt contiene una lista de IDs de registros que se eliminarán de la siguiente versión del índice.

Formatos de archivo de datos

JSON

  • Codifica el archivo JSON con UTF-8.
  • Cada línea del archivo JSON se interpretará como un objeto JSON independiente.
  • Cada registro debe contener un campo id para especificar el ID del vector.
  • Cada registro debe contener al menos uno de los campos embedding o sparse_embedding.
  • El campo embedding es una matriz de números de punto flotante N que representa el vector de características, donde N es la dimensión del vector de características que se configuró al crear el índice. Este campo solo se puede usar para las inserciones densas.
    • configs.dimensions, que se especifica en el momento de la creación del índice, debe tener la misma longitud que embeddings. configs.dimensions solo se aplica a embedding, no a sparse_embedding.
  • El campo sparse_embedding es un objeto con los campos values y dimensions. El campo values es una lista de números de punto flotante que representa el vector de características, y el campo dimensions es una lista de números enteros que representa la dimensión en la que se encuentra el valor correspondiente. Por ejemplo, una inserción dispersa como [0,0.1,0,0,0.2] se puede representar como "sparse_embedding": {"values": [0.1, 0.2], "dimensions": [1,4]}. Este campo solo se puede usar para las inserciones dispersas.
    • La longitud de sparse_embedding.values debe ser la misma que la de sparse_embedding.dimensions. No tienen que tener la misma longitud que configs.dimensions, que se especifica al crear el índice y no se aplica a sparse_embedding.
  • Se puede incluir un campo restricts opcional que especifique una matriz de objetos TokenNamespace en restricts. Sigue estos pasos en cada objeto:
    • Especifica un campo namespace que sea el TokenNamespace.namespace.
    • Se puede asignar un campo allow opcional a una matriz de cadenas que sean la lista de TokenNamespace.string_tokens.
    • Se puede asignar un campo deny opcional a una matriz de cadenas que sean la lista de TokenNamespace.string_blacklist_tokens.
    • El valor del campo crowding_tag, si está presente, debe ser una cadena.
  • Se puede incluir un campo numeric_restricts opcional que especifique una matriz de NumericRestrictNamespace. Sigue estos pasos en cada objeto:
    • Especifica un campo namespace que sea el NumericRestrictNamespace.namespace.
    • Uno de los campos de valor value_int, value_float y value_double.
    • No debe tener un campo llamado op. Este campo solo se usa en las consultas.

Avro

  • Usa un archivo Avro válido.
  • Para representar un punto de datos solo disperso, proporciona una inserción dispersa en el campo sparse_embedding e introduce una lista vacía en el campo embedding.
  • Crea registros que se ajusten al siguiente esquema:

    {
      "type": "record",
      "name": "FeatureVector",
      "fields": [
        {
          "name": "id",
          "type": "string"
        },
        {
          "name": "embedding",
          "type": {
            "type": "array",
            "items": "float"
          }
        },
        {
          "name": "sparse_embedding",
          "type": [
            "null",
            {
              "type": "record",
              "name": "sparse_embedding",
              "fields": [
                {
                  "name": "values",
                  "type": {
                    "type": "array",
                    "items": "float"
                  }
                },
                {
                  "name": "dimensions",
                  "type": {
                    "type": "array",
                    "items": "long"
                  }
                }
              ]
            }
          ]
        },
        {
          "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": "numeric_restricts",
          "type": [
            "null",
            {
              "type": "array",
              "items": {
                "name": "NumericRestrict",
                "type": "record",
                "fields": [
                  {
                    "name": "namespace",
                    "type": "string"
                  },
                  {
                    "name": "value_int",
                    "type": [ "null", "int" ],
                    "default": null
                  },
                  {
                    "name": "value_float",
                    "type": [ "null", "float" ],
                    "default": null
                  },
                  {
                    "name": "value_double",
                    "type": [ "null", "double" ],
                    "default": null
                  }
                ]
              }
            }
          ],
          "default": null
        },
        {
          "name": "crowding_tag",
          "type": [
            "null",
            "string"
          ]
        }
      ]
    }
    

CSV

  • Formato: ID,N feature vector values,Any number of dimension:value sparse values,name=value lists
  • Codifica el archivo CSV con UTF-8.
  • Cada línea del archivo CSV debe contener exactamente un registro.
  • El primer valor de cada línea debe ser el ID del vector, que debe ser una cadena UTF-8 válida.
  • Después del ID, se debe especificar al menos una de las opciones de inserción densa o dispersa.
  • En el caso de una inserción densa, los siguientes valores de N representan el vector de características, donde N es la dimensión del vector de características que se configuró al crear el índice.
  • En el caso de una inserción dispersa, se puede especificar cualquier número de dimension:value, donde value se analiza como un valor float y dimension se analiza como un long.
  • En el caso de las inserciones híbridas que tienen inserciones densas y dispersas, las inserciones densas deben especificarse antes que las dispersas.
  • Los valores del vector de características deben ser literales de coma flotante, tal como se definen en la especificación del lenguaje Java.
  • Los valores adicionales pueden tener el formato name=value.
  • El nombre crowding_tag se interpreta como la etiqueta de aglomeración y solo puede aparecer una vez en el registro.
  • Todos los demás pares name=value se interpretan como restricciones del espacio de nombres de los tokens. El mismo nombre se puede repetir si hay varios valores en un espacio de nombres.

    Por ejemplo, color=red,color=blue representa este TokenNamespace:

    {
      "namespace": "color"
      "string_tokens": ["red", "blue"]
    }
    
  • Si el valor empieza por !, el resto de la cadena se interpreta como un valor excluido.

    Por ejemplo, color=!red representa este TokenNamespace:

    {
      "namespace": "color"
      "string_blacklist_tokens": ["red"]
    }
    
  • #name=numericValue emparejado con un sufijo de tipo numérico se interpreta como restricciones de espacio de nombres numérico. El sufijo del tipo de número es i para int, f para float y d para double. No se debe repetir el mismo nombre, ya que debe haber un único valor asociado por espacio de nombres.

    Por ejemplo, #size=3i representa este NumericRestrictNamespace:

    {
      "namespace": "size"
      "value_int": 3
    }
    

    #ratio=0.1f representa lo siguiente: NumericRestrictNamespace

    {
      "namespace": "ratio"
      "value_float": 0.1
    }
    

    #weight=0.3d representa lo siguiente: NumericRestriction

    {
      "namespace": "weight"
      "value_double": 0.3
    }
    
  • En el siguiente ejemplo se muestra un punto de datos con id: "6", embedding: [7, -8.1], sparse_embedding: {values: [0.1, -0.2, 0.5], dimensions: [40, 901, 1111]}, la etiqueta de aglomeración test, la lista de tokens permitidos color: red, blue, la lista de tokens no permitidos color: purple y la restricción numérica ratio con el valor flotante 0.1:

    6,7,-8.1,40:0.1,901:-0.2,1111:0.5,crowding_tag=test,color=red,color=blue,color=!purple,ratio=0.1f
    

Siguientes pasos