Skip to content

fix: respect PQ num_bits for numpy codebooks#7586

Open
ddupg wants to merge 2 commits into
lance-format:mainfrom
ddupg:codex/ddu-257-pq-codebook-num-bits
Open

fix: respect PQ num_bits for numpy codebooks#7586
ddupg wants to merge 2 commits into
lance-format:mainfrom
ddupg:codex/ddu-257-pq-codebook-num-bits

Conversation

@ddupg

@ddupg ddupg commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Summary

  • validate numpy PQ codebooks against 2 ** num_bits instead of always requiring 256 centroids
  • update the pq_codebook docstring to describe the num_bits-dependent shape
  • extend the existing PQ codebook test to cover 4-bit numpy codebooks and the mismatched-shape error

Reason

Dataset.create_index(..., index_type="IVF_PQ", num_bits=4, pq_codebook=<numpy array>) should accept a codebook with 16 centroids per sub-vector. The Python wrapper already exposes num_bits, and the Rust PQ implementation supports 4-bit and 8-bit PQ, but the numpy validation path was still hard-coded to the 8-bit shape with 256 centroids. This rejected a valid 4-bit user-supplied codebook before it reached the Rust layer.

Validation

  • uv run --frozen --python 3.12 pytest python/tests/test_vector_index.py::test_index_with_pq_codebook python/tests/test_vector_index.py::test_index_with_pq_codebook_rejects_wrong_num_bits_shape
  • uv run --frozen --python 3.12 ruff format --check --diff python/lance/dataset.py python/tests/test_vector_index.py
  • uv run --frozen --python 3.12 ruff check python/lance/dataset.py python/tests/test_vector_index.py
  • git diff --check

Local lint note

  • uv run --frozen --python 3.12 make lint was attempted. Ruff passed, but pyright failed in this local environment because optional imports such as tensorflow and torch are not installed.

@github-actions github-actions Bot added A-python Python bindings bug Something isn't working labels Jul 2, 2026
@ddupg ddupg marked this pull request as ready for review July 2, 2026 13:51
@wjones127 wjones127 self-assigned this Jul 2, 2026
@wjones127 wjones127 self-requested a review July 2, 2026 15:51
validate_vector_index(dataset, "vector", refine_factor=10, pass_threshold=0.99)


def test_index_with_pq_codebook_rejects_wrong_num_bits_shape(tmp_path):

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.

praise: thanks for adding a test for the error message.

"index_kwargs,num_centroids,pass_threshold",
[
pytest.param({}, 256, 0.99, id="default_num_bits"),
pytest.param({"num_bits": 4}, 16, 0.5, id="four_bit"),

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.

question: why the 50% recall threshold here? Seems rather low.

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.

Good point. 50% wasn't a meaningful threshold here since the codebook is random. I split out the 4-bit case to check nbits == 4 and that queries run. This also matches the Rust 4-bit PQ tests, which don't assert recall today.

@ddupg ddupg force-pushed the codex/ddu-257-pq-codebook-num-bits branch from 1d620b4 to 5ae8390 Compare July 3, 2026 02:15
@ddupg ddupg force-pushed the codex/ddu-257-pq-codebook-num-bits branch from 5ae8390 to 55f8c59 Compare July 3, 2026 02:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-python Python bindings bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants