Konfigurera kvantisering av vektorer och minskad lagring för mindre vektorer i Azure AI Search

Viktigt!

Dessa funktioner är i offentlig förhandsversion under kompletterande användningsvillkor. REST-API:et 2024-03-01-Preview innehåller de nya datatyperna, vektorkomprimeringsegenskaperna stored och egenskapen.

Den här artikeln beskriver kvantisering av vektorer och andra tekniker för att komprimera vektorindex i Azure AI Search.

Utvärdera alternativen

Som ett första steg granskar du de tre alternativen för att minska mängden lagringsutrymme som används av vektorfält. De här alternativen utesluter inte varandra.

Vi rekommenderar skalbar kvantisering eftersom den komprimerar vektorstorleken i minnet och på disken med minimal ansträngning och som tenderar att ge mest nytta i de flesta scenarier. Däremot kräver smala typer (förutom ) en särskild ansträngning för Float16att göra dem och stored sparar på disklagring, vilket inte är lika dyrt som minne.

Metod Varför använda detta alternativ?
Tilldela mindre primitiva datatyper till vektorfält Smala datatyper, till exempel Float16, Int16och Int8, förbrukar mindre utrymme i minnet och på disken, men du måste ha en inbäddningsmodell som matar ut vektorer i ett smalt dataformat. Eller så måste du ha anpassad kvantiseringslogik som matar ut små data. Ett tredje användningsfall som kräver mindre arbete är att omarbeta inbyggda Float32 inbäddningar som produceras av de flesta modeller till Float16.
Eliminera valfri lagring av hämtningsbara vektorer Vektorer som returneras i ett frågesvar lagras separat från vektorer som används vid frågekörning. Om du inte behöver returnera vektorer kan du inaktivera hämtningsbar lagring, vilket minskar den totala disklagringen per fält med upp till 50 procent.
Lägga till skalära kvantiseringar Använd inbyggd scalar-kvantisering för att komprimera inbyggda Float32 inbäddningar till Int8. Det här alternativet minskar lagringen i minnet och på disken utan försämrad frågeprestanda. Mindre datatyper som Int8 producerar vektorindex som är mindre innehållsrika än de med Float32 inbäddningar. För att kompensera för informationsförlust innehåller inbyggd komprimering alternativ för bearbetning efter fråga med okomprimerade inbäddningar och översampling för att returnera mer relevanta resultat. Omrankning och översampling är specifika funktioner i den inbyggda skalära kvantiseringen av Float32 eller Float16 fälten och kan inte användas för inbäddningar som genomgår anpassad kvantisering.

Alla dessa alternativ definieras för ett tomt index. Om du vill implementera någon av dem använder du REST-API:er för Förhandsversion av Azure Portal 2024-03-01 eller ett Beta Azure SDK-paket.

När indexet har definierats kan du läsa in och indexeras som ett separat steg.

Alternativ 1: Tilldela smala datatyper till vektorfält

Vektorfält lagrar vektorbäddningar, som representeras som en matris med tal. När du anger en fälttyp anger du den underliggande primitiva datatypen som används för att lagra varje tal i dessa matriser. Datatypen påverkar hur mycket utrymme varje tal tar upp.

Med hjälp av förhandsversions-API:er kan du tilldela smala primitiva datatyper för att minska lagringskraven för vektorfält.

  1. Granska datatyperna för vektorfält:

    • Collection(Edm.Single) 32-bitars flyttals (standard)
    • Collection(Edm.Half) 16-bitars flyttals
    • Collection(Edm.Int16) 16-bitars signerat heltal
    • Collection(Edm.SByte) 8-bitars signerat heltal

    Kommentar

    Binära datatyper stöds inte för närvarande.

  2. Välj en datatyp som är giltig för inbäddningsmodellens utdata eller för vektorer som genomgår anpassad kvantisering.

    De flesta inbäddningsmodeller matar ut 32-bitars flyttalsnummer, men om du tillämpar anpassad kvantisering kan dina utdata vara Int16 eller Int8. Nu kan du definiera vektorfält som accepterar det mindre formatet.

    Inbäddningsmodeller för text har ett inbyggt utdataformat som Float32mappar till Collection(Edm.Single) i Azure AI Search. Du kan inte mappa utdata till Int8 eftersom gjutning från float till int är förbjuden. Du kan dock casta från Float32 till Float16 (eller Collection(Edm.Half)), och det här är ett enkelt sätt att använda smala datatyper utan extra arbete.

    Följande tabell innehåller länkar till flera inbäddningsmodeller som använder de smala datatyperna.

    Inbäddningsmodell Interna utdata Giltiga typer i Azure AI Search
    text-embedding-ada-002 Float32 Collection(Edm.Single) eller Collection(Edm.Half)
    text-embedding-3-small Float32 Collection(Edm.Single) eller Collection(Edm.Half)
    text-embedding-3-large Float32 Collection(Edm.Single) eller Collection(Edm.Half)
    Cohere V3-inbäddningsmodeller med int8 embedding_type Int8 Collection(Edm.SByte)
  3. Se till att du förstår kompromisserna för en smal datatyp. Collection(Edm.Half) har mindre information, vilket resulterar i lägre upplösning. Om dina data är homogena eller kompakta kan det leda till oacceptabla resultat vid frågetillfället om du förlorar extra detaljer eller nyanser eftersom det finns mindre information som kan användas för att skilja mellan närliggande vektorer.

  4. Definiera och skapa indexet. Du kan använda Azure Portal, 2024-03-01-preview eller ett Beta Azure SDK-paket för det här steget.

  5. Kontrollera resultatet. Förutsatt att vektorfältet är markerat som hämtningsbart använder du Sökutforskaren eller REST API för att verifiera att fältinnehållet matchar datatypen. Se till att använda rätt 2024-03-01-preview API-version för frågan, annars visas inte de nya egenskaperna.

