Skip to content

[WIP] Implement HNSW_RABITQ#1400

Open
CLiqing wants to merge 3 commits intozilliztech:mainfrom
CLiqing:hnsw_rbq
Open

[WIP] Implement HNSW_RABITQ#1400
CLiqing wants to merge 3 commits intozilliztech:mainfrom
CLiqing:hnsw_rbq

Conversation

@CLiqing
Copy link
Contributor

@CLiqing CLiqing commented Dec 4, 2025

Implement HNSW_RABITQ

kind/feature

@mergify
Copy link

mergify bot commented Dec 4, 2025

@CLiqing 🔍 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!.

continue;
}
}

Copy link
Collaborator

Choose a reason for hiding this comment

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

Please confirm this — it looks like it should be an else?

return Status::success;
}
}

Copy link
Collaborator

Choose a reason for hiding this comment

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

same here

// Create IndexIVFRaBitQWrapper with METRIC_L2 (data will be normalized for cosine)
expected<std::unique_ptr<knowhere::IndexIVFRaBitQWrapper>> ivfrabitq_result;
if (is_cosine) {
// For cosine: use normalized data for IVF_RABITQ, L2 metric
Copy link
Collaborator

Choose a reason for hiding this comment

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

What’s the reason for this?

knowhere::feature::MMAP | knowhere::feature::MV | knowhere::feature::EMB_LIST)
KNOWHERE_SIMPLE_REGISTER_DENSE_FLOAT_ALL_GLOBAL(HNSW_RABITQ, BaseFaissRegularIndexHNSWRaBitQNodeTemplate,
knowhere::feature::MMAP | knowhere::feature::MV |
knowhere::feature::EMB_LIST)
Copy link
Collaborator

Choose a reason for hiding this comment

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

I didn’t see the implementation of EMB_LIST — it might need to be added.

if (wrapper_storage != nullptr) {
auto* ivfrabitq_idx = wrapper_storage->get_ivfrabitq_index();
if (ivfrabitq_idx != nullptr) {
ivfrabitq_idx->qb = qb;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Modification behavior shouldn’t occur within the const search interface.

@foxspy
Copy link
Collaborator

foxspy commented Dec 4, 2025

Please add some unit tests to ensure the logic runs correctly.

if (hnsw_index != nullptr && hnsw_index->storage != nullptr) {
// The storage was serialized as the internal faiss::Index
// Now wrap it back in IndexHNSWRaBitQWrapper (specialized for HNSW)
std::unique_ptr<faiss::Index> storage_index(hnsw_index->storage);
Copy link
Collaborator

Choose a reason for hiding this comment

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

move here?

if (hnsw_index != nullptr) {
auto* wrapper_storage = dynamic_cast<knowhere::IndexIVFRaBitQWrapper*>(hnsw_index->storage);
if (wrapper_storage != nullptr && wrapper_storage->index != nullptr) {
// Temporarily replace storage with the internal index for serialization
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please add a comment here explaining why “Temporarily replace“ is needed.


// RaBitQ Params
constexpr const char* RABITQ_QUERY_BITS = "rbq_bits_query";
constexpr const char* RBQ_QUERY_NBITS = "rbq_query_nbits"; // for HNSW_RABITQ
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why is it necessary to create a new one instead of directly using rbq_bits_query?

knowhere::feature::MMAP | knowhere::feature::MV |
knowhere::feature::EMB_LIST)
KNOWHERE_SIMPLE_REGISTER_DENSE_INT_GLOBAL(HNSW_RABITQ, BaseFaissRegularIndexHNSWRaBitQNodeTemplate,
knowhere::feature::MMAP | knowhere::feature::MV | knowhere::feature::EMB_LIST)
Copy link
Collaborator

Choose a reason for hiding this comment

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

https://github.com/zilliztech/knowhere/blob/main/include/knowhere/index/index_table.h
Newly added indexes need to be registered in the IndexTable.

@sre-ci-robot
Copy link
Collaborator

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: CLiqing, marcelo-cjl

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:

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

Signed-off-by: Cliqing <2208529306@qq.com>
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.

4 participants