Share via


Vector kwantisatie en verminderde opslag configureren voor kleinere vectoren in Azure AI Search

Belangrijk

Deze functies zijn beschikbaar als openbare preview onder aanvullende gebruiksvoorwaarden. De REST API 2024-03-01-Preview biedt de nieuwe gegevenstypen, vectorcompressie-eigenschappen en de stored eigenschap.

In dit artikel worden vector kwantisatie en andere technieken voor het comprimeren van vectorindexen in Azure AI Search beschreven.

De opties evalueren

Als eerste stap bekijkt u de drie opties voor het verminderen van de hoeveelheid opslagruimte die door vectorvelden wordt gebruikt. Deze opties sluiten elkaar niet uit.

We raden scalaire kwantisatie aan omdat het vectorgrootte in het geheugen en op schijf met minimale inspanning comprimeert en dat meestal het meeste voordeel biedt in de meeste scenario's. Daarentegen vereisen smalle typen (met uitzondering van Float16) een speciale inspanning om ze te maken en stored besparen op schijfopslag, wat niet zo duur is als geheugen.

Methode Waarom deze optie gebruiken?
Kleinere primitieve gegevenstypen toewijzen aan vectorvelden Smalle gegevenstypen, zoals Float16, Int16en Int8, verbruiken minder ruimte in het geheugen en op schijf, maar u moet een insluitmodel hebben dat vectoren uitvoert in een smalle gegevensindeling. U moet ook aangepaste kwantisatielogica hebben die kleine gegevens uitvoert. Een derde use-case waarvoor minder moeite nodig is, is het herschikken van systeemeigen Float32 insluitingen die door de meeste modellen worden geproduceerd.Float16
Optionele opslag van ophaalbare vectoren elimineren Vectoren die in een queryantwoord worden geretourneerd, worden afzonderlijk opgeslagen van vectoren die worden gebruikt tijdens het uitvoeren van de query. Als u geen vectoren hoeft te retourneren, kunt u ophaalbare opslag uitschakelen, waardoor de totale schijfopslag per veld met maximaal 50 procent wordt verminderd.
Scalaire kwantisatie toevoegen Gebruik ingebouwde scalaire kwantisatie om systeemeigen Float32 insluitingen te comprimeren.Int8 Deze optie vermindert de opslag in het geheugen en op de schijf zonder de prestaties van query's te verminderen. Kleinere gegevenstypen zoals Int8 vectorindexen produceren die minder inhoudsrijk zijn dan die met Float32 insluitingen. Om informatieverlies te compenseren, bevat ingebouwde compressie opties voor het verwerken van query's met behulp van niet-gecomprimeerde insluitingen en oversampling om relevantere resultaten te retourneren. Herrankering en oversampling zijn specifieke functies van ingebouwde scalaire kwantisatie van Float32 of Float16 velden en kunnen niet worden gebruikt voor insluitingen die aangepaste kwantisatie ondergaan.

Al deze opties worden gedefinieerd in een lege index. Als u een van deze api's wilt implementeren, gebruikt u Azure Portal, 2024-03-01-preview REST API's of een bèta-Azure SDK-pakket.

Nadat de index is gedefinieerd, kunt u documenten laden en indexeren als een afzonderlijke stap.

Optie 1: Smalle gegevenstypen toewijzen aan vectorvelden

Vectorvelden slaan vector-insluitingen op die worden weergegeven als een matrix met getallen. Wanneer u een veldtype opgeeft, geeft u het onderliggende primitieve gegevenstype op dat wordt gebruikt voor het opslaan van elk getal binnen deze matrices. Het gegevenstype is van invloed op de hoeveelheid ruimte die elk getal inneemt.

