Compartilhar via


Compactar vetores usando a compartimentalização escalar ou binária

A Pesquisa de IA do Azure dá suporte à compartimentalização escalar e binária para reduzir o tamanho dos vetores em um índice de pesquisa. A compartimentalização é recomendada para reduzir o tamanho do vetor porque reduz o consumo de armazenamento em memória e disco para inserções float16 e float32. Para compensar os efeitos da compactação com perdas, você pode adicionar sobreamostragem e reclassificação sobre vetores não compactados.

Para usar a compartimentalização interna, siga estas etapas:

  • Comece com campos de vetor e uma configuração de vectorSearch para um índice
  • Adicione vectorSearch.compressions
  • Adicione uma configuração de scalarQuantization ou binaryQuantization e forneça um nome a ela
  • Defina propriedades opcionais para atenuar os efeitos da indexação com perda
  • Crie um novo perfil de vetor que usa a configuração nomeada
  • Crie o campo vetorial com o novo perfil de vetor
  • Carregue o índice com dados float32 ou float16 que são compartimentalizados durante a indexação com a configuração definida
  • Opcionalmente, consulte dados compartimentalizados usando o parâmetro de sobreamostragem se você quiser substituir o padrão

Pré-requisitos

  • Campos de vetor em um índice de pesquisa com uma configuração vectorSearch, usando os algoritmos HNSW (Hierarchical Navigable Small Worlds) ou eKNN (exhaustive K-nearest neighbor) e um novo perfil de vetor.

Técnicas de compartimentalização com suporte

A compartimentalização se aplica a campos vetoriais que recebem vetores do tipo float. Nos exemplos deste artigo, o tipo de dados de campo é Collection(Edm.Single) para inserções float32 de entrada, mas também há suporte para float16. Quando os vetores são recebidos em um campo com compactação configurada, o mecanismo executa automaticamente a compartimentalização para reduzir o volume dos dados vetoriais na memória e no disco.

Dois tipos de compartimentalização são compatíveis:

  • A compartimentalização escalar compacta valores floats em tipos de dados mais estreitos. A Pesquisa de IA atualmente dá suporte ao int8, que é de 8 bits, reduzindo o tamanho do índice vetorial quatro vezes.

  • A compartimentalização binária converte floats em bits binários, o que ocupa 1 bit. Isso resulta em um tamanho de índice vetorial até 28 vezes menor.

Adicionar "compactações" a um índice de pesquisa

O exemplo a seguir mostra uma definição de índice parcial com uma coleção de campos que inclui um campo vetorial e uma seção vectorSearch.compressions.

Inclui scalarQuantization ou binaryQuantization. Você pode especificar quantas configurações de compactação forem necessárias e atribuir as que deseja a um perfil de vetor.

A sintaxe para vectorSearch.Compressions varia entre APIs REST estáveis e em versão prévia, com a versão prévia adicionando novas opções para otimização de armazenamento, além de alterações na sintaxe existente. A compatibilidade com versões anteriores é preservada por meio de mapeamentos internos da API, mas você deve adotar a nova sintaxe no código que tem como destino as versões 2024-11-01-preview e futuras.

Use a API REST Criar Índice ou Criar ou Atualizar Índice para definir as configurações de compactação.

POST https://[servicename].search.windows.net/indexes?api-version=2024-07-01

{
  "name": "my-index",
  "fields": [
    { "name": "Id", "type": "Edm.String", "key": true, "retrievable": true, "searchable": true, "filterable": true },
    { "name": "content", "type": "Edm.String", "retrievable": true, "searchable": true },
    { "name": "vectorContent", "type": "Collection(Edm.Single)", "retrievable": false, "searchable": true, "dimensions": 1536,"vectorSearchProfile": "vector-profile-1"},
  ],
  "vectorSearch": {
        "profiles": [ ],
        "algorithms": [ ],
        "compressions": [
          {
            "name": "use-scalar",
            "kind": "scalarQuantization",
            "scalarQuantizationParameters": {
              "quantizedDataType": "int8"
            },
            "rerankWithOriginalVectors": true,
            "defaultOversampling": 10
          },
          {
            "name": "use-binary",
            "kind": "binaryQuantization",
            "rerankWithOriginalVectors": true,
            "defaultOversampling": 10
          }
        ]
    }
}

Pontos principais:

  • kind deve ser definido como scalarQuantization ou binaryQuantization.

  • rerankWithOriginalVectors usa os vetores originais e não compactados para recalcular a similaridade e recalcular os resultados principais retornados pela consulta de pesquisa inicial. Os vetores não compactados existem no índice de pesquisa mesmo que stored seja false. Essa propriedade é opcional. O padrão é verdadeiro.

  • defaultOversampling considera um conjunto mais amplo de resultados potenciais para compensar a redução das informações da compartimentalização. A fórmula para resultados potenciais consiste em k na consulta, com um multiplicador de sobreamostragem. Por exemplo, se a consulta especificar um k de 5, e a sobrecarga for 20, a consulta solicitará efetivamente 100 documentos para uso no reclassificado, usando o vetor não compactado original para essa finalidade. Somente os principais k resultados reclassificados são retornados. Essa propriedade é opcional. O padrão é 4.

  • quantizedDataType é opcional e se aplica somente à compartimentalização escalar. Se você adicioná-lo, deve ser definido como int8. Esse é o único tipo de dados primitivo com suporte para compartimentalização escalar no momento. O padrão é int8.

Adicionar o algoritmo da busca em vetores

