BugZoid commited on
Commit
36a6cb1
·
verified ·
1 Parent(s): d51a494

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +118 -70
app.py CHANGED
@@ -5,6 +5,7 @@ from torch.utils.data import Dataset, DataLoader
5
  import json
6
  import os
7
  from datetime import datetime
 
8
 
9
  # Custom dataset for fine-tuning
10
  class TextHumanizerDataset(Dataset):
@@ -40,6 +41,17 @@ class TextHumanizerDataset(Dataset):
40
  'labels': target_encoding['input_ids'].squeeze()
41
  }
42
 
 
 
 
 
 
 
 
 
 
 
 
43
  def save_feedback(input_text, output_text, rating):
44
  """Salva o feedback do usuário para futuro treinamento"""
45
  feedback_data = {
@@ -49,53 +61,74 @@ def save_feedback(input_text, output_text, rating):
49
  'timestamp': datetime.now().isoformat()
50
  }
51
 
52
- # Cria diretório se não existir
53
- os.makedirs('feedback_data', exist_ok=True)
54
 
55
- # Salva em arquivo JSON
56
- with open('feedback_data/feedback.json', 'a') as f:
57
- f.write(json.dumps(feedback_data) + '\n')
 
 
 
 
 
 
 
 
 
 
 
58
 
59
  def fine_tune_model():
60
  """Realiza fine-tuning do modelo com dados de feedback positivo"""
61
- if not os.path.exists('feedback_data/feedback.json'):
62
- return
63
-
64
- # Carrega dados de feedback
65
- positive_examples = []
66
- with open('feedback_data/feedback.json', 'r') as f:
67
- for line in f:
68
- feedback = json.loads(line)
69
- if feedback['rating'] >= 4: # Usa apenas feedback positivo
70
- positive_examples.append({
71
- 'input_text': feedback['input_text'],
72
- 'output_text': feedback['output_text']
73
- })
74
 
75
- if not positive_examples:
76
  return
77
 
78
- # Cria dataset e dataloader
79
- dataset = TextHumanizerDataset(positive_examples, st.session_state.tokenizer)
80
- dataloader = DataLoader(dataset, batch_size=4, shuffle=True)
81
-
82
- # Configura otimizador
83
- optimizer = torch.optim.AdamW(st.session_state.model.parameters(), lr=1e-5)
84
-
85
- # Fine-tuning
86
- st.session_state.model.train()
87
- for batch in dataloader:
88
- optimizer.zero_grad()
89
- outputs = st.session_state.model(
90
- input_ids=batch['input_ids'],
91
- attention_mask=batch['attention_mask'],
92
- labels=batch['labels']
93
- )
94
- loss = outputs.loss
95
- loss.backward()
96
- optimizer.step()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
 
98
- st.session_state.model.eval()
 
 
99
 
100
  def clean_generated_text(text):
101
  """Remove comandos e limpa o texto gerado"""
@@ -130,33 +163,44 @@ def humanize_text(text):
130
  """Humaniza o texto mantendo coerência e tamanho"""
131
  prompt = f"reescreva em português natural, mantendo todas as informações: {text}"
132
 
133
- input_ids = st.session_state.tokenizer(
 
134
  prompt,
135
  return_tensors="pt",
136
- max_length=512,
 
137
  truncation=True
138
- ).input_ids
139
-
140
- # Parâmetros ajustados para melhor coerência
141
- outputs = st.session_state.model.generate(
142
- input_ids,
143
- max_length=1024,
144
- min_length=len(text.split()),
145
- do_sample=False,
146
- temperature=0.1,
147
- top_p=0.95,
148
- num_beams=2,
149
- repetition_penalty=1.1,
150
- length_penalty=1.0
151
  )
152
- result = st.session_state.tokenizer.decode(outputs[0], skip_special_tokens=True)
153
- result = clean_generated_text(result)
154
-
155
- # Garante tamanho mínimo
156
- while len(result.split()) < len(text.split()):
157
- result += " " + " ".join(text.split()[-(len(text.split()) - len(result.split())):])
158
-
159
- return result
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
160
 
161
  # Initialize session state
162
  if 'model_loaded' not in st.session_state:
@@ -214,14 +258,18 @@ if st.button("Humanizar", type="primary"):
214
  )
215
 
216
  if st.button("Enviar Feedback"):
217
- save_feedback(input_text, final_text, rating)
218
- st.success("Feedback salvo com sucesso! Obrigado pela contribuição.")
219
-
220
- # Trigger fine-tuning if we have enough positive feedback
221
- if rating >= 4:
222
- with st.spinner("Atualizando modelo com seu feedback..."):
223
- fine_tune_model()
224
- st.success("Modelo atualizado com sucesso!")
 
 
 
 
225
 
226
  except Exception as e:
227
  st.error(f"❌ Erro no processamento: {str(e)}")
 
5
  import json
6
  import os
7
  from datetime import datetime
8
+ import tempfile
9
 
10
  # Custom dataset for fine-tuning
11
  class TextHumanizerDataset(Dataset):
 
41
  'labels': target_encoding['input_ids'].squeeze()
42
  }
43
 
44
+ def get_storage_path():
45
+ """Retorna o caminho correto para armazenamento no Hugging Face Spaces"""
46
+ if os.environ.get('SPACE_ID'): # Verifica se está rodando no Spaces
47
+ return '/data' # Diretório persistente no Spaces
48
+ else:
49
+ # Fallback para desenvolvimento local
50
+ temp_dir = tempfile.gettempdir()
51
+ feedback_dir = os.path.join(temp_dir, 'feedback_data')
52
+ os.makedirs(feedback_dir, exist_ok=True)
53
+ return feedback_dir
54
+
55
  def save_feedback(input_text, output_text, rating):