Om du vill kontrollera storleken på vektorindexet använder du Azure-portalen eller förhandsversionen 2024-03-01.

Kommentar

Fältets datatyp används för att skapa den fysiska datastrukturen. Om du vill ändra en datatyp senare kan du antingen släppa och återskapa indexet eller skapa ett andra fält med den nya definitionen.

Alternativ 2: Ställ in egenskapen stored för att ta bort hämtningsbar lagring

Egenskapen stored är ett nytt booleskt värde i en vektorfältdefinition som avgör om lagringen allokeras för innehåll i hämtningsbara vektorfält. Om du inte behöver vektorinnehåll i ett frågesvar kan du spara upp till 50 procent lagringsutrymme per fält genom att ange stored falskt.

Eftersom vektorer inte är läsbara för människor utelämnas de vanligtvis i ett frågesvar som återges på en söksida. Men om du använder vektorer i nedströmsbearbetning, som att skicka frågeresultat till en modell eller process som använder vektorinnehåll, bör du behålla stored värdet true och välja en annan teknik för att minimera vektorstorleken.

I följande exempel visas fältsamlingen för ett sökindex. Ställ in stored på false för att permanent ta bort hämtningsbar lagring för vektorfältet.

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" 
         } 
       ] 
     } 

Viktiga punkter:

  • Gäller endast för vektorfält .

  • Påverkar lagring på disk, inte minne, och det har ingen effekt på frågor. Frågekörningen använder ett separat vektorindex som inte påverkas av stored egenskapen.

  • Egenskapen stored anges när index skapas på vektorfält och kan inte ångras. Om du vill hämta innehåll senare måste du släppa och återskapa indexet eller skapa och läsa in ett nytt fält som har den nya attributionen.

  • Standardvärden är stored inställda på true och retrievable inställda på false. I en standardkonfiguration lagras en hämtningsbar kopia, men den returneras inte automatiskt i resultat. När stored är sant kan du växla retrievable mellan sant och falskt när som helst utan att behöva återskapa ett index. När stored är falskt, retrievable måste vara falskt och kan inte ändras.

Alternativ 3: Konfigurera skalära kvantiseringar

Inbyggd skalbar kvantisering rekommenderas eftersom den minskar kraven på minne och disklagring, och lägger till reranking och översampling för att kompensera effekterna av ett mindre index. Inbyggda skalära kvantiseringar kan tillämpas på vektorfält som innehåller Float32 eller Float16 data.

Så här använder du inbyggd vektorkomprimering:

  • Lägg till vectorSearch.compressions i ett sökindex. Komprimeringsalgoritmen som stöds i den här förhandsversionen är skalbar kvantisering.
  • Ange valfria egenskaper för att minimera effekterna av förlust av indexering. Både rerankWithOriginalVectors och defaultOversampling ger optimeringar under frågekörningen.
  • Lägg till vectorSearch.profiles.compression i en ny vektorprofil.
  • Tilldela den nya vektorprofilen till ett nytt vektorfält.

Lägg till komprimeringsinställningar och ange valfria egenskaper

Lägg till ett compressions avsnitt i en indexdefinition som skapats med rest-API:et 2024-03-01-preview. Använd följande JSON som mall.

