Il s'agit d'une version WebAssembly (WASM) de la bibliothèque d'index HNSWLIB écrite en C ++. Ce port Wasm a été créé par @shravansunder à l'aide du compilateur EMCC WASM, voir le référentiel ici.
Inspiré par la bibliothèque hnswlib-node. @yoshoku a fourni une merveilleuse documentation pour le nœud hnswlib. Merci, @yoshoku!
Remarque: cette bibliothèque est encore à ses débuts! Il est en cours de construction pour un cas d'utilisation qui nécessite l'exécution de HNSWLIB dans le navigateur.
hnswlib-wasm fournit des liaisons WasM pour HNSWLIB qui met en œuvre une recherche approximative la plus proche de l'Eightbor basée sur des graphiques hiérarchiques de petit monde navigable. Il fonctionne dans les navigateurs et est compilé avec Emscripten.
$ yarn add hnswlib-wasmVoir le package NPM ici.
indexedDB (dans le navigateur) et utilise FS à partir d'EMScripten pour enregistrer et charger l'index via le système de fichiers virtuel et les IDBF.hnswlib-node pour plus de détails par @Yoshoku Changelog.Créez d'abord une instance d'exécution de la bibliothèque:
import { loadHnswlib } from 'hnswlib-wasm' ;
const lib = await loadHnswlib ( ) ;Voici un exemple complet de chargement d'un index s'il existe ou de créer un nouvel index s'il n'existe pas:
const filename = 'ghost.dat' ;
const { loadHnswlib } = await import ( 'hnswlib-wasm' ) ;
this . hnswlib = await loadHnswlib ( ) ;
this . hnswlib . EmscriptenFileSystemManager . setDebugLogs ( true ) ;
this . vectorHnswIndex = new this . hnswlib . HierarchicalNSW ( 'cosine' , 1536 ) ;
await syncFileSystem ( 'read' ) ;
const exists = this . hnswlib . EmscriptenFileSystemManager . checkFileExists ( filename ) ;
if ( ! exists ) {
this . vectorHnswIndex . initIndex ( 100000 , 48 , 128 , 100 ) ;
this . vectorHnswIndex . setEfSearch ( 32 ) ;
this . vectorHnswIndex . writeIndex ( 'ghost.dat' ) ;
} else {
this . vectorHnswIndex . readIndex ( filename , 100000 , true ) ;
this . vectorHnswIndex . setEfSearch ( 32 ) ;
}Vous pouvez créer l'index et l'utiliser comme ainsi.
// Here you're creating a new index with the L2 distance metric and 1000 as the max number of elements
const hnswIndex = lib . HierarchicalNSW ( 'l2' , 100 ) ;
// Initialize the index with the dimensions (1536), m, efConstruction. See the section below on parameters for more details. These cannot be changed after the index is created.
index . initIndex ( 1536 , 36 , 16 , 200 ) ;
// Set efSearch parameters. This can be changed after the index is created.
index . setEfSearch ( efSearch ) ;
// Now you can add items to the index, labels are returned as an array for the vectors. It will reuse deleted labels if possible based on the second parameter.
const labels = index . addItems ( vectors , true ) ;
// Now you can search the index
const result1 = index . searchKnn ( vectors [ 10 ] , 10 , undefined ) ;
// You can also search the index with a label filter
const labelFilter = ( label : number ) => {
return label >= 10 && label < 20 ;
}
const result2 = index . searchKnn ( testVectorData . vectors [ 10 ] , 10 , labelFilter ) ;Plus d'exemples d'utilisation à ajouter.
Pour l'instant, consultez le fichier
HierarchicalNSW.test.tsdans le dossier Tests et référez-vous à la documentation de l'API HNSWLIB-node.
La bibliothèque hnswlib-wasm fournit une prise en charge étendue pour IndededDB (IDBFS) pour stocker et gérer l'index de recherche dans le navigateur. Cela vous permet d'enregistrer et de charger facilement l'index de recherche dans un environnement Web et vous n'avez pas à déplacer les données du système de fichiers EMCC vers la mémoire JavaScript. Il utilise le FS de Emscripten pour enregistrer et charger l'index via le système de fichiers virtuel. Le système de fichiers virtuel est synchronisé avec IDBFS.
Pour enregistrer l'index de recherche, utilisez la méthode writeIndex :
await index . writeIndex ( 'savedIndex' ) ; Pour charger un index de recherche précédemment enregistré, utilisez la méthode readIndex :
await index . readIndex ( 'savedIndex' , false ) ; La méthode syncFs est utilisée pour synchroniser le système de fichiers EMScripten avec les IDBF de stockage persistants. Vous pouvez utiliser cette méthode pour enregistrer ou lire des données à partir de la source persistante du système de fichiers.
await lib . EmscriptenFileSystemManager . syncFS ( true , emscripten :: val :: undefined ( ) ) ; // Read data from the persistent source
await lib . EmscriptenFileSystemManager . syncFS ( false , emscripten :: val :: undefined ( ) ) ; // Save data to the persistent source Cette section fournira un aperçu des paramètres de l'algorithme HNSW et de leur impact sur les performances lors de l'utilisation de la bibliothèque HNSWLIB-WASM. HNSW (Hiérarchical Navigable Small World) est une structure d'index basée sur des graphiques pour une recherche de similitude efficace dans les espaces de haute dimension.
Image de pinecone.io
Il a plusieurs paramètres qui peuvent être réglés pour contrôler le compromis entre la qualité de la recherche et la taille de l'indice ou le temps de construction. Voici quelques-uns des paramètres clés.
EFSearch est la taille de la liste dynamique pour les voisins les plus proches utilisés lors de la recherche. Des valeurs EFSearch plus élevées conduisent à des recherches plus précises mais plus lentes. EFSearch ne peut pas être défini inférieur au nombre de voisins les plus proches interrogés K et peut être n'importe quelle valeur entre K et la taille de l'ensemble de données.
M est le nombre de liens bidirectionnels créés pour chaque nouvel élément pendant la construction d'index. Une plage raisonnable pour M est de 2-100. Des valeurs M plus élevées fonctionnent mieux sur les ensembles de données avec une dimensionnalité intrinsèque élevée et / ou un rappel élevé, tandis que les valeurs M plus faibles fonctionnent mieux pour les ensembles de données avec une dimensionnalité intrinsèque faible et / ou un faible rappel. Le paramètre détermine également la consommation de mémoire des algorithmes, qui est à peu près M * 8-10 octets par élément stocké.
Efconstruction contrôle le temps de construction de l'indice et la précision. Des valeurs d'efconstruction plus importantes entraînent des temps de construction plus longs mais une meilleure qualité d'indice. À un moment donné, l'augmentation de l'efconstruction n'améliore pas la qualité de l'indice. Pour vérifier si la valeur d'efconstruction sélectionnée est appropriée, mesurez le rappel de la recherche de voisin le plus proche lorsque efSearch = efConstruction. Si le rappel est inférieur à 0,9, il y a place à amélioration.
Lorsque vous utilisez HNSWLIB-WASM, il est essentiel de choisir des valeurs appropriées pour M, EfSearch et Efconstruction en fonction de la taille et de la dimensionnalité de vos ensembles de données. Étant donné que HNSWLIB-WASM fonctionne dans le navigateur, vous devez considérer les limitations de mémoire et de performances disponibles. Voici quelques recommandations:
Choisissez une valeur dans la plage de 12-48, car elle fonctionne bien pour la plupart des cas d'utilisation. Vous devrez peut-être expérimenter pour trouver la valeur optimale pour votre ensemble de données spécifique.
Commencez par une valeur proche de M et ajustez-le en fonction du compromis souhaité entre la vitesse de recherche et la précision. Les valeurs plus faibles seront plus rapides mais moins précises, tandis que des valeurs plus élevées seront plus précises mais plus lentes.
Définissez cette valeur en tenant compte du volume de requête attendu. Si vous prévoyez un faible volume de requête, vous pouvez définir une valeur plus élevée pour l'efconstruction afin d'améliorer le rappel avec un impact minimal sur le temps de recherche, en particulier lorsque vous utilisez des valeurs M inférieures.
N'oubliez pas que les valeurs M plus élevées augmenteront l'utilisation de la mémoire de l'index, vous devez donc équilibrer les performances et les contraintes de mémoire lors du choix de vos paramètres pour HNSWLIB-WASM.
Apprenez HNSW par Pinecone
Index vectoriels par pignon
Images de pinecone.io
HNSWLIB-WASM est disponible en open source en vertu des termes de la licence Apache-2.0.
Pour construire
yarn install
make rebuild
yarn build
Pour tester
yarn test
Contactez @shravansunder en premier!