エンジニアリング

ベクトル検索:HotKVとRedis 8のベクトルセット、1~100クライアントで比較

HotKVとRedis 8.10.2のベクトル検索を、100,000件と999,000件の埋め込み、1~100クライアントで比較。スループット、レイテンシ、再現率、読み込み速度、メモリ、制約をまとめました。

HotKVのベクトル検索:スループットと再現率を、つながった近傍ノードで表したイラスト。

ベクトル検索は、RAGのための検索、セマンティックキャッシュ、エージェントメモリなど、多くのAI機能の土台になっています。Redis 8はベータ版のデータ型であるベクトルセットをサーバーに組み込んで提供しているため、比較対象としては当然の選択です。同じOpenAIの埋め込みをHotKVとRedis 8.10.2に読み込み、それぞれに対して同じ1,000件のクエリを1~100の同時クライアント接続で実行し、回答の正確さ、各エンジンが処理した毎秒クエリ数、各クエリにかかった時間を測定しました。

要点。 999,000ベクトルで、最低再現率95%の条件では、HotKVはRedisと比べて、1クライアントで1.4倍、100クライアントで7.9倍(51,146対6,510)の毎秒クエリ数を処理しました。再現率99%では、倍率は1.8倍と5.4倍でした。HotKVのレイテンシの中央値は、すべてのクライアント数でRedisより低くなりました。Redisのスループットは32クライアントまでに頭打ちになりましたが、HotKVのスループットは100クライアントまで伸び続けました。HotKVはベクトルの読み込みが約5倍速く、再現率もすべての探索深度でRedisより高くなりました。これは1台のマシン上の1つのデータセットでの結果であり、HotKVのビルドは未リリースの開発ビルドです。また、RedisのQuery Engineや8ビットモードは測定していません。順位付けではなく、測定結果としてお読みください。

テストの内容

データ

Kumar ShivenduとNirant Kasliwalによるdbpedia-entities-openai-1M(MITライセンス)の最初の999,000行と、小さいほうのインデックス用には最初の100,000行を使用しました。各行は、OpenAIのtext-embedding-ada-002で埋め込んだDBpediaのエンティティで、1,536次元です。最後の1,000行がクエリなので、両方のセットに含まれる行はありません。正解データは、各クエリの正確な上位10件の最近傍で、どちらのエンジンとも独立に、64ビット浮動小数点の総当たりで計算しています。そのため、両エンジンは同じ正解に対して評価されます。

エンジンと設定

  • エンジン。 HotKVのコミットc8dafd37(VSIM.CREATEINDEX、VSIM.SET、VSIM.SEARCH)。未リリースの開発ビルドで、-march=nativeではなくデフォルトのリリースフラグでコンパイルしています。Redis 8.10.2は、リリースタグから標準のmakeでビルドしました(VADD、VSIM)。どちらもHNSWグラフを構築します。
  • インデックス設定。 両方ともコサイン類似度、M=16とef_construction=200のHNSWで、明示的に設定しました。これらは各エンジン自身のデフォルト値でもあります。
  • 精度。 両方とも全精度のfloat32ベクトルです。Redisのデフォルトは8ビット量子化なので、NOQUANTを指定して実行しました。
  • マシン。 Azure Standard_D160alds_v7(AMD EPYC 9V45、160 vCPU)1台。両サーバーを同じ128個のvCPUに固定し、負荷生成プロセスを残りの32個に固定して、すべてループバック経由で通信しました。HotKVは128スレッド、RedisはデフォルトのI/Oスレッド数で実行しました。1、4、8、16も試しましたが、設定による一貫した差はありませんでした。
  • 負荷生成。 クライアント接続ごとに1プロセスで、各プロセスは常に1つのリクエストを応答待ちの状態に保ち、リクエストは計測部分の前に作成しておきました。最も負荷の高い負荷生成プロセスでも、どの実行でも1つのCPUの8%しか使用しなかったため、クライアントが上限を決めることはありませんでした。

