Download scripts/eval/build_local_index.py from build-small-hackathon/pay-equity-for-eu: direct link, hf CLI and curl.
- Browser
- Download file 2.07 kB
-
https://huggingface.co/spaces/build-small-hackathon/pay-equity-for-eu/resolve/main/scripts/eval/build_local_index.py
- Command line
-
hf download hf://spaces/build-small-hackathon/pay-equity-for-eu/scripts/eval/build_local_index.py
-
curl -L -o build_local_index.py https://huggingface.co/spaces/build-small-hackathon/pay-equity-for-eu/resolve/main/scripts/eval/build_local_index.py
2.07 kB
| """Rebuild the FAISS index locally from the committed chunks.jsonl. | |
| The committed ``data/processed/index/index.faiss`` is a git-LFS pointer (not | |
| pulled here), so retrieval cannot run. ``chunks.jsonl`` IS real, so we re-embed | |
| those exact chunk texts with the pinned Nemotron embedder and the same | |
| ``passage:`` prefix / L2-normalization the runtime uses, then write a usable | |
| ``index.faiss`` next to it. | |
| This reproduces the runtime retrieval path faithfully: | |
| embeddings.repo / revision / query_prefix / passage_prefix / normalize | |
| all come from configs/models.yaml. | |
| """ | |
| from __future__ import annotations | |
| import json | |
| import sys | |
| import time | |
| from pathlib import Path | |
| import numpy as np | |
| REPO_ROOT = Path(__file__).resolve().parents[2] | |
| sys.path.insert(0, str(REPO_ROOT / "src")) | |
| import yaml # noqa: E402 | |
| CHUNKS = REPO_ROOT / "data" / "processed" / "index" / "chunks.jsonl" | |
| INDEX_OUT = REPO_ROOT / "data" / "processed" / "index" / "index.faiss" | |
| def main() -> None: | |
| cfg = yaml.safe_load((REPO_ROOT / "configs" / "models.yaml").read_text())["embeddings"] | |
| chunks = [json.loads(l) for l in CHUNKS.read_text(encoding="utf-8").splitlines() if l.strip()] | |
| print(f"loaded {len(chunks)} chunks") | |
| from sentence_transformers import SentenceTransformer | |
| t = time.time() | |
| model = SentenceTransformer( | |
| cfg["repo"], revision=cfg.get("revision"), device="cpu", trust_remote_code=True | |
| ) | |
| print(f"model loaded in {time.time()-t:.1f}s") | |
| prefix = cfg.get("passage_prefix", "") | |
| texts = [f"{prefix}{c['text']}" for c in chunks] | |
| t = time.time() | |
| vecs = model.encode( | |
| texts, batch_size=16, normalize_embeddings=cfg.get("normalize", True), | |
| convert_to_numpy=True, show_progress_bar=True, | |
| ).astype("float32") | |
| print(f"embedded {vecs.shape} in {time.time()-t:.1f}s") | |
| import faiss | |
| index = faiss.IndexFlatIP(vecs.shape[1]) | |
| index.add(vecs) | |
| faiss.write_index(index, str(INDEX_OUT)) | |
| print(f"wrote index: {index.ntotal} vectors, dim {vecs.shape[1]} -> {INDEX_OUT}") | |
| if __name__ == "__main__": | |
| main() | |