56
  """Salva o feedback do usuário para futuro treinamento"""
57
  feedback_data = {
 
61
  'timestamp': datetime.now().isoformat()
62
  }
63
 
64
+ storage_path = get_storage_path()
65
+ feedback_file = os.path.join(storage_path, 'feedback.json')
66
 
67
+ try:
68
+ # Cria arquivo se não existir
69
+ if not os.path.exists(feedback_file):
70
+ with open(feedback_file, 'w') as f:
71
+ f.write('')
72
+
73
+ # Append do novo feedback
74
+ with open(feedback_file, 'a') as f:
75
+ f.write(json.dumps(feedback_data) + '\n')
76
+
77
+ return True
78
+ except Exception as e:
79
+ st.error(f"Erro ao salvar feedback: {str(e)}")
80
+ return False
81
 
82
  def fine_tune_model():
83
  """Realiza fine-tuning do modelo com dados de feedback positivo"""
84
+ storage_path = get_storage_path()
85
+ feedback_file = os.path.join(storage_path, 'feedback.json')
 
 
 
 
 
 
 
 
 
 
 
86
 
87
+ if not os.path.exists(feedback_file):
88
  return
89
 
90
+ try:
91
+ # Carrega dados de feedback
92
+ positive_examples = []
93
+ with open(feedback_file, 'r') as f:
94
+ for line in f:
95
+ if line.strip(): # Ignora linhas vazias
96
+ feedback = json.loads(line)
97
+ if feedback['rating'] >= 4: # Usa apenas feedback positivo
98
+ positive_examples.append({
99
+ 'input_text': feedback['input_text'],
100
+ 'output_text': feedback['output_text']
101
+ })
102
+
103
+ if not positive_examples:
104
+ return
105
+
106
+ # Cria dataset e dataloader
107
+ dataset = TextHumanizerDataset(positive_examples, st.session_state.tokenizer)
108
+ dataloader = DataLoader(dataset, batch_size=4, shuffle=True)
109
+
110
+ # Configura otimizador
111
+ optimizer = torch.optim.AdamW(st.session_state.model.parameters(), lr=1e-5)
112
+
113
+ # Fine-tuning
114
+ st.session_state.model.train()
115
+ for batch in dataloader:
116
+ optimizer.zero_grad()
117
+ outputs = st.session_state.model(
118
+ input_ids=batch['input_ids'],
119
+ attention_mask=batch['attention_mask'],
120
+ labels=batch['labels']
121
+ )
122
+ loss = outputs.loss
123
+ loss.backward()
124
+ optimizer.step()
125
+
126
+ st.session_state.model.eval()
127
+ return True
128
 
129
+ except Exception as e:
130
+ st.error(f"Erro durante o fine-tuning: {str(e)}")
131
+ return False
132
 
133
  def clean_generated_text(text):
134
  """Remove comandos e limpa o texto gerado"""
 
163
  """Humaniza o texto mantendo coerência e tamanho"""
164
  prompt = f"reescreva em português natural, mantendo todas as informações: {text}"
165
 
166
+ # Tokenização com padding
167
+ inputs = st.session_state.tokenizer(
168
  prompt,
169
  return_tensors="pt",
170
+ max_length=512, # Reduzido para evitar problemas de memória
171
+ padding=True,
172
  truncation=True
 
 
 
 
 
 
 
 
 
 
 
 
 
173
  )
174
+
175
+ # Parâmetros mais conservadores para geração
176
+ try:
177
+ outputs = st.session_state.model.generate(
178
+ inputs.input_ids,
179
+ max_length=512, # Reduzido para maior estabilidade
180
+ min_length=int(len(text.split()) * 0.8), # Garante pelo menos 80% do tamanho original
181
+ do_sample=False, # Desativa amostragem para maior estabilidade
182
+ num_beams=2, # Reduzido para evitar problemas de memória
183
+ repetition_penalty=1.1, # Reduzido para evitar instabilidades
184
+ length_penalty=1.0, # Valor neutro
185
+ early_stopping=True, # Ativa early stopping
186
+ no_repeat_ngram_size=2 # Evita repetições de bigramas
187
+ )
188
+
189
+ result = st.session_state.tokenizer.decode(outputs[0], skip_special_tokens=True)
190
+ result = clean_generated_text(result)
191
+
192
+ # Garante tamanho mínimo de forma mais suave
193
+ if len(result.split()) < len(text.split()):
194
+ missing_words = len(text.split()) - len(result.split())
195
+ original_words = text.split()[-missing_words:]
196
+ result = result + " " + " ".join(original_words)
197
+
198
+ return result
199
+
200
+ except Exception as e:
201
+ st.error(f"Erro durante a geração: {str(e)}")
202
+ # Fallback: retorna o texto original em caso de erro
203
+ return text
204
 
205
  # Initialize session state
206
  if 'model_loaded' not in st.session_state:
 
258
  )
259
 
260
  if st.button("Enviar Feedback"):
261
+ if save_feedback(input_text, final_text, rating):
262
+ st.success("Feedback salvo com sucesso! Obrigado pela contribuição.")
263
+
264
+ # Trigger fine-tuning if we have enough positive feedback
265
+ if rating >= 4:
266
+ with st.spinner("Atualizando modelo com seu feedback..."):
267
+ if fine_tune_model():
268
+ st.success("Modelo atualizado com sucesso!")
269
+ else:
270
+ st.warning("Não foi possível atualizar o modelo neste momento.")
271
+ else:
272
+ st.error("Não foi possível salvar o feedback. Tente novamente mais tarde.")
273
 
274
  except Exception as e:
275
  st.error(f"❌ Erro no processamento: {str(e)}")