701ae503
tangwang
docs
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
|
# 模块扩展规范(向量化 / 重排 可插拔设计)
本文档定义**向量化(embedding)**与**重排(rerank)**模块的扩展规范,保证新增模型/推理引擎时框架统一、配置统一、可插拔。新增 Qwen3-Reranker-0.6B(vLLM)等模块时需遵循本规范。
**相关文档**:
- 调用方(Provider 选择、HTTP 客户端):[PROVIDER_ARCHITECTURE.md](./PROVIDER_ARCHITECTURE.md)
- 向量化使用说明:[embeddings/README.md](../embeddings/README.md)、[向量化模块和API说明文档.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` 下结构一致:
```yaml
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` 一致):
```python
# 行为契约(不强制继承,实现以下方法即可)
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` 顶层配置区分:顶层为搜索侧融合参数,此处为服务/后端配置):
```yaml
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 逻辑迁移或封装为 `BGERerankerBackend`
- `reranker/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)` 得到实例,再对外提供同一 `/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/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 推理)时,建议步骤:
1. **实现协议**
- 在 `reranker/backends/qwen3_vllm.py` 中实现类(如 `Qwen3VLLMReranker`),提供 `score_with_meta(query, docs, normalize) -> (scores, meta)`。
- 推理逻辑参考 [Qwen3-Reranker-0.6B](https://huggingface.co/Qwen/Qwen3-Reranker-0.6B) 的 vLLM 用法(format_instruction、process_inputs、compute_logits、yes/no token 等),输出与 `docs` 等长且顺序一致的 scores。
2. **配置**
- 在 `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`。
3. **注册**
- 在 `reranker/backends/__init__.py` 的 `get_rerank_backend(name, config)` 中增加 `"qwen3_vllm"` 分支,实例化 `Qwen3VLLMReranker` 并传入 config。
4. **服务启动**
- 若尚未重构:可暂时在 `reranker/server.py` 中根据 `RERANK_BACKEND` 或 config 选择加载 `BGEReranker` 或 `Qwen3VLLMReranker`。
- 若已引入 `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.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`),便于部署与多环境。
|