Skip to content

feat: migrate multi-vector query and reranker logic to C++#405

Open
chinaux wants to merge 16 commits into
alibaba:mainfrom
chinaux:feat/refact_py_to_cpp
Open

feat: migrate multi-vector query and reranker logic to C++#405
chinaux wants to merge 16 commits into
alibaba:mainfrom
chinaux:feat/refact_py_to_cpp

Conversation

@chinaux
Copy link
Copy Markdown
Collaborator

@chinaux chinaux commented May 14, 2026

refact:

  • Add Reranker base class with RrfReRanker and WeightedReRanker implementations
  • Add Collection::MultiQuery interface for multi-vector queries with reranking
  • Add MultiVectorQuery struct in doc.h with forward declaration for Reranker
  • Add C API bindings for reranker and MultiQuery (zvec_reranker_, zvec_multi_vector_query_, zvec_collection_multi_query)
  • Add Python binding for reranker classes with py::function bridge for callback

Comment thread src/include/zvec/db/collection.h Outdated
Comment thread src/db/collection.cc
Comment thread src/include/zvec/db/doc.h Outdated
Comment thread src/include/zvec/db/doc.h Outdated
Comment thread src/include/zvec/db/doc.h Outdated
Comment thread src/include/zvec/db/reranker.h Outdated
Comment thread src/db/reranker/reranker.cc
Comment thread src/binding/c/c_api.cc
auto *mvq = reinterpret_cast<zvec::MultiVectorQuery *>(query);
auto *reranker_ptr =
reinterpret_cast<zvec::Reranker::Ptr *>(reranker);
mvq->reranker = *reranker_ptr;
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.

这里是不是内存泄漏了?mvq 的 reranker copy 了这个 shared pointer。但是用户传入的shared pointer 还存在 heap 上,所以用户得手动 free(reranker) 才能释放这个 shared pointer。但 .h 文件里注释说这个函数 take ownership,用户可能会认为不需要释放

Comment thread src/include/zvec/c_api.h
* @return zvec_error_code_t Error code
*
* @note The returned array is allocated by the library and should be freed
* using zvec_free() when no longer needed. The individual string pointers
Copy link
Copy Markdown
Collaborator

@zhourrr zhourrr May 15, 2026

Choose a reason for hiding this comment

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

这句话给我看的有点懵😳

Image

Comment thread src/include/zvec/db/query.h Outdated
Comment thread src/include/zvec/db/query.h Outdated
chinaux added 12 commits May 25, 2026 10:47
- Add Reranker base class with RrfReRanker and WeightedReRanker implementations
- Add Collection::MultiQuery interface for multi-vector queries with reranking
- Add MultiVectorQuery struct in doc.h with forward declaration for Reranker
- Add C API bindings for reranker and MultiQuery (zvec_reranker_*, zvec_multi_vector_query_*, zvec_collection_multi_query)
- Add Python binding for reranker classes with py::function bridge for callback
- Validate duplicate field names in multi-vector queries (C++ and Python consistent)
- Remove TODO comment about concurrent execution (SQLEngine is not thread-safe)
- Update collection.h MultiQuery doc comment from concurrently to sequentially
- Add C++ collection tests (6 MultiQuery test cases)
- Add C API tests (reranker functions + multi_vector_query end-to-end)
- Implement Python test cases (11 previously skipped tests now active)
- Simplify Python query_executor validation for unified duplicate field check
- Register _SubVectorQuery in pybind11 with from_vector_query() factory
- Convert _VectorQuery to _SubVectorQuery in MultiVectorQueryExecutor
- Relax RRF/Weighted score assertion tolerance from 1e-10 to 1e-6
- Fix WeightedReRanker test metric to IP (matching HnswIndexParam default)
@zhourrr zhourrr force-pushed the feat/refact_py_to_cpp branch from 9f92f1b to 3d46458 Compare May 25, 2026 02:47
@zhourrr zhourrr requested a review from egolearner May 25, 2026 05:44
Comment thread src/include/zvec/db/reranker.h Outdated
Comment thread src/include/zvec/db/reranker.h Outdated
//! relevance scores. The RRF score for a document at rank r is:
//! score = 1 / (k + r + 1)
//! where k is the rank constant.
class RrfReRanker : public Reranker {
Copy link
Copy Markdown
Collaborator

@egolearner egolearner May 26, 2026

Choose a reason for hiding this comment

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

命名不一致,RrfReRanker/Reranker,rerank作为一个单词,cpp使用RrfReranker/Reranker更合理。Python为了兼容,可以保持之前的命名。
@Cuiyus 觉得呢?

Comment thread src/include/zvec/db/reranker.h Outdated
WeightedReRanker(MetricType metric = MetricType::L2,
const std::map<std::string, double> &weights = {});

MetricType metric() const {
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.

metric不应该放这里。加权时,可能每个向量的距离类型都不一样,metric放这里要求所有向量的距离类型必须一致。

//! Callback-based re-ranker for cross-language bridging.
//!
//! Wraps a user-provided callback (e.g., a Python callable) as a Reranker.
//! When the callback is a Python function, GIL must be managed by the caller.
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.

用Python传callback这个方式跑通了吗?

Comment thread src/db/reranker/reranker.cc Outdated

// ==================== RrfReRanker ====================

DocPtrList RrfReRanker::rerank(
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.

reranker应该只提供rescore的接口,打分的逻辑对于rrf/weighted完全一样,放外面更合适。可以参考一下内部gateway的实现。

Comment thread src/include/zvec/db/query.h Outdated
//! Multi-vector query structure for querying multiple vector fields
//! with optional re-ranking of combined results.

struct SubVectorQuery {
Copy link
Copy Markdown
Collaborator

@egolearner egolearner May 26, 2026

Choose a reason for hiding this comment

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

SubVectorQuery没必要加?MultiVectorQuery可以直接用std::vector<VectorQuery>?

  1. 调用的时候显式设置output_fields_为vector{}就不会召回任何字段了,
  2. 复用topk_作为num_candidates_语义。
  3. 在多向量检索时,显然filter也需要支持,因此复用VectorQuery能够直接支持filter。

chinaux added 3 commits May 27, 2026 20:31
- import Callable from collections.abc instead of typing (UP035)
- remove redundant quotes around MetricType annotations (UP037)
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.

3 participants