Compresser des vecteurs à l’aide de la quantification scalaire ou binaire
La recherche Azure AI prend en charge la quantification scalaire et binaire pour réduire la taille des vecteurs dans un index de recherche. Nous recommandons la quantification pour réduire la taille de vecteurs, car elle diminue la consommation de mémoire et de disque pour les incorporations float16 et float32. Pour compenser les effets de la compression avec perte, vous pouvez ajouter un suréchantillonnage et un rescoring sur les vecteurs non compressés.
Pour utiliser la quantification intégrée, suivez ces étapes :
- Commencer par des champs vectoriels et une
vectorSearch
configuration à un index - Ajouter
vectorSearch.compressions
- Ajouter une configuration
scalarQuantization
oubinaryQuantization
et lui donner un nom - Définir des propriétés facultatives pour atténuer les effets de l’indexation avec perte
- Créer un profil vectoriel qui utilise la configuration nommée
- Créer un profil vectoriel ayant le nouveau profil vectoriel
- Charger l’index avec des données float32 ou float16 quantifiées pendant l’indexation par la configuration définie
- Vous pouvez également interroger des données quantifiées en utilisant le paramètre de suréchantillonnage si vous voulez remplacer la valeur par défaut
Prérequis
- Champs vectoriels dans un index de recherche avec une
vectorSearch
configuration, à l’aide des algorithmes HNSW (Hierarchical Navigable Small Worlds) ou des algorithmes de plus proche voisin K (eKNN) complets et d’un nouveau profil vectoriel.
Techniques de quantification prises en charge
La quantification s’applique aux champs vectoriels recevant des vecteurs de type float. Dans les exemples de cet article, le type de données du champ est Collection(Edm.Single)
pour les incorporations float32 entrantes, mais float16 est également pris en charge. Quand les vecteurs sont reçus sur un champ ayant la compression configurée, le moteur effectue automatiquement une quantification pour réduire l’empreinte mémoire des données vectorielles dans la mémoire et sur le disque.
Deux types de quantification sont pris en charge :
La quantification scalaire compresse les valeurs flottantes en types de données plus étroits. Recherche Azure AI prend actuellement en charge int8, qui est 8 bits, ce qui réduit la taille d’index vectoriel par quatre.
La quantification binaire convertit des floats en bits binaires qui prennent jusqu’à 1 bit. Ce qui se traduit par une taille d’index vectoriel réduite jusqu’à 28 fois.
Ajouter « compressions » à un index de recherche
L’exemple suivant montre une définition d’index partiel avec une collection de champs qui inclut un champ vectoriel et une section vectorSearch.compressions
.
Elles comprennent scalarQuantization
ou binaryQuantization
. Vous pouvez spécifier autant de configurations de compression que nécessaire, puis attribuez celles souhaitées au profil vectoriel.
La syntaxe pour vectorSearch.Compressions
varie entre les API REST stables et en préversion, avec la préversion ajoutant de nouvelles options pour l’optimisation du stockage, ainsi que les modifications apportées à la syntaxe existante. La rétrocompatibilité est préservée par les mappings internes de l'API, mais vous devez adopter la nouvelle syntaxe dans le code qui cible la version 2024-11-01-preview et les versions ultérieures.
Utilisez l'API REST Créer un index ou Créer ou mettre à jour un index pour configurer les paramètres de compression.
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
}
]
}
}
Points essentiels :
kind
doit être défini surscalarQuantization
oubinaryQuantization
.rerankWithOriginalVectors
utilise les vecteurs originaux non compressés pour recalculer la similarité et reclasser les meilleurs résultats renvoyés par la requête de recherche initiale. Les vecteurs non compressés existent dans l'index de recherche même sistored
sont faux. Cette propriété est facultative. La valeur par défaut est true.defaultOversampling
considère un ensemble plus large de résultats potentiels pour compenser la réduction des informations résultant de la quantification. La formule des résultats potentiels consiste en lek
dans la requête, avec un multiplicateur de suréchantillonnage. Par exemple, si la requête spécifie unk
de 5 et que le suréchantillonnage est de 20, alors la requête demande effectivement 100 documents à utiliser dans le reclassement, en utilisant le vecteur non compressé d'origine à cette fin. Seuls les résultatsk
les mieux classés sont renvoyés. Cette propriété est facultative. La valeur par défaut est 4.quantizedDataType
est facultatif et s’applique à la quantification scalaire uniquement. Si vous l’ajoutez, il doit être défini surint8
. Il s’agit du seul type de données primitif pris en charge pour la quantification scalaire à l’heure actuelle. La valeur par défaut estint8
.
Ajouter l’algorithme de recherche vectorielle
Vous pouvez utiliser l’algorithme HNSW ou un KNN exhaustif dans l’API REST 2024-11-01-preview. Pour la version stable, utilisez uniquement HNSW.
"vectorSearch": {
"profiles": [ ],
"algorithms": [
{
"name": "use-hnsw",
"kind": "hnsw",
"hnswParameters": {
"m": 4,
"efConstruction": 400,
"efSearch": 500,
"metric": "cosine"
}
}
],
"compressions": [ <see previous section>]
}
Créer et attribuer un profil vectoriel
Pour utiliser une nouvelle configuration de quantification, vous devez créer un profil vectoriel. La création d'un nouveau profil vectoriel est nécessaire pour créer des index compressés en mémoire. Votre nouveau profil utilise HNSW.
Dans la même définition d’index, créez un profil vectoriel et ajoutez une propriété de compression et un algorithme. Voici deux profils, un pour chaque approche de quantification.
"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> ] }
Attribuez un profil vectoriel à un nouveau champ vectoriel. Le type de données du champ est soit float32 ou soit float16.
Dans Recherche Azure AI, les équivalents EDM (Entity Data Model) des types float32 et float16 sont
Collection(Edm.Single)
etCollection(Edm.Half)
, respectivement.{ "name": "vectorContent", "type": "Collection(Edm.Single)", "searchable": true, "retrievable": true, "dimensions": 1536, "vectorSearchProfile": "vector-profile-hnsw-scalar", }
Chargez l'index à l'aide d'indexeurs pour l'indexation du modèle pull ou d'API pour l'indexation du modèle push.
Fonctionnement de la quantification scalaire dans Azure AI Search
La quantification scalaire réduit la résolution de chaque nombre dans chaque intégration vectorielle. Au lieu de décrire chaque nombre comme un nombre à virgule flottante de 16 bits ou 32 bits, il utilise un entier de 8 bits. Il identifie une plage de nombres (généralement le minimum et le maximum du 99e percentile) et les divise en un nombre fini de niveaux ou de catégories, en attribuant à chaque catégorie un identifiant. Dans la quantification scalaire 8 bits, il existe 2 ^ 8, soit 256, bacs possibles.
Chaque composante du vecteur est mappée à la valeur représentative la plus proche au sein de cet ensemble de niveaux de quantification dans un processus semblable à l'arrondi d'un nombre réel à l'entier le plus proche. Dans le vecteur quantifié de 8 bits, le numéro d'identification remplace la valeur d'origine. Après quantification, chaque vecteur est représenté par un tableau d'identifiants pour les bacs auxquels appartiennent ses composants. Ces vecteurs quantifiés nécessitent beaucoup moins de bits à stocker par rapport au vecteur d'origine, réduisant ainsi les besoins de stockage et l'empreinte mémoire.
Fonctionnement de la quantification scalaire dans Recherche Azure AI
La quantification binaire compresse des vecteurs hautement dimensionnels en représentant chaque composant en tant que bit unique, 0 ou 1. Cette méthode réduit considérablement l’empreinte mémoire et accélère les opérations de comparaison vectorielle qui sont essentielles pour les tâches de recherche et d’extraction. Les tests de point de référence montrent jusqu’à 96 % de réduction en taille d’index vectoriel.
C’est particulièrement efficace pour les incorporations ayant des dimensions supérieures à 1024. Pour les dimensions plus petites, nous vous recommandons de tester la qualité de la quantification binaire ou d’essayer le type scalaire à la place. De plus, nous avons constaté que la quantification binaire fonctionne très bien lorsque les incorporations sont centrées sur zéro. La plupart des modèles d’incorporation connus tels qu’OpenAI, Cohere et Mistral sont centrés sur zéro.
Interroger un champ vectoriel quantifié en utilisant le suréchantillonnage
La syntaxe de requête d’un champ vectoriel compressé ou quantifié est la même que pour des champs vectoriels non compressés, sauf si vous souhaitez remplacer les paramètres associés au suréchantillonnage ou au rescoring par les vecteurs d’origine.
N’oubliez pas que la définition de compression vectorielle dans l’index a des paramètres pour rerankWithOriginalVectors
et defaultOversampling
qui permettent d’atténuer les effets d’une compression avec perte. Vous pouvez remplacer les valeurs par défaut afin de faire varier le comportement au moment de la requête. Par exemple, si defaultOversampling
est 10.0, vous pouvez le remplacer par autre chose dans la demande de requête.
Vous pouvez définir le paramètre de suréchantillonnage même si l'index n'a pas explicitement de définition rerankWithOriginalVectors
ou defaultOversampling
. Fournir oversampling
au moment de la requête remplace les paramètres d'index pour cette requête et exécute la requête rerankWithOriginalVectors
avec la valeur 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
}
]
}
Points essentiels :
S'applique aux champs vectoriels soumis à une compression vectorielle, conformément à l'affectation du profil vectoriel.
Remplace la valeur
defaultOversampling
ou introduit un suréchantillonnage au moment de la requête, même si la configuration de compression de l'index ne spécifie pas d'options de suréchantillonnage ou de reclassement.