Skip to content

[experimental] Add SINDI IP U12 + E5M7 storage - #1864

Merged
sre-ci-robot merged 1 commit into
zilliztech:mainfrom
alexanderguzhva:sindi_ip_u12_e5m7
Oct 20, 2026
Merged

sre-ci-robot merged 1 commit into
zilliztech:mainfrom
alexanderguzhva:sindi_ip_u12_e5m7

Conversation

@alexanderguzhva

@alexanderguzhva alexanderguzhva commented Sep 30, 2026 •

Copy link
Copy Markdown
Collaborator

This is an experimental PR, which tests U12 instead of U16 and E5M7 instead of FP16 for SINDI IP. It trades the QPS & recall for the smaller database size (~25% less for MSMARCO / SPLADE).

This PR is based on top of #1856, so the refinement is also enabled.

The full results are https://zilliverse.feishu.cn/wiki/KLwZw50Lmi0zCYk1R0pctgp5nug?sheet=LNmWIz

Some short results for M7i 8c32b machine with clang-22 compiler:

Dataset k U16/FP16 QPS Recall@k U12/E5M7 QPS Recall@k E5M7 / FP16 QPS Index saving
msmarco_splade 10 530.02 0.999054 545.26 0.993209 1.029× 24.44%
msmarco_splade 100 379.80 0.999428 407.90 0.995815 1.074× 24.44%
fever_splade 10 380.67 0.999145 380.37 0.994659 0.999× 24.45%
fever_splade 100 308.57 0.999301 315.14 0.995414 1.021× 24.45%
hotpotqa_splade 10 388.74 0.999284 381.81 0.994988 0.982× 24.40%
hotpotqa_splade 100 319.97 0.999385 278.33 0.995616 0.870× 24.40%
nq_splade 10 1,106.81 0.998928 1,084.48 0.994699 0.980× 24.44%
nq_splade 100 778.65 0.998928 809.57 0.995785 1.040× 24.44%

@mergify

mergify Bot commented Sep 30, 2026

Copy link
Copy Markdown

@alexanderguzhva 🔍 Important: PR Classification Needed!

For efficient project management and a seamless review process, it's essential to classify your PR correctly. Here's how:

  1. If you're fixing a bug, label it as kind/bug.
  2. For small tweaks (less than 20 lines without altering any functionality), please use kind/improvement.
  3. Significant changes that don't modify existing functionalities should be tagged as kind/enhancement.
  4. Adjusting APIs or changing functionality? Go with kind/feature.

For any PR outside the kind/improvement category, ensure you link to the associated issue using the format: “issue: #”.

Thanks for your efforts and contribution to the community!.

@alexanderguzhva

Copy link
Copy Markdown
Collaborator Author

/kind improvement

@mergify

mergify Bot commented Oct 10, 2026

Copy link
Copy Markdown

@alexanderguzhva e2e jenkins job failed, comment /run-e2e can trigger the job again.

@alexanderguzhva

Copy link
Copy Markdown
Collaborator Author

wait for #1871

@alexanderguzhva
alexanderguzhva force-pushed the sindi_ip_u12_e5m7 branch 2 times, most recently from 39c91e9 to 0eefdde Compare October 16, 2026 17:02
@mergify mergify Bot added the ci-passed label Oct 16, 2026
Comment thread src/index/sparse/sindi_inverted_index.h Outdated

