habulaj commited on
Commit
b6db17e
·
verified ·
1 Parent(s): c1b201d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +49 -139
app.py CHANGED
@@ -10,15 +10,10 @@ import os
10
  import gc
11
  from typing import Dict, Any, Optional, List, Tuple
12
  import psutil
13
- import threading
14
- import concurrent.futures
15
  from contextlib import contextmanager
16
- import numpy as np
17
 
18
- # -------- CONFIGURAÇÕES AVANÇADAS DE OTIMIZAÇÃO --------
19
- # Configuração de CPU baseada no hardware disponível
20
  num_cores = psutil.cpu_count(logical=False)
21
- num_threads = min(4, num_cores) # Limite para evitar oversubscription
22
 
23
  os.environ["TOKENIZERS_PARALLELISM"] = "false"
24
  os.environ["OMP_NUM_THREADS"] = str(num_threads)
@@ -29,53 +24,36 @@ os.environ["NUMEXPR_NUM_THREADS"] = str(num_threads)
29
 
30
  torch.set_num_threads(num_threads)
31
  torch.set_num_interop_threads(1)
32
-
33
- # Configurações avançadas para otimização
34
  torch.backends.mkl.enabled = True
35
  torch.backends.mkldnn.enabled = True
36
  torch.backends.quantized.engine = 'qnnpack'
 
37
 
38
- # Configuração de flushing para memória
39
- torch.cuda.empty_cache = lambda: None # Evita chamadas desnecessárias
40
-
41
- # -------- LOGGING CONFIG --------
42
  logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")
43
  log = logging.getLogger("news-filter-optimized")
44
 
45
- # Configuração global para usar CPU
46
  device = "cpu"
47
  torch.set_default_device(device)
48
 
49
- # -------- OTIMIZAÇÕES DE MEMÓRIA --------
50
  @contextmanager
51
  def memory_efficient_context():
52
- """Context manager para otimizar uso de memória durante inferência"""
53
  try:
54
- # Força garbage collection antes da operação
55
  gc.collect()
56
  yield
57
  finally:
58
- # Limpa memória após a operação
59
  gc.collect()
60
 
61
  class OptimizedTokenizerWrapper:
62
- """Wrapper otimizado para tokenizer com cache de operações comuns"""
63
-
64
  def __init__(self, tokenizer):
65
  self.tokenizer = tokenizer
66
- self._encode_cache = {}
67
- self._decode_cache = {}
68
  self._template_cache = {}
69
 
70
  def apply_chat_template(self, messages, **kwargs):
71
- """Versão otimizada do chat template com cache"""
72
- # Cria key baseada no conteúdo da mensagem
73
  content = messages[0]['content'] if messages else ""
74
- key = hash(content[:100]) # Usa apenas primeiros 100 chars para key
75
 
76
  if key not in self._template_cache:
77
  result = self.tokenizer.apply_chat_template(messages, **kwargs)
78
- # Limita cache a 100 entradas
79
  if len(self._template_cache) > 100:
80
  self._template_cache.clear()
81
  self._template_cache[key] = result
@@ -83,91 +61,80 @@ class OptimizedTokenizerWrapper:
83
  return self._template_cache[key]
84
 
85
  def decode(self, *args, **kwargs):
86
- """Versão otimizada do decode"""
87
  return self.tokenizer.decode(*args, **kwargs)
88
 
89
  def __getattr__(self, name):
90
- """Proxy para outros métodos do tokenizer"""
91
  return getattr(self.tokenizer, name)
92
 
93
- # -------- CONFIGURAÇÃO DE MODELO COM OTIMIZAÇÕES AVANÇADAS --------
94
- print("🚀 Carregando modelo e tokenizer com otimizações avançadas...")
95
- log.info("🚀 Carregando modelo e tokenizer com otimizações avançadas...")
96
 
