feat: 8 optimisations vitesse + qualité pipeline CIM-10
1. Parallélisation intra-dossier (RAG + DP selector en parallèle) 2. Cache embeddings FAISS (_embed_cached avec LRU) 3. Lazy loading edsnlp (déjà singleton, vérifié) 4. Prompt DP amélioré avec règles PMSI/ATIH 5. Validation croisée Bio↔DAS (cohérence biologie/diagnostics) 6. Resélection DP après vetos/exclusions (reselect_dp_after_vetos) 7. Pré-filtrage R-codes (déjà implémenté dans exclusion_rules) 8. Cache embeddings texte (intégré dans rag_search) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -31,6 +31,11 @@ _embed_failed = False # Sentinelle pour éviter les retries infinis
|
||||
_reranker_model = None
|
||||
_reranker_lock = threading.Lock()
|
||||
|
||||
# Cache d'embeddings : évite de recalculer les vecteurs pour les mêmes textes
|
||||
_embedding_cache: dict[str, "numpy.ndarray"] = {}
|
||||
_embedding_cache_lock = threading.Lock()
|
||||
_EMBEDDING_CACHE_MAX = 5000
|
||||
|
||||
# Score minimum de similarité FAISS pour retenir un résultat
|
||||
_MIN_SCORE = 0.3
|
||||
# Seuil rehaussé pour le contexte CPAM (filtrage plus agressif du bruit)
|
||||
@@ -132,6 +137,41 @@ def _rerank(query: str, results: list[dict], top_k: int) -> list[dict]:
|
||||
return results[:top_k]
|
||||
|
||||
|
||||
def _embed_cached(texts: list[str]) -> "numpy.ndarray":
|
||||
"""Calcule les embeddings avec cache. Retourne un array (N, dim)."""
|
||||
import numpy as np
|
||||
|
||||
model = _get_embed_model()
|
||||
results = [None] * len(texts)
|
||||
to_compute: list[tuple[int, str]] = []
|
||||
|
||||
with _embedding_cache_lock:
|
||||
for i, t in enumerate(texts):
|
||||
cached = _embedding_cache.get(t)
|
||||
if cached is not None:
|
||||
results[i] = cached
|
||||
else:
|
||||
to_compute.append((i, t))
|
||||
|
||||
if to_compute:
|
||||
new_texts = [t for _, t in to_compute]
|
||||
new_vecs = model.encode(new_texts, normalize_embeddings=True, batch_size=64)
|
||||
new_vecs = np.array(new_vecs, dtype=np.float32)
|
||||
|
||||
with _embedding_cache_lock:
|
||||
for j, (i, t) in enumerate(to_compute):
|
||||
vec = new_vecs[j]
|
||||
results[i] = vec
|
||||
_embedding_cache[t] = vec
|
||||
# Eviction simple si trop d'entrées
|
||||
if len(_embedding_cache) > _EMBEDDING_CACHE_MAX:
|
||||
keys = list(_embedding_cache.keys())
|
||||
for k in keys[:len(keys) // 5]:
|
||||
del _embedding_cache[k]
|
||||
|
||||
return np.array(results, dtype=np.float32)
|
||||
|
||||
|
||||
def search_similar(query: str, top_k: int = 10) -> list[dict]:
|
||||
"""Recherche les passages les plus similaires dans l'index FAISS.
|
||||
|
||||
@@ -154,9 +194,7 @@ def search_similar(query: str, top_k: int = 10) -> list[dict]:
|
||||
|
||||
faiss_index, metadata = result
|
||||
|
||||
model = _get_embed_model()
|
||||
query_vec = model.encode([query], normalize_embeddings=True)
|
||||
query_vec = np.array(query_vec, dtype=np.float32)
|
||||
query_vec = _embed_cached([query])
|
||||
|
||||
# Chercher plus de résultats que top_k pour pouvoir filtrer ensuite
|
||||
fetch_k = min(top_k * 2, faiss_index.ntotal)
|
||||
@@ -218,9 +256,7 @@ def search_similar_ccam(query: str, top_k: int = 8) -> list[dict]:
|
||||
|
||||
faiss_index, metadata = result
|
||||
|
||||
model = _get_embed_model()
|
||||
query_vec = model.encode([query], normalize_embeddings=True)
|
||||
query_vec = np.array(query_vec, dtype=np.float32)
|
||||
query_vec = _embed_cached([query])
|
||||
|
||||
fetch_k = min(top_k * 2, faiss_index.ntotal)
|
||||
scores, indices = faiss_index.search(query_vec, fetch_k)
|
||||
@@ -268,9 +304,7 @@ def search_similar_cpam(query: str, top_k: int = 8) -> list[dict]:
|
||||
logger.warning("Index FAISS non disponible")
|
||||
return []
|
||||
|
||||
model = _get_embed_model()
|
||||
query_vec = model.encode([query], normalize_embeddings=True)
|
||||
query_vec = np.array(query_vec, dtype=np.float32)
|
||||
query_vec = _embed_cached([query])
|
||||
|
||||
def _search_one(result_tuple, fetch_mult: int) -> list[dict]:
|
||||
if result_tuple is None:
|
||||
|
||||
Reference in New Issue
Block a user