if constexpr (AllowIncremental) {
if (packed_ready_) {
expand_for_add();

@chasingegg chasingegg Oct 19, 2026 •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Keep growing-index additions incremental

Every subsequent packed Add unpacks all existing postings, then repacks the entire index while holding the CC write lock. Repeated small inserts therefore become quadratic. With 65,536 rows and 32 values per row, single-row additions averaged 52 ms for E5M7 versus 0.49 ms for FP16. Preserve an appendable representation or defer packing until sealing.
We can also simply disable this configuration (quant_type="e5m7") for growing indexes.

@alexanderguzhva alexanderguzhva Oct 19, 2026 •

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added a needed speedup

"Invalid ground-truth score order");
previous = score;
if (id < 0) {
Check(base.rows.size() < k && j >= base.rows.size() && score == 0, "Invalid truth padding");

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Accept padding when sparse queries have fewer than k matches

Padding is now accepted only when the entire corpus contains fewer than k documents. Sparse queries can have fewer than k positive matches in a larger corpus. A reproduction with 100 documents, k=10, and one match aborts with Invalid truth padding. Accept trailing sentinels independently of corpus size.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

}

if (refine_) {
rebuild_refinement_seek();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a similar pre-existing issue with refine=true, introduced in #1856. Even with quant_type="fp16", every incremental Add calls rebuild_refinement_seek(), which rebuilds the seek metadata for all dimensions/windows and validates every existing posting while the CC write lock is held. Repeated small inserts therefore have quadratic cumulative cost and block concurrent searches during each rebuild.

In a local test on this PR with 65,536 existing rows and 32 nonzeros per row, 20 single-row additions averaged 14.29 ms with refine=true versus 0.30 ms with refine=false. We can also disable refine=true for growing indexes until the seek metadata is maintained incrementally and validation during Add is limited to new postings.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

introduced #1902

std::vector<uint8_t> ids(sindi::packed12_bytes(count), 0), vals(ids.size(), 0);
max_scores_per_dim_.assign(this->nr_inner_dims_, 0);
// Sequential pair ownership avoids shared-nibble races at term boundaries.
for (size_t dim = 0; dim < this->nr_inner_dims_; ++dim) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-blocking optimization suggestion; we can leave this to subsequent PRs.

On the full msmarco_splade dataset (8,841,823 rows), with 8 build workers and refine=false, U12+E5M7 took 28.66 s to build versus 10.22 s for U16+FP16. The existing log timestamps suggest roughly 10.3 s in the serial validation/counting phase before parallel construction and 7.6 s in the final packing phase (approximate phase timings, including nearby setup/cleanup).

We could merge the validation and posting-count checks into one parallel row scan, potentially reusing scan_rows_for_build(). For packing, partition work by complete pairs of 12-bit entries (3 bytes per pair in each buffer), rather than by dimension, so workers never share an output byte; handle the odd tail separately. This would allow parallel packing without changing the storage format. The sealed-build path could also reuse the already-computed maxima of the quantized values instead of recomputing max_scores_per_dim_ here.

@alexanderguzhva alexanderguzhva Oct 19, 2026 •

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will do in a follow up, if you don't mind. The candidate is available

@chasingegg chasingegg Oct 20, 2026 •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no problem, we can improve the build time/build memory usage in the next prs

@mergify mergify Bot removed the ci-passed label Oct 19, 2026
@alexanderguzhva
alexanderguzhva force-pushed the sindi_ip_u12_e5m7 branch 2 times, most recently from ca5ee8d to 037a350 Compare October 19, 2026 20:34
Signed-off-by: Alexandr Guzhva <alexanderguzhva@gmail.com>
@alexanderguzhva

Copy link
Copy Markdown
Collaborator Author

issue: #1903

if constexpr (is_bm25_u8) {
if constexpr (is_ip) {
const size_t count = plists_dim_offsets_span_.back();
std::vector<uint8_t> ids(sindi::packed12_bytes(count), 0), vals(ids.size(), 0);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-blocking follow-up: reduce peak memory during sealed packing. We can leave this to a subsequent PR.

The complete packed output is allocated while the typed posting arrays are still retained. For N postings, U12+E5M7 temporarily holds about 4N bytes of U16/FP16 input plus 3N bytes of packed output (7N total, versus 3N after packing). The existing BM25 U4 path has the same overlap: about 5N bytes for U12+U4 or 5.5N for U16+U4, and it also builds temporary seek metadata before releasing the typed arrays. These are posting-buffer estimates, excluding input vectors and other metadata, not measured peak RSS.

A follow-up could construct the final packed buffers directly once sizing and codec setup are known (BM25 needs the histogram/LUT pass first), or use a construction layout that allows bounded chunks to be converted and their source storage released incrementally. As a smaller improvement, BM25 could release its typed posting arrays immediately after packing, before building the temporary seek metadata.

@chasingegg chasingegg left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/lgtm

@sre-ci-robot

Copy link
Copy Markdown
Collaborator

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: alexanderguzhva, chasingegg

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:
  • OWNERS [alexanderguzhva,chasingegg]

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@sre-ci-robot
sre-ci-robot merged commit 07d8726 into zilliztech:main Oct 20, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants