Finish-him commited on
Commit
2df7e36
·
verified ·
1 Parent(s): 637e732

fix: complete truncated app.py - add embedding generation + gradio UI

Browse files
Files changed (1) hide show
  1. app.py +57 -48
app.py CHANGED
@@ -1,5 +1,4 @@
1
  # --- 1. IMPORTS ---
2
- # Imports do seu train.py e do Gradio
3
  import os
4
  import glob
5
  import json
@@ -11,24 +10,16 @@ import xml.etree.ElementTree as ET
11
  import gradio as gr
12
  import shutil
13
 
14
- # --- 2. CONFIGURAÇÕES E CONSTANTES ---
15
- # Caminhos relativos são melhores para portabilidade no Hugging Face Spaces
16
  DATA_DIR = "dados"
17
  EXTRACT_DIR = os.path.join(DATA_DIR, "dados_extraidos")
 
18
 
19
- # ATIVA O ARMAZENAMENTO PERSISTENTE NAS CONFIGURAÇÕES DO SEU SPACE!
20
- # Se ativado, mude o caminho para algo como "/data/meus_embeddings.npy"
21
- OUTPUT_FILENAME = "meus_embeddings_e5_large.npy"
22
-
23
- # --- 3. SUAS FUNÇÕES DE PROCESSAMENTO (DO TRAIN.PY) ---
24
- # Copiamos suas funções de ajuda diretamente para cá.
25
-
26
  def setup_data():
27
- """Descompacta os arquivos .zip e retorna o diretório de processamento."""
28
  os.makedirs(EXTRACT_DIR, exist_ok=True)
29
- zip_files = glob.glob(os.path.join(DATA_DIR, "*.zip")) # Simplificado para buscar zips na pasta 'dados'
30
  if not zip_files:
31
- print("Nenhum arquivo .zip encontrado, usando o diretório de dados principal.")
32
  return DATA_DIR
33
  for zip_path in zip_files:
34
  with zipfile.ZipFile(zip_path, 'r') as zf:
@@ -36,7 +27,6 @@ def setup_data():
36
  return EXTRACT_DIR
37
 
38
  def xml_to_dict(element):
39
- """Converte um elemento XML para um dicionário Python."""
40
  d = {}
41
  for child in element:
42
  child_dict = xml_to_dict(child)
@@ -51,73 +41,92 @@ def xml_to_dict(element):
51
  return d
52
 
53
  def serialize_item_to_text(item_dict):
54
- """Converte um dicionário (de JSON, CSV, etc.) para uma string de texto plano."""
55
  parts = []
56
  if not isinstance(item_dict, dict):
57
  return str(item_dict)
58
  for key, value in item_dict.items():
59
  if isinstance(value, dict):
60
- nested_text = serialize_item_to_text(value)
61
- parts.append(f"{key} ({nested_text})")
62
  elif isinstance(value, list):
63
- list_str = ', '.join([serialize_item_to_text(i) for i in value])
64
  parts.append(f"{key}: [{list_str}]")
65
  else:
66
  parts.append(f"{key}: {value}")
67
  return ", ".join(parts)
68
 
69
- # --- 4. FUNÇÃO ORQUESTRADORA (LÓGICA PRINCIPAL) ---
70
- # Esta função substitui a sua função `main()` e é chamada pelo Gradio.
71
- # Ela usa `yield` para enviar atualizações de progresso para a interface.
72
-
73
  def run_full_process():
74
- """Executa o pipeline completo e envia o progresso para a UI."""
75
-
76
- # --- ETAPA 1: SETUP E PROCESSAMENTO DE ARQUIVOS ---
77
  yield "Iniciando... Descompactando arquivos..."
78
  process_dir = setup_data()
79
-
80
  csv.field_size_limit(10_000_000)