"compressions": [

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

Viktiga punkter:

  • kind måste anges till scalarQuantization. Det här är den enda kvantiseringsmetod som stöds just nu.

  • rerankWithOriginalVectors använder de ursprungliga, okomprimerade vektorerna för att beräkna om likheten och beräkna om de översta resultaten som returneras av den första sökfrågan. De okomprimerade vektorerna finns i sökindexet även om stored det är falskt. Den här egenskapen är valfri. Standard är sant.

  • defaultOversampling Parlamentet anser att det finns en bredare uppsättning potentiella resultat för att kompensera för minskningen av informationen från kvantiseringen. Formeln för potentiella resultat består av k i frågan, med en översamplingsmultiplikator. Om frågan till exempel anger en k av 5 och översampling är 20, begär frågan effektivt 100 dokument för användning vid omrankning, med den ursprungliga okomprimerade vektorn för det ändamålet. Endast de högst k rankade resultaten returneras. Den här egenskapen är valfri. Standardvärdet är 4.

  • quantizedDataType måste anges till int8. Det här är den enda primitiva datatypen som stöds just nu. Den här egenskapen är valfri. Standard är int8.

Lägga till en komprimeringsinställning i en vektorprofil

Scalar-kvantisering anges som en egenskap i en ny vektorprofil. Det är nödvändigt att skapa en ny vektorprofil för att skapa komprimerade index i minnet.

I profilen måste du använda HNSW-algoritmen (Hierarchical Navigable Small Worlds). Inbyggd kvantisering stöds inte med fullständig KNN.

  1. Skapa en ny vektorprofil och lägg till en komprimeringsegenskap.

    "profiles": [
       {
          "name": "my-vector-profile",
          "compression": "my-scalar-quantization", 
          "algorithm": "my-hnsw-vector-config-1",
          "vectorizer": null
       }
     ]
    
  2. Tilldela en vektorprofil till ett nytt vektorfält. Scalar-kvantisering minskar innehållet till , så se till Int8att innehållet är antingen Float32 eller Float16.

    I Azure AI Search är motsvarigheterna till entitetsdatamodellen (EDM) och Float16 typerna Float32 respektive och Collection(Edm.Half).Collection(Edm.Single)

    {
       "name": "DescriptionVector",
       "type": "Collection(Edm.Single)",
       "searchable": true,
       "retrievable": true,
       "dimensions": 1536,
       "vectorSearchProfile": "my-vector-profile"
    }
    
  3. Läs in indexet med indexerare för pull-modellindexering eller API:er för push-modellindexering.

Scalar-kvantisering minskar upplösningen för varje tal inom varje vektorbäddning. I stället för att beskriva varje tal som ett 32-bitars flyttalnummer använder det ett 8-bitars heltal. Den identifierar ett intervall med tal (vanligtvis 99:e percentilens lägsta och högsta) och delar upp dem i ett begränsat antal nivåer eller lagerplatser och tilldelar varje lagerplats en identifierare. I 8-bitars scalar-kvantisering finns det 2^8 eller 256 möjliga intervall.

Varje komponent i vektorn mappas till närmaste representativa värde inom den här uppsättningen kvantiseringsnivåer i en process som liknar avrundning av ett verkligt tal till närmaste heltal. I den kvantiserade 8-bitarsvektorn står identifierarnumret i stället för det ursprungliga värdet. Efter kvantiseringen representeras varje vektor av en matris med identifierare för de lagerplatser som dess komponenter tillhör. Dessa kvantiserade vektorer kräver mycket färre bitar att lagra jämfört med den ursprungliga vektorn, vilket minskar lagringskraven och minnesfotavtrycket.

Exempelindex med vectorCompression, datatyper och lagrad egenskap

Här är ett sammansatt exempel på ett sökindex som anger smala datatyper, minskad lagring och vektorkomprimering.

  • "HotelNameVector" innehåller ett exempel på en smal datatyp som omarbetar de ursprungliga Float32 värdena till Float16, uttryckt som Collection(Edm.Half) i sökindexet.
  • "HotelNameVector" har stored också värdet false. Extra inbäddningar som används i ett frågesvar lagras inte. När stored är falskt retrievable måste också vara falskt.
  • "DescriptionVector" är ett exempel på vektorkomprimering. Vektorkomprimering definieras i indexet, refereras i en profil och tilldelas sedan till ett vektorfält. "DescriptionVector" har stored också angetts till 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" }
                    ]
                }
            }
        ]
    }
}

Fråga ett kvantiserat vektorfält med hjälp av översampling

Frågesyntaxen i det här exemplet gäller för vektorfält med inbyggd skalär kvantisering. Som standard använder rerankWithOriginalVectors även vektorfält som använder skalbar kvantisering och defaultOversampling för att minimera effekterna av ett mindre vektorindex. Dessa inställningar anges i sökindexet.

På frågan kan du åsidosätta standardvärdet för översampling. Om defaultOversampling det till exempel är 10.0 kan du ändra det till något annat i frågebegäran.

Du kan ange översamplingsparametern även om indexet inte uttryckligen har en rerankWithOriginalVectors definition eller defaultOversampling definition. Om du oversampling anger vid frågetillfället åsidosätter indexinställningarna för den frågan och kör frågan med en effektiv rerankWithOriginalVectors som true.

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   
            }
      ]    
    }

Viktiga punkter:

  • Gäller för vektorfält som genomgår vektorkomprimering per tilldelning av vektorprofil.

  • Åsidosätter defaultOversampling värdet eller introducerar översampling vid frågetillfället, även om indexets komprimeringskonfiguration inte angav alternativ för översampling eller omrankning.

Se även