97
- # Configurações de otimização para carregamento do modelo
98
  model_config = {
99
  "device_map": device,
100
- "torch_dtype": torch.float16, # Mudança para float16 (mais rápido em algumas CPUs)
101
  "low_cpu_mem_usage": True,
102
  "use_cache": True,
103
  "trust_remote_code": True,
104
- "attn_implementation": "eager", # Implementação mais rápida para CPU
105
  }
106
 
107
- # Carrega modelo com configurações otimizadas
108
  model = AutoPeftModelForCausalLM.from_pretrained(
109
  "habulaj/filterinstruct180",
110
  **model_config
111
  )
112
 
113
- # Configuração otimizada do tokenizer
114
  tokenizer = AutoTokenizer.from_pretrained(
115
  "habulaj/filterinstruct180",
116
  use_fast=True,
117
  padding_side="left",
118
- model_max_length=1024, # Limite explícito para evitar sequências muito longas
119
- clean_up_tokenization_spaces=False, # Mais rápido
120
  )
121
 
122
- # Otimizações de tokenizer
123
  if tokenizer.pad_token is None:
124
  tokenizer.pad_token = tokenizer.eos_token
125
 
126
- # Wrapper otimizado para tokenizer
127
  tokenizer = OptimizedTokenizerWrapper(tokenizer)
128
 
129
- # -------- OTIMIZAÇÕES DE MODELO --------
130
- # Modo de avaliação com otimizações
131
  model.eval()
132
-
133
- # Otimizações específicas para inferência
134
  for param in model.parameters():
135
  param.requires_grad = False
136
 
137
- # Compila o modelo para otimização (se disponível)
138
  try:
139
  model = torch.compile(model, mode="reduce-overhead")
140
- log.info("✅ Modelo compilado com torch.compile")
141
  except Exception as e:
142
  log.warning(f"⚠️ Torch compile não disponível: {e}")
143
 
144
- # Otimização de fusão de operações
145
  if hasattr(model, 'fuse_linear_layers'):
146
  model.fuse_linear_layers()
147
 
148
- log.info("✅ Modelo carregado com otimizações avançadas.")
 
 
 
 
149
 
150
- # -------- CONFIGURAÇÃO DE TEMPLATE E GERAÇÃO --------
151
- # Chat template otimizado (sem formatação desnecessária)
152
- tokenizer.tokenizer.chat_template = """{% for message in messages %}{% if message['role'] == 'user' %}{% if loop.first %}<|begin_of_text|><|start_header_id|>user<|end_header_id|>{{ message['content'] }}<|eot_id|>{% else %}<|start_header_id|>user<|end_header_id|>{{ message['content'] }}<|eot_id|>{% endif %}{% elif message['role'] == 'assistant' %}<|start_header_id|>assistant<|end_header_id|>{{ message['content'] }}<|eot_id|>{% endif %}{% endfor %}{% if add_generation_prompt %}<|start_header_id|>assistant<|end_header_id|>{% endif %}"""
 
 
153
 
154
- # Configuração otimizada de geração
155
  generation_config = GenerationConfig(
156
- max_new_tokens=150, # Reduzido para acelerar
157
- temperature=0.8, # Reduzido para mais determinismo
158
- do_sample=False, # Desativado para maximum speed
159
  use_cache=True,
160
  eos_token_id=tokenizer.eos_token_id,
161
  pad_token_id=tokenizer.eos_token_id,
162
  repetition_penalty=1.1,
163
  length_penalty=1.0,
164
- num_beams=1, # Força greedy decoding
165
  early_stopping=True,
166
  )
167
 
168
- # -------- FUNÇÕES OTIMIZADAS --------
169
  def extract_json_optimized(text: str) -> str:
170
- """Extração otimizada de JSON com regex compilado"""
171
  if not hasattr(extract_json_optimized, 'pattern'):
172
  extract_json_optimized.pattern = re.compile(r'\{.*?\}', re.DOTALL)
173
 