81
- all_files = glob.glob(os.path.join(process_dir, "**/*.json"), recursive=True) + \
82
- glob.glob(os.path.join(process_dir, "**/*.csv"), recursive=True) + \
83
- glob.glob(os.path.join(process_dir, "**/*.xml"), recursive=True)
84
-
85
- yield f"🔎 Encontrados {len(all_files)} arquivos para processar."
 
86
 
87
  documents = []
88
  for idx, filepath in enumerate(all_files):
89
  try:
90
- # Mostra o progresso na interface em vez de usar tqdm
91
  yield f"Processando arquivo {idx + 1}/{len(all_files)}: {os.path.basename(filepath)}"
92
-
93
- if filepath.endswith('.json'):
94
- with open(filepath, 'r', encoding='utf-8') as f:
95
  data = json.load(f)
96
  if isinstance(data, list):
97
- for item in data: documents.append(serialize_item_to_text(item))
 
98
  else:
99
  documents.append(serialize_item_to_text(data))
100
- elif filepath.endswith('.csv'):
101
- with open(filepath, 'r', encoding='utf-8') as f:
102
  reader = csv.DictReader(f)
103
- for row in reader: documents.append(serialize_item_to_text(row))
104
- elif filepath.endswith('.xml'):
 
105
  tree = ET.parse(filepath)
106
  root = tree.getroot()
107
  xml_dict = {root.tag: xml_to_dict(root)}
108
  documents.append(serialize_item_to_text(xml_dict))
109
  except Exception as e:
110
- yield f"⚠️ Erro ao processar {os.path.basename(filepath)}: {e}"
111
 
112
- yield f"Processamento de arquivos concluído! {len(documents)} documentos criados."
113
  if not documents:
114
- yield "Nenhum documento encontrado para gerar embeddings. Processo encerrado."
115
  return
116
 
117
  # --- ETAPA 2: GERAÇÃO DE EMBEDDINGS ---
118
- yield "Carregando modelo de alta performance: intfloat/multilingual-e5-large..."
119
-
120
- # Use um cache dentro do seu Space para não baixar o modelo toda vez
121
- cache_path = './model_cache'
122
  os.makedirs(cache_path, exist_ok=True)