Met behulp van preview-API's kunt u smalle primitieve gegevenstypen toewijzen om de opslagvereisten van vectorvelden te verminderen.

  1. Bekijk de gegevenstypen voor vectorvelden:

    • Collection(Edm.Single) 32-bits drijvende komma (standaard)
    • Collection(Edm.Half) 16-bits drijvende komma
    • Collection(Edm.Int16) 16-bits geheel getal ondertekend
    • Collection(Edm.SByte) 8-bits geheel getal ondertekend

    Notitie

    Binaire gegevenstypen worden momenteel niet ondersteund.

  2. Kies een gegevenstype dat geldig is voor de uitvoer van het insluitmodel of voor vectoren die aangepaste kwantisatie ondergaan.

    De meeste insluitmodellen leveren 32-bits drijvendekommanummers op, maar als u aangepaste kwantisatie toepast, kan uw uitvoer wel Int16 of Int8. U kunt nu vectorvelden definiëren die de kleinere indeling accepteren.

    Modellen voor het insluiten van Float32tekst hebben een systeemeigen uitvoerindeling, die wordt toegewezen aan Collection(Edm.Single) in Azure AI Search. U kunt die uitvoer Int8 niet toewijzen omdat casten van float naar int is verboden. U kunt echter van Float32 (of) naar Float16 (of Collection(Edm.Half)) casten en dit is een eenvoudige manier om smalle gegevenstypen te gebruiken zonder extra werk.

    De volgende tabel bevat koppelingen naar verschillende insluitmodellen die gebruikmaken van de smalle gegevenstypen.

    Model insluiten Systeemeigen uitvoer Geldige typen in Azure AI Search
    tekst-insluiten-ada-002 Float32 Collection(Edm.Single) of Collection(Edm.Half)
    tekst-insluiten-3-klein Float32 Collection(Edm.Single) of Collection(Edm.Half)
    tekst-insluiten-3-groot Float32 Collection(Edm.Single) of Collection(Edm.Half)
    Cohere V3 insluitmodellen met int8 embedding_type Int8 Collection(Edm.SByte)
  3. Zorg ervoor dat u de compromissen van een smal gegevenstype begrijpt. Collection(Edm.Half) heeft minder informatie, wat resulteert in een lagere resolutie. Als uw gegevens homogeen of dicht zijn, kan het verlies van extra details of nuance leiden tot onaanvaardbare resultaten op het moment van de query, omdat er minder details zijn die kunnen worden gebruikt om nabijgelegen vectoren van elkaar te onderscheiden.

  4. Definieer en bouw de index. U kunt de Azure-portal, 2024-03-01-preview of een bèta-Azure SDK-pakket voor deze stap gebruiken.

  5. Controleer de resultaten. Ervan uitgaande dat het vectorveld is gemarkeerd als ophaalbaar, gebruikt u Search Explorer of REST API om te controleren of de veldinhoud overeenkomt met het gegevenstype. Zorg ervoor dat u de juiste 2024-03-01-preview API-versie voor de query gebruikt, anders worden de nieuwe eigenschappen niet weergegeven.

Als u de grootte van de vectorindex wilt controleren, gebruikt u Azure Portal of de preview-versie 2024-03-01.

Notitie

Het gegevenstype van het veld wordt gebruikt om de fysieke gegevensstructuur te maken. Als u later een gegevenstype wilt wijzigen, kunt u de index verwijderen en opnieuw opbouwen of een tweede veld maken met de nieuwe definitie.

Optie 2: Stel de stored eigenschap in om ophaalbare opslag te verwijderen

De stored eigenschap is een nieuwe Booleaanse waarde op een vectorvelddefinitie die bepaalt of opslag wordt toegewezen voor inhoud van het vectorveld dat kan worden opgehaald. Als u geen vectorinhoud in een queryantwoord nodig hebt, kunt u maximaal 50 procent opslag per veld opslaan door in te stellen stored op false.

Omdat vectoren niet door mensen leesbaar zijn, worden ze meestal weggelaten in een queryantwoord dat wordt weergegeven op een zoekpagina. Als u echter vectoren in downstreamverwerking gebruikt, zoals het doorgeven van queryresultaten aan een model of proces dat vectorinhoud verbruikt, moet u ingesteld blijven stored op waar en een andere techniek kiezen om de vectorgrootte te minimaliseren.

In het volgende voorbeeld ziet u de veldenverzameling van een zoekindex. Ingesteld stored op onwaar om permanent ophaalbare opslag voor het vectorveld te verwijderen.

PUT https://[service-name].search.windows.net/indexes/[index-name]?api-version=2024-03-01-preview  
   Content-Type: application/json  
   api-key: [admin key]  
 
     { 
       "name": "myindex", 
       "fields": [ 
         { 
           "name": "myvector", 
           "type": "Collection(Edm.Single)", 
           "retrievable": false, 
           "stored": false, 
           "dimensions": 1536, 
           "vectorSearchProfile": "vectorProfile" 
         } 
       ] 
     } 

