MODULE_EXTENSION_SPEC.md
11.8 KB
模块扩展规范(向量化 / 重排 可插拔设计)
本文档定义向量化(embedding)与重排(rerank)模块的扩展规范,保证新增模型/推理引擎时框架统一、配置统一、可插拔。新增 Qwen3-Reranker-0.6B(vLLM)等模块时需遵循本规范。
相关文档:
- 调用方(Provider 选择、HTTP 客户端):PROVIDER_ARCHITECTURE.md
- 向量化使用说明:embeddings/README.md、向量化模块和API说明文档.md
1. 设计原则
| 原则 | 说明 |
|---|---|
| 接口契约 | 所有同类型后端实现同一协议(Protocol),调用方只依赖协议不依赖具体实现。 |
| 单一配置源 | 能力类型、后端类型、后端参数均来自 config/config.yaml 的 services 块,环境变量可覆盖。 |
| 服务与后端分离 | 调用方通过 Provider(如 HttpRerankProvider)访问服务;服务内部通过后端实现(如 BGE、Qwen3-vLLM)完成推理。新增“提供者”时区分:是新增一种调用方式(新 Provider)还是新增一种推理实现(新 Backend)。 |
| 可插拔后端 | 重排/向量化服务在启动时根据配置加载一个后端;新增后端 = 实现协议 + 在配置与工厂中注册,不改服务入口代码。 |
2. 配置体系(统一结构)
2.1 配置来源与优先级
- 主配置:
config/config.yaml下的services.<capability> - 覆盖:环境变量(如
RERANKER_SERVICE_URL、RERANK_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.py→create_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.yaml 的 services.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_vllm、RERANKER_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 逻辑迁移或封装为BGERerankerBackendreranker/backends/qwen3_vllm.py:新增 Qwen3-Reranker-0.6B + vLLM 实现
- 服务启动:
reranker/server.py在startup中读取services.rerank.backend与services.rerank.backends.<name>,调用get_rerank_backend(backend, cfg)得到实例,再对外提供同一/rerankAPI。
3.5 重排 HTTP API 契约(不变)
无论后端是 BGE 还是 Qwen3-vLLM,对外接口保持一致,便于调用方与运维统一:
- POST /rerank
- Request:
{ "query": string, "docs": [string], "normalize": optional bool } - Response:
{ "scores": [float], "meta": object }
- Request:
- GET /health
- Response:
{ "status": "ok"|"unavailable", "model_loaded": bool, "model": string, "backend": string }
- Response:
4. 向量化(Embedding)模块规范
4.1 调用链
- 调用方:通过
providers.create_embedding_provider()得到 HTTP 客户端,请求POST /embed/text、POST /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/URL:
config/config.yaml→services.embedding,环境变量EMBEDDING_SERVICE_URL。 - 服务内:
embeddings/config.py中已有TEXT_*、IMAGE_*、USE_CLIP_AS_SERVICE、CLIP_AS_SERVICE_SERVER;若未来支持多种文本/图像后端,建议在services.embedding.backend/services.embedding.backends中统一,与重排结构对齐。
5. 新增后端清单(以 Qwen3-Reranker-0.6B + vLLM 为例)
按本规范新增「重排后端」Qwen3-Reranker-0.6B(vLLM 推理)时,建议步骤:
实现协议
- 在
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。
- 在
配置
- 在
config/config.yaml的services.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。
- 在
注册
- 在
reranker/backends/__init__.py的get_rerank_backend(name, config)中增加"qwen3_vllm"分支,实例化Qwen3VLLMReranker并传入 config。
- 在
服务启动
- 若尚未重构:可暂时在
reranker/server.py中根据RERANK_BACKEND或 config 选择加载BGEReranker或Qwen3VLLMReranker。 - 若已引入
get_rerank_backend():reranker/server.py启动时统一调用get_rerank_backend(backend_name, backend_cfg)得到实例。
- 若尚未重构:可暂时在
调用方
- 无需修改:
providers/rerank.py仍为 HTTP,search/rerank_client.py仍调用同一/rerank接口;仅部署时启动使用 Qwen3-vLLM 后端的 reranker 服务即可。
- 无需修改:
文档与依赖
- 在
reranker/README.md或docs/中说明 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.py中RerankerConfig(PORT、MODEL_NAME、BATCH_SIZE 等)仅被 BGE 服务使用。扩展多后端时,建议:- 保留该文件作为默认/兜底(仅当未配置
services.rerank.backend时使用),或 - 将 BGE 的默认值迁移到
config.yaml的services.rerank.backends.bge,reranker/config.py只读环境变量与 YAML,不再硬编码模型名。
- 保留该文件作为默认/兜底(仅当未配置
- embeddings:
embeddings/config.py的EmbeddingConfig已包含文本/图片及 clip-as-service 开关,与services.embedding的 URL 分离(URL 由services_config管)。后续若增加多种文本/图像后端,可同样在services.embedding.backends中增加条目,与重排对齐。 - 环境变量:所有能力均支持通过环境变量覆盖(如
RERANKER_SERVICE_URL、RERANK_BACKEND、EMBEDDING_SERVICE_URL),便于部署与多环境。