Konfigurieren der Vektorquantisierung und reduzierter Speicher für kleinere Vektoren in Azure KI Search

Wichtig

Dieses Feature befindet sich in der öffentlichen Vorschau unter Zusätzliche Nutzungsbedingungen. Die REST-API 2024-03-01-Preview stellt die neuen Datentypen, Vektorkomprimierungseigenschaften und die stored Eigenschaft bereit.

In diesem Artikel werden die Vektorquantisierung und andere Techniken zum Komprimieren von Vektorindizes in Azure KI Search beschrieben.

Auswerten der Optionen

Überprüfen Sie im ersten Schritt Ihre Optionen, um die Menge des von Vektorfeldern verwendeten Speichers zu verringern. Diese Optionen schließen sich nicht gegenseitig aus, sodass Sie mehrere Optionen zusammen verwenden können.

Wir empfehlen skalare Quantisierung, da sie für die meisten Szenarien die effektivste Option ist. Schmale Typen (mit Ausnahme Float16von ) erfordern einen speziellen Aufwand, um sie zu machen, und stored speichert Speicher, was nicht so teuer wie Arbeitsspeicher ist.

Vorgehensweise Warum sollten Sie diese Option verwenden?
Zuweisen kleinerer primitiver Datentypen zu Vektorfeldern Schmale Datentypen, z. B. Float16, Int16und Int8 verbrauchen weniger Speicherplatz im Arbeitsspeicher und auf dem Datenträger. Diese Option ist praktikabel, wenn ihr Einbettungsmodell Vektoren in einem schmalen Datenformat ausgibt. Oder wenn Sie über eine benutzerdefinierte Quantisierungslogik verfügen, die kleine Daten ausgibt. Ein häufigerer Anwendungsfall ist die Neufassung der systemeigenen Float32 Einbettungen, die von den meisten Modellen Float16erzeugt werden.
Entfernen optionaler Speicher von abrufbaren Vektoren In einer Abfrageantwort zurückgegebene Vektoren werden getrennt von Vektoren gespeichert, die während der Abfrageausführung verwendet werden. Wenn Sie keine Vektoren zurückgeben müssen, können Sie den abrufbaren Speicher deaktivieren, wodurch der gesamte Speicher pro Feld um bis zu 50 Prozent reduziert wird.
Hinzufügen einer skalaren Quantisierung Verwenden Sie die integrierte skalare Quantisierung, um systemeigene Float32 Einbettungen zu komprimieren. Int8 Mit dieser Option wird der Speicher im Arbeitsspeicher und auf dem Datenträger reduziert, ohne dass die Abfrageleistung beeinträchtigt wird. Kleinere Datentypen wie Int8 z. B. erzeugen Vektorindizes, die weniger inhaltsreich sind als solche mit Float32 Einbettungen. Um den Informationsverlust zu verrechnen, enthält die integrierte Komprimierung Optionen für die Nachabfrageverarbeitung mit nicht komprimierten Einbettungen und Oversampling, um relevantere Ergebnisse zurückzugeben. Reranking und Oversampling sind spezifische Features der integrierten skalaren Quantisierung oder Float16 Felder Float32 und können nicht für Einbettungen verwendet werden, die einer benutzerdefinierten Quantisierung unterzogen werden.

Alle diese Optionen werden für einen leeren Index definiert. Verwenden Sie zum Implementieren eines dieser APIs das Azure-Portal, 2024-03-01-Preview-REST-APIsoder ein Beta-Azure SDK-Paket.

Nachdem der Index definiert wurde, können Sie Dokumente als separaten Schritt laden und indiziert werden.

Option 1: Zuweisen schmaler Datentypen zu Vektorfeldern

Vektorfelder speichern Vektoreinbettungen, die als Array von Zahlen dargestellt werden. Wenn Sie einen Feldtyp angeben, geben Sie den zugrunde liegenden primitiven Datentyp an, der verwendet wird, um jede Zahl in diesen Arrays zu enthalten. Der Datentyp wirkt sich darauf aus, wie viel Speicherplatz jede Zahl beansprucht.

