1 ビット粗探索 — 設計¶
翻訳について: 正本は英語版です。日本語版が古い場合は英語版を参照してください。
Status: 2.6.2 に向けて実装済みです。粗探索の索引 (第 3 節)、供給者 (第 4 節)、窓の外の席 (第 5 節)、
手がかりの腕の残り (第 6 節)、計測 (第 9 節) は master にあります。
SCHEMA_VERSION は変わらず、実行時の依存も増えません。
窓の外の席は既定で off です。2.6.4 からは手がかりの腕の残りを既定で探しますが、答えられる
粗探索の索引を通す時だけです (第 7 節)。その索引を自動で作るものはありません。窓の外の席が
off で索引が無ければ、同じ類似度の行の並び順まで含めて、返る行はすべて 2.6.1 とビット単位で
同じです。
0. この段階は何か¶
ローカルのベクトル検索は、新しい方から CPERSONA_MAX_MEMORIES 件 (既定 10,000) のレコードを
cosine で順位付けします。その窓より古いレコードは、問いにどれほど近くても、意味では一切
届きません。字句の腕はコーパス全体を探すので、問いと語を共有していれば届き、共有して
いなければ届きません。
後の 2 つの段階がこの隙間を狭めましたが、閉じてはいません。
- Block による到達は、2 つ以上の Block に分かれるすべてのレコードについて、節に相当する Block をコーパス全体で順位付けします (Block による到達)。1 節だけの レコードは Block を持ちません。その 1 つの Block がレコードそのものになるからです。窓の外に あるそうしたレコードは、今も意味では届きません。
- 時間の手がかりは、それが指す期間 (出荷されている
動的検索窓 (Dynamic Retrieval Envelope)) をコーパス全体で探します
(想起のプロセス)。ただしそのベクトル側は、期間内で
最も新しく保存された
CPERSONA_MAX_MEMORIES件しか順位付けしません。大きなストアで長い 期間や曖昧な期間を指すと、期間の残りはベクトル側から外れます。
この段階は 1 つの機構と、その 2 つの使い道を加えます。
- 全レコードの 1 ビット索引。Hamming 距離で走査し、上位の候補を保存済みの float32 ベクトルで並べ直します。
- 窓の外の席 (第 5 節): 索引が見つけた窓の外のレコードを、Block や時間の手がかりが 見つけたものと同じく、答えの横に別枠で置きます。
- 時間の手がかりの残り (第 6 節): 手がかりの期間のうち、ベクトル側の上限を超えた部分を 同じ索引で探します。
2 つの使い道は独立しており、どちらか一方だけを出荷できます。
この段階が主張するのは到達であって、精度ではありません。 今は意味で届かない種類の レコードを、常駐 1 次元 1 ビットの費用で届くようにします。届いたレコードが問いに答えるか どうかは別の計測であり、このページはそれについて何も言いません。このプロジェクトが運用する 環境では、Block による到達を設計した時点でストアは 5,341 件で、窓に収まります。そこでは、 ストアが 10,000 件を超えるまで、この段階は何も変えません。
呼び名について。 ベクトル走査はすでに 2 段で読んでおり (まず (id, embedding)、次に
生き残った行の本文を id で)、コードはその分割を "two phases" と呼んでいます。あれは行の
ペイロードについての分割で、ベクトルの表現についてのこの段階とは関係ありません。このページと、
それが記述するコードは binary coarse search と呼び、もう一方の語を使い回しません。
1. 到達のために窓を広げず、票も入れない理由¶
窓の外へ届く直接のやり方は、窓を広げることです。実際の recall 経路で 237,654 件の文書に 対して測ると、窓を 10,000 から 200,000 にすると、答えが窓の外にある問いでは NDCG@10 が 4.93 点上がり、窓の内にある問いでは 20.19 点下がりました (走査窓の到達範囲と新しさの優遇)。 窓は新しさの事前分布でもあります。最近の答えに小さな競争の場を与えており、広げるとそれが 消えます。
次のやり方は、窓を保ったまま、窓の外の行を融合へもう 1 本の順位リストとして足すことです。 窓自身のリストは厳密に保たれましたが、遠いリストの票が最近の答えを押し出しました。そこで 遠い票の重みを測りました。0 より大きいどの重みでも、近い層は 3.01 点以上下がりました。 損失を生む行は遠い票と字句の票の両方を持っており、1 つの重みは利得と損失を一緒に動かす からです (結果: 遠い票の値段)。 その計測は、次の候補は構造の側にあると述べて終わっています。
この段階は、このプロジェクトがすでに 2 度使った構造の道を取ります。窓の外のレコードは 融合へ票として入れず、答えの横に別枠で置きます。 別枠の席は融合が返したものを何も 押し出さないので、近い層が行を失うことは構造上ありません。それが何を代償にするかは 第 5 節が述べます。
2. 表現¶
各レコードの保存済みベクトルを次元ごとの符号に量子化し (成分が 0 より大きければ 1)、
8 次元を 1 バイトに詰めます。これは Block による到達がすでに使っている量子化で、Hamming
距離も同じ関数で計算します。Block とレコードを 1 つのコード経路が扱います。
モデル自身の座標の符号をとる表現の忠実度は、経験則です。ランダム超平面の恒等式がそのままでは 当てはまらない理由は Block による到達が述べており (Block による到達 §3)、 同じ注意がここにも当てはまります。この設計では、そこから 2 つのことが従います。
- Hamming の走査は候補を選ぶだけです。答えに届きうる候補はすべて、保存済みの float32 ベクトルの cosine で並べ直します。近い窓の走査が順位付けに使うのと同じ量です。
- Hamming の走査が残す候補の数 (
K') は、恒等式でなく計測で決めます (第 9 節)。
3. 粗探索の索引¶
ビットは連続埋め込み索引 (埋め込み索引の連続配置) の隣に置く 派生ファイルに入り、同じコマンドで作られ、同じ方針に従います。バックアップされず、修復も されず、消しても安全で、間違っていれば捨てて作り直します。
| 部分 | 内容 |
|---|---|
| ヘッダ | マジック、形式の版、次元、行数、watermark、連続索引と同じ fingerprint、下の名指しリスト |
ids |
int64[count] |
bits |
uint8[count][dim/8] |
agent_code, project_code, channel_code, source_code |
int32[count]。連続索引とまったく同じ方法で整数化 |
created_at |
19 バイトの ASCII、正準形 |
timestamp |
19 バイトの ASCII。SQLite の datetime() が読んだレコード自身の時刻。読めなければ 19 バイトのゼロ |
行は走査順 (created_at 降順、次に id 昇順) で書くので、ファイル内の位置がそのまま走査上の
位置です。watermark、除外行のリスト、埋め込みの無い行のリストは、連続索引と同じ意味を
持ちます (同 §5)。watermark を
超える行と名指しされた行はその場で読むので、作り直しが遅れたせいでこの経路から見えなくなる
保存済みレコードはありません。
連続索引に配列を足さず、ファイルを分ける理由。 ローダの作りに関係なく成り立つ理由が 2 つあります。
- 既存の索引が使えるままになります。 連続索引に配列を足すと形式の版が上がり、古い版の ファイルは新しいリーダには使えません。索引を作っていたすべての環境が、何も頼んでいないのに、 作り直すまで遅い走査に戻ってしまいます。
- 窓の外への到達に float32 の索引が要りません。 1 次元 1 ビットにする目的は常駐量です。 ファイルを分ければ、1,024 次元で 100 万レコードの常駐費用は 1 行あたり約 190 バイト (ビット 128、id・軸・時刻 62)、合計約 190 MB です。同じファイルにすると、窓の外の席を 有効にする前に、4.1 GB の float32 も持つファイルを作る必要があります。
今のローダについては 3 つ目の理由も成り立ちます。Windows では、ファイルを作り直せるように、 ローダがすべての配列を写像せずメモリへ読み込むので、float32 がビットと一緒に常駐してしまいます。 ファイルを分ける代償は、id・軸の整数コード・作成時刻を 2 回書くこと (1 行あたり約 43 バイト) と、 ファイルごとに watermark を持つことです。後者は安全です。どちらも自分の watermark 以下の行に しか答えないからです。
timestamp は第 6 節のためだけに持ちます。 これは手がかりの期間を測る軸で、ファイルの
並び順の軸ではありません。保存されたタイムスタンプは綴りが混在するので、SQLite はそれを
datetime() で瞬間として比較します。ビルダは datetime() が返す固定幅の値を保存するので、
ファイル上のバイト比較は SQL の比較と同じ比較になります。datetime() が読めないタイムスタンプの
レコードは、SQL と同じくファイルでも、どの期間にも入りません。
4. 供給者の契約¶
2 つの使い道は 1 つの問いを立てます。
この軸、この走査位置、必要ならこの期間の中で、問いのビットに対して Hamming 距離が 最も小さい
K'件のレコードはどれか。
答えはレコード id と距離のリストで、距離、次に走査位置の順に並びます。本文もメタデータも 含みません。
供給者は 2 つあり、同じアルゴリズムを実行します。
- 粗探索の索引。上のとおり。
- ライブのストア。索引が無い、使えない、次元が違う時に使います。保存済みの float32
ベクトルを走査順に、有界なチャンクで読み、同じ関数で量子化し、同じ
K'を残します。
保存済みベクトルの量子化は決定的で、Hamming 距離は整数なので、同じストアに対して 2 つは同じ リストを返します。索引を作っても消しても、recall の費用は変わりますが、返すものは変わり ません。 これはライブのストアに落ちうる読み手すべてに当てはまります。手がかりの腕の既定の 動き方 (第 7 節) だけはライブに落ちません。索引にしか尋ねないので、索引が無ければ残りは 探さず、応答がそう伝えます。連続索引はすでにこの規則に従っており、到達設定の遠いリストもこれを満たすことを 求められました。この段階も同じです。ライブの供給者は大きなストアでは遅く、それが費用の すべてです。索引が無いことは、連続索引の不在と同じく、システムの健全性を読む人が目にする 場所で報告します。
索引は権威ではありません。 軸の整数コードは K' を切る前に走査を絞ります。軸を無視した
索引は、hydrate が落とす行で K' を埋めてしまうからです。索引の義務は、
連続索引と同じく一方向だけです。
索引が差し出す行は、隔離の述語が認めるすべての行を含みます。isolation_where() は唯一の
権威のままで、hydrate がそれを再適用します。
K' はソートでなく計数で選びます。 Hamming 距離は 0 から次元数までの整数なので、上位
K' は距離のヒストグラム 1 つと、切り捨て距離より下の行を残す 1 パスで見つかり、切り捨て
距離での同点は走査位置で分けます。ヒープも全体のソートも要らず、結果は決定的です。
5. 窓の外の席¶
どこを探すか。 走査位置 max(CPERSONA_MAX_MEMORIES, CPERSONA_VECTOR_REACH) から
ストアの終わりまで、つまり recall のどのベクトルリストもまだ順位付けしていないレコードです。
窓自身の行はここでは探しません。ベクトルの腕が低く順位付けした近いレコードは、それを担う腕が
すでに判定しており、それに席を与えると、到達ではなく、より深いベクトル検索になってしまいます。
どう順位付けするか。 供給者は K' 件の候補を返します。それらの保存済み float32 ベクトルを、
隔離と出所の述語を再適用して id で読み、ベクトルの腕がすでに埋め込んだ問いのベクトルとの
cosine で順位付けします。ベクトルの腕が自分の行に課す類似度の下限を下回る候補は落とします。
窓の外のレコードはレコード全体であり、その下限が設定された母集団と同じなので、近いレコードが
順位付けされるために越えるべき基準と同じ基準を課します。cosine の同点は走査位置で分けます。
どう通すか。 Block の予約枠の後ろに 2 つの席を用意し、答えがまだ 持っていないレコードを cosine の順に入れます。時間の手がかりの席と同じく、通常の腕が届いて 品質 gate または autocut が拒んだレコードは対象外です。拒まれた行がこの道で戻ることはありません。 席について品質 gate には問い合わせず、他の行についても gate を変えません。
そこから従うことを、言い繕わずに述べます。
- 融合が返した答えは変わりません。 席は行を足すだけで取り除かないので、最近の答えが 窓の外の答えに押し出されることはありません。これが第 1 節の求める性質です。
- 応答が長くなりえます。 席は Block の予約枠、手がかりの席、伝播の席と同じく
limitの外に あります。応答を抑える件数の検査は、その 2 席の分だけ大きくなります。 - 席は、窓の外の悪いヒットが及ぼしうる損失の上限です。 窓の外のヒットが良いという主張では ありません。席の数は Block の予約枠と同じ 2 に固定し、調整したパラメータではなく保守的な 上限として扱います。理由は Block の予約枠と同じで (Block による到達 §5)、 数を調整するには読み手を使った計測が必要であり、それは精度の段階に属します。
- 席に置かれた行は、レコードの recall 回数に加算しません。 他の別枠の行と同じ理由です。 どの gate もそれを通していないからです。
- 席に置かれた行は出所を示します。
match_reason.signal=far、admission=reservationで、recall trace は予約を独自の種類として記録します。reconstructは席のレコードを、Block の ものと同じく、窓の後ろの独立した item として扱います。
適用されない場面。 ベクトル検索がリモートの構成ではローカル走査が走らないので、量子化する 問いのベクトルが無く、Block による到達と同じく窓の外の席もありません。エピソードは探しません (第 11 節)。
6. 時間の手がかりの残り¶
手がかりの期間は、想起のプロセスが出荷している動的検索窓です。今、時間の手がかりの腕のベクトル側は、タイムスタンプが期間に入るレコードを順位付けしますが、
保存順で最大 CPERSONA_MAX_MEMORIES 件しか読みません。それより多くの埋め込み済みレコードを
持つ期間では残りがベクトル側から外れ、どれが外れるかは、期間ではなく保存された時刻で決まります。
この変更は厳密な部分をそのまま残し、残りだけを探します。
- 期間内のレコードのうち、走査順で最初の
CPERSONA_MAX_MEMORIES位置にあるものは、今と 同じく厳密な cosine で順位付けします。 - 期間内の残りのレコードを、期間を
timestamp列のフィルタとして供給者に渡します。そのK'件の候補を、第 5 節と同じく保存済み float32 ベクトルの cosine で並べ直します。 - 2 つのリストを cosine で併合し (どちらも保存済みベクトルの厳密な cosine で、同じ下限を 課しているので同じ尺度です)、同点は走査位置で分け、手がかりの腕は併合から自分の深さだけを 取ります。
埋め込み済みレコードが CPERSONA_MAX_MEMORIES 件以下の期間では、答えは今とまったく同じです。
残りが空だからです。手がかりが行をどう動かすか、席をどう埋めるか、どう広げ直すかは何も
変わらず、変わるのはベクトル側の候補だけです。
この部分は窓の外の席とは別に CPERSONA_CUE_COARSE_ENABLED で切り替え、どちらか一方だけを出荷できる
ようにします。3 つの動き方は第 7 節にあります。
7. 設定¶
| 設定 | 意味 | 既定 |
|---|---|---|
CPERSONA_FAR_SEATS_ENABLED |
窓の外のレコードのために 2 つの席を用意する。off なら窓の外の走査は走らない | false |
CPERSONA_CUE_COARSE_ENABLED |
手がかりの期間の残りを粗探索の索引で探す | 未設定 (auto) |
CPERSONA_CUE_COARSE_ENABLED は 3 つの動き方を持ちます:
| 値 | 残りの探し方 | 使える索引が無い時 |
|---|---|---|
未設定・空・auto (2.6.4 からの既定) |
粗探索の索引だけで探す | 探さない。recall は false の時と同じで、time_cue.remainder が期間を全部は探していないことを伝える |
true |
索引、またはライブのストアで探す | ライブのストア。見つかるレコードは同じで、費用はストアの大きさとともに増える |
false とそれ以外の値 |
探さない | — |
true を既定にせず 3 つにした理由。 2.6.2 や 2.6.3 で true を設定した運用者は、答えが
索引の有無に左右されないことを前提にしています。true の意味を変えれば、その運用者の答えが
黙って変わります。既定の動き方は、誰も選んでいない値にだけ意味を与えます。ライブのストアを
決して読まないので費用はストアの大きさとともに増えず、索引ができた時点で残りを探します。
「答えられない」とは、供給者がライブに落ちる状態すべてを指します。ファイルが無い、次元が違う、
ファイルが使えない、作成後に埋め込みが消えた行がある、作成後に消えた候補がある、のいずれかです。
判定は recall ごとに行います。time_cue.remainder が付くのは、期間に上限より後ろのレコードが
あり、それを探さなかった時だけです ({"searched": false, "reason": "no_usable_index",
"hint": ...})。そうしたレコードがあるかは、期間を CPERSONA_MAX_MEMORIES の位置から id だけで
1 行読んで判定し、この読み出しは索引が答えなかった時にだけ行います。残りを探した recall や、
期間が上限に収まる recall には何も足しません。trace の段に供給者が記録されるのもその時だけです。
索引は作らず、エージェントに知らせます。 既定の動き方では、recall の範囲が窓の外に
INDEX_MATTERS_ROWS (1,000) 件以上のレコードを持ち、読み込める粗探索の索引が無い時に、
その recall に suggestion が付きます。セッションごとに 1 回 (セッションキーが無ければ
プロセスごとに 1 回) です。契約は update の通知と同じで、言うことが無ければ付かず、品質ゲートが
すでに取ったプールの件数と、キャッシュされたファイルの確認から決めるので、recall に問い合わせを
足しません。中身は、エージェントが伝える message と、fix の呼び出し
check_health(checks=["coarse_index"], fix=true) です。作成は全エージェントのレコードを 1 つの
ファイルに書くので全エージェントへの書き込み権限が要り、決めるのは利用者です。動き方を明示した
運用者には知らせません。
窓の外の席が off で手がかりの動き方が false なら、新しいコードは走りません。何も返さない
走査ではなく、ガードです。窓の外の席の数と
K' は設定ではありません。Block の予約枠や Block の並べ直しの深さと同じく、呼び出し側が
頼むものからは何も導かれないサーバーの方針です。席は 2 に固定し、K' は第 9 節の計測で
決めた 256 です。
CPERSONA_MAX_MEMORIES は意味を保ちます。近い窓であり、それとともに新しさの事前分布でもあって、
窓の外の走査はそこから始まります。
8. 不変条件¶
- 隔離は迂回されません。 索引は第 4 節の一方向の保証のもとで軸の整数コードで絞り、hydrate は
isolation_where()と出所の前方一致フィルタを再適用し、閉じた側に倒れます。 - 近いリストには触れません。 窓の行、そのスコア、その順序、融合が返す行は、どの設定でも 2.6.1 のものです。
- ライブのストアが答えうるところでは、索引は答えを変えません。 同じストアに対して、 索引とライブのストアは同じ候補を返します。手がかりの腕の既定の動き方では索引だけが 供給者で、索引が答えられない時は残りを探さず、応答がそう伝えます。
- 順序は全順序で、明示されています。 Hamming の同点も cosine の同点も走査位置
(
created_at降順、id昇順) で分け、ソートがたまたま残した順には頼りません。 - hydrate は閾値でなく件数で切ります。 id で読むのは
K'件の候補だけで、本文を具体化するのは 席に置く行だけです。 - 幅の違うベクトルは読み飛ばし、決して reshape しません。 ビルダは連続索引のビルダと同じく 幅の混在したストアでは作成を断り、ライブの供給者は幅の違う行を読み飛ばします。
- 増え方は有界です。 応答が持つのは最大で
limitと、すべての種類の別枠の席の合計で、 そこに窓の外の 2 席が加わります。 - 既定値では、窓に収まるストアにとって何も変わりません。 behaviour golden で固定します。
行も、応答の欄も、trace の段も変わりません。窓を超えて索引の無いストアでは、返る行は同じで、
time_cue.remainderとセッションごとに 1 回のsuggestionが付くことがあります。
9. 計測¶
計測は、走査のこれまでの最適化と同じく、ハーネスと一緒にコミットします。
benchmarks/measurements/results-binary-coarse-search.md と、それを再導出するスクリプトです。
費用は、大きさを変えた合成ストアで測ります。索引経由、ライブの供給者経由、同じ位置の厳密な float32 走査のそれぞれでの窓の外の走査のレイテンシ、Hamming の走査と並べ直しで読むバイト数、 ピークメモリ、索引の作成時間とサイズです。粗探索が厳密な走査より遅くなるストアの大きさを 報告します。その手前には、索引が節約する以上に費用がかかる大きさがあるからです。
計測の結果 (結果): 同じ行を SQLite から読む厳密な走査に対しては、粗探索はどの大きさでも 速く、窓の外 2,000 件から 990,000 件まで勝ちました (最大で 197 ms 対 15.9 秒)。連続配置の float32 索引の厳密な走査に対しては、計測したどの大きさでも遅くなりました (197 ms 対 55 ms)。その 4.1 GB の 索引がメモリに載っている機械での値です。1 ビットの索引が買うのは常駐量 (100 万レコードで 190 MB、 窓の外の順位付け 1 回のピークメモリ 59 MB) であってレイテンシではなく、これはスケールの計画が連続 配置の索引とこの索引の間に引いた分担のとおりです。粗探索の索引が無いと、その大きさではライブの 供給者に 1 回 約 16 秒かかります。
K'。 近似は 1 か所にしかありません。どの窓の外のレコードが Hamming の走査を生き残って
並べ直しに進むかです。K' が窓の外のレコード数に等しければ、窓の外の席は同じ位置の厳密な
float32 走査とまったく同じように埋まり、計測はこの恒等から始めます。
物差しは席ごとの一致率です。厳密な走査なら席に入るレコードのうち、粗探索でも席に入った 割合を、問いについて平均します。2 席のうち 1 件が違えば、失敗ではなく 2 分の 1 と数えます。 基準は 95% です (第 10 節の C)。取りこぼしは、届きえた窓の外のレコードから席を奪うだけで、 正しい行の代わりに誤った行を置くことはありません。席は何も押し出さないからです。
基準を満たす K' はストアが大きくなるほど増えると見込んでいました。大きなストアほど、偶然に問いのビットの
近くに来るレコードが多いからです。そこで曲線は複数の大きさで取ります。10 万件と 100 万件の
合成ストア、そして走査窓の計測が使った 237,654 文書のストアで、実行前に固定した K' の格子の
上で測り、K' は、その中で最も大きいストアで基準を満たす最小の値、またはストアの大きさに
応じた最小の規則とします。出発点の 1,000 は出発点であって、結果ではありませんでした。
計測の結果: K' = 256 (結果)。8 つのセルすべて (10 万・237,654・100 万レコード、最大の
ストアでは 2 種類の問い、両方の融合) で基準を満たし、最も低いセルは 97.3% でした。128 では 3 つの
セルが基準を割りました。候補 1 件ごとに float32 の読み出しの費用がかかり、1,024 次元で 4 KB、256 件
なら 1 回の想起で約 1 MB です。ストアとともに値が増えるという見込みは当たりませんでした。同じ問いに
対して、237,654 レコードのストアの方が 100 万レコードのストアより多くを必要としました。その下に
足したレコードは別のコーパスのもので、問いのビットの近くにはほとんど来なかったからです。K' を
決めるのは、Hamming 距離で問いの近くに競合するレコードの数であって、行数ではありません。
精度はここでは測りません。 窓の外の席が答えを良くするという主張には、実際に窓の外の層を 持つストアと事前に固定した規則が必要で、さらに、席の代わりに同じ数の行を足しただけの対照に 勝たなければなりません。時間の手がかりが課された規則と同じです。そうした計測ができるまで、 この段階は到達として報告します。
公開しているベンチマークの数値は、設定が off なら動きえません (不変条件 8)。on にした時、 ストアが窓に収まるベンチマークには窓の外のレコードが無いので、席は何も置きません。収まらない ものは、仮定せずに測ります。
10. 保守担当者が決めること¶
- A. 置き場所 — 決定: 独立したファイルを連続索引の隣に置きます。理由は第 3 節のとおりです。 スキーマは変わりません。
- B. 索引をいつ作るか — 決定: 既存の作成コマンドで作ります。
python -m cpersona.vector_index buildが連続索引の隣に粗探索の索引を書きます。watermark により、 作成の遅れは正しさでなくレイテンシの問題になるので、この段階は自動作成を加えません。 2.6.4 からは、作成が必要になったことを健全性チェックが言います。check_healthのcoarse_indexチェックは、設定がファイルを読み、あるエージェントが窓の外に記録を持つ間、 そのファイルを報告し、fix=trueで作ります。所見は他と同じく配送され、それを受けてどうするかは 読む側に残します。ファイルを読むのが手がかりの腕の既定の動き方だけなら、ファイルが無くても 使えなくても recall の時間は増えないので、所見は警告でなく印なし (info) にします。2.6.4 からは recall 自身も第 7 節のsuggestionを運ぶので、エージェントは健全性を問わなくても記憶の 増加に気づけます。作成はそれでも自動ではありません。 - C. 許容する近似 — 決定: 厳密な走査との席ごとの一致率 95% 以上を、測った中で最も大きい ストアで満たすこと (第 9 節)。
- D. 有効化 — 決定: 切り替えと固定の上限。 窓の外の席は既定で off で、Block の予約枠と 同じ 2 に固定し、読み手を使った計測が変える理由を示すまで変えません。手がかりの腕の残りは 2.6.4 から、第 7 節の索引だけの動き方で既定オンです。足すのは到達だけで、それも索引を通す時 だけです。索引が無い時の費用は、そのことを伝えるかを決める id だけの読み出しがすべてです。
- E.
CPERSONA_MAX_MEMORIES— 決定: 変えません。 近い窓であり、新しさの事前分布です。 窓の外の走査はそこが終わるところ、CPERSONA_VECTOR_REACHの方が先ならそこが終わるところから始まります。 - F. 窓の外の席の下限 — 決定: ベクトルの腕の類似度の下限です。同じ recall の近いレコードが
満たした下限 (cascade では閾値そのもの、
rrfとrsfでは閾値にCPERSONA_RRF_THRESHOLD_FACTORを 掛けた値) を使います。Block に下限が無いのは短い区間が別の尺度で点を取るからで、窓の外のレコードは そうではありません。 - G. 設定の名前 — 決定: 第 7 節のとおり
CPERSONA_FAR_SEATS_ENABLEDとCPERSONA_CUE_COARSE_ENABLEDです。
11. 目標としないこと¶
- 2 つ目の言語。 走査は numpy です。コンパイルされた索引サービスは、numpy の走査が遅すぎる 大きさを超えたストアのための後の段階であり、第 4 節の供給者の契約を置き換えるのでなく、 それを実装する形になります。
- HNSW や IVF のような近似最近傍の構造。
- エピソード。 件数がはるかに少なく窓に収まります。レコードの索引が確立した後に別途 決めます。
- リモートのベクトル経路。 それ自身が答えます。
CPERSONA_VECTOR_REACHの遠い票のリスト。変わりません。窓の外の席はそれが終わるところから 始まります。- 精度の主張 (第 9 節)。