プログラミング
RIP、ベクトルデータベース
RIP, vector database (turbopuffer.com)
要約
Turbopufferは、検索パフォーマンスを向上させるためにストレージアーキテクチャをv3へ移行することを発表しました。従来のベクトル検索中心の設計から、ANN(近似最近傍)検索を二次インデックスとして扱い、他のクエリタイプ(テキスト、正規表現、SQLなど)のパフォーマンスを向上させる新しいプライマリインデックスを採用します。これにより、ストレージと書き込みの効率化、およびベクトル化の向上が期待されます。
全文翻訳
tpuf v3が登場します:進捗をフォローしてくださいtpuf v3が登場します:進捗をフォローしてくださいRIP、ベクトルデータベース2026年9月30日•Dan Harrison (エンジニア)検索を次のレベルに引き上げるために、Turbopufferのストレージアーキテクチャを変更します。Turbopuffer v3は、ドキュメントとインデックスがTurbopuffer内でどのようにレイアウトされ、書き込まれ、圧縮され、クエリされるかを変更します。これにより、テキスト、正規表現、ベクトル検索を含むすべての面で検索を高速化できるだけでなく、より多くのSQLクエリをTurbopufferに移行して高速化するための基盤も提供します。Turbopufferは、サーバーレスベクトルデータベース(v1)として、非常に安価で合理的に高速なベクトル検索の提供に特化して立ち上げられました。ソースオブトゥルースとしてのオブジェクトストレージが経済性を提供し、階層化されたNVMe SSD/メモリキャッシュがパフォーマンスを提供しました。これらの特定のトレードオフの価値は、CursorやNotionを含む初期の顧客によって検証されました。Turbopufferは、非常に強力なテキストおよび正規表現検索(v2)を持つように進化し、Linearの同期エンジンなどの多くの非検索ユースケースで使用されています。クエリエンジンは、これらすべてのクエリプランをサポートするように進化しましたが、ストレージアーキテクチャはほとんど変更されていませんでした。ANNベクトルインデックスは、他のすべてのインデックスとクエリプランが中心となるプライマリインデックスであり、かつそうであり続けました。この設計は、GROUP BYや集計などのいくつかのクエリプランを制限していました。私たちはベクトルプライマリアーキテクチャを可能な限り推し進めましたが、次に進む時が来ました。私たちは新しいプライマリインデックスに移行するプロセスにあり、ANNを「単なる」セカンダリインデックスにしています。私たちは、その理由を皆さんに共有すると楽しいかもしれないと思いました。最初のアップデートでは、なぜ私たちがこれをやっているのかの舞台を設定します。tpuf v1から今日までの短い旅を私と一緒に歩んでください。v1:IDとベクトルTurbopufferの最初のバージョンでは、ドキュメントはIDとベクトルのみで構成されていました。当時の一般的な考え方はグラフベースのベクトルインデックスでしたが、階層型クラスタリングインデックスはオブジェクトストレージとより相性が良いです。SPANNから始め、最終的に増分インデックス作成をサポートするためにSPFreshに移行しました。ベクトルはグループにクラスタリングされ、その中心点はさらにクラスタリングされ、ツリーを形成するために繰り返されます。単一のルートを持ちます。┌───────────────────┐│ root centroid │└───────────────────┘╱ │ ╲╱ │ ╲┌───────────────────┐┌───────────────────┐┌───────────────────┐│ leaf centroid ││ leaf centroid ││ leaf centroid │└───────────────────┘└───────────────────┘└───────────────────┘╱ ╲╱ ╲╱ ╲╱ ╲╱ ╲╱ ╲┌────────┐┌────────┐┌────────┐┌────────┐┌────────┐┌────────┐│ vector ││ vector ││ vector ││ vector ││ vector ││ vector │└────────┘└────────┘└────────┘└────────┘└────────┘└────────┘┌───────────────┐│ root centroid │└───────────────┘╱ │ ╲╱ │ ╲┌────────┐┌────────┐┌────────┐│ leaf ││ leaf ││ leaf ││centroid││centroid││centroid│└────────┘└────────┘└────────┘╱ ╲╱ ╲╱ ╲┌───┐┌───┐┌───┐┌───┐┌───┐┌───┐│vec││vec││vec││vec││vec││vec│└───┘└───┘└───┘└───┘└───┘└───┘ご覧のように、すべてがClusterIdとLocalId(例:C0L1)でキー付けされており、これらを合わせてANNアドレスと呼びます。これが、ANNインデックスがプライマリインデックスであると私たちが言う理由です。v2:属性フィルタリングと全文検索2つの新しいクエリプランが、Turbopuffer v1 → v2への非公式な移行を示しました。属性フィルタリングと全文検索です。属性フィルタリング当然のことながら、顧客は属性値を追加し、それに基づいてベクトル検索をフィルタリングできるようになりたいと考えていました。フィルタリングを高速かつ高リコールにするために、属性値をそれに含まれるドキュメントのANNアドレスにマッピングする転置インデックスとしてモデル化しました。K::AttrIndex("family", "Alcidae") -> vec![C0L3, C1L2, C1L3, ...]K::AttrIndex("genus", "Fratercula") -> vec![C0L3, C1L2, C1L9, ...]射影(include_attributes)のため、ドキュメントの属性をIDとベクトルと一緒に格納しました。K::Vector(C0L0) = vec![0.45, 0.32, ...]K::Id(C0L0) = 7K::Attr(C0L0, "family") = "Alcidae"K::Attr(C0L0, "genus") = "Fratercula"全文検索BM25全文検索は、もう一つの明白で非常に要望の多かったクエリプランでした。属性検索と同様に、全文検索は、まずクエリ用語が存在するドキュメント(一般に「投稿」と呼ばれる)を見つけることから始まります。FTSインデックスの場合、BM25スコアリングに必要な(用語数、ドキュメント長)メタデータも含まれます。K::FTS("description", "Atlantic") -> vec![(C0L0, 2, 37), (C9L4, 1, 42), ...]K::Attr(C0L0, "description") -> "A sharply dressed black-and-white seabird with a
huge, multicolored bill, the Atlantic Puffin is often
called the clown of the sea. It breeds in burrows on
islands in the North Atlantic, and winters at sea."時間の経過とともに、私たちはいくつかの他のインデックス構造とクエリエンジンを出荷してきました。集計、正規表現検索、あいまいマッチング、スパースベクトル検索、属性順序付けなど、すべて同じベクトルプライマリストレージレイアウトを中心に構築されています。ベクトルプライマリインデックスの問題ANNプライマリインデックスは、オブジェクトストレージ上でのANN検索に非常にうまく機能するという単純な理由で、今日までほとんどそのまま残っていました。このアーキテクチャの上に、100B以上のベクトルを持つ単一インデックスで、1k+ QPSで200msのp99読み取りを提供するようにベクトル検索をプッシュしてきました。ここでの重大な変更は、ANNパフォーマンスに後退をもたらすリスクがあります。しかし、このレイアウトは、サポートしている非ベクトルクエリ形状において、3つの主な方法で最先端になることを妨げています。ストレージ増幅、書き込み増幅、および限定的なベクトル化。ストレージ増幅上記で説明したように、Turbopufferは現在、各ドキュメントの全内容をANNアドレスの下に配置しています。ベクトルが1つしかない場合、非ベクトルデータはベクトルと一緒に一度だけ格納されます。しかし、ドキュメントのネストや遅延インタラクションのような、ドキュメントの複数のベクトル表現の場合、これは各ベクトルに対してコンテンツを複製する必要があることを意味します。これが、いくつかのより不幸な制限の理由です。書き込み増幅ドキュメントの挿入、更新、または削除が行われるたびに、SPFreshはベクトルが適切にクラスタリングされたままであることを保証するためにベクトルを再調整する場合があります(そうでなければリコールが低下する可能性があります)。ドキュメント内のすべてがドキュメントベクトルのANNアドレスでキー付けされて格納されているため、この再調整は、完全なドキュメントコンテンツ、およびそれを参照する転置(属性およびFTS)インデックスの移動に連鎖します。1つのベクトルを更新するだけで、数百の属性とそのインデックスが移動する可能性があります。この書き込み増幅は非常に大きいため、インデックス作成スループットを調整する努力は、収穫逓減に達し始めています。限定的なベクトル化最新のクエリエンジンはベクトル化されています。つまり、ブロックごとにタイトなループを実行し、ブロックごとの固定コストを償却し、より圧縮し、CPUパイプラインをフルに保ち、SIMDをアンロックします。たとえば、DuckDBは2,048行のバッチで動作し、ClickHouseは最大約65k、Luceneの投稿ブロックは256ドキュメントであり、ANNインデックスは100〜200ドキュメントのクラスタで最もよく機能します。すべてのクエリプランには最適なブロックサイズがありますが、今日ではすべてANNプライマリインデックスによって制約されています。CPUを飽和させるために数千ドキュメントのブロックを必要とするプランは、依然として100〜200に制限されています。これがTurbopufferでどれほど重要であるかはすでに文書化しています。全文検索の最初のバージョンでは、投稿リストをANNクラスタ境界に沿ってパーティション化していましたが、中央のブロックには約1.5の投稿しか含まれていませんでした。FTS v2は投稿を約256の固定ブロックに再編成し、インデックスは10倍小さくなり、クエリは最大20倍高速になりました。投稿リストは、それらが固定ブロックで...