手順

探索深度(ef)40、80、150、300と、大きいほうのインデックスでは500について、1,000件のクエリを1、2、4、8、16、32、50、100クライアントで繰り返し実行しました。1秒間のウォームアップの後に4秒間を計測し、これを各3回、2つのエンジンの順序を交互に入れ替えて行いました。報告しているのは中央値です。再現率は別途、1つの接続で測定しました。HotKVへの読み込みは、どの実行でも32接続で行いました。Redisのインデックスは32接続でVADD ... CASを使って1回だけ構築して保存し、測定のために読み込みました。スクリプトとすべての試行はベンチマークリポジトリにあります。

結果

再現率の目標値をそろえた比較

2つのエンジンは同じefで同じ再現率に達するわけではないため、共通の最低再現率の目標値でスループットを比較します。各目標値について、それを達成した測定済みの探索深度のうち最も高速なものを使います。達成した深度と再現率はわずかに異なるため、表に記載しています。補間ではなく、実際に測定した深度を使っています。999,000ベクトルでの毎秒クエリ数:

Recall@10の目標値クライアント数HotKVRedis 8.10.2HotKVのRedis比レイテンシの中央値
95%以上11,328(ef 80、0.970)946(ef 80、0.962)1.40倍0.77 / 1.07 ms
95%以上810,3425,5311.87倍0.79 / 1.43 ms
95%以上1618,5007,2652.55倍0.87 / 2.15 ms
95%以上5037,5086,8255.50倍1.33 / 7.17 ms
95%以上10051,1466,5107.86倍1.91 / 13.49 ms
99%以上1507(ef 300、0.993)287(ef 500、0.994)1.77倍1.99 / 3.31 ms
99%以上166,9612,3223.00倍2.30 / 6.70 ms
99%以上5012,3932,4834.99倍4.02 / 18.91 ms
99%以上10013,8432,5835.36倍7.11 / 37.65 ms

レイテンシの中央値はHotKV / Redisの順です。目標値90%でも同じ傾向で、100クライアントで毎秒90,003対7,973クエリ(11.3倍)、いずれもef 40でした。

すべての探索深度

efHotKV再現率Redis再現率HotKV、1クライアントRedis、1クライアントHotKV、50クライアントRedis、50クライアントHotKV、100クライアントRedis、100クライアント
400.9400.9232,1081,25963,8978,06190,0037,973
800.9700.9621,32894637,5086,82551,1466,510
1500.9870.98087563621,9125,24126,1224,942
3000.9930.99050739612,3933,45413,8433,402
5000.9970.9943382877,6882,4838,8432,583

999,000ベクトルでの毎秒クエリ数です。100,000ベクトルでも傾向は同じで、再現率95%では、HotKVはRedisと比べて、1クライアントで1.5倍(1,816対1,214)、100クライアントで8.9倍(63,247対7,119)の毎秒クエリ数を処理しました。

ノイズの影響はどの程度か

各セルは3回の試行の中央値です。最低値と最高値の試行の差が中央値の1.3%以下だったセルが半数、7%以下だったセルが9割で、最も大きかったのは26%でした(Redis、100,000ベクトル、ef 300、50クライアント)。レポートにはすべての試行を掲載しています。

再現率はインデックスの構築ごとに1回測定しました。100,000ベクトルで各エンジンを独立に3回構築したところ、同じ深度で最大0.013の差がありました。そのため、HotKVの再現率の高さはef 300までは明確で、小さいほうのインデックスのef 500ではビルド間のばらつきの範囲内です。

読み込みとメモリ

