Aidahaouas commited on
Commit
acf0656
·
verified ·
1 Parent(s): 8533b77

Update pinecone_utilsB.py

Browse files
Files changed (1) hide show
  1. pinecone_utilsB.py +27 -60
pinecone_utilsB.py CHANGED
@@ -13,6 +13,8 @@ import base64
13
  import json
14
  nltk.download('punkt_tab')
15
 
 
 
16
  CONFIG_FILE = "indexing_state.json"
17
 
18
  def load_indexing_state():
@@ -29,32 +31,25 @@ def save_indexing_state(state):
29
 
30
  class HybridSearchEngine:
31
  def __init__(self):
32
- # Initialisation des modèles et encodeurs
33
  self.model = SentenceTransformer("intfloat/multilingual-e5-large")
34
  self.sparse_encoder = BM25Encoder().default()
35
-
36
- # Créer une instance de HuggingFaceEmbeddings
37
  self.embeddings = HuggingFaceEmbeddings(model_name="intfloat/multilingual-e5-large")
38
-
39
- # Utiliser st.session_state pour stocker l'état de l'indexation
40
- if "bm25_corpus" not in st.session_state:
41
- st.session_state.bm25_corpus = []
42
- if "indexing_done" not in st.session_state:
43
- st.session_state.indexing_done = False
44
-
45
- # Initialisation du PineconeVectorStore
46
  self.vectorstore = PineconeVectorStore(index=indexB, embedding=self.embeddings)
47
-
48
- # Initialisation du retriever hybride
49
  self.retriever = PineconeHybridSearchRetriever(
50
  embeddings=self.embeddings,
51
  sparse_encoder=self.sparse_encoder,
52
  index=indexB
53
  )
54
 
 
 
 
 
 
 
55
  def is_initialized(self):
56
- """Vérifie si l'index BM25 est initialisé."""
57
- return bool(st.session_state.bm25_corpus)
58
 
59
  def tokenize(self, text):
60
  """Tokenise un texte avec NLTK."""
@@ -63,110 +58,82 @@ class HybridSearchEngine:
63
  def get_existing_vectors(self):
64
  """Récupère les textes compressés déjà indexés dans Pinecone."""
65
  existing_texts = set()
66
-
67
  try:
68
- # Effectuer une recherche avec un mot-clé fictif pour récupérer des documents
69
  results = self.vectorstore.similarity_search("random_query", k=10000)
70
-
71
  for doc in results:
72
  if "compressed_text" in doc.metadata:
73
  existing_texts.add(doc.metadata["compressed_text"])
74
-
75
  except Exception as e:
76
  st.error(f"Erreur lors de la récupération des vecteurs existants : {e}")
77
-
78
  return existing_texts
79
 
80
  def index_pdf_B(self, texts, pdf_path):
81
- """Indexe les textes en évitant les doublons (même contenu)."""
82
  if not texts:
83
  st.error("La liste des textes ne peut pas être vide.")
84
  return
85
 
 
 
 
 
 
86
  # Charger l'état d'indexation
87
  indexing_state = load_indexing_state()
88
-
89
- # Vérifier si ce fichier PDF a déjà été indexé
90
  if pdf_path in indexing_state["indexed_files"]:
91
  st.write("Ce fichier PDF a déjà été indexé.")
92
  return
93
 
94
  st.write("Indexation en cours, veuillez patienter...")
95
 
96
- # Récupérer les textes déjà indexés dans Pinecone
97
  existing_texts = self.get_existing_vectors()
98
 
99
- # Initialiser BM25
100
  st.session_state.bm25_corpus = texts
101
  self.sparse_encoder.fit(texts)
102
 
103
  documents = []
104
- for i, text in enumerate(texts):
105
  chunks = self.split_text_into_chunks(text, max_chunk_size=1024)
106
- for j, chunk in enumerate(chunks):
107
  compressed_chunk = self.compress_text(chunk)
108
-
109
- # Vérifier si ce texte est déjà dans l'index Pinecone
110
  if compressed_chunk in existing_texts:
