Number_one / dedup_store.py
EnriqueAlves's picture
Add ingestion/OCR/exploration tooling + improvements roadmap; ignore local artifacts
7e2d97f
Raw
History Blame Contribute Delete
2.13 kB
"""
Déduplication de la base ChromaDB
=================================
Supprime les chunks redondants : quand une même paire (source, chunk_index)
existe plusieurs fois (= fichier ingéré plusieurs fois), on garde 1 exemplaire
et on supprime les autres. Lecture/écriture locale, AUCUN appel Azure.
Usage : ./.venv/Scripts/python.exe dedup_store.py
"""
import os
from pathlib import Path
from collections import defaultdict
os.environ.setdefault("ANONYMIZED_TELEMETRY", "False")
import chromadb
from chromadb.config import Settings
PROJECT_ROOT = Path(__file__).parent
DATA_DIR = Path("/data") if Path("/data").is_dir() else PROJECT_ROOT / "data"
COLLECTION_NAME = "rag_documents"
client = chromadb.PersistentClient(path=str(DATA_DIR / "chroma_db"), settings=Settings(anonymized_telemetry=False))
col = client.get_or_create_collection(name=COLLECTION_NAME, metadata={"hnsw:space": "cosine"})
total = col.count()
print(f"Total chunks avant : {total}")
# (source, chunk_index) -> liste d'ids
pair_to_ids = defaultdict(list)
off, step = 0, 2000
while off < total:
got = col.get(include=["metadatas"], limit=step, offset=off)
for _id, m in zip(got["ids"], got["metadatas"]):
pair_to_ids[(m.get("source"), m.get("chunk_index"))].append(_id)
off += step
# pour chaque paire en double, on garde le 1er id, on supprime les autres
to_delete = []
affected = defaultdict(int)
for (src, idx), ids in pair_to_ids.items():
if len(ids) > 1:
extra = ids[1:] # on garde ids[0]
to_delete.extend(extra)
affected[src] += len(extra)
print(f"Chunks redondants à supprimer : {len(to_delete)}")
print("Mémoires concernés :")
for src, n in sorted(affected.items(), key=lambda x: -x[1]):
print(f" -{n} {src}")
if not to_delete:
print("Aucun doublon. Rien à faire.")
else:
# suppression par lots (limite SQLite sur le nombre de variables)
B = 500
for i in range(0, len(to_delete), B):
col.delete(ids=to_delete[i:i + B])
print(f" supprimé {min(i + B, len(to_delete))}/{len(to_delete)}")
print(f"Total chunks après : {col.count()}")