@@ -175,8 +142,6 @@ def extract_json_optimized(text: str) -> str:
175
  return match.group(0) if match else text
176
 
177
  def preprocess_input_optimized(title: str, content: str) -> List[Dict[str, str]]:
178
- """Preprocessamento otimizado de entrada"""
179
- # Trunca entradas muito longas para acelerar processamento
180
  max_title_length = 100
181
  max_content_length = 500
182
 
@@ -195,26 +160,22 @@ Content: "{content}"
195
  }]
196
 
197
  def analyze_news_optimized(title: str, content: str) -> str:
198
- """Versão ultra-otimizada da análise de notícias"""
199
  try:
200
  with memory_efficient_context():
201
  start_time = time.time()
202
 
203
- # Prepara entrada otimizada
204
  messages = preprocess_input_optimized(title, content)
205
 
206
- # Tokenização otimizada
207
  inputs = tokenizer.apply_chat_template(
208
  messages,
209
  tokenize=True,
210
  add_generation_prompt=True,
211
  return_tensors="pt",
212
- padding=False, # Sem padding desnecessário
213
  truncation=True,
214
  max_length=1024,
215
  )
216
 
217
- # Inferência otimizada com múltiplas optimizações
218
  with torch.no_grad(), torch.inference_mode():
219
  with torch.autocast(device_type='cpu', dtype=torch.float16):
220
  outputs = model.generate(
@@ -226,10 +187,9 @@ def analyze_news_optimized(title: str, content: str) -> str:
226
  output_attentions=False,
227
  return_dict_in_generate=False,
228
  use_cache=True,
229
- do_sample=False, # Greedy para máxima velocidade
230
  )
231
 
232
- # Decodificação otimizada
233
  generated_tokens = outputs[0][inputs.shape[1]:]
234
  generated_text = tokenizer.decode(
235
  generated_tokens,
@@ -237,17 +197,13 @@ def analyze_news_optimized(title: str, content: str) -> str:
237
  clean_up_tokenization_spaces=False
238
  )
239
 
240
- # Extração otimizada de JSON
241
  json_result = extract_json_optimized(generated_text)
242
 
243
- # Logging de performance
244
  duration = time.time() - start_time
245
  log.info(f"✅ Análise concluída em {duration:.2f}s")
246
 
247
- # Limpeza de memória otimizada
248
  del outputs, inputs, generated_tokens
249
 
250
- # Validação de JSON otimizada
251
  try:
252
  parsed_json = json.loads(json_result)
253
  return json.dumps(parsed_json, indent=2, ensure_ascii=False)
@@ -258,26 +214,19 @@ def analyze_news_optimized(title: str, content: str) -> str:
258
  log.exception("❌ Erro durante análise:")
259
  return f"Erro durante a análise: {str(e)}"
260
 
261
- # -------- WARMUP OTIMIZADO --------
262
  def warmup_optimized():
263
- """Warmup otimizado com múltiplas execuções"""
264
- log.info("🔥 Executando warmup otimizado...")
265
  try:
266
- # Múltiplas execuções de warmup para otimizar cache
267
  for i in range(3):
268
  result = analyze_news_optimized(f"Test title {i}", f"Test content {i}")
269
  log.info(f"Warmup {i+1}/3 concluído")
270
 
271
- # Força garbage collection após warmup
272
  gc.collect()
273
- log.info("✅ Warmup otimizado concluído")
274
  except Exception as e:
275
  log.warning(f"⚠️ Warmup falhou: {e}")
276
 
277
- # -------- INTERFACE OTIMIZADA --------
278
  def create_optimized_interface():
279
- """Interface otimizada para melhor performance"""
280
-
281
  with gr.Blocks(
282
  title="Analisador de Notícias - Ultra Otimizado",
283
  theme=gr.themes.Monochrome(),
@@ -291,19 +240,10 @@ def create_optimized_interface():
291
  padding: 15px;
292
  margin: 10px 0;
293
  }