111
  continue # Ignorer ce document car il est déjà indexé
112
 
113
- # Générer un ID unique pour ce chunk
114
  doc_id = f"doc_{zlib.crc32(chunk.encode('utf-8'))}"
115
-
116
  metadata = {"compressed_text": compressed_chunk}
117
- metadata_size = self.get_metadata_size(metadata)
118
-
119
- if metadata_size <= 40960: # 40 KB
120
- document = Document(
121
- page_content=chunk,
122
- metadata=metadata
123
- )
124
- documents.append((doc_id, document))
125
 
126
- # Ajouter uniquement les nouveaux documents
127
  if documents:
128
- self.vectorstore.add_documents([doc for _, doc in documents])
129
 
130
- # Mettre à jour l'état d'indexation
131
  indexing_state["indexed_files"].append(pdf_path)
132
  save_indexing_state(indexing_state)
 
133
 
134
  st.success("Indexation terminée sans duplication de contenu.")
135
 
136
  def hybrid_search(self, query):
137
- """Récupère les documents pertinents en combinant les résultats de Pinecone et BM25."""
138
  if not self.is_initialized():
139
  st.warning("L'index BM25 n'est pas encore prêt. Veuillez patienter pendant l'indexation...")
140
  return []
141
 
142
  try:
143
- # Recherche hybride avec PineconeHybridSearchRetriever
144
  results = self.retriever.get_relevant_documents(query)
145
-
146
- # Récupérer les documents pertinents
147
  relevant_docs = []
148
  for result in results:
149
- # Vérifier si le résultat est un objet Document
150
- if hasattr(result, "metadata"):
151
- metadata = result.metadata or {} # Assurez-vous que metadata n'est jamais None
152
- else:
153
- metadata = {}
154
-
155
- # Vérifier si 'context' existe avant d'y accéder
156
- if "context" in metadata:
157
- _ = metadata.pop("context", None) # Sécuriser l'accès à 'context'
158
-
159
  compressed_text = metadata.get("compressed_text")
160
  if compressed_text:
161
  relevant_docs.append(self.decompress_text(compressed_text))
162
-
163
  return relevant_docs
164
-
165
  except Exception as e:
166
  st.error(f"Erreur lors de la recherche hybride : {e}")
167
  return []
168
 
169
-
170
  def compress_text(self, text):
171
  """Compresse un texte en base64."""
172
  compressed = zlib.compress(text.encode("utf-8"))
@@ -187,4 +154,4 @@ class HybridSearchEngine:
187
 
188
  def get_metadata_size(self, metadata):
189
  """Calcule la taille des métadonnées en octets."""
190
- return len(str(metadata).encode("utf-8"))
 
13
  import json
14
  nltk.download('punkt_tab')
15
 
16
+
17
+
18
  CONFIG_FILE = "indexing_state.json"
19
 
20
  def load_indexing_state():
 
31
 
32
  class HybridSearchEngine:
33
  def __init__(self):
 
34
  self.model = SentenceTransformer("intfloat/multilingual-e5-large")
35
  self.sparse_encoder = BM25Encoder().default()
 
 
36
  self.embeddings = HuggingFaceEmbeddings(model_name="intfloat/multilingual-e5-large")
 
 
 
 
 
 
 
 
37
  self.vectorstore = PineconeVectorStore(index=indexB, embedding=self.embeddings)
 
 
38
  self.retriever = PineconeHybridSearchRetriever(
39
  embeddings=self.embeddings,
40
  sparse_encoder=self.sparse_encoder,
41
  index=indexB
42
  )
43
 
44
+ # Utiliser st.session_state pour stocker l'état de l'indexation
45
+ if "bm25_corpus" not in st.session_state:
46
+ st.session_state.bm25_corpus = []
47
+ if "indexing_done" not in st.session_state:
48
+ st.session_state.indexing_done = False
49
+
50
  def is_initialized(self):
51
+ """Vérifie si l'index BM25 est bien prêt à être utilisé."""
52
+ return bool(st.session_state.get("bm25_corpus")) and st.session_state.get("indexing_done")
53
 
