fix: bge-m3 1024d向量维度 + save兼容list + search_by_vector + 修复_log.recall

This commit is contained in:
小唯 A06
2026-05-27 02:33:07 +08:00
parent 981b837361
commit 38abc1cab6
5 changed files with 1078 additions and 537 deletions
File diff suppressed because one or more lines are too long
+504 -498
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1 +1 @@
{"model_name": "moka-ai/m3e-base", "doc_count": 498, "vector_dim": 768, "index_type": "FlatIP", "updated_at": "2026-05-26T16:15:26.247609"}
{"model_name": "bge-m3", "doc_count": 504, "updated_at": "2026-05-27T02:32:31.802561"}
+504 -35
View File
File diff suppressed because one or more lines are too long
+63 -3
View File
@@ -143,9 +143,14 @@ class SBertIndex:
with open(path, 'w', encoding='utf-8') as f:
json.dump(meta, f, ensure_ascii=False)
# 保存向量(NumPy 格式)
# 保存向量(NumPy 格式或 Python list)
if self.vectors:
vectors_list = [v.tolist() for v in self.vectors]
vectors_list = []
for v in self.vectors:
if hasattr(v, 'tolist'):
vectors_list.append(v.tolist())
else:
vectors_list.append(list(v)) # 已经是 list
with open(vectors_path, 'w', encoding='utf-8') as f:
for v in vectors_list:
f.write(json.dumps(v, ensure_ascii=False) + '\n')
@@ -252,9 +257,64 @@ class SentenceTransformersRecall:
self._needs_rebuild = False # 增量添加后索引已更新,不需要重建
def search(self, query: str, top_k: int = 10) -> list[tuple[str, float, dict]]:
"""语义搜索"""
"""语义搜索(文本查询,内部用 m3e-base 编码)"""
return self.index.search(query, top_k)
def search_by_vector(self, query_vector: np.ndarray, top_k: int = 10) -> list[tuple[str, float, dict]]:
"""向量搜索(使用预计算向量,避免重复编码)
query_vector: 预计算好的查询向量(1024d,来自 bge-m3)
返回: [(doc_id, cosine_score, doc_dict)]
"""
import numpy as np
if not self.index.vectors or not self.index.documents:
return []
# 归一化查询向量(传入向量已是归一化bge-m3,这里确保格式正确)
q = np.array(query_vector, dtype=np.float32)
q = q / (np.linalg.norm(q) + 1e-8)
vectors_matrix = np.array(self.index.vectors) # (n, 1024)
# cosine similarity = dot product(查询和向量都已归一化)
scores = np.dot(vectors_matrix, q).astype(np.float64)
top_indices = np.argsort(scores)[::-1][:top_k]
results = []
for idx in top_indices:
score = float(scores[idx])
if score < 0.0: # 余弦相似度可为负,但归一化后范围 [0,1]
score = max(0.0, score)
results.append((
self.index.documents[idx]['id'],
score,
self.index.documents[idx]
))
return results
def index_documents_with_vectors(self, docs: list[dict], vectors: list[np.ndarray]):
"""全量重建索引(使用预计算向量,来自 bge-m3 1024d)
每次 commit 调用:从 JSONLShardStore 读取全部 docs,
用 bge-m3 API 编码为 1024d 向量,传入此方法存储。
"""
self.index.documents = []
self.index.vectors = []
for doc, vec in zip(docs, vectors):
text = doc.get('content', '') + ' ' + ' '.join(str(f) for f in doc.get('facts', []))
self.index.documents.append({
'id': doc.get('id', ''),
'text': text,
'facts': doc.get('facts', []),
'category': doc.get('category', 'unknown'),
'timestamp': doc.get('timestamp', ''),
})
self.index.vectors.append(np.array(vec)) # 统一存为 numpy 数组
self.index.model_name = "bge-m3" # 存储的是 bge-m3 1024d 向量
self.index.save()
self._needs_rebuild = False
def _append_to_disk(self, docs: list[dict], vectors: list[np.ndarray]):
"""增量持久化:追加文档和向量到磁盘(不覆盖现有数据)