thejarll commited on
Commit
7ed55d9
·
verified ·
1 Parent(s): 0b4db83

Upload indexador.py

Browse files
Files changed (1) hide show
  1. indexador.py +90 -0
indexador.py ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import fitz # PyMuPDF
3
+ import faiss
4
+ import pickle
5
+ import numpy as np
6
+ from transformers import AutoTokenizer, AutoModel
7
+ import torch
8
+ import re
9
+
10
+ # Modelo de embeddings
11
+ modelo_id = "jinaai/jina-embeddings-v2-base-es"
12
+ tokenizer = AutoTokenizer.from_pretrained(modelo_id)
13
+ model = AutoModel.from_pretrained(modelo_id)
14
+
15
+ def cargar_pdfs(ruta="."):
16
+ textos = []
17
+ for archivo in os.listdir(ruta):
18
+ if archivo.endswith(".pdf"):
19
+ ruta_pdf = os.path.join(ruta, archivo)
20
+ print(f"Procesando: {archivo}")
21
+ doc = fitz.open(ruta_pdf)
22
+ texto = ""
23
+ for pagina in doc:
24
+ texto += pagina.get_text()
25
+ texto = texto.replace("\n", " ").replace(" ", " ").strip()
26
+ doc.close()
27
+ if texto:
28
+ textos.append(texto)
29
+ return textos
30
+
31
+ def chunk_por_articulo(texto):
32
+ patron = r"(art[íi]culo[s]?[\s\n]+\d+[A-Z]?(?:\s*\.\s*)?)"
33
+ secciones = re.split(patron, texto, flags=re.IGNORECASE)
34
+
35
+ chunks = []
36
+ for i in range(1, len(secciones), 2):
37
+ titulo = secciones[i].strip()
38
+ contenido = secciones[i + 1].strip()
39
+ chunk = f"{titulo} {contenido}"
40
+ chunks.append(chunk)
41
+ return chunks
42
+
43
+ def generar_embedding(textos, tokenizer, model, batch_size=32):
44
+ all_embeddings = []
45
+
46
+ for i in range(0, len(textos), batch_size):
47
+ batch = textos[i:i + batch_size]
48
+ inputs = tokenizer(batch, return_tensors="pt", padding=True, truncation=True)
49
+ with torch.no_grad():
50
+ outputs = model(**inputs)
51
+ last_hidden = outputs.last_hidden_state
52
+ mask = inputs["attention_mask"].unsqueeze(-1).expand(last_hidden.size()).float()
53
+ summed = torch.sum(last_hidden * mask, 1)
54
+ counted = torch.clamp(mask.sum(1), min=1e-9)
55
+ mean_pooled = summed / counted
56
+ all_embeddings.extend(mean_pooled.cpu().numpy())
57
+
58
+ return np.array(all_embeddings)
59
+
60
+ def crear_index_y_guardar(ruta=".", archivo_salida="index.pkl"):
61
+ print("Cargando PDFs...")
62
+ textos = cargar_pdfs(ruta)
63
+
64
+ print("Dividiendo en chunks por artículos...")
65
+ chunks = []
66
+ for texto in textos:
67
+ trozos = chunk_por_articulo(texto)
68
+ chunks.extend(trozos)
69
+
70
+ if not chunks:
71
+ raise ValueError("No se generaron chunks. Revisa los archivos PDF.")
72
+
73
+ print(f"Total de chunks generados: {len(chunks)}")
74
+
75
+ print("Generando embeddings...")
76
+ embeddings = generar_embedding(chunks, tokenizer, model)
77
+
78
+ print("Creando índice FAISS...")
79
+ index = faiss.IndexFlatL2(embeddings.shape[1])
80
+ index.add(embeddings)
81
+
82
+ print(f"Guardando índice en: {archivo_salida}")
83
+ with open(archivo_salida, "wb") as f:
84
+ pickle.dump((index, chunks), f)
85
+
86
+ print("Indexación completada.")
87
+ return index, chunks
88
+
89
+ if __name__ == "__main__":
90
+ crear_index_y_guardar()