BugZoid commited on
Commit
dd9cc55
·
verified ·
1 Parent(s): 3d65b9d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +63 -270
app.py CHANGED
@@ -1,278 +1,71 @@
1
- import streamlit as st
2
- from transformers import T5ForConditionalGeneration, T5Tokenizer
3
- import torch
4
- from torch.utils.data import Dataset, DataLoader
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):
12
- def __init__(self, data, tokenizer, max_length=512):
13
- self.data = data
14
- self.tokenizer = tokenizer
15
- self.max_length = max_length
16
 
17
- def __len__(self):
18
- return len(self.data)
19
-
20
- def __getitem__(self, idx):
21
- item = self.data[idx]
22
- input_encoding = self.tokenizer(
23
- f"reescreva em português natural, mantendo todas as informações: {item['input_text']}",
24
- max_length=self.max_length,
25
- padding='max_length',
26
- truncation=True,
27
- return_tensors='pt'
28
- )
29
-
30
- target_encoding = self.tokenizer(
31
- item['output_text'],
32
- max_length=self.max_length,
33
- padding='max_length',
34
- truncation=True,
35
- return_tensors='pt'
36
- )
37
-
38
- return {
39
- 'input_ids': input_encoding['input_ids'].squeeze(),
40
- 'attention_mask': input_encoding['attention_mask'].squeeze(),
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 = {
58
- 'input_text': input_text,
59
- 'output_text': output_text,
60
- 'rating': rating,
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"""
135
- text = text.strip()
136
-
137
- # Lista de prefixos de comando para remover
138
- prefixes = [
139
- "reescreva o seguinte texto",
140
- "reescreva este texto",
141
- "reescreva o texto",
142
- "traduza",
143
- "humanize:",
144
- "humanizar:",
145
- "em português",
146
- "de forma mais natural"
147
- ]
148
-
149
- # Remove os prefixos de comando
150
- text_lower = text.lower()
151
- for prefix in prefixes:
152
- if text_lower.startswith(prefix):
153
- text = text[len(prefix):].strip()
154
- text_lower = text.lower()
155
-
156
- # Capitaliza a primeira letra
157
- if text:
158
- text = text[0].upper() + text[1:]
159
-
160
- return text
161
-
162
- def humanize_text(text):
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:
207
- st.session_state.tokenizer = T5Tokenizer.from_pretrained("t5-base")
208
- st.session_state.model = T5ForConditionalGeneration.from_pretrained("t5-base")
209
- st.session_state.model_loaded = True
210
-
211
- # UI Components
212
- st.set_page_config(page_title="Advanced Text Humanizer", page_icon="🤖")
213
-
214
- st.title("🤖 → 🧑 Humanizador de Texto Avançado")
215
- st.markdown("""
216
- Este aplicativo transforma textos robotizados em linguagem mais natural e humana,
217
- mantendo todas as informações originais e incluindo sistema de feedback para melhoria contínua.
218
- """)
219
-
220
- # Input area
221
- input_text = st.text_area(
222
- "Cole seu texto de robô aqui:",
223
- height=150,
224
- help="Cole seu texto aqui para transformá-lo em uma versão mais natural e humana."
225
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
226
 
227
- # Process button and results
228
- if st.button("Humanizar", type="primary"):
229
- if not input_text:
230
- st.warning("⚠️ Por favor, cole um texto primeiro!")
231
- else:
232
- with st.spinner("Processando o texto..."):
233
- try:
234
- final_text = humanize_text(input_text)
235
-
236
- # Display results
237
- st.success("✨ Texto humanizado:")
238
- col1, col2 = st.columns(2)
239
-
240
- with col1:
241
- st.text("Original:")
242
- st.info(input_text)
243
- st.write(f"Palavras: {len(input_text.split())}")
244
-
245
- with col2:
246
- st.text("Resultado:")
247
- st.info(final_text)
248
- st.write(f"Palavras: {len(final_text.split())}")
249
-
250
- # Feedback section
251
- st.markdown("### Feedback")
252
- rating = st.slider(
253
- "Como você avalia a qualidade do texto humanizado?",
254
- min_value=1,
255
- max_value=5,
256
- value=3,
257
- help="1 = Muito ruim, 5 = Excelente"
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)}")
276
 
277
  # Footer
278
  st.markdown("---")
 
1
+ import tweepy
2
+ from transformers import pipeline, GPT2LMHeadModel, GPT2Tokenizer
 
 
 
3
  import os
 
 
4
 
5
+ # Autenticação com Twitter para leitura
6
+ client = tweepy.Client(bearer_token=os.environ.get('AAAAAAAAAAAAAAAAAAAAAFhdyAEAAAAAIG7CES2Ej98j9NGylgrb0yOrvvA%3DoSuAx9ZWUbyofrjM5VYiQBqjZA0oXXs4Ik21py9BZEn8mrAvzW'))
 
 
 
 
7
 
8
+ # Autenticação com Twitter para postagem
9
+ auth = tweepy.OAuth1UserHandler(
10
+ os.environ.get('lXr9PmhTdm2hxC20AmNIguxsn'),
11
+ os.environ.get('LMsDCue1BSBGydpC9ykw0MJTzJ35rbWwcIjkVbgp8PW1apjmFo'),
12
+ os.environ.get('69748110-yMiyeul89rwhUDJmgCNW0vfAVm3hIJRdFhOlVUc6d'),
13
+ os.environ.get('ioExZSIT0LZ5pvUXxDRtTuNUp8lCaoIP2H5vCJsphvFbk')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  )
15
+ api = tweepy.API(auth)
16
+
17
+ # Coletar tweets
18
+ query = 'BBB25 -filter:retweets'
19
+ tweets = client.search_recent_tweets(query=query, lang='pt', max_results=100)
20
+
21
+ # Análise de sentimentos
22
+ sentiment_pipeline = pipeline('sentiment-analysis', model='cardiffnlp/twitter-xlm-roberta-base-sentiment')
23
+
24
+ sentiments = []
25
+ for tweet in tweets.data:
26
+ result = sentiment_pipeline(tweet.text)
27
+ sentiments.append(result[0]['label'])
28
+
29
+ # Calcular taxas
30
+ positive = sentiments.count('positive')
31
+ negative = sentiments.count('negative')
32
+ total = len(sentiments)
33
+
34
+ positive_ratio = positive / total
35
+ negative_ratio = negative / total
36
+
37
+ # Gerar mensagem com IA
38
+ tokenizer = GPT2Tokenizer.from_pretrained('gpt2')
39
+ model = GPT2LMHeadModel.from_pretrained('gpt2')
40
+
41
+ if positive_ratio > 0.6:
42
+ prompt = "Write an exciting tweet about BBB25 with a positive tone in Portuguese."
43
+ elif negative_ratio > 0.6:
44
+ prompt = "Write an informative tweet about BBB25 with a neutral tone in Portuguese."
45
+ else:
46
+ prompt = "Write a buzzing tweet about BBB25 with an engaging tone in Portuguese."
47
+
48
+ input_ids = tokenizer.encode(prompt, return_tensors='pt')
49
+
50
+ # Gerar texto com limite de tokens correspondente a 280 caracteres
51
+ outputs = model.generate(input_ids, max_length=25, do_sample=True)
52
+ generated_text = tokenizer.decode(outputs[0], skip_special_tokens=True)
53
+
54
+ # Limitar o tweet a 280 caracteres
55
+ generated_text = generated_text[:280]
56
+
57
+ # Postar no Twitter
58
+ try:
59
+ api.update_status(status=generated_text)
60
+ print(f"Postado: {generated_text}")
61
+ except Exception as e:
62
+ print(f"Erro ao postar: {e}")
63
+
64
+ # Logging (opcional)
65
+ with open('posting_log.txt', 'a') as f:
66
+ f.write(f"Positive Ratio: {positive_ratio}, Negative Ratio: {negative_ratio}, Posted: {generated_text}\n")
67
+
68
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
 
70
  # Footer
71
  st.markdown("---")