MODULE_EXTENSION_SPEC.md 11.8 KB

模块扩展规范(向量化 / 重排 可插拔设计)

本文档定义向量化(embedding)重排(rerank)模块的扩展规范,保证新增模型/推理引擎时框架统一、配置统一、可插拔。新增 Qwen3-Reranker-0.6B(vLLM)等模块时需遵循本规范。

相关文档


1. 设计原则

原则 说明
接口契约 所有同类型后端实现同一协议(Protocol),调用方只依赖协议不依赖具体实现。
单一配置源 能力类型、后端类型、后端参数均来自 config/config.yamlservices 块,环境变量可覆盖。
服务与后端分离 调用方通过 Provider(如 HttpRerankProvider)访问服务服务内部通过后端实现(如 BGE、Qwen3-vLLM)完成推理。新增“提供者”时区分:是新增一种调用方式(新 Provider)还是新增一种推理实现(新 Backend)。
可插拔后端 重排/向量化服务在启动时根据配置加载一个后端;新增后端 = 实现协议 + 在配置与工厂中注册,不改服务入口代码。

2. 配置体系(统一结构)

2.1 配置来源与优先级

  • 主配置config/config.yaml 下的 services.<capability>
  • 覆盖:环境变量(如 RERANKER_SERVICE_URLRERANK_BACKEND)> config 文件
  • 解析config/services_config.py 提供 get_*_config(),各模块从该处读取,避免散落多处。

2.2 能力块通用结构

每种能力(translation / embedding / rerank)在 services 下结构一致:

services:
  <capability>:
    provider: "http"          # 调用方使用的提供者:http | direct | vllm 等
    base_url: "http://..."   # 对外服务 URL(provider=http 时)
    providers:
      http: { base_url: "...", ... }
      direct: { ... }
      vllm: { ... }
    # 以下为「服务内部后端」配置(仅当本能力由本仓库启动的服务承载时使用)
    backend: "bge"           # 可选:服务内加载的后端类型
    backends:
      bge: { model_name: "...", batch_size: 64, ... }
      qwen3_vllm: { model_name: "Qwen/Qwen3-Reranker-0.6B", ... }
  • provider:调用方(搜索 API、索引等)如何访问该能力(如 HTTP 调 base_url)。
  • backend / backends:当该能力由本仓库内的服务进程提供时,该进程内应加载哪个后端及参数(如 reranker 服务内用 BGE 还是 Qwen3-vLLM)。

3. 重排(Rerank)模块规范

3.1 调用链

  • 调用方search/rerank_client.pycreate_rerank_provider()HttpRerankProvider.rerank(query, docs, timeout_sec)
  • 协议:HTTP POST <base>/rerank,请求体 { "query": str, "docs": [str] },响应体 { "scores": [float], "meta": dict },scores 与 docs 一一对应。
  • 服务实现reranker/server.py(FastAPI)在启动时加载一个重排后端,对 /rerank 的请求用该后端计算分数。

因此:

  • 新增一种“调用方式”(如 gRPC):在 providers/rerank.py 增加新 Provider 类,并在 create_rerank_provider() 中按 provider 选择。
  • 新增一种“推理实现”(如 Qwen3-vLLM):在 reranker 服务内实现重排后端协议并注册,服务通过配置选择后端。

3.2 重排后端协议(服务内)

所有在 reranker 服务内加载的后端必须实现以下接口(与当前 BGEReranker 一致):

# 行为契约(不强制继承,实现以下方法即可)
class RerankBackendProtocol(Protocol):
    def score_with_meta(
        self,
        query: str,
        docs: List[str],
        normalize: bool = True,
    ) -> Tuple[List[float], Dict[str, Any]]:
        """
        输入:
          - query: 搜索查询字符串
          - docs: 文档列表,与返回的 scores 一一对应
          - normalize: 是否对分数做归一化(如 sigmoid)
        输出:
          - scores: 与 docs 等长的分数列表,顺序一致
          - meta: 至少含 input_docs, usable_docs, unique_docs, elapsed_ms 等,供日志与调试
        """
        ...
  • 顺序:返回的 scores[i] 必须对应 docs[i]
  • 空/无效:对无法打分的 doc 可填 0.0,并在 meta 中说明。
  • 去重:后端可对 docs 去重再推理以省算力,但返回的 scores 必须按原始 docs 顺序与长度还原。

