これは、C ++で書かれたHNSWLIBインデックスライブラリのWebAssembly(WASM)バージョンです。このWASMポートは、EMCC WASMコンパイラを使用して@shravansunderによって作成されました。ここのリポジトリを参照してください。
ライブラリhnswlib-nodeに触発されました。 @yoshokuは、hnswlib-nodeにいくつかの素晴らしいドキュメントを提供しました。ありがとう、@yoshoku!
注:このライブラリはまだ初期の頃です!ブラウザでHNSWLIBを実行する必要があるユースケース用に構築されています。
hnswlib-wasm 、階層的なナビゲーション可能な小さな世界グラフに基づいて、近似の近似の検索を実装するHnswlibのWasm Bindingsを提供します。ブラウザで動作し、emscriptenでコンパイルされています。
$ yarn add hnswlib-wasmこちらのNPMパッケージをご覧ください。
indexedDB (ブラウザ内)をサポートし、EmscriptenのFSを使用して、仮想ファイルシステムとIDBFSを介してインデックスを保存およびロードします。hnswlib-nodeのchangelogを参照してください。まず、ライブラリのランタイムインスタンスを作成します。
import { loadHnswlib } from 'hnswlib-wasm' ;
const lib = await loadHnswlib ( ) ;インデックスが存在する場合は、インデックスが存在する場合、または存在しない場合は新しいインデックスを作成する完全な例を次に示します。
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 ) ;
}インデックスを作成して、そのように使用できます。
// 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 ) ;追加されるより多くの使用例。
今のところ、テストフォルダーの
HierarchicalNSW.test.tsファイルを参照し、hnswlib-node APIドキュメントを参照してください。
hnswlib-wasmライブラリは、Browserの検索インデックスを保存および管理するためのIndexEdDB(IDBFS)の拡張サポートを提供します。これにより、Web環境で検索インデックスを簡単に保存およびロードでき、EMCCファイルシステムからJavaScriptメモリにデータを移動する必要はありません。 EmscriptenのFSを使用して、仮想ファイルシステムを介してインデックスを保存およびロードします。仮想ファイルシステムはIDBFSと同期されています。
検索インデックスを保存するには、 writeIndexメソッドを使用します。
await index . writeIndex ( 'savedIndex' ) ;以前に保存された検索インデックスをロードするには、 readIndexメソッドを使用します。
await index . readIndex ( 'savedIndex' , false ) ; syncFsメソッドは、EMScriptenファイルシステムを永続的なストレージIDBFSと同期するために使用されます。この方法を使用して、ファイルシステムの永続的なソースからデータを保存または読み取ることができます。
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 このセクションでは、HNSWアルゴリズムパラメーターの概要と、HNSWLIB-WASMライブラリを使用する際のパフォーマンスへの影響について説明します。 HNSW(Hierarchical Navigable Small World)は、高次元空間での効率的な類似性検索のためのグラフベースのインデックス構造です。
Pinecone.ioの画像
検索品質とインデックスサイズまたは建設時間のトレードオフを制御するために調整できるいくつかのパラメーターがあります。主要なパラメーターの一部を以下に示します。
efsearchは、検索中に使用される最近隣人の動的リストのサイズです。 EFSearch値が高いと、より正確ではあるが遅い検索につながります。 efsearchは、クエリの最近隣接kの数よりも低く設定することはできず、Kとデータセットのサイズの間の値になることができます。
Mは、インデックス構造中に新しい要素ごとに作成された双方向リンクの数です。 Mの合理的な範囲は2〜100です。より高いM値は、本質的な次元および/または高いリコールを持つデータセットでより良く動作しますが、低い本質的な次元および/または低リコールを持つデータセットでは、m値が低い場合にはより良い動作があります。パラメーターは、保存された要素ごとに約M * 8〜10バイトであるアルゴリズムメモリ消費も決定します。
efconstructionは、インデックスの構築時間と精度を制御します。より大きなefconstruction値は、建設時間が長くなりますが、インデックスの品質が向上します。ある時点で、EFConstructionの増加はインデックスの品質を改善しません。選択したefconstruction値が適切であるかどうかを確認するには、efsearch = efconstructionの場合、m最近隣接検索のリコールを測定します。リコールが0.9未満の場合、改善の余地があります。
Hnswlib-wasmを使用する場合、データセットのサイズと寸法に基づいて、m、efsearch、およびefconstructionの適切な値を選択することが不可欠です。 Hnswlib-wasmはブラウザで実行されているため、使用可能なメモリとパフォーマンスの制限を考慮する必要があります。ここにいくつかの推奨事項があります:
ほとんどのユースケースではうまく機能するため、12〜48の範囲で値を選択します。特定のデータセットに最適な値を見つけるために実験する必要がある場合があります。
Mに近い値から始めて、検索速度と精度の間の目的のトレードオフに基づいて調整します。値が低くなりますが、より正確ではありませんが、より高い値はより正確ですが遅くなります。
予想されるクエリボリュームを考慮して、この値を設定します。クエリボリュームが低いと予想される場合は、特に低いM値を使用する場合、検索時間への影響を最小限に抑えてリコールを改善するために、eFconstructionの高い値を設定できます。
M値が高いとインデックスのメモリ使用量が増加するため、HNSWLIB-WASMのパラメーターを選択する際には、パフォーマンスとメモリの制約のバランスをとる必要があることを忘れないでください。
PineconeでHNSWを学びます
Pineconeによるベクトルインデックス
Pinecone.ioの画像
Hnswlib-wasmは、Apache-2.0ライセンスの条件の下でオープンソースとして利用できます。
構築する
yarn install
make rebuild
yarn build
テストします
yarn test
最初に@shravansunderに連絡してください!