Mithilfe von Vorschau-APIs können Sie schmale primitive Datentypen zuweisen, um die Speicheranforderungen von Vektorfeldern zu verringern.

  1. Überprüfen Sie die Datentypen für Vektorfelder:

    • Collection(Edm.Single) 32-Bit-Gleitkomma (Standard)
    • Collection(Edm.Half) 16-Bit-Gleitkommazahl
    • Collection(Edm.Int16) 16-Bit-Ganzzahl mit Vorzeichen
    • Collection(Edm.SByte) 8-Bit-Ganzzahl mit Vorzeichen

    Hinweis

    Binäre Datentypen werden derzeit nicht unterstützt.

  2. Wählen Sie einen Datentyp aus, der für die Ausgabe des Einbettungsmodells oder für Vektoren gültig ist, die einer benutzerdefinierten Quantisierung unterzogen werden.

    Die meisten Einbettungsmodelle geben 32-Bit-Gleitkommazahlen aus, aber wenn Sie eine benutzerdefinierte Quantisierung anwenden, kann Int16 die Ausgabe oder Int8. Sie können jetzt Vektorfelder definieren, die das kleinere Format akzeptieren.

    Texteinbettungsmodelle weisen ein systemeigenes Ausgabeformat Float32auf, das in Azure KI Search zugeordnet ist Collection(Edm.Single). Sie können diese Ausgabe Int8 nicht zuordnen, da das Umwandeln von float zu int " verboten" ist. Sie können jedoch von Float32 ( Float16 oder Collection(Edm.Half)) umwandeln, und dies ist eine einfache Möglichkeit, schmale Datentypen ohne zusätzliche Arbeit zu verwenden.

    Die folgende Tabelle enthält Links zu mehreren Einbettungsmodellen, die die schmalen Datentypen verwenden.

    Einbettungsmodell Native Ausgabe Gültige Typen in Azure KI Search
    text-embedding-ada-002 Float32 Collection(Edm.Single) oder Collection(Edm.Half)
    text-embedding-3-small Float32 Collection(Edm.Single) oder Collection(Edm.Half)
    text-embedding-3-large Float32 Collection(Edm.Single) oder Collection(Edm.Half)
    Cohere V3 Einbettungsmodell mit int8 Einbettungstyp Int8 Collection(Edm.SByte)
  3. Stellen Sie sicher, dass Sie die Kompromisse eines schmalen Datentyps verstehen. Collection(Edm.Half) hat weniger Informationen, was zu einer niedrigeren Auflösung führt. Wenn Ihre Daten homogen oder dicht sind, kann der Verlust zusätzlicher Details oder Nuancen zu inakzeptablen Ergebnissen zur Abfragezeit führen, da es weniger Details gibt, die verwendet werden können, um nahe gelegene Vektoren voneinander zu unterscheiden.

  4. Definieren und erstellen Sie den Index. Sie können das Azure-Portal, 2024-03-01-Previewoder ein Beta-Azure SDK-Paket für diesen Schritt verwenden.

  5. Prüfen Sie die Ergebnisse. Wenn das Vektorfeld als abrufbar gekennzeichnet ist, verwenden Sie den Such-Explorer oder die REST-API, um zu überprüfen, ob der Feldinhalt dem Datentyp entspricht. Achten Sie darauf, die richtige 2024-03-01-preview API-Version für die Abfrage zu verwenden, andernfalls werden die neuen Eigenschaften nicht angezeigt.

Verwenden Sie zum Überprüfen der Vektorindexgröße das Azure-Portal oder die Vorschau 2024-03-01.

Hinweis

Der Datentyp des Felds wird verwendet, um die physische Datenstruktur zu erstellen. Wenn Sie später einen Datentyp ändern möchten, legen Sie den Index ab, und erstellen Sie ein zweites Feld mit der neuen Definition.

Option 2: Festlegen der stored Eigenschaft zum Entfernen des abrufbaren Speichers

Die stored Eigenschaft ist ein neuer boolescher Wert für eine Vektorfelddefinition, der bestimmt, ob Speicher für abrufbare Vektorfeldinhalte zugewiesen wird. Wenn Sie Vektorinhalte in einer Abfrageantwort nicht benötigen, können Sie bis zu 50 Prozent Speicherplatz pro Feld sparen, indem Sie auf "false" festlegen stored.

Da Vektoren nicht lesbar sind, werden sie in der Regel in einer Abfrageantwort weggelassen, die auf einer Suchseite gerendert wird. Wenn Sie jedoch Vektoren in der nachgelagerten Verarbeitung verwenden, z. B. das Übergeben von Abfrageergebnissen an ein Modell oder einen Prozess, der Vektorinhalte nutzt, sollten Sie auf "true" festgelegt bleiben stored und eine andere Technik zum Minimieren der Vektorgröße auswählen.

Das folgende Beispiel zeigt die Fields-Auflistung eines Suchindexes. Legen Sie stored diesen Wert auf "false" fest, um den abrufbaren Speicher für das Vektorfeld dauerhaft zu entfernen.

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

