Filtri nelle query vettoriali

È possibile impostare le modalità di filtro vettoriale in una query vettoriale per specificare se si desidera filtrare prima o dopo l'esecuzione della query.

I filtri determinano l'ambito di una query vettoriale. I filtri vengono impostati su e eseguono l'iterazione su stringhe nonvector e campi numerici attribuiti come filterable nell'indice, ma lo scopo di un filtro determina l'esecuzione della query vettoriale: l'intero spazio ricercabile o il contenuto di un risultato di ricerca.

Questo articolo descrive ogni modalità di filtro e fornisce indicazioni su quando usare ognuno di essi.

Modalità prefiltro

Il prefiltro applica filtri prima dell'esecuzione della query, riducendo la superficie di ricerca su cui l'algoritmo di ricerca vettoriale cerca contenuto simile. In una query vettoriale preFilter è l'impostazione predefinita.

Diagram of prefilters.

Modalità postfiltro

Il post-filtro applica filtri dopo l'esecuzione della query, restringendo i risultati della ricerca.

Diagram of post-filters.

Test di benchmark delle modalità di filtro vettoriale

Per comprendere le condizioni in cui una modalità filtro offre prestazioni migliori rispetto all'altra, è stata eseguita una serie di test per valutare i risultati delle query su indici di piccole, medie e grandi dimensioni.

  • Piccolo (100.000 documenti, indice da 2,5 GB, 1536 dimensioni)
  • Medio (1 milione di documenti, indice da 25 GB, 1536 dimensioni)
  • Grandi dimensioni (1 miliardo di documenti, indice da 1,9 TB, 96 dimensioni)

Per i carichi di lavoro di piccole e medie dimensioni, è stato usato un servizio Standard 2 (S2) con una partizione e una replica. Per il carico di lavoro di grandi dimensioni è stato usato un servizio Standard 3 (S3) con 12 partizioni e una replica.

Gli indici hanno una costruzione identica: un campo chiave, un campo vettore, un campo di testo e un campo filtrabile numerico. L'indice seguente viene definito usando la sintassi 2023-07-01-preview.

def get_index_schema(self, index_name, dimensions):
    return {
        "name": index_name,
        "fields": [
            {"name": "id", "type": "Edm.String", "key": True, "searchable": True},
            {"name": "content_vector", "type": "Collection(Edm.Single)", "dimensions": dimensions,
              "searchable": True, "retrievable": True, "filterable": False, "facetable": False, "sortable": False,
              "vectorSearchConfiguration": "defaulthnsw"},
            {"name": "text", "type": "Edm.String", "searchable": True, "filterable": False, "retrievable": True,
              "sortable": False, "facetable": False},
            {"name": "score", "type": "Edm.Double", "searchable": False, "filterable": True,
              "retrievable": True, "sortable": True, "facetable": True}
        ],
        "vectorSearch":
        {
            "algorithmConfigurations": [
                {"name": "defaulthnsw", "kind": "hnsw", "hnswParameters": {"metric": "euclidean"}}
            ]
        }
    }

Nelle query è stato usato un filtro identico per le operazioni di prefiltro e postfiltro. È stato usato un filtro semplice per garantire che le variazioni delle prestazioni fossero dovute alla modalità di filtro e non alla complessità del filtro.

I risultati sono stati misurati nelle query al secondo (QPS).

Risultati

  • Il prefiltramento è quasi sempre più lento rispetto al postfiltro, tranne per gli indici di piccole dimensioni in cui le prestazioni sono approssimativamente uguali.

  • Nei set di dati più grandi, il prefiltramento è l'ordine di grandezza più lento.

  • Perché è quindi prefiltro il valore predefinito se è quasi sempre più lento? La prefiltrazione garantisce che k i risultati vengano restituiti se presenti nell'indice, in cui la distorsione favorisce il richiamo e la precisione rispetto alla velocità.

  • Il postfiltro è destinato ai clienti che:

    • velocità del valore rispetto alla selezione (il postfiltro può restituire meno dei k risultati)
    • usare filtri che non sono eccessivamente selettivi
    • hanno indici di dimensioni sufficienti in modo che le prestazioni di prefiltrazione non siano accettabili

Dettagli

  • Dato un set di dati con 100.000 vettori a 1536 dimensioni:

    • Quando si filtra più del 30% del set di dati, i prefiltri e i postfiltri erano confrontabili.
    • Quando si filtra meno dello 0,1% del set di dati, il prefiltramento è stato circa il 50% più lento rispetto al postfiltro.
  • Dato un set di dati con 1 milione di vettori a 1536 dimensioni:

    • Quando si filtra più del 30% del set di dati, il prefiltramento è stato circa il 30% più lento.
    • Quando si filtra meno del 2% del set di dati, il filtro preliminare era circa sette volte più lento.
  • Dato un set di dati con 1 miliardo di vettori a 96 dimensioni:

    • Quando si filtra più del 5% del set di dati, il filtro preliminare era circa il 50% più lento.
    • Quando si filtra meno del 10% del set di dati, il filtro preliminare era circa sette volte più lento.

Il grafico seguente mostra il QPS relativo del prefiltro, calcolato come QPS prefiltro diviso per QPS postfiltro.

Chart showing QPS performance for small, medium, and large indexes for relative QPS.

L'asse verticale è QPS di prefiltrazione su QPS di postfiltrazione. Ad esempio, un valore pari a 0,0 indica che il prefiltro è più lento del 100%, 0,5 sull'asse verticale significa che il prefiltro è più lento del 50%, 1,0 significa prefiltrazione e post filtro sono equivalenti.

L'asse orizzontale rappresenta la velocità di filtro o la percentuale di documenti candidati dopo l'applicazione del filtro. Ad esempio, 1.00% significa che il 1% del corpus di ricerca è stato selezionato dai criteri di filtro.