3.3 重排服务配置项(建议)

config/config.yamlservices.rerank 下建议结构(与现有 rerank 顶层配置区分:顶层为搜索侧融合参数,此处为服务/后端配置):

services:
  rerank:
    provider: "http"
    base_url: "http://127.0.0.1:6007"
    providers:
      http:
        base_url: "http://127.0.0.1:6007"
        service_url: "http://127.0.0.1:6007/rerank"
    # 服务内后端(reranker 进程启动时读取)
    backend: "bge"   # bge | qwen3_vllm
    backends:
      bge:
        model_name: "BAAI/bge-reranker-v2-m3"
        device: null
        use_fp16: true
        batch_size: 64
        max_length: 512
        cache_dir: "./model_cache"
        enable_warmup: true
      qwen3_vllm:
        model_name: "Qwen/Qwen3-Reranker-0.6B"
        engine: "vllm"
        max_model_len: 8192
        tensor_parallel_size: 1
        gpu_memory_utilization: 0.8
        instruction: "Given a web search query, retrieve relevant passages that answer the query"
  • 环境变量示例:RERANK_BACKEND=qwen3_vllmRERANKER_SERVICE_URL=http://127.0.0.1:6007

3.4 重排后端目录与注册

  • 推荐目录reranker/backends/
    • reranker/backends/__init__.py:导出 get_rerank_backend(name, config) -> 实现 RerankBackendProtocol 的实例
    • reranker/backends/bge.py:现有 BGE 逻辑迁移或封装为 BGERerankerBackend
    • reranker/backends/qwen3_vllm.py:新增 Qwen3-Reranker-0.6B + vLLM 实现
  • 服务启动reranker/server.pystartup 中读取 services.rerank.backendservices.rerank.backends.<name>,调用 get_rerank_backend(backend, cfg) 得到实例,再对外提供同一 /rerank API。

3.5 重排 HTTP API 契约(不变)

无论后端是 BGE 还是 Qwen3-vLLM,对外接口保持一致,便于调用方与运维统一:

  • POST /rerank
    • Request: { "query": string, "docs": [string], "normalize": optional bool }
    • Response: { "scores": [float], "meta": object }
  • GET /health
    • Response: { "status": "ok"|"unavailable", "model_loaded": bool, "model": string, "backend": string }

4. 向量化(Embedding)模块规范

4.1 调用链

  • 调用方:通过 providers.create_embedding_provider() 得到 HTTP 客户端,请求 POST /embed/textPOST /embed/image
  • 服务实现embeddings/server.py 在启动时按配置加载文本后端图片后端,二者可独立选择。

4.2 向量化后端协议(服务内)

  • 文本:与当前 BgeTextModel 一致,需支持 encode_batch(texts, batch_size, device) -> List[ndarray],元素与 texts 一一对应,失败可为 None。
  • 图片:已定义 embeddings/protocols.ImageEncoderProtocol
    • encode_image_urls(urls: List[str], batch_size: Optional[int]) -> List[Optional[np.ndarray]]
    • urls 等长,失败位置为 None。

新增文本/图片后端时实现对应协议即可;服务通过配置选择后端(如 USE_CLIP_AS_SERVICE 选 clip-as-service 或本地 CN-CLIP)。

4.3 向量化配置(现有与扩展)

  • Provider/URLconfig/config.yamlservices.embedding,环境变量 EMBEDDING_SERVICE_URL
  • 服务内embeddings/config.py 中已有 TEXT_*IMAGE_*USE_CLIP_AS_SERVICECLIP_AS_SERVICE_SERVER;若未来支持多种文本/图像后端,建议在 services.embedding.backend / services.embedding.backends 中统一,与重排结构对齐。