Belangrijkste punten:

  • Alleen van toepassing op vectorvelden .

  • Beïnvloedt de opslag op schijf, niet het geheugen en heeft geen invloed op query's. Bij het uitvoeren van query's wordt een afzonderlijke vectorindex gebruikt die niet wordt beïnvloed door de stored eigenschap.

  • De stored eigenschap wordt ingesteld tijdens het maken van de index op vectorvelden en kan niet ongedaan worden gemaakt. Als u later inhoud wilt ophalen, moet u de index verwijderen en opnieuw opbouwen, of een nieuw veld maken en laden met de nieuwe toeschrijving.

  • De standaardwaarden zijn stored ingesteld op waar en retrievable ingesteld op onwaar. In een standaardconfiguratie wordt een ophaalbare kopie opgeslagen, maar deze wordt niet automatisch geretourneerd in de resultaten. Wanneer stored is waar, kunt retrievable u op elk gewenst moment schakelen tussen waar en onwaar zonder dat u een index opnieuw hoeft op te bouwen. Wanneer stored onwaar is, retrievable moet onwaar zijn en kan niet worden gewijzigd.

Optie 3: Scalaire kwantisatie configureren

Ingebouwde scalaire kwantisatie wordt aanbevolen omdat het geheugen- en schijfopslagvereisten vermindert, en er wordt herrankering en oversampling toegevoegd om de effecten van een kleinere index te compenseren. Ingebouwde scalaire kwantisatie kan worden toegepast op vectorvelden die of Float16 gegevens bevattenFloat32.

Ingebouwde vectorcompressie gebruiken:

  • Toevoegen vectorSearch.compressions aan een zoekindex. Het compressie-algoritme dat in deze preview wordt ondersteund, is scalaire kwantisatie.
  • Stel optionele eigenschappen in om de gevolgen van lossy indexering te beperken. Beide rerankWithOriginalVectors en defaultOversampling bieden optimalisaties tijdens het uitvoeren van query's.
  • Toevoegen vectorSearch.profiles.compression aan een nieuw vectorprofiel.
  • Wijs het nieuwe vectorprofiel toe aan een nieuw vectorveld.

Compressie-instellingen toevoegen en optionele eigenschappen instellen

Voeg een compressions sectie toe in een indexdefinitie die is gemaakt met behulp van REST API 2024-03-01-preview. Gebruik de volgende JSON als sjabloon.

"compressions": [

      {  
        "name": "my-scalar-quantization",  
        "kind": "scalarQuantization",  
        "rerankWithOriginalVectors": true,  (optional)
        "defaultOversampling": 10.0,  (optional)
        "scalarQuantizationParameters": {  (optional)
             "quantizedDataType": "int8",  (optional)
        }
      }  
   ]

Belangrijkste punten:

  • kind moet zijn ingesteld op scalarQuantization. Dit is de enige kwantisatiemethode die op dit moment wordt ondersteund.

  • rerankWithOriginalVectors gebruikt de oorspronkelijke, niet-gecomprimeerde vectoren om overeenkomsten opnieuw te berekenen en de belangrijkste resultaten die door de eerste zoekquery worden geretourneerd, opnieuw te rangschikken. De niet-gecomprimeerde vectoren bestaan in de zoekindex, zelfs als stored deze onwaar is. Deze eigenschap is optioneel. De standaardwaarde is waar.

  • defaultOversampling beschouwt een bredere set potentiële resultaten om de vermindering van de informatie van kwantisatie te compenseren. De formule voor mogelijke resultaten bestaat uit de k in de query, met een vermenigvuldiger voor oversampling. Als de query bijvoorbeeld een k van 5 opgeeft en oversampling 20 is, vraagt de query in feite 100 documenten aan voor gebruik bij het opnieuw rangschikken, waarbij de oorspronkelijke niet-gecomprimeerde vector voor dat doel wordt gebruikt. Alleen de meest k gererankeerde resultaten worden geretourneerd. Deze eigenschap is optioneel. De standaardwaarde is 4.

  • quantizedDataType moet zijn ingesteld op int8. Dit is het enige primitieve gegevenstype dat op dit moment wordt ondersteund. Deze eigenschap is optioneel. Standaard is int8.

Een compressie-instelling toevoegen aan een vectorprofiel

Scalaire kwantisatie wordt opgegeven als een eigenschap in een nieuw vectorprofiel. Het maken van een nieuw vectorprofiel is nodig voor het bouwen van gecomprimeerde indexen in het geheugen.

