Skip to content

[diskann-quantization] Add SphericalQ 3-bit support and AVX2 kernel - #1474

Open
xinyuwen2 wants to merge 4 commits into
mainfrom
wxy/3_bit_kernel_01
Open

xinyuwen2 wants to merge 4 commits into
mainfrom
wxy/3_bit_kernel_01

Conversation

@xinyuwen2

@xinyuwen2 xinyuwen2 commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor
  • Does this PR have a descriptive title that could go in our release notes?
  • Does this PR add any new dependencies?
  • Does this PR modify any existing APIs?
  • Is the change to the API backwards compatible?
  • Should this result in any changes to our documentation, either updating existing docs or adding new ones?

Reference Issues/PRs

What does this implement/fix? Briefly explain your changes.

Adds SphericalQ3 support and an AVX2 inner-product kernel for full-precision queries against densely packed 3-bit codes. The kernel uses four accumulators for all dimensions, with bounded tail loads and no padding requirement.
The change includes compression, distance dispatch, serialization, existing in-memory provider and benchmark registration, shared correctness tests, and codegen inspection entry points.
The motivation is to provide another memory/accuracy tradeoff. Compared with PQ using two dimensions per chunk, SphericalQ3 achieves similar recall and broadly comparable end-to-end latency while reducing query-process memory by approximately 11–17% in the experiments below. Recall differences range from −0.740 to +0.028 percentage points.

Any other comments?

Dataset Estimator Build time (s) Latency (ms/query) Recall@100 Query memory (MiB)
BIGANN PQ 37.415 12.430 91.850% 90.8
BIGANN SphericalQ2 36.847 12.896 86.230% 65.3
BIGANN SphericalQ3 37.457 12.638 91.260% 80.7
BIGANN SphericalQ4 38.710 12.434 91.560% 95.9
BIGANN FP 35.924 12.757 91.780% 517.4
MSMARCO-FBV8rc1 PQ 45.243 11.915 96.580% 195.3
MSMARCO-FBV8rc1 SphericalQ2 44.571 12.037 90.980% 139.0
MSMARCO-FBV8rc1 SphericalQ3 45.859 11.905 96.070% 169.5
MSMARCO-FBV8rc1 SphericalQ4 48.545 11.696 96.410% 200.0
MSMARCO-FBV8rc1 FP 42.725 11.914 96.490% 1048.8
Enron PQ 52.109 12.771 92.567% 261.5
Enron SphericalQ2 51.098 12.859 90.391% 166.9
Enron SphericalQ3 53.699 12.817 92.436% 216.5
Enron SphericalQ4 58.259 12.760 92.540% 266.5
Enron FP 48.505 12.790 92.593% 857.6
OpenAI-embedding-1M PQ 94.206 14.130 98.685% 1063.2
OpenAI-embedding-1M SphericalQ2 89.946 11.900 98.654% 697.0
OpenAI-embedding-1M SphericalQ3 99.966 12.214 98.674% 880.0
OpenAI-embedding-1M SphericalQ4 119.334 13.005 98.678% 1063.1
OpenAI-embedding-1M FP 79.924 16.628 98.666% 6184.4
Wikipedia-Cohere PQ 62.899 12.775 92.578% 542.4
Wikipedia-Cohere SphericalQ2 60.379 12.466 92.082% 362.4
Wikipedia-Cohere SphericalQ3 65.066 12.444 92.627% 453.9
Wikipedia-Cohere SphericalQ4 74.238 12.614 92.639% 545.5
Wikipedia-Cohere FP 55.282 14.137 92.641% 3103.1

@xinyuwen2
xinyuwen2 requested review from a team and a balanced review from Copilot October 9, 2026 13:59
@xinyuwen2
xinyuwen2 marked this pull request as draft October 9, 2026 14:00

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 Needs a closer look

The new unsafe architecture-specific SIMD kernel and broad dispatch integration warrant final human validation.

0 open findings

What changed in this PR

Adds end-to-end SphericalQ 3-bit support, including optimized AVX2 distance computation.

Changes:

  • Adds 3-bit compression, dispatch, serialization, and provider support.
  • Implements a bounded-tail AVX2 inner-product kernel.
  • Registers 3-bit benchmarks and expands correctness coverage.
File Description
diskann-quantization/​src/​spherical/​vectors.rs Adds 3-bit distance tests and metadata-aware references.
diskann-quantization/​src/​spherical/​quantizer.rs Enables 3-bit compression.
diskann-quantization/​src/​spherical/​iface.rs Adds dispatch, plans, and serialization support.
diskann-quantization/​src/​spherical/​__codegen/​x86_64.rs Adds 3-bit codegen inspection entry points.
diskann-quantization/​src/​bits/​distances.rs Implements and tests the AVX2 kernel.
diskann-providers/​src/​model/​graph/​provider/​async_/​inmem/​spherical.rs Enables 3-bit in-memory stores.
diskann-benchmark/​src/​inputs/​exhaustive.rs Accepts compatible 3-bit benchmark queries.
diskann-benchmark/​src/​index/​inmem/​spherical.rs Registers 3-bit graph benchmarks.
diskann-benchmark/​src/​exhaustive/​spherical.rs Registers 3-bit exhaustive benchmarks.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@codecov-commenter

Codecov Comments Bot (codecov-commenter) commented Oct 9, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 85.93750% with 27 lines in your changes missing coverage. Please review.
✅ Project coverage is 92.07%. Comparing base (2739203) to head (bc784b6).
⚠️ Report is 7 commits behind head on main.

Files with missing lines Patch % Lines
...ann-quantization/src/spherical/__codegen/x86_64.rs 0.00% 25 Missing ⚠️
diskann-benchmark/src/index/inmem/spherical.rs 88.88% 1 Missing ⚠️
diskann-quantization/src/spherical/iface.rs 95.45% 1 Missing ⚠️