294
- .status-success {
295
- color: #28a745;
296
- font-weight: bold;
297
- }
298
- .status-error {
299
- color: #dc3545;
300
- font-weight: bold;
301
- }
302
  """
303
  ) as demo:
304
 
305
  gr.Markdown("# 🚀 Analisador de Notícias - Ultra Otimizado")
306
- gr.Markdown("🔥 Versão otimizada para máxima performance em CPU")
307
 
308
  with gr.Row():
309
  with gr.Column(scale=1):
@@ -319,9 +259,8 @@ def create_optimized_interface():
319
  max_lines=6
320
  )
321
 
322
- analyze_btn = gr.Button("⚡ Analisar Notícia (Otimizado)", variant="primary")
323
 
324
- # Exemplos
325
  with gr.Row():
326
  example_btn1 = gr.Button("📻 Exemplo 1", size="sm")
327
  example_btn2 = gr.Button("⚽ Exemplo 2", size="sm")
@@ -335,15 +274,12 @@ def create_optimized_interface():
335
  show_copy_button=True
336
  )
337
 
338
- # Status com informações de performance
339
- with gr.Row():
340
- status = gr.Textbox(
341
- label="Status",
342
- value="⚡ Pronto para análise ultra-rápida",
343
- interactive=False
344
- )
345
 
346
- # Função otimizada para análise
347
  def analyze_with_status(title: str, content: str) -> Tuple[str, str]:
348
  if not title.strip() or not content.strip():
349
  return "❌ Preencha todos os campos", "Erro: Campos obrigatórios não preenchidos"
@@ -357,65 +293,39 @@ def create_optimized_interface():
357
  except Exception as e:
358
  return f"❌ Erro: {str(e)}", f"Erro: {str(e)}"
359
 
360
- # Exemplos otimizados
361
  examples = [
362
  ("Legendary Musician Carlos Mendes Dies at 78", "Carlos Mendes, the internationally acclaimed Brazilian guitarist and composer known for blending traditional bossa nova with modern jazz, has died at the age of 78."),
363
  ("Brazil Defeats Argentina 2-1 in Copa America Final", "In a thrilling match at the Maracana Stadium, Brazil secured victory over Argentina with goals from Neymar and Vinicius Jr. The match was watched by over 200 million viewers worldwide."),
364
  ("Tech Giant Announces Major Layoffs Affecting 10,000 Employees", "The technology company announced significant workforce reductions citing economic uncertainty and changing market conditions. The layoffs will affect multiple departments across different regions.")
365
  ]
366
 
367
- # Event handlers
368
  analyze_btn.click(
369
  fn=analyze_with_status,
370
  inputs=[title_input, content_input],
371
  outputs=[status, output]
372
  )
373
 
374
- for i, (title, content) in enumerate(examples):
375
- locals()[f'example_btn{i+1}'].click(
376
- fn=lambda t=title, c=content: (t, c),
377
- outputs=[title_input, content_input]
378
- )
379
 
380
- # Informações de otimização
381
- with gr.Accordion("⚡ Otimizações Aplicadas", open=False):
382
- gr.Markdown(f"""
383
- **Otimizações de Hardware:**
384
- - Threads otimizadas: {num_threads} threads para {num_cores} cores
385
- - MKL/BLAS otimizado para operações matemáticas
386
- - Floating point otimizado (float16 com autocast)
387
- - Torch.compile ativado (se disponível)
388
-
389
- **Otimizações de Modelo:**
390
- - Modo de inferência com torch.inference_mode()
391
- - Cache de tokenização inteligente
392
- - Processamento sem gradientes
393
- - Fusão de camadas lineares
394
- - Greedy decoding para máxima velocidade
395
-
396
- **Otimizações de Memória:**
397
- - Garbage collection otimizado
398
- - Context manager para gestão de memória
399
- - Limpeza automática de tensores
400
- - Limite de tamanho de entrada
401
-
402
- **Otimizações de I/O:**
403
- - Regex compilado para extração JSON
404
- - Preprocessamento otimizado
405
- - Cache inteligente de operações
406
- - Múltiplas execuções de warmup
407
-
408
- ⚡ **Resultado esperado:** 30-50% mais rápido que a versão anterior
409
- """)
410
 
411
  return demo
412
 
413
- # -------- EXECUÇÃO PRINCIPAL --------
414
  if __name__ == "__main__":
415
- # Executa warmup otimizado
416
  warmup_optimized()
417
 
418
- print("🚀 Iniciando interface ultra-otimizada...")
419
  demo = create_optimized_interface()
420
  demo.launch(
421
  share=False,
@@ -423,5 +333,5 @@ if __name__ == "__main__":
423
  server_port=7860,
424
  show_error=True,
425
  max_threads=num_threads,
426
- show_api=False, # Desativa API para economizar recursos
427
  )
 
10
  import gc
11
  from typing import Dict, Any, Optional, List, Tuple
12
  import psutil
 
 
13
  from contextlib import contextmanager
 
14
 
 
 
15
  num_cores = psutil.cpu_count(logical=False)
16
+ num_threads = min(4, num_cores)
17
 
18
  os.environ["TOKENIZERS_PARALLELISM"] = "false"
19
  os.environ["OMP_NUM_THREADS"] = str(num_threads)
 
24
 
25
  torch.set_num_threads(num_threads)
26
  torch.set_num_interop_threads(1)
 
 
27
  torch.backends.mkl.enabled = True
28
  torch.backends.mkldnn.enabled = True
29
  torch.backends.quantized.engine = 'qnnpack'
30
+ torch.cuda.empty_cache = lambda: None
31
 
 
 
 
 
32
  logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")
33
  log = logging.getLogger("news-filter-optimized")
34
 
 
35
  device = "cpu"
36
  torch.set_default_device(device)
37
 
 
38
  @contextmanager
39
  def memory_efficient_context():
 
40
  try:
 
41
  gc.collect()
42
  yield
43
  finally:
 
44
  gc.collect()
45
 
46
  class OptimizedTokenizerWrapper:
 
 
47
  def __init__(self, tokenizer):
48
  self.tokenizer = tokenizer
 
 
49
  self._template_cache = {}
50
 
51
  def apply_chat_template(self, messages, **kwargs):
 
 
52
  content = messages[0]['content'] if messages else ""
53
+ key = hash(content[:100])
54
 
55
  if key not in self._template_cache:
56
  result = self.tokenizer.apply_chat_template(messages, **kwargs)
 
57
  if len(self._template_cache) > 100:
58
  self._template_cache.clear()
59
  self._template_cache[key] = result
 
61
  return self._template_cache[key]
62
 
63
  def decode(self, *args, **kwargs):
 
64
  return self.tokenizer.decode(*args, **kwargs)
65
 
66
  def __getattr__(self, name):
 
67
  return getattr(self.tokenizer, name)
68
 
69
+ print("🚀 Carregando modelo...")
70
+ log.info("🚀 Carregando modelo...")
 
71
 
 
72
  model_config = {
73
  "device_map": device,
74
+ "torch_dtype": torch.float16,
75
  "low_cpu_mem_usage": True,
76
  "use_cache": True,
77
  "trust_remote_code": True,
78
+ "attn_implementation": "eager",
79
  }
80
 
 
81
  model = AutoPeftModelForCausalLM.from_pretrained(
82
  "habulaj/filterinstruct180",
83
  **model_config
84
  )
85
 
 
86
  tokenizer = AutoTokenizer.from_pretrained(
87
  "habulaj/filterinstruct180",
88
  use_fast=True,
89
  padding_side="left",
90
+ model_max_length=1024,
91
+ clean_up_tokenization_spaces=False,
92
  )
93
 
 
94
  if tokenizer.pad_token is None:
95
  tokenizer.pad_token = tokenizer.eos_token
96
 
 
97
  tokenizer = OptimizedTokenizerWrapper(tokenizer)
98
 
 
 
99
  model.eval()
 
 
100
  for param in model.parameters():
101
  param.requires_grad = False
102
 
 
103
  try:
104
  model = torch.compile(model, mode="reduce-overhead")
105
+ log.info("✅ Modelo compilado")
106
  except Exception as e:
107
  log.warning(f"⚠️ Torch compile não disponível: {e}")
108
 
 
109
  if hasattr(model, 'fuse_linear_layers'):
110
  model.fuse_linear_layers()
111
 
112
+ log.info("✅ Modelo carregado")
113
+
114
+ tokenizer.tokenizer.chat_template = """{% for message in messages %}{% if message['role'] == 'user' %}{% if loop.first %}<|begin_of_text|><|start_header_id|>user<|end_header_id|>
115
+
116
+ {{ message['content'] }}<|eot_id|>{% else %}<|start_header_id|>user<|end_header_id|>
117
 
