Finish-him commited on
Commit
d54fcdc
·
verified ·
1 Parent(s): e302caf
Files changed (1) hide show
  1. app.py +112 -41
app.py CHANGED
@@ -1,52 +1,123 @@
1
- import gradio as gr
 
2
  import os
3
- import time
 
 
 
 
4
  import zipfile
 
 
5
  import shutil
6
 
7
- # --- 1. CONFIGURAÇÕES E CONSTANTES ---
8
- # Defina os caminhos e nomes de arquivos importantes aqui.
9
- # Isso facilita a manutenção.
 
 
 
 
 
10
 
11
- # ATENÇÃO: No Hugging Face Spaces, o armazenamento é efêmero por padrão.
12
- # Para salvar os embeddings permanentemente, ative o "Persistent Storage" nas configurações do seu Space.
13
- # O caminho para o armazenamento persistente geralmente começa com /data
14
- # Se você tiver armazenamento persistente, mude o caminho abaixo:
15
- # OUTPUT_EMBEDDINGS_FILE = "/data/embeddings_gerados.faiss"
16
- OUTPUT_EMBEDDINGS_FILE = "embeddings_gerados.faiss" # Usando armazenamento temporário por enquanto
17
 
18
- DATA_DIR = "dados"
19
- ZIP_FILE_PATH = os.path.join(DATA_DIR, "Treinamento do PGL_4.zip")
20
- EXTRACT_PATH = os.path.join(DATA_DIR, "extraidos")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
 
22
- # --- 2. FUNÇÕES DE PROCESSAMENTO ---
23
- # Cada etapa do seu processo original foi transformada em uma função.
 
 
 
 
 
 
 
 
 
 
 
 
 
24
 
25
- def unzip_data():
26
- """Descompacta o arquivo ZIP de dados."""
27
- if os.path.exists(EXTRACT_PATH):
28
- shutil.rmtree(EXTRACT_PATH) # Limpa extrações antigas
29
- os.makedirs(EXTRACT_PATH, exist_ok=True)
 
 
 
 
 
30
 
31
- with zipfile.ZipFile(ZIP_FILE_PATH, 'r') as zip_ref:
32
- zip_ref.extractall(EXTRACT_PATH)
 
 
33
 
34
- # Conta os arquivos para dar um feedback similar ao original
35
- files = [os.path.join(root, name) for root, dirs, files in os.walk(EXTRACT_PATH) for name in files]
36
- return len(files)
37
-
38
- def process_files(num_files_to_process):
39
- """
40
- Simula o processamento dos 265 arquivos.
41
- Esta função usa 'yield' para enviar o progresso para a interface.
42
- """
43
- yield f"🔎 Encontrados {num_files_to_process} arquivos para processar."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
 
45
- # Simulação do processamento de arquivos
46
- for i in range(num_files_to_process + 1):
47
- # ATENÇÃO: Substitua este 'time.sleep' pelo seu CÓDIGO REAL de processamento de um arquivo.
48
- time.sleep(0.01)
49
-
50
- # Atualiza a barra de progresso a cada iteração
51
- progress_bar = "█" * int((i / num_files_to_process) * 20)
52
- yield f"Processando arquivos: {int((i / num_files_to_process) *
 
1
+ # --- 1. IMPORTS ---
2
+ # Imports do seu train.py e do Gradio
3
  import os
4
+ import glob
5
+ import json
6
+ import csv
7
+ import numpy as np
8
+ from sentence_transformers import SentenceTransformer
9
  import zipfile
10
+ 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:
35
+ zf.extractall(EXTRACT_DIR)
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)
43
+ if child.tag in d:
44
+ if not isinstance(d[child.tag], list):
45
+ d[child.tag] = [d[child.tag]]
46
+ d[child.tag].append(child_dict)
47
+ else:
48
+ d[child.tag] = child_dict
49
+ if not d:
50
+ return element.text
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-