Para criar um novo índice ou atualizar um existente, forneça vetores ao Vector Search no formato e na estrutura descritos nas seções a seguir.
Pré-requisitos
Armazene os dados de entrada em um bucket do Cloud Storage no projeto Google Cloud .
Os arquivos de dados de entrada precisam ser organizados da seguinte maneira:
- Cada lote de arquivos de dados de entrada precisa estar em um único diretório do Cloud Storage.
- Os arquivos de dados precisam ser colocados diretamente em
batch_roote nomeados com os seguintes sufixos:.csv,.jsone.avro. - Há um limite de 5.000 objetos no diretório raiz do lote.
- Cada arquivo de dados é interpretado como um conjunto de registros. O formato do registro é determinado pelo sufixo do nome do arquivo, e esses requisitos de formato são descritos. Consulte Formatos de arquivo de dados.
- Cada registro precisa ter um
id, um vetor de recurso e campos opcionais compatíveis com o Feature Store da Vertex AI, como restrições e distanciamento. - Um subdiretório chamado
deletepode estar presente. Cada arquivo diretamente colocado embatch_root/deleteé processado como um arquivo de texto de registrosidcom umidem cada linha. - Todos os outros subdiretórios não são permitidos.
- A transcodificação de arquivos compactados por gzip não é compatível como dados de entrada.
Processamento de dados de entrada
- Todos os registros de todos os arquivos de dados, incluindo aqueles em
delete, consistem em um único lote de entrada. - A ordem relativa dos registros em um arquivo de dados não é importante.
- Um único ID só deve aparecer uma vez em um lote. Se houver uma cópia com o mesmo ID, ela será mostrada como uma contagem de vetores.
- Um ID não pode aparecer em um arquivo de dados normal e em um arquivo de dados de exclusão.
- Todos os IDs de um arquivo de dados em exclusão fazem com que ele seja removido da próxima versão do índice.
- Os registros de arquivos de dados regulares serão incluídos na próxima versão, possivelmente substituindo um valor em uma versão de índice mais antiga.
Confira a seguir exemplos de embeddings densos, esparsos e híbridos:
Embeddings densos
{"id": "1", "embedding": [1,1,1]} {"id": "2", "embedding": [2,2,2]}Embeddings esparsos:
{"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]}}Embeddings híbridos:
{"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]}}
Veja a seguir um exemplo de organização válida de arquivos de dados de entrada:
batch_root/
feature_file_1.csv
feature_file_2.csv
delete/
delete_file.txt
Os arquivos feature_file_1.csv e feature_file_2.csv contêm registros no formato CSV. O arquivo delete_file.txt contém uma lista de IDs de registro a serem excluídos da
próxima versão do índice.
Formatos de arquivo de dados
JSON
- Codifique o arquivo JSON usando UTF-8.
- Cada linha do arquivo JSON será interpretada como um objeto JSON separado.
- Cada registro precisa conter um campo
idpara especificar o ID do vetor. - Cada registro precisa conter pelo menos
embeddingousparse_embedding. - O campo
embeddingé uma matriz de números de ponto flutuanteNque representa o vetor de atributos, em queNé a dimensão do vetor de atributos que foi configurado quando o índice foi criado. Esse campo só pode ser usado para embeddings densos.- O
configs.dimensions, especificado no momento da criação do índice, precisa ter o mesmo comprimento queembeddings.configs.dimensionsse aplica apenas aembedding, não asparse_embedding.
- O
- O campo
sparse_embeddingé um objeto com camposvaluesedimensions. O campovaluesé uma lista de números de pontos flutuantes que representam o vetor do atributo e o campodimensionsé uma lista de números inteiros que representa a dimensão na qual o valor correspondente está localizado. Por exemplo, um embedding esparso que se parece com[0,0.1,0,0,0.2]pode ser representado como"sparse_embedding": {"values": [0.1, 0.2], "dimensions": [1,4]}. Isso pode ser usado apenas para embeddings esparsos.- O comprimento de
sparse_embedding.valuesprecisa ser igual ao desparse_embedding.dimensions. Elas não precisam ter o mesmo tamanho queconfigs.dimensions, que é especificado no momento da criação do índice e não se aplica asparse_embedding.
- O comprimento de
- É possível incluir um campo
restrictsopcional para especificar uma matriz de objetosTokenNamespaceem restrições. Para cada objeto:- Especifique um campo
namespaceque seja oTokenNamespace.namespace. - Um campo
allowopcional pode ser definido como uma matriz de strings, que são a lista deTokenNamespace.string_tokens. - Um campo
denyopcional pode ser definido como uma matriz de strings, que são a lista deTokenNamespace.string_blacklist_tokens. - O valor do campo
crowding_tag, se presente, precisa ser uma string.
- Especifique um campo
- É possível incluir um campo
numeric_restrictsopcional que especifica uma matriz deNumericRestrictNamespace. Para cada objeto:- Especifique um campo
namespaceque seja oNumericRestrictNamespace.namespace. - Um dos campos de valor
value_int,value_floatevalue_double. - Ele não pode ter um campo chamado op. Esse campo é apenas para consultas.
- Especifique um campo
Avro
- Use um arquivo Avro válido.
- Para representar um ponto de dados apenas com valores esparsos, forneça uma embedding esparso no campo
sparse_embeddinge insira uma lista vazia no campoembedding. Faça registros que estejam em conformidade com o seguinte 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 - Codifique o arquivo CSV usando UTF-8.
- Cada linha do CSV precisa conter exatamente um registro.
- O primeiro valor em cada linha precisa ser o ID do vetor, que precisa ser uma string UTF-8 válida.
- Após o ID, pelo menos um dos embeddings densos ou esparsos precisa ser especificado.
- Para um embedding denso, os próximos valores de
Nrepresentam o vetor de atributo, em queNé a dimensão do vetor de atributo que foi configurada quando o índice foi criado. - Em um embedding esparso, qualquer número de
dimension:valuepode ser especificado, em quevalueé analisado como um ponto flutuante edimensioné analisado como umlong. - Para um embedding híbrido com embeddings densos e esparsos, os densos precisam ser especificados antes dos esparsos.
- Os valores de vetor de recurso precisam ser literais de ponto flutuante, conforme definido na especificação da linguagem Java.
- Os valores adicionais podem estar no formato
name=value. - O nome
crowding_tagé interpretado como a tag de distanciamento e só pode aparecer uma vez no registro. Todos os outros pares
name=valuesão interpretados como restrições de namespace. O mesmo nome pode ser repetido se houver vários valores em um namespace.Por exemplo,
color=red,color=bluerepresenta esteTokenNamespace:{ "namespace": "color" "string_tokens": ["red", "blue"] }Se o valor começar com
!, o restante da string será interpretado como um valor excluído.Por exemplo,
color=!redrepresenta esteTokenNamespace:{ "namespace": "color" "string_blacklist_tokens": ["red"] }Pares
#name=numericValuecom sufixo de tipo numérico são interpretados como restrições numéricas de namespace. O sufixo do tipo de número éipara int,fpara flutuante edpara duplo. O mesmo nome não pode ser repetido, porque precisa haver um único valor associado por namespace.Por exemplo,
#size=3irepresenta esteNumericRestrictNamespace:{ "namespace": "size" "value_int": 3 }#ratio=0.1frepresenta esteNumericRestrictNamespace:{ "namespace": "ratio" "value_float": 0.1 }#weight=0.3drepresenta esteNumericRestriction:{ "namespace": "weight" "value_double": 0.3 }O exemplo a seguir é um ponto de dados com
id: "6",embedding: [7, -8.1],sparse_embedding: {values: [0.1, -0.2, 0.5], dimensions: [40, 901, 1111]}, tag de distanciamentotest, lista de permissões de token docolor: red, blue, lista de bloqueio de token docolor: purplee restrição numérica doratiocom0.1flutuante: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
A seguir
- Saiba como criar e gerenciar seu índice.