Binnen het profiel moet u het HNSW-algoritme (Hierarchical Navigable Small Worlds) gebruiken. Ingebouwde kwantisatie wordt niet ondersteund met uitgebreide KNN.

  1. Maak een nieuw vectorprofiel en voeg een compressie-eigenschap toe.

    "profiles": [
       {
          "name": "my-vector-profile",
          "compression": "my-scalar-quantization", 
          "algorithm": "my-hnsw-vector-config-1",
          "vectorizer": null
       }
     ]
    
  2. Wijs een vectorprofiel toe aan een nieuw vectorveld. Scalaire kwantisatie vermindert inhoud tot Int8, dus zorg ervoor dat uw inhoud is Float32 of Float16.

    In Azure AI Search zijn Collection(Edm.Single)Collection(Edm.Half)respectievelijk de EDM-equivalenten (Entity Data Model) en Float16Float32 typen.

    {
       "name": "DescriptionVector",
       "type": "Collection(Edm.Single)",
       "searchable": true,
       "retrievable": true,
       "dimensions": 1536,
       "vectorSearchProfile": "my-vector-profile"
    }
    
  3. Laad de index met indexeerfuncties voor het indexeren van pull-modellen of API's voor pushmodelindexering.

Scalaire kwantisatie vermindert de resolutie van elk getal binnen elke vector insluiten. In plaats van elk getal als een 32-bits drijvendekommanummer te beschrijven, wordt een 8-bits geheel getal gebruikt. Het identificeert een bereik van getallen (meestal 99e percentiel minimum en maximum) en verdeelt ze in een eindig aantal niveaus of bin, waarbij elke bin een id wordt toegewezen. In 8-bits scalaire kwantisatie zijn er 2^8 of 256 mogelijke bins.

Elk onderdeel van de vector wordt toegewezen aan de dichtstbijzijnde representatieve waarde binnen deze set kwantisatieniveaus in een proces dat lijkt op het afronden van een reëel getal op het dichtstbijzijnde gehele getal. In de gekwantiseerde 8-bits vector staat het id-getal in plaats van de oorspronkelijke waarde. Na kwantisatie wordt elke vector vertegenwoordigd door een matrix met id's voor de bins waartoe de onderdelen behoren. Deze gekwantiseerde vectoren vereisen veel minder bits om op te slaan in vergelijking met de oorspronkelijke vector, waardoor de opslagvereisten en geheugenvoetafdruk worden verminderd.

Voorbeeldindex met vectorCompression, gegevenstypen en opgeslagen eigenschap

Hier volgt een samengesteld voorbeeld van een zoekindex die smalle gegevenstypen, beperkte opslag en vectorcompressie aangeeft.

  • "HotelNameVector" biedt een smal gegevenstypevoorbeeld, waarbij de oorspronkelijke Float32 waarden worden Float16gerecast naar , uitgedrukt Collection(Edm.Half) in de zoekindex.
  • "HotelNameVector" is stored ook ingesteld op false. Extra insluitingen die worden gebruikt in een queryantwoord worden niet opgeslagen. Wanneer stored onwaar is, retrievable moet dit ook onwaar zijn.
  • DescriptionVector biedt een voorbeeld van vectorcompressie. Vectorcompressie wordt gedefinieerd in de index, waarnaar wordt verwezen in een profiel en vervolgens toegewezen aan een vectorveld. DescriptionVector is stored ook ingesteld op false.
### Create a new index
POST {{baseUrl}}/indexes?api-version=2024-03-01-preview  HTTP/1.1
    Content-Type: application/json
    api-key: {{apiKey}}

