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.
Armazenamento de dados de entrada e organização de arquivos
Pré-requisito
Armazene os dados de entrada em um bucket do Cloud Storage no projeto do 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_root
e nomeados com os seguintes sufixos:.csv
,.json
e.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
delete
pode estar presente. Cada arquivo diretamente colocado embatch_root
/delete
é processado como um arquivo de texto de registrosid
com umid
em cada linha. - Todos os outros diretórios e arquivos são ignorados.
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 (pré-lançamento público):
{"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 (pré-lançamento público):
{"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
id
para especificar o ID do vetor. - Cada registro precisa conter pelo menos
embedding
ousparse_embedding
. - O campo
embedding
é uma matriz de números de ponto flutuanteN
que 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.dimensions
se aplica apenas aembedding
, não asparse_embedding
.
- O
- O campo
sparse_embedding
é um objeto com camposvalues
edimensions
. 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.values
precisa 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
restricts
opcional para especificar uma matriz de objetosTokenNamespace
em restrições. Para cada objeto:- Especifique um campo
namespace
que seja oTokenNamespace.namespace
. - Um campo
allow
opcional pode ser definido como uma matriz de strings, que são a lista deTokenNamespace.string_tokens
. - Um campo
deny
opcional 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_restricts
opcional que especifica uma matriz deNumericRestrictNamespace
. Para cada objeto:- Especifique um campo
namespace
que seja oNumericRestrictNamespace.namespace
. - Um dos campos de valor
value_int
,value_float
evalue_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_embedding
e 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
N
representam 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:value
pode 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=value
sã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=blue
representa 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=!red
representa esteTokenNamespace
:{ "namespace": "color" "string_blacklist_tokens": ["red"] }
Pares
#name=numericValue
com sufixo de tipo numérico são interpretados como restrições numéricas de namespace. O sufixo do tipo de número éi
para int,f
para flutuante ed
para duplo. O mesmo nome não pode ser repetido, porque precisa haver um único valor associado por namespace.Por exemplo,
#size=3i
representa esteNumericRestrictNamespace
:{ "namespace": "size" "value_int": 3 }
#ratio=0.1f
representa esteNumericRestrictNamespace
:{ "namespace": "ratio" "value_float": 0.1 }
#weight=0.3d
representa 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: purple
e restrição numérica doratio
com0.1
flutuante: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.