5. 新增后端清单(以 Qwen3-Reranker-0.6B + vLLM 为例)

按本规范新增「重排后端」Qwen3-Reranker-0.6B(vLLM 推理)时,建议步骤:

  1. 实现协议

    • reranker/backends/qwen3_vllm.py 中实现类(如 Qwen3VLLMReranker),提供 score_with_meta(query, docs, normalize) -> (scores, meta)
    • 推理逻辑参考 Qwen3-Reranker-0.6B 的 vLLM 用法(format_instruction、process_inputs、compute_logits、yes/no token 等),输出与 docs 等长且顺序一致的 scores。
  2. 配置

    • config/config.yamlservices.rerank.backends 下增加 qwen3_vllm 块(model_name、engine、max_model_len、tensor_parallel_size、gpu_memory_utilization、instruction 等)。
    • config/services_config.py 或 reranker 专用 config 中增加对 backend / backends 的读取;环境变量支持 RERANK_BACKEND=qwen3_vllm
  3. 注册

    • reranker/backends/__init__.pyget_rerank_backend(name, config) 中增加 "qwen3_vllm" 分支,实例化 Qwen3VLLMReranker 并传入 config。
  4. 服务启动

    • 若尚未重构:可暂时在 reranker/server.py 中根据 RERANK_BACKEND 或 config 选择加载 BGERerankerQwen3VLLMReranker
    • 若已引入 get_rerank_backend()reranker/server.py 启动时统一调用 get_rerank_backend(backend_name, backend_cfg) 得到实例。
  5. 调用方

    • 无需修改:providers/rerank.py 仍为 HTTP,search/rerank_client.py 仍调用同一 /rerank 接口;仅部署时启动使用 Qwen3-vLLM 后端的 reranker 服务即可。
  6. 文档与依赖

    • reranker/README.mddocs/ 中说明 Qwen3-vLLM 的依赖(vllm>=0.8.5、transformers 等)、显存建议、与 BGE 的对比。
    • 若 vLLM 为可选依赖,在 requirements_ml.txt 或可选 extra 中声明。

6. 小结表

层次 配置键 重排 向量化(文本/图)
调用方 services.<capability>.provider http http
调用方 services.<capability>.providers.http.base_url 6007 6005
服务内 services.<capability>.backend bge / qwen3_vllm (当前在 embeddings/config.py)
服务内 services.<capability>.backends.<name> 模型名、batch、vLLM 参数等 模型名、device 等
协议 重排 score_with_meta(query, docs, normalize)
协议 向量化 文本: encode_batch;图: ImageEncoderProtocol

遵循上述规范后,新增 Qwen3-Reranker-0.6B 或其它重排/向量化后端时,只需实现协议、在配置与工厂中注册,即可与现有 BGE/CLIP 等并列切换,保持框架统一与可插拔。


7. 与现有配置文件的兼容说明

  • reranker:当前 reranker/config.pyRerankerConfig(PORT、MODEL_NAME、BATCH_SIZE 等)仅被 BGE 服务使用。扩展多后端时,建议:
    • 保留该文件作为默认/兜底(仅当未配置 services.rerank.backend 时使用),或
    • 将 BGE 的默认值迁移到 config.yamlservices.rerank.backends.bgereranker/config.py 只读环境变量与 YAML,不再硬编码模型名。
  • embeddingsembeddings/config.pyEmbeddingConfig 已包含文本/图片及 clip-as-service 开关,与 services.embedding 的 URL 分离(URL 由 services_config 管)。后续若增加多种文本/图像后端,可同样在 services.embedding.backends 中增加条目,与重排对齐。
  • 环境变量:所有能力均支持通过环境变量覆盖(如 RERANKER_SERVICE_URLRERANK_BACKENDEMBEDDING_SERVICE_URL),便于部署与多环境。