Spaces:
Sleeping
Sleeping
Commit ·
538d976
1
Parent(s): f48746c
fix: rebuild BM25 index from Qdrant if pkl not found
Browse files- Dockerfile +0 -3
- src/vector_store.py +29 -0
Dockerfile
CHANGED
|
@@ -16,9 +16,6 @@ COPY src/ ./src/
|
|
| 16 |
COPY static/ ./static/
|
| 17 |
COPY api.py .
|
| 18 |
|
| 19 |
-
# Download bm25_index.pkl từ HF Spaces repo
|
| 20 |
-
RUN python -c "from huggingface_hub import hf_hub_download; hf_hub_download(repo_id='thaidinhz1/rag-vietnamese', repo_type='space', filename='bm25_index.pkl', local_dir='.')"
|
| 21 |
-
|
| 22 |
# Model sẽ được download tự động lần đầu chạy
|
| 23 |
|
| 24 |
# Qdrant storage và BM25 index mount từ volume
|
|
|
|
| 16 |
COPY static/ ./static/
|
| 17 |
COPY api.py .
|
| 18 |
|
|
|
|
|
|
|
|
|
|
| 19 |
# Model sẽ được download tự động lần đầu chạy
|
| 20 |
|
| 21 |
# Qdrant storage và BM25 index mount từ volume
|
src/vector_store.py
CHANGED
|
@@ -75,7 +75,36 @@ def add_chunks(chunks: list[dict]):
|
|
| 75 |
print(f"Đã lưu {len(chunks)} chunks vào Qdrant + BM25")
|
| 76 |
|
| 77 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 78 |
def _load_bm25():
|
|
|
|
|
|
|
| 79 |
with open(BM25_PATH, "rb") as f:
|
| 80 |
return pickle.load(f)
|
| 81 |
|
|
|
|
| 75 |
print(f"Đã lưu {len(chunks)} chunks vào Qdrant + BM25")
|
| 76 |
|
| 77 |
|
| 78 |
+
def _build_bm25_from_qdrant() -> dict:
|
| 79 |
+
"""Rebuild BM25 index từ Qdrant nếu file pkl không tồn tại."""
|
| 80 |
+
print("BM25 index không tìm thấy, đang rebuild từ Qdrant...")
|
| 81 |
+
client = get_client()
|
| 82 |
+
texts, metadatas = [], []
|
| 83 |
+
offset = None
|
| 84 |
+
while True:
|
| 85 |
+
result, next_offset = client.scroll(
|
| 86 |
+
collection_name=COLLECTION_NAME,
|
| 87 |
+
limit=100, offset=offset,
|
| 88 |
+
with_payload=True, with_vectors=False,
|
| 89 |
+
)
|
| 90 |
+
for p in result:
|
| 91 |
+
texts.append(p.payload.get("text", ""))
|
| 92 |
+
metadatas.append({k: v for k, v in p.payload.items() if k != "text"})
|
| 93 |
+
if next_offset is None:
|
| 94 |
+
break
|
| 95 |
+
offset = next_offset
|
| 96 |
+
tokenized = [_tokenize_vi(t) for t in texts]
|
| 97 |
+
bm25 = BM25Okapi(tokenized)
|
| 98 |
+
data = {"bm25": bm25, "texts": texts, "metadatas": metadatas}
|
| 99 |
+
with open(BM25_PATH, "wb") as f:
|
| 100 |
+
pickle.dump(data, f)
|
| 101 |
+
print(f"Rebuild xong: {len(texts)} chunks.")
|
| 102 |
+
return data
|
| 103 |
+
|
| 104 |
+
|
| 105 |
def _load_bm25():
|
| 106 |
+
if not Path(BM25_PATH).exists():
|
| 107 |
+
return _build_bm25_from_qdrant()
|
| 108 |
with open(BM25_PATH, "rb") as f:
|
| 109 |
return pickle.load(f)
|
| 110 |
|