{
    "name": "hotels-vector-quickstart",
    "fields": [
        {
            "name": "HotelId", 
            "type": "Edm.String",
            "searchable": false, 
            "filterable": true, 
            "retrievable": true, 
            "sortable": false, 
            "facetable": false,
            "key": true
        },
        {
            "name": "HotelName", 
            "type": "Edm.String",
            "searchable": true, 
            "filterable": false, 
            "retrievable": true, 
            "sortable": true, 
            "facetable": false
        },
        {
            "name": "HotelNameVector",
            "type": "Collection(Edm.Half)",
            "searchable": true,
            "retrievable": false,
            "dimensions": 1536,
            "stored": false,
            "vectorSearchProfile": "my-vector-profile-no-compression"
        },
        {
            "name": "Description", 
            "type": "Edm.String",
            "searchable": true, 
            "filterable": false, 
            "retrievable": false, 
            "sortable": false, 
            "facetable": false
        },
        {
            "name": "DescriptionVector",
            "type": "Collection(Edm.Single)",
            "searchable": true,
            "retrievable": false,
            "dimensions": 1536,
            "stored": false,
            "vectorSearchProfile": "my-vector-profile-with-compression"
        },
        {
            "name": "Category", 
            "type": "Edm.String",
            "searchable": true, 
            "filterable": true, 
            "retrievable": true, 
            "sortable": true, 
            "facetable": true
        },
        {
            "name": "Tags",
            "type": "Collection(Edm.String)",
            "searchable": true,
            "filterable": true,
            "retrievable": true,
            "sortable": false,
            "facetable": true
        },
        {
            "name": "Address", 
            "type": "Edm.ComplexType",
            "fields": [
                {
                    "name": "City", "type": "Edm.String",
                    "searchable": true, "filterable": true, "retrievable": true, "sortable": true, "facetable": true
                },
                {
                    "name": "StateProvince", "type": "Edm.String",
                    "searchable": true, "filterable": true, "retrievable": true, "sortable": true, "facetable": true
                }
            ]
        },
        {
            "name": "Location",
            "type": "Edm.GeographyPoint",
            "searchable": false, 
            "filterable": true, 
            "retrievable": true, 
            "sortable": true, 
            "facetable": false
        }
    ],
"vectorSearch": {
    "compressions": [
        {
            "name": "my-scalar-quantization",
            "kind": "scalarQuantization",
            "rerankWithOriginalVectors": true,
            "defaultOversampling": 10.0,
                "scalarQuantizationParameters": {
                    "quantizedDataType": "int8"
                }
        }
    ],
    "algorithms": [
        {
            "name": "my-hnsw-vector-config-1",
            "kind": "hnsw",
            "hnswParameters": 
            {
                "m": 4,
                "efConstruction": 400,
                "efSearch": 500,
                "metric": "cosine"
            }
        },
        {
            "name": "my-hnsw-vector-config-2",
            "kind": "hnsw",
            "hnswParameters": 
            {
                "m": 4,
                "metric": "euclidean"
            }
        },
        {
            "name": "my-eknn-vector-config",
            "kind": "exhaustiveKnn",
            "exhaustiveKnnParameters": 
            {
                "metric": "cosine"
            }
        }
    ],
    "profiles": [      
        {
            "name": "my-vector-profile-with-compression",
            "compression": "my-scalar-quantization",
            "algorithm": "my-hnsw-vector-config-1",
            "vectorizer": null
        },
        {
            "name": "my-vector-profile-no-compression",
            "compression": null,
            "algorithm": "my-eknn-vector-config",
            "vectorizer": null
        }
    ]
},
    "semantic": {
        "configurations": [
            {
                "name": "my-semantic-config",
                "prioritizedFields": {
                    "titleField": {
                        "fieldName": "HotelName"
                    },
                    "prioritizedContentFields": [
                        { "fieldName": "Description" }
                    ],
                    "prioritizedKeywordsFields": [
                        { "fieldName": "Tags" }
                    ]
                }
            }
        ]
    }
}

Een query uitvoeren op een gekwantiseerd vectorveld met behulp van oversampling

De querysyntaxis in dit voorbeeld is van toepassing op vectorvelden met behulp van ingebouwde scalaire kwantisatie. Vectorvelden die gebruikmaken van scalaire kwantisatie gebruiken rerankWithOriginalVectors standaard ook en defaultOversampling om de effecten van een kleinere vectorindex te beperken. Deze instellingen worden opgegeven in de zoekindex.

In de query kunt u de standaardwaarde voor oversampling overschrijven. Als dit bijvoorbeeld defaultOversampling 10.0 is, kunt u deze wijzigen in iets anders in de queryaanvraag.

U kunt de parameter oversampling instellen, zelfs als de index niet expliciet een rerankWithOriginalVectors of defaultOversampling definitie heeft. Op het moment van oversampling query's worden de indexinstellingen voor die query overschreven en wordt de query uitgevoerd met een effectieve rerankWithOriginalVectors als waar.

POST https://[service-name].search.windows.net/indexes/[index-name]/docs/search?api-version=2024-03-01-Preview   
  Content-Type: application/json   
  api-key: [admin key]   

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

Belangrijkste punten:

  • Is van toepassing op vectorvelden die vectorcompressie ondergaan, volgens de toewijzing van het vectorprofiel.

  • Overschrijft de defaultOversampling waarde of introduceert oversampling tijdens query's, zelfs als de compressieconfiguratie van de index geen opties voor oversampling of herrankering heeft opgegeven.

Zie ook