54
  def tokenize(self, text):
55
  """Tokenise un texte avec NLTK."""
 
58
  def get_existing_vectors(self):
59
  """Récupère les textes compressés déjà indexés dans Pinecone."""
60
  existing_texts = set()
 
61
  try:
 
62
  results = self.vectorstore.similarity_search("random_query", k=10000)
 
63
  for doc in results:
64
  if "compressed_text" in doc.metadata:
65
  existing_texts.add(doc.metadata["compressed_text"])
 
66
  except Exception as e:
67
  st.error(f"Erreur lors de la récupération des vecteurs existants : {e}")
 
68
  return existing_texts
69
 
70
  def index_pdf_B(self, texts, pdf_path):
71
+ """Indexe les textes en évitant les doublons."""
72
  if not texts:
73
  st.error("La liste des textes ne peut pas être vide.")
74
  return
75
 
76
+ # Vérifier si l'indexation est déjà faite
77
+ if st.session_state.get("indexing_done", False):
78
+ st.write("L'indexation est déjà terminée, pas besoin de la refaire.")
79
+ return
80
+
81
  # Charger l'état d'indexation
82
  indexing_state = load_indexing_state()
 
 
83
  if pdf_path in indexing_state["indexed_files"]:
84
  st.write("Ce fichier PDF a déjà été indexé.")
85
  return
86
 
87
  st.write("Indexation en cours, veuillez patienter...")
88
 
 
89
  existing_texts = self.get_existing_vectors()
90
 
91
+ # Entraîner BM25 uniquement si ce n'est pas déjà fait
92
  st.session_state.bm25_corpus = texts
93
  self.sparse_encoder.fit(texts)
94
 
95
  documents = []
96
+ for text in texts:
97
  chunks = self.split_text_into_chunks(text, max_chunk_size=1024)
98
+ for chunk in chunks:
99
  compressed_chunk = self.compress_text(chunk)
 
 
100
  if compressed_chunk in existing_texts:
101
  continue # Ignorer ce document car il est déjà indexé
102
 
 
103
  doc_id = f"doc_{zlib.crc32(chunk.encode('utf-8'))}"
 
104
  metadata = {"compressed_text": compressed_chunk}
105
+ if self.get_metadata_size(metadata) <= 40960:
106
+ documents.append(Document(page_content=chunk, metadata=metadata))
 
 
 
 
 
 
107
 
 
108
  if documents:
109
+ self.vectorstore.add_documents(documents)
110
 
111
+ # Marquer l'indexation comme terminée
112
  indexing_state["indexed_files"].append(pdf_path)
113
  save_indexing_state(indexing_state)
114
+ st.session_state.indexing_done = True
115
 
116
  st.success("Indexation terminée sans duplication de contenu.")
117
 
118
  def hybrid_search(self, query):
119
+ """Effectue une recherche hybride combinant BM25 et Pinecone."""
120
  if not self.is_initialized():
121
  st.warning("L'index BM25 n'est pas encore prêt. Veuillez patienter pendant l'indexation...")
122
  return []
123
 
124
  try:
 
125
  results = self.retriever.get_relevant_documents(query)
 
 
126
  relevant_docs = []
127
  for result in results:
128
+ metadata = result.metadata or {}
 
 
 
 
 
 
 
 
 
129
  compressed_text = metadata.get("compressed_text")
130
  if compressed_text:
131
  relevant_docs.append(self.decompress_text(compressed_text))
 
132
  return relevant_docs
 
133
  except Exception as e:
134
  st.error(f"Erreur lors de la recherche hybride : {e}")
135
  return []
136
 
 
137
  def compress_text(self, text):
138
  """Compresse un texte en base64."""
139
  compressed = zlib.compress(text.encode("utf-8"))
 
154
 
155
  def get_metadata_size(self, metadata):
156
  """Calcule la taille des métadonnées en octets."""
157
+ return len(str(metadata).encode("utf-8"))