Formato e struttura dei dati di input

Per creare un nuovo indice o aggiornarne uno esistente, fornisci vettori a Vector Search nel formato e nella struttura descritti nelle sezioni seguenti.

Archiviazione dei dati di input e organizzazione dei file

Prerequisito

Archivia i dati di input in un bucket Cloud Storage nel tuo progetto Google Cloud.

I file di dati di input devono essere organizzati come segue:

  • Ogni batch di file di dati di input deve trovarsi in un'unica directory Cloud Storage.
  • I file di dati devono essere posizionati direttamente sotto batch_root e denominati con i seguenti suffissi: .csv, .json e .avro.
  • La directory principale del batch ha un limite di 5000 oggetti (file).
  • Ogni file di dati viene interpretato come un insieme di record. Il formato del record è determinato dal suffisso del nome file e questi requisiti di formato sono descritti. Consulta Formati dei file di dati.
  • Ogni record deve avere un id, un vettore di funzionalità e i campi facoltativi supportati da Vertex AI Feature Store, come limitazioni e affollamento.
  • Potrebbe essere presente una sottodirectory denominata delete. Ogni file direttamente sotto batch_root/delete viene considerato un file di testo di record id con un id in ogni riga.
  • Tutte le altre sottodirectory non sono consentite.

Elaborazione dei dati di input

  • Tutti i record di tutti i file di dati, inclusi quelli in delete, sono costituiti da un unico batch di input.
  • L'ordinamento relativo dei record all'interno di un file di dati non è importante.
  • Un singolo ID deve apparire una sola volta in un batch. Se esiste un duplicato con lo stesso ID, viene visualizzato come un conteggio di vettori.
  • Un ID non può comparire sia in un file di dati normale sia in un file di dati di eliminazione.
  • Tutti gli ID di un file di dati in fase di eliminazione vengono rimossi dalla successiva versione dell'indice.
  • I record dei file di dati regolari vengono inclusi nella versione successiva, sovrascrivendo un valore in una versione dell'indice precedente.