❌ Your patch status has failed because the patch coverage (85.93%) is below the target coverage (90.00%). You can increase the patch coverage or adjust the target coverage.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff            @@
##             main    #1474     +/-   ##
=========================================
  Coverage   92.07%   92.07%             
=========================================
  Files         586      591      +5     
  Lines      119997   122384   +2387     
=========================================
+ Hits       110488   112690   +2202     
- Misses       9509     9694    +185     
Flag Coverage Δ
miri 92.07% <85.93%> (+<0.01%) ⬆️
unittests 92.02% <85.93%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
diskann-benchmark/src/exhaustive/spherical.rs 93.51% <100.00%> (+0.02%) ⬆️
diskann-benchmark/src/inputs/exhaustive.rs 59.13% <100.00%> (ø)
...src/model/graph/provider/async_/inmem/spherical.rs 93.76% <100.00%> (+0.16%) ⬆️
diskann-quantization/src/bits/distances.rs 99.51% <100.00%> (+0.01%) ⬆️
diskann-quantization/src/spherical/quantizer.rs 98.30% <100.00%> (+0.10%) ⬆️
diskann-quantization/src/spherical/vectors.rs 99.11% <100.00%> (+0.03%) ⬆️
diskann-benchmark/src/index/inmem/spherical.rs 53.94% <88.88%> (+0.81%) ⬆️
diskann-quantization/src/spherical/iface.rs 91.21% <95.45%> (-0.48%) ⬇️
...ann-quantization/src/spherical/__codegen/x86_64.rs 0.00% <0.00%> (ø)

... and 22 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@hildebrandmw

Copy link
Copy Markdown
Contributor

Just did a quick glance through of the perf numbers - something seems off. This is saying that the index build times for PQ are comparable to spherical? This definitely should not be the case - spherical builds should be significantly faster.

@xinyuwen2

Copy link
Copy Markdown
Contributor Author

Just did a quick glance through of the perf numbers - something seems off. This is saying that the index build times for PQ are comparable to spherical? This definitely should not be the case - spherical builds should be significantly faster.

Yes SphericalQ quantizer training is significantly faster than PQ. The earlier “build time” included graph construction, which obscured this difference.

Wikipedia-Cohere, 1M × 768; same 50K training sample, 16 encoding threads, median of three runs:

Stage PQ (2 dim/chunk) SphericalQ3
Quantizer training 2.315 s 0.045 s
Full-dataset encoding, including I/O 5.019 s 12.141 s

PQ’s encoder is currently better optimized: it uses transposed codebooks and batched SIMD, while SphericalQ3 encodes each vector separately and searches for its scaling factor.

I'll try to improve it, it does seem weird that SphericalQ has same or even worse build time than PQ.

@xinyuwen2
xinyuwen2 force-pushed the wxy/3_bit_kernel_01 branch from 4ce63c7 to 4f3fa48 Compare October 19, 2026 07:26
@xinyuwen2
xinyuwen2 marked this pull request as ready for review October 19, 2026 07:52
Implement packed 3-bit inner products and enable spherical quantization, serialization, and existing provider/benchmark paths. Reuse shared distance tests across bit widths and architectures, including long-vector tails and stored-metadata references. Add L2, inner-product, and cosine codegen entry points without new dependencies.
@xinyuwen2
xinyuwen2 force-pushed the wxy/3_bit_kernel_01 branch from 4f3fa48 to 19eab8a Compare October 20, 2026 05:34

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks - there's some clean-up work to do, particularly around serialization. If you don't need serialization for this current line of work, can we leave it off?

Otherwise, we'll need to refactor deserialization at least to allow callers to control which bit widths they wish to support.

Comment thread diskann-quantization/src/bits/distances.rs Outdated
// Full //
//////////

fn test_full_distance_tails<const NBITS: usize>(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

What is this test covering that isn't already covered in test_full-distance?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The additional coverage was explicit misalignment, longer vectors, and non-integer query values. Folded those cases into the existing test_full_distance helper and removed the separate tails helper.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I don't think this additional coverage is needed.

  1. Miri will already allocated base byte vectors at strange alignments - and Miri is really the only situation that would catch unannotated unaligned loads since x86 and aarch64 are fine with unaligned loads and so will happen to work.
  2. What additional coverage is given by longer vectors? Longer runs take significant time under Miri. We need only exercise enough of the implementation that the various unrolling bounds are hit. If the current upper bound is insufficient, then we should use more precise, architecture dependent upper bounds like raw bit distances.
  3. Also, what additional coverage is provided by using non-integer values for these tests?

@xinyuwen2 xinyuwen2 Oct 22, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thank you! So

  1. alignment checking is left to Miri.
  2. Longer vectors make no sense since current dimension bounds already cover 32/16/8-element boundaries and tail paths.
  3. Non-integer values can be used to verify numerical precision. However, since there are no explicit precision requirements or specific issues to reproduce, there is no need to have the additional coverage.

Removed additional coverage.

Comment thread diskann-quantization/src/bits/distances.rs Outdated
Comment thread diskann-quantization/src/spherical/iface.rs Outdated
Comment thread diskann-quantization/src/spherical/iface.rs Outdated
Comment thread diskann-quantization/src/spherical/vectors.rs Outdated
Inline the V3 kernel, reuse architecture dispatch, and consolidate distance tests. Downcast 3-bit V4 computers to V3 and preserve the generic deserializer support set. Restore independent reference formulas with targeted 3-bit rounding tolerances.

Validation: quantization tests with flatbuffers/codegen, spherical provider tests, baseline distance tests, cargo fmt --all, and workspace Clippy with warnings denied.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants