Faissでベクトル検索するDBを開発した
広告プラットフォームcraft に投入
24000次元のSCDVベクトルを数百万件入れてインデクシングしています。
PQ圧縮しているのでメモリー負担は殆ど無く小さなサーバーで運用できています(トレーニングの時だけメモリーが大変)
順次利用範囲を広げていく予定。
faissdb
https://github.com/crumbjp/faissdb
- Faissインデックスを使ったベクトル検索が出来るDB
- ベクトルはユニークキーで管理(Faissの面倒なID管理をしなくて良い)
- 複数のFaiss indexを扱える。(検索対象が用途的に、全体データ、weeklyデータ、monthlyデータ、といった具合に分けたい時には予めfaiss indexを3つ作っておかなきゃならない)
- PRIMARY-SECONDARY の簡易レプリケーション
- クライアントI/FがgRPCなのでクライアントライブラリの開発が容易
依存技術
- golang => C言語を書かずにC言語ライブラリが使えるのが売り
- faiss => ベクトルインデックス検索
- rocksdb => 高性能key-value store
- gRPC => Google製RPC
開発の経緯
faissを使いたいが・・・
C/C++のfacebook製のベクトルANN検索ライブラリ。群を抜いて完成度と柔軟性が高い。
この手のライブラリは作ったインデックスを更新出来ないのが普通だがfaissではインデックスのアルゴリズムを指定する事で、用途に応じたインデックスのメリットと制限をコントロール出来る。
しかしあくまで純粋な検索ライブラリなのでサービスに使うには周辺の処理(メモリー管理やデータ管理など)を自前で書かなきゃならない。
高速実装のトレードオフでインデクスの永続化周りは非常に弱い。
golang
容易にCライブラリを叩く事ができる言語の中では最も高級言語の内の一つ。
goルーチンがメチャクチャ便利なのでデータストアを書くのには向いている。
golang内で取得したメモリーに関してはGCが面倒を見てくれるがCライブラリを叩く場合は帰ってくるデータのメモリーの扱いを気にしなきゃならないので結局ソースは全部読まなきゃ使えない。
駄目なら全部自分で書く覚悟が出来てる時だけgolangを使うのであまり気にならないが・・・
gRPC
protocol-bufferベースの言語非依存RPCライブラリ。
が、クロス言語でコールする場合はちょくちょくバグがあったりして地雷を回避しながらじゃないと使えない。
インターフェース定義ファイル(.proto)から各言語実装をジェネレート出来、使う側は限りなく言語ネイティブで実装できるので負担が少ない。