118
+ {{ message['content'] }}<|eot_id|>{% endif %}{% elif message['role'] == 'assistant' %}<|start_header_id|>assistant<|end_header_id|>
119
+
120
+ {{ message['content'] }}<|eot_id|>{% endif %}{% endfor %}{% if add_generation_prompt %}<|start_header_id|>assistant<|end_header_id|>
121
+
122
+ {% endif %}"""
123
 
 
124
  generation_config = GenerationConfig(
125
+ max_new_tokens=150,
126
+ temperature=0.8,
127
+ do_sample=False,
128
  use_cache=True,
129
  eos_token_id=tokenizer.eos_token_id,
130
  pad_token_id=tokenizer.eos_token_id,
131
  repetition_penalty=1.1,
132
  length_penalty=1.0,
133
+ num_beams=1,
134
  early_stopping=True,
135
  )
136
 
 
137
  def extract_json_optimized(text: str) -> str:
 
138
  if not hasattr(extract_json_optimized, 'pattern'):
139
  extract_json_optimized.pattern = re.compile(r'\{.*?\}', re.DOTALL)
140
 
 
142
  return match.group(0) if match else text
143
 
144
  def preprocess_input_optimized(title: str, content: str) -> List[Dict[str, str]]:
 
 
145
  max_title_length = 100
146
  max_content_length = 500
147
 
 
160
  }]
161
 
162
  def analyze_news_optimized(title: str, content: str) -> str:
 
163
  try:
164
  with memory_efficient_context():
165
  start_time = time.time()
166
 
 
167
  messages = preprocess_input_optimized(title, content)
168
 
 
169
  inputs = tokenizer.apply_chat_template(
170
  messages,
171
  tokenize=True,
172
  add_generation_prompt=True,
173
  return_tensors="pt",
174
+ padding=False,
175
  truncation=True,
176
  max_length=1024,
177
  )
178
 
 
179
  with torch.no_grad(), torch.inference_mode():
180
  with torch.autocast(device_type='cpu', dtype=torch.float16):
181
  outputs = model.generate(
 
187
  output_attentions=False,
188
  return_dict_in_generate=False,
189
  use_cache=True,
190
+ do_sample=False,
191
  )
192
 
 
193
  generated_tokens = outputs[0][inputs.shape[1]:]
194
  generated_text = tokenizer.decode(
195
  generated_tokens,
 
197
  clean_up_tokenization_spaces=False
198
  )
199
 
 
200
  json_result = extract_json_optimized(generated_text)
201
 
 
202
  duration = time.time() - start_time
203
  log.info(f"✅ Análise concluída em {duration:.2f}s")
204
 
 
205
  del outputs, inputs, generated_tokens
206
 
 
207
  try:
208
  parsed_json = json.loads(json_result)
209
  return json.dumps(parsed_json, indent=2, ensure_ascii=False)
 
214
  log.exception("❌ Erro durante análise:")
215
  return f"Erro durante a análise: {str(e)}"
216
 
 
217
  def warmup_optimized():
218
+ log.info("🔥 Executando warmup...")
 
219
  try:
 
220
  for i in range(3):
221
  result = analyze_news_optimized(f"Test title {i}", f"Test content {i}")
222
  log.info(f"Warmup {i+1}/3 concluído")
223
 
 
224
  gc.collect()
225
+ log.info("✅ Warmup concluído")
226
  except Exception as e:
227
  log.warning(f"⚠️ Warmup falhou: {e}")
228
 
 
229
  def create_optimized_interface():
 
 
230
  with gr.Blocks(
231
  title="Analisador de Notícias - Ultra Otimizado",
232
  theme=gr.themes.Monochrome(),
 
240
  padding: 15px;
241
  margin: 10px 0;
242
  }
 
 
 
 
 
 
 
 
243
  """