それぞれ32接続で読み込んだ場合、999,000ベクトルの読み込みにHotKVは188秒(毎秒5,325件)、Redisは935秒(毎秒1,069件)かかりました。これには、負荷生成プロセスが各ベクトルの整形に費やした時間も含まれます。100,000ベクトルでは15秒対57秒でした。20,000ベクトルでの確認では、RedisはCASありのほうがなしより速く読み込めた(毎秒2,279対1,488ベクトル)ため、これを使用しました。 Redisの読み込みは前の手順で行われ、その際Redisは4つのvCPUに固定され、同じマシンで他のチェックも動いていました。HotKVは128のvCPUで単独で読み込みました。したがってRedisの読み込み時間はその速度の下限であり、同条件での比較ではありません。

999,000ベクトルの読み込み後、HotKVのプロセスは6.77 GB、Redisのプロセスは7.01 GBを使用していました。

ここでRedis 8.10.2を制限しているもの

Redisのベクトルセットは各検索を専用のスレッドで実行しますが、HNSWのコードには固定数のスレッドスロット(Redisのコンパイル時に設定される32)があり、ベクトルの追加はメインスレッドで行われます。私たちの実行では、32クライアント以上で、Redisが稼働させていたのはマシンのvCPUのうち6~30個で、スループットは頭打ちになっていました。HotKVはef 80、100クライアントで約92個のvCPUを稼働させ、スループットはまだ伸び続けていました。これはこのマシン上での各エンジンの振る舞いであり、ベンチマークで設定したものではありません。

制約事項

これらは上記のバージョンと構成についてHotKV Ltdが測定した結果であり、あらゆるRedisのデプロイについて主張するものではありません。

テスト構成

  • 開発ビルド。 コミットc8dafd37はリリース版ではなく開発ビルドです。
  • 1つのデータセット、1台のマシン。 1,536次元のOpenAIの埋め込み、上位10件のみ、float32、コサインです。次元数、データ、ハードウェアが異なれば、倍率も異なる可能性があります。
  • クライアントはマシンを共有。 負荷生成プロセスは別のvCPU上で実行しましたが、メモリシステムとラストレベルキャッシュはサーバーと共有していました。
  • 永続化はオフ。 どちらのサーバーも、スナップショットや追記専用ファイルを書き込みませんでした。

測定していない項目

  • Redisの8ビットモード。 Redisはデフォルトで8ビットに量子化したベクトルを格納し、そのほうがメモリ使用量は少なくなります。私たちはfloat32対float32で比較しました。
  • Redis Query Engine。 RedisはFT.CREATEとFT.SEARCHによるベクトル検索も提供しています。テストしたのはベクトルセットのみなので、この結果はQuery Engineについて何も示していません。
  • Redisの読み込みと再読み込み。 Redisのインデックスは以前の実行でRedisを4つのvCPUに固定して構築し、保存して測定時に再読み込みしたため、Redisの読み込み時間は下限であり、HotKVと同条件では比較できません。20,000件のベクトルでのチェックでは、再読み込みしたインデックスでの検索は新規構築したものより約10%遅かったため、Redisのクエリ数値も同程度低く出ている可能性があります。

試してみる

ベクトル検索はHotKVのプロンプトキャッシュと同じサーバーに組み込まれており、同じベクトルインデックスがセマンティックキャッシュとエージェントメモリを支えています。ベクトル検索はHotKV Cloudのすべてのプランに含まれ、プロンプトキャッシュ、セマンティックキャッシュ、エージェントメモリはPerformanceプラン以上で利用できます。HotKV Cloudで始めるか、お手持ちの埋め込みでベンチマークするには営業チームにご相談ください。

お役に立ちましたか?

記事を共有

会話を続けましょう

コメント

手法について質問がありますか?お使いのハードウェアで異なる結果が出ましたか?わかったことをぜひ共有してください。コメントは審査後に表示されます。

コメントを書く

表示名とコメントは承認後に公開されます。メールアドレスは上記の通知にのみ使用され、公開されることはありません。入力を始めると、Cloudflare Turnstileがスパムをチェックします。 プライバシーの詳細.