refactor: make Reranker stateless with std::variant value semantics (…#471
refactor: make Reranker stateless with std::variant value semantics (…#471Cuiyus wants to merge 8 commits into
Conversation
…libaba#461) Replace class hierarchy (Reranker/ScoreBasedReranker/RrfReranker/ WeightedReranker/CallbackReranker) with std::variant<RrfParams, WeightedParams, CallbackParams> value type and a stateless free function reranker::rerank(). Key changes: - reranker.h: define RerankParams variant + reranker::rerank() API - query.h: MultiQuery::reranker (shared_ptr) -> MultiQuery::rerank (value) - schema.h: add CollectionSchema::get_field_ptr() returning FieldSchema::Ptr - collection.cc: push field lookup to caller, pass vector<FieldSchema::Ptr> - c_api: remove opaque zvec_reranker_t, add zvec_multi_query_set_rerank_* - python binding: expose _RrfParams/_WeightedParams/_CallbackParams + setters - python layer: WeightedReRanker(list[float]), remove Python rerank logic - all tests updated to new interface Benefits: - Thread-safe by design: no mutable state, safe to share across threads - Collection-decoupled: no bind_schema(), field info passed as parameter - Simpler lifecycle: value semantics, no shared_ptr management Closes alibaba#461
5a02f13 to
af54e77
Compare
After the reranker stateless refactor the C++ MultiQuery rerank strategy uses a std::variant with a default value, so the implicit 'reranker required' validation no longer triggered. Restore the check in QueryExecutor._execute_multi_query so that a hybrid (multi-query) request without a reranker raises ValueError.
| return tl::make_unexpected( | ||
| Status::InvalidArgument("WeightedReranker: field '", field.name(), | ||
| "' has no vector index params")); | ||
| // Non-vector fields (e.g., FTS/BM25): use IP-like normalization |
There was a problem hiding this comment.
需要保留用index_type()判断fts的逻辑,避免后续添加其他检索方式走到这里发现不了
| "' has no vector index params")); | ||
| // Non-vector fields (e.g., FTS/BM25): use IP-like normalization | ||
| // that maps positive scores to (0.5, 1.0). | ||
| return 0.5 + std::atan(score) / M_PI; |
There was a problem hiding this comment.
done. 好几处comment 都因为amend 提交被回滚了...
| # SubQuery default of 10 to ensure sufficient candidates for reranking. | ||
| _DEFAULT_NUM_CANDIDATES = 10 | ||
| for sub in multi_query.queries: | ||
| sub.num_candidates = max(ctx.topk, _DEFAULT_NUM_CANDIDATES) |
There was a problem hiding this comment.
需要允许用户指定比topk大的num_candidates
There was a problem hiding this comment.
python 层的query 暂未透出num_candidates。
理想情况下,python 接口中的topk(include_vec & filter) 归属于 subQuery,可适配单路&多路 Query场景。
但现阶段topk 与 query参数并列,调整会有breaking change。
若透出num_candidates,则 topk & topn & num_candidates 三个参数 都有召回数量的含义,担心会给用户带来confuse。
此外,多向量场景每一路召回数量不一致,rerank打分的公平性会被每一路召回数量影响。
个人建议先不透出num_candidates 。 @zhourrr 你觉得呢?
| search_queries.reserve(query.queries.size()); | ||
| field_names.reserve(query.queries.size()); | ||
| struct PendingQuery { | ||
| std::string field_name; |
There was a problem hiding this comment.
field_name没用到?继续用std::vector<SearchQuery>就可以?
| Re-ranked document list. | ||
| """ | ||
| return None # noqa: RET501 | ||
| ... |
There was a problem hiding this comment.
去掉abstruct,基类默认实现为raise NotImplementedError ,这样qwen/sentence不用再重复实现了
| // Public: Rerank execution API (stateless free function) | ||
| // =========================================================================== | ||
|
|
||
| namespace reranker { |
There was a problem hiding this comment.
为啥有些在zvec有些在zvec::reranker中?区分的考虑是什么?
| int rank_constant_; | ||
| /// RRF (Reciprocal Rank Fusion) parameters. | ||
| /// Score formula: 1 / (rank_constant + rank + 1) | ||
| struct RrfParams { |
There was a problem hiding this comment.
这些定义都带上Reranker吧,XxxRerankerParams,不然有些泛。或者都放到reranker ns中,这样不带也没有歧义
Replace dynamic_cast nullptr check with explicit IndexType::FTS check and map FTS/BM25 positive scores to (0.0, 1.0) via 2*atan(score)/pi.
…lify usages Move RrfParams, WeightedParams, CallbackParams and RerankParams into the zvec::reranker namespace, and add explicit reranker:: qualification at all usage sites outside the reranker module (query.h, python/c bindings, tests).
…archQuery> directly
…#461)
Replace class hierarchy (Reranker/ScoreBasedReranker/RrfReranker/ WeightedReranker/CallbackReranker) with std::variant<RrfParams, WeightedParams, CallbackParams> value type and a stateless free function reranker::rerank().
Key changes:
Benefits:
Closes #461