244
  ) as demo:
245
 
246
  gr.Markdown("# 🚀 Analisador de Notícias - Ultra Otimizado")
 
247
 
248
  with gr.Row():
249
  with gr.Column(scale=1):
 
259
  max_lines=6
260
  )
261
 
262
+ analyze_btn = gr.Button("⚡ Analisar Notícia", variant="primary")
263
 
 
264
  with gr.Row():
265
  example_btn1 = gr.Button("📻 Exemplo 1", size="sm")
266
  example_btn2 = gr.Button("⚽ Exemplo 2", size="sm")
 
274
  show_copy_button=True
275
  )
276
 
277
+ status = gr.Textbox(
278
+ label="Status",
279
+ value="⚡ Pronto para análise",
280
+ interactive=False
281
+ )
 
 
282
 
 
283
  def analyze_with_status(title: str, content: str) -> Tuple[str, str]:
284
  if not title.strip() or not content.strip():
285
  return "❌ Preencha todos os campos", "Erro: Campos obrigatórios não preenchidos"
 
293
  except Exception as e:
294
  return f"❌ Erro: {str(e)}", f"Erro: {str(e)}"
295
 
 
296
  examples = [
297
  ("Legendary Musician Carlos Mendes Dies at 78", "Carlos Mendes, the internationally acclaimed Brazilian guitarist and composer known for blending traditional bossa nova with modern jazz, has died at the age of 78."),
298
  ("Brazil Defeats Argentina 2-1 in Copa America Final", "In a thrilling match at the Maracana Stadium, Brazil secured victory over Argentina with goals from Neymar and Vinicius Jr. The match was watched by over 200 million viewers worldwide."),
299
  ("Tech Giant Announces Major Layoffs Affecting 10,000 Employees", "The technology company announced significant workforce reductions citing economic uncertainty and changing market conditions. The layoffs will affect multiple departments across different regions.")
300
  ]
301
 
 
302
  analyze_btn.click(
303
  fn=analyze_with_status,
304
  inputs=[title_input, content_input],
305
  outputs=[status, output]
306
  )
307
 
308
+ example_btn1.click(
309
+ fn=lambda: examples[0],
310
+ outputs=[title_input, content_input]
311
+ )
 
312
 
313
+ example_btn2.click(
314
+ fn=lambda: examples[1],
315
+ outputs=[title_input, content_input]
316
+ )
317
+
318
+ example_btn3.click(
319
+ fn=lambda: examples[2],
320
+ outputs=[title_input, content_input]
321
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
322
 
323
  return demo
324
 
 
325
  if __name__ == "__main__":
 
326
  warmup_optimized()
327
 
328
+ print("🚀 Iniciando interface...")
329
  demo = create_optimized_interface()
330
  demo.launch(
331
  share=False,
 
333
  server_port=7860,
334
  show_error=True,
335
  max_threads=num_threads,
336
+ show_api=False,
337
  )