Die wichtigsten Punkte:

  • Gilt nur für Vektorfelder.

  • Wirkt sich auf den Speicher auf dem Datenträger, nicht auf den Arbeitsspeicher aus, und hat keine Auswirkungen auf Abfragen. Die Abfrageausführung verwendet einen separaten Vektorindex, der von der stored Eigenschaft nicht betroffen ist.

  • Die stored Eigenschaft wird während der Indexerstellung für Vektorfelder festgelegt und ist unumkehrbar. Wenn Sie später abrufbare Inhalte abrufen möchten, müssen Sie den Index ablegen und neu erstellen oder ein neues Feld erstellen und laden, das über die neue Zuordnung verfügt.

  • Standardwerte sind stored auf "true" festgelegt und retrievable auf "false" festgelegt. In einer Standardkonfiguration wird eine abrufbare Kopie gespeichert, aber sie wird nicht automatisch in Ergebnissen zurückgegeben. Wenn stored dies der Fall ist, können Sie jederzeit zwischen "true" und "false" umschalten retrievable, ohne einen Index neu erstellen zu müssen. Ist stored "false", retrievable muss "false" sein und kann nicht geändert werden.

Option 3: Konfigurieren der skalaren Quantisierung

Die integrierte skalare Quantisierung wird empfohlen, da die Speicher- und Datenträgerspeicheranforderungen reduziert werden, und sie fügt eine Neurankung und Oversampling hinzu, um die Auswirkungen eines kleineren Indexes zu verlagern. Integrierte skalare Quantisierung kann auf Vektorfelder angewendet werden, die Float32 oder Float16 Daten enthalten.

So verwenden Sie die integrierte Vektorkomprimierung:

  • Zu einem Suchindex hinzufügen vectorSearch.compressions. Der in dieser Vorschau unterstützte Komprimierungsalgorithmus ist eine skalare Quantisierung.
  • Legen Sie optionale Eigenschaften fest, um die Auswirkungen der Verlustindizierung zu verringern. Sowohl rerankWithOriginalVectors als auch defaultOversampling bieten Optimierungen während der Abfrageausführung.
  • Zu einem neuen Vektorprofil hinzufügen vectorSearch.profiles.compression.
  • Weisen Sie das neue Vektorprofil einem neuen Vektorfeld zu.

Hinzufügen von Komprimierungseinstellungen und Festlegen optionaler Eigenschaften

Fügen Sie in einer Indexdefinition, die mit der REST-API2024-03-01-preview erstellt wurde, einen compressions Abschnitt hinzu. Verwenden Sie den folgenden JSON-Code als Vorlage.

