Esta es una versión WebAssembly (WASM) de la biblioteca de índice HNSWLIB escrita en C ++. Este puerto WASM fue creado por @shravansunder utilizando el compilador de WASM EMCC, vea el repositorio aquí.
Inspirado en la biblioteca hnswlib-nodo. @Yoshoku ha proporcionado una documentación maravillosa para el nodo HNSWLIB. ¡Gracias, @yoshoku!
Nota: ¡esta biblioteca todavía está en sus primeros días! Se está construyendo para un caso de uso que requiere ejecutar hnswlib en el navegador.
hnswlib-wasm proporciona enlaces WASM para HNSWLIB que implementa la búsqueda aproximada de vecino más cercano basado en gráficos jerárquicos de pequeños mundos navegables. Funciona en los navegadores y se compila con Emscripten.
$ yarn add hnswlib-wasmVea el paquete NPM aquí.
indexedDB (en el navegador) y usa FS de Emscripten para guardar y cargar el índice a través del sistema de archivos virtual e IDBFS.hnswlib-node para obtener más detalles de @Yoshoku Changelog.Primero, cree una instancia de tiempo de ejecución de la biblioteca:
import { loadHnswlib } from 'hnswlib-wasm' ;
const lib = await loadHnswlib ( ) ;Aquí hay un ejemplo completo de cargar un índice si existe o crear un nuevo índice si no existe:
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 ) ;
}Puede crear el índice y usarlo como así.
// 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 ) ;Más ejemplos de uso que se agregarán.
Por ahora, consulte el archivo
HierarchicalNSW.test.tsen la carpeta de pruebas y consulte la documentación de la API de nodo HNSWLIB.
La biblioteca hnswlib-wasm proporciona soporte extendido para indexedDB (IDBFS) para almacenar y administrar el índice de búsqueda en el navegador. Esto le permite guardar y cargar el índice de búsqueda fácilmente en un entorno web y no tiene que mover datos del sistema de archivos EMCC a la memoria JavaScript. Utiliza el FS de Emscripten para guardar y cargar el índice a través del sistema de archivos virtuales. El sistema de archivos virtuales se sincroniza con IDBFS.
Para guardar el índice de búsqueda, use el método writeIndex :
await index . writeIndex ( 'savedIndex' ) ; Para cargar un índice de búsqueda previamente guardado, use el método readIndex :
await index . readIndex ( 'savedIndex' , false ) ; El método syncFs se utiliza para sincronizar el sistema de archivos Emscripten con el IDBFS de almacenamiento persistente. Puede usar este método para guardar o leer datos de la fuente persistente del sistema de archivos.
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 Esta sección proporcionará una descripción general de los parámetros del algoritmo HNSW y su impacto en el rendimiento al usar la biblioteca HNSWLIB-WASM. HNSW (mundo pequeño jerárquico navegable) es una estructura de índice basada en gráficos para una búsqueda de similitud eficiente en espacios de alta dimensión.
Imagen de pinecone.io
Tiene varios parámetros que se pueden ajustar para controlar la compensación entre la calidad de búsqueda y el tamaño del índice o el tiempo de construcción. Estos son algunos de los parámetros clave.
EFSearch es el tamaño de la lista dinámica para los vecinos más cercanos utilizados durante la búsqueda. Los valores de EFSearch más altos conducen a búsquedas más precisas pero más lentas. EFSearch no se puede establecer más bajo que el número de vecinos más cercanos consultados K y puede ser cualquier valor entre K y el tamaño del conjunto de datos.
M es el número de enlaces bidireccionales creados para cada nuevo elemento durante la construcción del índice. Un rango razonable para M es 2-100. Los valores de M más altos funcionan mejor en conjuntos de datos con alta dimensionalidad intrínseca y/o alto retiro, mientras que los valores de M más bajos funcionan mejor para conjuntos de datos con baja dimensionalidad intrínseca y/o bajo retiro. El parámetro también determina el consumo de memoria de algoritmos, que es aproximadamente m * 8-10 bytes por elemento almacenado.
EFConstruction controla el tiempo de construcción del índice y la precisión. Los valores más grandes de EFConstruction conducen a tiempos de construcción más largos pero una mejor calidad del índice. En algún momento, el aumento de EFConstruction no mejora la calidad del índice. Para verificar si el valor EFConstruction seleccionado es apropiado, mida la recuperación de la búsqueda del vecino más cercano cuando EFSearch = efConstruction. Si el retiro es inferior a 0.9, hay margen de mejora.
Cuando se usa HNSWLib-Wasm, es esencial elegir los valores apropiados para M, EFSearch y EFConstruction en función del tamaño y la dimensionalidad de sus conjuntos de datos. Dado que HNSWLib-Wasm se está ejecutando en el navegador, debe considerar las limitaciones de memoria y rendimiento disponibles. Aquí hay algunas recomendaciones:
Elija un valor en el rango de 12-48, ya que funciona bien para la mayoría de los casos de uso. Es posible que deba experimentar para encontrar el valor óptimo para su conjunto de datos específico.
Comience con un valor cercano a M y ajustelo en función de su compensación deseada entre la velocidad de búsqueda y la precisión. Los valores más bajos serán más rápidos pero menos precisos, mientras que los valores más altos serán más precisos pero más lentos.
Establezca este valor considerando el volumen de consulta esperado. Si anticipa un volumen de consulta bajo, puede establecer un valor más alto para EFConstruction para mejorar el retiro con un impacto mínimo en el tiempo de búsqueda, especialmente cuando se usa valores M más bajos.
Recuerde que los valores M más altos aumentarán el uso de la memoria del índice, por lo que debe equilibrar las limitaciones de rendimiento y memoria al elegir sus parámetros para HNSWLIB-WASM.
Aprenda HNSW por Pinecone
Índices vectoriales por Pinecone
Imágenes de pinecone.io
Hnswlib-Wasm está disponible como código abierto bajo los términos de la licencia Apache-2.0.
Para construir
yarn install
make rebuild
yarn build
Para probar
yarn test
Póngase en contacto con @Shravansunder primero!