Esta é uma versão WebAssembly (WASM) da biblioteca de índice HNSWLIB escrita em C ++. Esta porta WASM foi criada por @shravansunder usando o compilador EMCC WASM, consulte o repositório aqui.
Inspirado na biblioteca hnswlib-node. @yoshoku forneceu uma documentação maravilhosa para o hnswlib-node. Obrigado, @yoshoku!
Nota: Esta biblioteca ainda está nos seus primeiros dias! Ele está sendo construído para um caso de uso que requer a execução do HNSWLIB no navegador.
hnswlib-wasm fornece ligações de WASM para o HNSWLIB que implementa a pesquisa aproximada do vizinho mais próximo com base em gráficos mundiais pequenos de navegação hierárquica. Funciona em navegadores e é compilado com EMSCRIPTEN.
$ yarn add hnswlib-wasmVeja o pacote NPM aqui.
indexedDB (no navegador) e usa o FS do EMSCRIPTEN para salvar e carregar o índice através do sistema de arquivos virtual e do IDBFS.hnswlib-node para obter mais detalhes do @yoshoku changelog.Primeiro, crie uma instância de tempo de execução da biblioteca:
import { loadHnswlib } from 'hnswlib-wasm' ;
const lib = await loadHnswlib ( ) ;Aqui está um exemplo completo de carregar um índice se existir ou criar um novo índice, se não existir:
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 ) ;
}Você pode criar o índice e usá -lo assim.
// 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 ) ;Mais exemplos de uso a serem adicionados.
Por enquanto, consulte o arquivo
HierarchicalNSW.test.ts.
A biblioteca hnswlib-wasm fornece suporte estendido ao IndexedDB (IDBFS) para armazenar e gerenciar o índice de pesquisa no navegador. Isso permite salvar e carregar o índice de pesquisa facilmente em um ambiente da Web e não precisa mover dados do sistema de arquivos EMCC para a memória JavaScript. Ele usa o FS do EMScript para salvar e carregar o índice através do sistema de arquivos virtual. O sistema de arquivos virtual é sincronizado com o IDBFS.
Para salvar o índice de pesquisa, use o método writeIndex :
await index . writeIndex ( 'savedIndex' ) ; Para carregar um índice de pesquisa salvo anteriormente, use o método readIndex :
await index . readIndex ( 'savedIndex' , false ) ; O método syncFs é usado para sincronizar o sistema de arquivos EMScripten com o Persistente Storage IDBFS. Você pode usar esse método para salvar ou ler dados da fonte persistente do sistema de arquivos.
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 seção fornecerá uma visão geral dos parâmetros do algoritmo HNSW e seu impacto no desempenho ao usar a biblioteca HNSWLIB-WASM. O HNSW (Hierárquico Small World) é uma estrutura de índice baseada em gráficos para pesquisa eficiente de similaridade em espaços de alta dimensão.
Imagem de Pinecone.io
Possui vários parâmetros que podem ser ajustados para controlar a troca entre a qualidade da pesquisa e o tamanho do índice ou o tempo de construção. Aqui estão alguns dos principais parâmetros.
O EFSearch é o tamanho da lista dinâmica dos vizinhos mais próximos usados durante a pesquisa. Valores mais altos do EFSearch levam a pesquisas mais precisas, mas mais lentas. O EFSearch não pode ser definido menor que o número de vizinhos mais próximos consultados K e pode ser qualquer valor entre K e o tamanho do conjunto de dados.
M é o número de links bidirecionais criados para todos os novos elementos durante a construção de índices. Um intervalo razoável para M é 2-100. Os valores M mais altos funcionam melhor nos conjuntos de dados com alta dimensionalidade intrínseca e/ou recall alto, enquanto os valores de M mais baixos funcionam melhor para conjuntos de dados com baixa dimensionalidade intrínseca e/ou recall baixo. O parâmetro também determina o consumo de memória de algoritmos, que é aproximadamente M * 8-10 bytes por elemento armazenado.
A EFConstruction controla o tempo de construção do índice e a precisão. Valores maiores de EfConstruction levam a tempos de construção mais longos, mas melhor qualidade do índice. Em algum momento, o aumento da efconstrução não melhora a qualidade do índice. Para verificar se o valor de efConstruction selecionado é apropriado, meda o recall para a pesquisa de vizinhos mais próxima quando o efsearch = efConstruction. Se o recall for menor que 0,9, há espaço para melhorias.
Ao usar o HNSWLIB-WASM, é essencial escolher valores apropriados para M, EFSearch e EfConstruction com base no tamanho e na dimensionalidade dos seus conjuntos de dados. Como o HNSWLIB-WASM está em execução no navegador, você deve considerar as limitações de memória e desempenho disponíveis. Aqui estão algumas recomendações:
Escolha um valor no intervalo de 12-48, pois funciona bem para a maioria dos casos de uso. Pode ser necessário experimentar para encontrar o valor ideal para o seu conjunto de dados específico.
Comece com um valor próximo a M e ajuste-o com base na troca desejada entre velocidade de pesquisa e precisão. Os valores mais baixos serão mais rápidos, mas menos precisos, enquanto valores mais altos serão mais precisos, mas mais lentos.
Defina esse valor considerando o volume esperado de consulta. Se você antecipar o baixo volume de consultas, poderá definir um valor mais alto para a efConstruction para melhorar a recuperação com o mínimo impacto no tempo de pesquisa, especialmente ao usar valores de M mais baixos.
Lembre-se de que os valores de M mais altos aumentarão o uso da memória do índice, portanto, você deve equilibrar as restrições de desempenho e memória ao escolher seus parâmetros para HNSWLIB-WASM.
Aprenda HNSW por Pinecone
ÍNDICES VETORES POR PINECONE
Imagens de Pinecone.io
O HNSWLIB-WASM está disponível como código aberto nos termos da licença Apache-2.0.
Para construir
yarn install
make rebuild
yarn build
Para testar
yarn test
Entre em contato com @shravansunder primeiro!