"compressions": [

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

Die wichtigsten Punkte:

  • kind muss auf scalarQuantization festgelegt werden. Dies ist die einzige Quantisierungsmethode, die derzeit unterstützt wird.

  • rerankWithOriginalVectors verwendet die ursprünglichen, nicht komprimierten Vektoren, um Die Ähnlichkeit neu zu berechnen und die top-Ergebnisse zu reranken, die von der ursprünglichen Suchabfrage zurückgegeben werden. Die nicht komprimierten Vektoren sind im Suchindex vorhanden, auch wenn stored "false" ist. Diese Eigenschaft ist optional. Der Standardwert ist korrekt.

  • defaultOversampling betrachtet eine breitere Reihe potenzieller Ergebnisse, um die Verringerung der Informationen aus der Quantisierung zu verrechnen. Die Formel für potenzielle Ergebnisse besteht aus der k Abfrage mit einem Oversampling-Multiplikator. Wenn die Abfrage beispielsweise einen k Wert von 5 angibt und die Oversampling 20 ist, fordert die Abfrage effektiv 100 Dokumente für die Verwendung in Reranking an, wobei der ursprüngliche nicht komprimierte Vektor zu diesem Zweck verwendet wird. Es werden nur die top rerangierten k Ergebnisse zurückgegeben. Diese Eigenschaft ist optional. Der Standardwert ist 4.

  • quantizedDataType muss auf int8 festgelegt werden. Dies ist der einzige Grundtyp, der derzeit unterstützt wird. Diese Eigenschaft ist optional. Der Standardwert ist int8.

Hinzufügen einer Komprimierungseinstellung zu einem Vektorprofil

Skalare Quantisierung wird als Eigenschaft in einem neuen Vektorprofil angegeben. Die Erstellung eines neuen Vektorprofils ist erforderlich, um komprimierte Indizes im Arbeitsspeicher zu erstellen.

Innerhalb des Profils müssen Sie den Hierarchischen Navigable Small Worlds (HNSW)-Algorithmus verwenden. Integrierte Quantisierung wird nicht mit erschöpfenden KNN unterstützt.

  1. Erstellen Sie ein neues Vektorprofil, und fügen Sie eine Komprimierungseigenschaft hinzu.

    "profiles": [
       {
          "name": "my-vector-profile",
          "compression": "my-scalar-quantization", 
          "algorithm": "my-hnsw-vector-config-1",
          "vectorizer": null
       }
     ]
    
  2. Weisen Sie einem neuenVektorfeld ein Vektorprofil zu. Die skalare Quantisierung reduziert den Inhalt auf Int8. Stellen Sie daher sicher, dass Ihre Inhalte entweder Float32 oder Float16.

    In Azure KI Search sind die Entitätsdatenmodell-Entsprechungen (Entity Data Model, EDM) der Typen Float32 und Float16 die Typen Collection(Edm.Single) bzw. Collection(Edm.Half).

    {
       "name": "DescriptionVector",
       "type": "Collection(Edm.Single)",
       "searchable": true,
       "retrievable": true,
       "dimensions": 1536,
       "vectorSearchProfile": "my-vector-profile"
    }
    
  3. Laden Sie den Index mithilfe von Indexern für die Pullmodellindizierung oder APIs für die Pushmodellindizierung.

Die skalare Quantisierung reduziert die Auflösung jeder Zahl innerhalb der Vektoreinbettung. Anstatt jede Zahl als 32-Bit-Gleitkommazahl zu beschreiben, wird eine 8-Bit-Ganzzahl verwendet. Er identifiziert einen Zahlenbereich (in der Regel 99. Quantil Minimum und Maximum) und dividiert sie in eine begrenzte Anzahl von Ebenen oder Bins, wobei jedem Bin ein Bezeichner zugewiesen wird. In der 8-Bit-Skalar-Quantisierung gibt es 2^8 oder 256 mögliche Bins.

Jede Komponente des Vektors wird dem nächstgelegenen repräsentativen Wert innerhalb dieses Satzes von Quantisierungsebenen in einem Prozess zugeordnet, der einer reellen Zahl auf die nächste ganze Zahl entspricht. Im quantisierten 8-Bit-Vektor steht die Bezeichnernummer anstelle des ursprünglichen Werts. Nach der Quantisierung wird jeder Vektor durch ein Array von Bezeichnern für die Bins dargestellt, zu denen seine Komponenten gehören. Diese quantisierten Vektoren erfordern im Vergleich zum ursprünglichen Vektor viel weniger Bits zu speichern, wodurch die Speicheranforderungen und der Speicherbedarf reduziert werden.

Beispielindex mit vectorCompression, Datentypen und gespeicherten Eigenschaften

Hier ist ein JSON-Beispiel für einen Suchindex, der für Float32 Feld, einen Float16 Datentyp für das zweite Vektorfeld und eine stored Eigenschaft auf "false" festgelegt vectorCompression ist. Dies ist eine Kombination aus den Vektorkomprimierungs- und Speicherfeatures in dieser Vorschau.

### 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,
            "stored": false,
        },
        {
            "name": "DescriptionVector",
            "type": "Collection(Edm.Single)",
            "searchable": true,
            "retrievable": true,
            "dimensions": 1536,
            "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" }
                    ]
                }
            }
        ]
    }
}

Abfragen eines quantisierten Vektorfelds mithilfe von Oversampling

Die Abfragesyntax in diesem Beispiel gilt für Vektorfelder mit integrierter skalarer Quantisierung. Standardmäßig verwenden Vektorfelder, die skalare Quantisierung verwenden rerankWithOriginalVectors und defaultOversampling verringern die Auswirkungen eines kleineren Vektorindexes. Diese Einstellungen werden im Suchindex angegeben.

In der Abfrage können Sie den Standardwert für die Oversampling außer Kraft setzen. Wenn defaultOversampling z. B. 10,0 ist, können Sie ihn in eine andere Abfrageanforderung ändern.

Sie können den Oversampling-Parameter auch dann festlegen, wenn der Index nicht explizit über eine rerankWithOriginalVectors Oder defaultOversampling Definition verfügt. Wenn Sie oversampling zur Abfragezeit angeben, werden die Indexeinstellungen für diese Abfrage außer Kraft gesetzt und die Abfrage mit einem effektiven rerankWithOriginalVectors Wert als "true" ausgeführt.

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

Die wichtigsten Punkte:

  • Gilt für Vektorfelder, die sich einer Vektorkomprimierung pro Vektorprofilzuweisung unterziehen.

  • Überschreibt den defaultOversampling Wert oder führt die Oversampling zur Abfragezeit ein, auch wenn die Komprimierungskonfiguration des Indexes keine Oversampling- oder Reranking-Optionen angegeben hat.

Weitere Informationen