123
- model = SentenceTransformer('intfloat/multilingual-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  # --- 1. IMPORTS ---
 
2
  import os
3
  import glob
4
  import json
 
10
  import gradio as gr
11
  import shutil
12
 
13
+ # --- 2. CONFIGURAÇÕES ---
 
14
  DATA_DIR = "dados"
15
  EXTRACT_DIR = os.path.join(DATA_DIR, "dados_extraidos")
16
+ OUTPUT_FILENAME = "meus_embeddings_e5_large.npy"
17
 
18
+ # --- 3. FUNÇÕES DE PROCESSAMENTO ---
 
 
 
 
 
 
19
  def setup_data():
 
20
  os.makedirs(EXTRACT_DIR, exist_ok=True)
21
+ zip_files = glob.glob(os.path.join(DATA_DIR, "*.zip"))
22
  if not zip_files:
 
23
  return DATA_DIR
24
  for zip_path in zip_files:
25
  with zipfile.ZipFile(zip_path, 'r') as zf:
 
27
  return EXTRACT_DIR
28
 
29
  def xml_to_dict(element):
 
30
  d = {}
31
  for child in element:
32
  child_dict = xml_to_dict(child)
 
41
  return d
42
 
43
  def serialize_item_to_text(item_dict):
 
44
  parts = []
45
  if not isinstance(item_dict, dict):
46
  return str(item_dict)
47
  for key, value in item_dict.items():
48
  if isinstance(value, dict):
49
+ parts.append(f"{key} ({serialize_item_to_text(value)})")
 
50
  elif isinstance(value, list):
51
+ list_str = ", ".join([serialize_item_to_text(i) for i in value])
52
  parts.append(f"{key}: [{list_str}]")
53
  else:
54
  parts.append(f"{key}: {value}")
55
  return ", ".join(parts)
56
 
57
+ # --- 4. PIPELINE PRINCIPAL ---
 
 
 
58
  def run_full_process():
 
 
 
59
  yield "Iniciando... Descompactando arquivos..."
60
  process_dir = setup_data()
61
+
62
  csv.field_size_limit(10_000_000)
63
+ all_files = (
64
+ glob.glob(os.path.join(process_dir, "**/*.json"), recursive=True)
65
+ + glob.glob(os.path.join(process_dir, "**/*.csv"), recursive=True)
66
+ + glob.glob(os.path.join(process_dir, "**/*.xml"), recursive=True)
67
+ )
68
+ yield f"Encontrados {len(all_files)} arquivos para processar."
69
 
70
  documents = []
71
  for idx, filepath in enumerate(all_files):
72
  try:
 
73
  yield f"Processando arquivo {idx + 1}/{len(all_files)}: {os.path.basename(filepath)}"
74
+ if filepath.endswith(".json"):
75
+ with open(filepath, "r", encoding="utf-8") as f:
 
76
  data = json.load(f)
77
  if isinstance(data, list):
78
+ for item in data:
79
+ documents.append(serialize_item_to_text(item))
80
  else:
81
  documents.append(serialize_item_to_text(data))
82
+ elif filepath.endswith(".csv"):
83
+ with open(filepath, "r", encoding="utf-8") as f:
84
  reader = csv.DictReader(f)
85
+ for row in reader:
86
+ documents.append(serialize_item_to_text(row))
87
+ elif filepath.endswith(".xml"):
88
  tree = ET.parse(filepath)
89
  root = tree.getroot()
90
  xml_dict = {root.tag: xml_to_dict(root)}
91
  documents.append(serialize_item_to_text(xml_dict))
92
  except Exception as e:
93
+ yield f"Erro ao processar {os.path.basename(filepath)}: {e}"
94
 
95
+ yield f"Processamento concluido! {len(documents)} documentos criados."
96
  if not documents:
97
+ yield "Nenhum documento encontrado. Processo encerrado."
98
  return
99
 
100
  # --- ETAPA 2: GERAÇÃO DE EMBEDDINGS ---
101
+ yield "Carregando modelo intfloat/multilingual-e5-large..."
102
+ cache_path = "./model_cache"
 
 
103
  os.makedirs(cache_path, exist_ok=True)
104
+ model = SentenceTransformer(
105
+ "intfloat/multilingual-e5-large", cache_folder=cache_path
106
+ )
107
+
108
+ yield f"Gerando embeddings para {len(documents)} documentos..."
109
+ batch_size = 32
110
+ all_embeddings = []
111
+ for i in range(0, len(documents), batch_size):
112
+ batch = documents[i : i + batch_size]
113
+ embeddings = model.encode(batch, show_progress_bar=False)
114
+ all_embeddings.append(embeddings)
115
+ yield f"Batch {i // batch_size + 1}/{(len(documents) - 1) // batch_size + 1} concluido."
116
+
117
+ final_embeddings = np.vstack(all_embeddings)
118
+ np.save(OUTPUT_FILENAME, final_embeddings)
119
+ yield f"Embeddings salvos em {OUTPUT_FILENAME}! Shape: {final_embeddings.shape}"
120
+ yield f"Processo completo! {final_embeddings.shape[0]} embeddings de dimensao {final_embeddings.shape[1]}."
121
+
122
+ # --- 5. INTERFACE GRADIO ---
123
+ with gr.Blocks(title="Prometheus Embedding Generator") as demo:
124
+ gr.Markdown("# Prometheus Embedding Generator")
125
+ gr.Markdown("Gera embeddings a partir dos dados do repositorio usando multilingual-e5-large.")
126
+
127
+ run_btn = gr.Button("Iniciar Processamento", variant="primary")
128
+ output = gr.Textbox(label="Progresso", lines=15, interactive=False)
129
+
130
+ run_btn.click(fn=run_full_process, outputs=output)
131
+
132
+ demo.launch()