Você pode usar o algoritmo HNSW ou o KNN exaustivo na API REST 2024-11-01-preview. Para a versão estável, use somente HNSW.

"vectorSearch": {
    "profiles": [ ],
    "algorithms": [
      {
          "name": "use-hnsw",
          "kind": "hnsw",
          "hnswParameters": {
              "m": 4,
              "efConstruction": 400,
              "efSearch": 500,
              "metric": "cosine"
          }
      }
    ],
     "compressions": [ <see previous section>] 
}

Criar e atribuir um novo perfil de vetor

Para usar uma nova configuração de compartimentalização, você deve criar um novo perfil de vetor. A criação de um novo perfil de vetor é necessária para criar índices compactados na memória. Seu novo perfil usa HNSW.

  1. Na mesma definição de índice, crie um novo perfil de vetor e adicione uma propriedade de compactação e algoritmo. Aqui estão dois perfis, um para cada abordagem de compartimentalização.

    "vectorSearch": {
        "profiles": [
           {
              "name": "vector-profile-hnsw-scalar",
              "compression": "use-scalar", 
              "algorithm": "use-hnsw",
              "vectorizer": null
           },
           {
              "name": "vector-profile-hnsw-binary",
              "compression": "use-binary", 
              "algorithm": "use-hnsw",
              "vectorizer": null
           }
         ],
         "algorithms": [  <see previous section> ],
         "compressions": [ <see previous section> ] 
    }
    
  2. Atribua um perfil de vetor a um novo campo de vetor. O tipo de dados de campo é float32 ou float16.

    Na Pesquisa de IA do Azure, os equivalentes de EDM (Modelo de Dados de Entidade) dos tipos float32 e float16 são Collection(Edm.Single) e Collection(Edm.Half), respectivamente.

    {
       "name": "vectorContent",
       "type": "Collection(Edm.Single)",
       "searchable": true,
       "retrievable": true,
       "dimensions": 1536,
       "vectorSearchProfile": "vector-profile-hnsw-scalar",
    }
    
  3. Carregue o índice usando indexadores para indexação de modelo de pull ou APIs para indexação de modelo push.

A compartimentalização escalar reduz a resolução de cada número em cada inserção de vetor. Em vez de descrever cada número como um número de ponto flutuante de 16 bits ou 32 bits, ele usa um inteiro de 8 bits. Ele identifica um intervalo de números (normalmente 99º percentil mínimo e máximo) e os divide em um número finito de níveis ou compartimento, atribuindo a cada compartimento um identificador. Na compartimentalização escalar de 8 bits, há 2^8 ou 256 compartimentos possíveis.

Cada componente do vetor é mapeado para o valor representativo mais próximo dentro desse conjunto de níveis de compartimentalização em um processo semelhante ao arredondamento de um número real para o inteiro mais próximo. No vetor de 8 bits quantificado, o número do identificador fica no lugar do valor original. Após a compartimentalização, cada vetor é representado por uma matriz de identificadores para as lixeiras às quais seus componentes pertencem. Esses vetores quantificados exigem muito menos bits para armazenar em comparação com o vetor original, reduzindo assim os requisitos de armazenamento e o volume de memória.

A compartimentalização binária compacta vetores de alta dimensão, representando cada componente como um único bit, 0 ou 1. Esse método reduz drasticamente o volume de memória e acelera as operações de comparação de vetores, que são cruciais para tarefas de pesquisa e recuperação. Os testes de parâmetro de comparação mostram uma redução de até 96% no tamanho do índice vetorial.

É particularmente eficaz para inserções com dimensões maiores que 1024. Para dimensões menores, recomendamos testar a qualidade da compartimentalização binária ou tentar a escalar. Além disso, descobrimos que o BQ tem um bom desempenho quando as inserções são centradas em torno de zero. Os modelos de inserção mais populares, como OpenAI, Cohere e Mistral, são centrados em torno de zero.

Consultar um campo de vetor quantificado usando sobrecarga

A sintaxe de consulta para um campo de vetor compactado ou compartimentalizado é a mesma de campos de vetor não compactados, a menos que você queira substituir parâmetros associados à sobreamostragem ou à revisão de pontuação com vetores originais.

Lembre-se de que a definição de compactação de vetor no índice tem configurações para rerankWithOriginalVectors e defaultOversampling para atenuar os efeitos da compactação com perdas. Você pode substituir os valores padrão para variar o comportamento no momento da consulta. Por exemplo, se defaultOversampling for 10.0, você poderá alterá-lo para outra coisa na solicitação de consulta.

Você pode definir o parâmetro de sobreamostragem mesmo que o índice não tenha explicitamente uma definição rerankWithOriginalVectors ou defaultOversampling. Fornecer oversampling em tempo de consulta substitui as configurações de índice para essa consulta e executa a consulta com um rerankWithOriginalVectors efetivo como true.

POST https://[service-name].search.windows.net/indexes/demo-index/docs/search?api-version=2024-07-01

{    
    "vectorQueries": [
        {    
            "kind": "vector",    
            "vector": [8, 2, 3, 4, 3, 5, 2, 1],    
            "fields": "myvector",
            "oversampling": 12.0,
            "k": 5   
        }
  ]    
}

Pontos principais:

  • Aplica-se a campos de vetor que passam por compactação de vetor, de acordo com a atribuição de perfil de vetor.

  • Substitui o valor defaultOversampling ou introduz a sobrecarga no momento da consulta, mesmo que a configuração de compactação do índice não especifique opções de sobrecarga ou reclassificador.