Di seguito sono riportati alcuni esempi di embedding densi, sparsi e ibridi:

  • Incorporamenti densi:

    {"id": "1", "embedding": [1,1,1]}
    {"id": "2", "embedding": [2,2,2]}
    
  • Incorporamenti sparsi (anteprima pubblica):

    {"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]}}
    
  • Embedding ibridi (anteprima pubblica):

    {"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]}}
    

Di seguito è riportato un esempio di organizzazione di un file di dati di input valido:

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

I file feature_file_1.csv e feature_file_2.csv contengono record in formato CSV. Il file delete_file.txt contiene un elenco di ID record da eliminare dalla versione successiva dell'indice.

Formati dei file di dati

JSON

  • Codifica il file JSON utilizzando UTF-8.
  • Ogni riga del file JSON verrà interpretata come un oggetto JSON separato.
  • Ogni record deve contenere un campo id per specificare l'ID del vettore.
  • Ogni record deve contenere almeno un valore embedding o sparse_embedding.
  • Il campo embedding è un array di numeri in virgola mobile N che rappresenta il vettore di funzionalità, dove N è la dimensione del vettore di funzionalità configurata al momento della creazione dell'indice. Questo campo può essere utilizzato solo per gli embedding densi.
    • configs.dimensions, specificato al momento della creazione dell'indice, deve avere la stessa lunghezza di embeddings. configs.dimensions si applica solo a embedding, non a sparse_embedding.
  • Il campo sparse_embedding è un oggetto con campi values e dimensions. Il campo values è un elenco di numeri con virgola mobile che rappresenta il vettore di funzionalità e il campo dimensions è un elenco di numeri interi che rappresentano la dimensione in cui si trova il valore corrispondente. Ad esempio, un embedding sparso che sembra [0,0.1,0,0,0.2] può essere rappresentato come "sparse_embedding": {"values": [0.1, 0.2], "dimensions": [1,4]}. Questo campo può essere utilizzato solo per gli embedding sparsi.
    • La lunghezza di sparse_embedding.values deve essere uguale a quella di sparse_embedding.dimensions. Non devono avere la stessa lunghezza di configs.dimensions, che viene specificato al momento della creazione dell'indice e non si applica a sparse_embedding.
  • È possibile includere un campo restricts facoltativo che specifica un array di oggetti TokenNamespace in restricts. Per ogni oggetto:
    • Specifica un campo namespace che sia il TokenNamespace.namespace.
    • Un campo allow facoltativo può essere impostato su un array di stringhe che rappresentano l'elenco di TokenNamespace.string_tokens.
    • Un campo facoltativo deny può essere impostato su un array di stringhe che rappresentano l'elenco di TokenNamespace.string_blacklist_tokens.
    • Il valore del campo crowding_tag, se presente, deve essere una stringa.
  • È possibile includere un campo facoltativo numeric_restricts che specifica un array di NumericRestrictNamespace. Per ogni oggetto:
    • Specifica un campo namespace che sia il NumericRestrictNamespace.namespace.
    • Uno dei campi di valore value_int, value_float e value_double.
    • Non deve avere un campo denominato op. Questo campo è solo per le query.

Avro

  • Utilizza un file Avro valido.
  • Per rappresentare un punto dati solo sparso, fornisci un embedding sparso nel campo sparse_embedding e inserisci un elenco vuoto nel campo embedding.
  • Crea record conformi allo schema seguente:

    {
      "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 il file CSV utilizzando UTF-8.
  • Ogni riga del file CSV deve contenere esattamente un record.
  • Il primo valore di ogni riga deve essere l'ID vettore, che deve essere una stringa UTF-8 valida.
  • Dopo l'ID, deve essere specificato almeno un embedding denso o sparso.
  • Per un embedding denso, i successivi N valori rappresentano il vettore di caratteristiche, dove N è la dimensione del vettore di caratteristiche configurata al momento della creazione dell'indice.
  • Per un embedding sparso, è possibile specificare un numero qualsiasi di dimension:value, in cui value viene analizzato come valore in virgola mobile e dimension viene analizzato come long.
  • Per un embedding ibrido che contiene sia embedding densi che sparsi, gli embedding densi devono essere specificati prima di quelli sparsi.
  • I valori del vettore di funzionalità devono essere letterali a virgola mobile come definito nella specifica del linguaggio Java.
  • I valori aggiuntivi possono essere nel formato name=value.
  • Il nome crowding_tag viene interpretato come tag di affollamento e può comparire solo una volta nel record.
  • Tutte le altre coppie name=value vengono interpretate come limitazioni dello spazio dei nomi dei token. Lo stesso nome può essere ripetuto se sono presenti più valori in un ambito.

    Ad esempio, color=red,color=blue rappresenta questo TokenNamespace:

    {
      "namespace": "color"
      "string_tokens": ["red", "blue"]
    }
    
  • Se il valore inizia con !, il resto della stringa viene interpretato come un valore escluso.

    Ad esempio, color=!red rappresenta questo TokenNamespace:

    {
      "namespace": "color"
      "string_blacklist_tokens": ["red"]
    }
    
  • Le coppie #name=numericValue con suffisso di tipo di numero vengono interpretate come limitazioni dello spazio dei nomi numerici. Il suffisso del tipo di numero è i per int, f per float e d per double. Lo stesso nome non deve essere ripetuto, in quanto deve essere associato un singolo valore per spazio dei nomi.

    Ad esempio, #size=3i rappresenta questo NumericRestrictNamespace:

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

    #ratio=0.1f rappresenta questo NumericRestrictNamespace:

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

    #weight=0.3d rappresenta questo NumericRestriction:

    {
      "namespace": "weight"
      "value_double": 0.3
    }
    
  • Il seguente esempio è un punto dati con id: "6", embedding: [7, -8.1], sparse_embedding: {values: [0.1, -0.2, 0.5], dimensions: [40, 901, 1111]}}, tag di affollamento test, lista consentita di token color: red, blue, lista vietata di token color: purple e limitazione numerica di ratio con valore float 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
    

Passaggi successivi