Lukeetah commited on
Commit
2a02792
·
verified ·
1 Parent(s): 52c1a75

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +569 -35
app.py CHANGED
@@ -1,41 +1,575 @@
1
- import gradio as gr
2
- from modules.analyzer import UltraAnalyzer
3
- from modules.visualization import create_consciousness_map, create_evolution_timeline, create_quantum_network
4
- from modules.fallback import minimal_response
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
 
6
- # Init
7
- analyzer = UltraAnalyzer()
8
- history = []
 
 
 
 
 
 
 
9
 
10
- def main_interface(text, deep_mode=False):
11
- if not text.strip():
12
- return minimal_response("Transmite tu pensamiento."), None, None, None
13
- try:
14
- result = analyzer.analyze(text, deep_mode)
15
- history.append(result)
16
- return (
17
- result["response_md"],
18
- create_consciousness_map(result),
19
- create_evolution_timeline(result["future_scenarios"]),
20
- create_quantum_network(result)
21
- )
22
- except Exception as e:
23
- return minimal_response(str(e)), None, None, None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
 
25
- # UI
26
- with gr.Blocks(title="Nexus Metamorphosis Ultra (PROD)") as app:
27
- gr.Markdown("# 🌌 Nexus Metamorphosis Ultra (PROD)")
28
- with gr.Row():
29
- inp = gr.Textbox(label="🧠 Tu pensamiento")
30
- deep = gr.Checkbox(label="Modo profundo", value=False)
31
- btn = gr.Button("🚀 Analizar")
32
- map_plot = gr.Plot(label="Mapa de Conciencia")
33
- timeline = gr.Plot(label="Timeline Evolutivo")
34
- network = gr.Plot(label="Red Cuántica")
35
- out_md = gr.Markdown()
36
 
37
- btn.click(main_interface, [inp, deep], [out_md, map_plot, timeline, network], api_name="analyze")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
 
39
- # Launch sin enable_queue
40
  if __name__ == "__main__":
41
- app.launch(server_name="0.0.0.0", server_port=7860) # [10]
 
 
 
 
 
 
 
 
1
+ mport gradio as gr
2
+ import torch
3
+ import torch.nn as nn
4
+ import numpy as np
5
+ import pandas as pd
6
+ from typing import Dict, List, Tuple, Optional, Union
7
+ import asyncio
8
+ import logging
9
+ from pathlib import Path
10
+ import json
11
+ import pickle
12
+ import requests
13
+ from PIL import Image
14
+ import librosa
15
+ import cv2
16
+ from transformers import (
17
+ AutoTokenizer, AutoModel, AutoProcessor,
18
+ BlipProcessor, BlipForConditionalGeneration,
19
+ pipeline
20
+ )
21
+ from sentence_transformers import SentenceTransformer
22
+ import umap
23
+ from sklearn.manifold import TSNE
24
+ from sklearn.cluster import DBSCAN
25
+ from sklearn.preprocessing import StandardScaler
26
+ import plotly.express as px
27
+ import plotly.graph_objects as go
28
+ from datetime import datetime
29
+ import warnings
30
+ warnings.filterwarnings('ignore')
31
 
32
+ # Configuración de logging avanzado
33
+ logging.basicConfig(
34
+ level=logging.INFO,
35
+ format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
36
+ handlers=[
37
+ logging.FileHandler('multimodal_system.log'),
38
+ logging.StreamHandler()
39
+ ]
40
+ )
41
+ logger = logging.getLogger(__name__)
42
 
43
+ class MultimodalAISystem:
44
+ """
45
+ Sistema principal de IA Multimodal que orquesta todos los componentes
46
+ del pipeline de procesamiento avanzado
47
+ """
48
+
49
+ def __init__(self):
50
+ """Inicialización del sistema multimodal con carga diferida de modelos"""
51
+ self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
52
+ logger.info(f"Sistema iniciado en dispositivo: {self.device}")
53
+
54
+ # Diccionario para almacenar modelos cargados
55
+ self.models = {}
56
+ self.processors = {}
57
+ self.embeddings_cache = {}
58
+
59
+ # Configuración de parámetros del sistema
60
+ self.config = {
61
+ 'max_text_length': 512,
62
+ 'image_size': (224, 224),
63
+ 'audio_sample_rate': 16000,
64
+ 'embedding_dim': 768,
65
+ 'clustering_eps': 0.5,
66
+ 'umap_n_components': 2,
67
+ 'tsne_perplexity': 30
68
+ }
69
+
70
+ # Inicializar componentes principales
71
+ self._initialize_system()
72
+
73
+ def _initialize_system(self):
74
+ """Inicialización diferida del sistema para optimizar memoria"""
75
+ try:
76
+ # Inicializar procesador de texto
77
+ self._load_text_models()
78
+
79
+ # Inicializar procesador de imágenes
80
+ self._load_vision_models()
81
+
82
+ # Configurar reducción dimensional
83
+ self._setup_dimensionality_reduction()
84
+
85
+ logger.info("Sistema multimodal inicializado correctamente")
86
+
87
+ except Exception as e:
88
+ logger.error(f"Error en inicialización del sistema: {str(e)}")
89
+ raise
90
+
91
+ def _load_text_models(self):
92
+ """Carga modelos de procesamiento de texto"""
93
+ try:
94
+ model_name = "sentence-transformers/all-MiniLM-L6-v2"
95
+ self.models['text_embedder'] = SentenceTransformer(model_name)
96
+
97
+ # Configurar pipeline de análisis de sentimientos
98
+ self.models['sentiment'] = pipeline(
99
+ "sentiment-analysis",
100
+ model="cardiffnlp/twitter-roberta-base-sentiment-latest",
101
+ return_all_scores=True
102
+ )
103
+
104
+ logger.info("Modelos de texto cargados exitosamente")
105
+
106
+ except Exception as e:
107
+ logger.error(f"Error cargando modelos de texto: {str(e)}")
108
+ # Fallback a modelo básico
109
+ self.models['text_embedder'] = None
110
+
111
+ def _load_vision_models(self):
112
+ """Carga modelos de procesamiento de imágenes"""
113
+ try:
114
+ # Cargar modelo BLIP para tareas visión-lenguaje
115
+ processor = BlipProcessor.from_pretrained("Salesforce/blip-image-captioning-base")
116
+ model = BlipForConditionalGeneration.from_pretrained("Salesforce/blip-image-captioning-base")
117
+
118
+ self.processors['blip'] = processor
119
+ self.models['blip'] = model.to(self.device)
120
+
121
+ # Pipeline de clasificación de imágenes
122
+ self.models['image_classifier'] = pipeline(
123
+ "image-classification",
124
+ model="google/vit-base-patch16-224"
125
+ )
126
+
127
+ logger.info("Modelos de visión cargados exitosamente")
128
+
129
+ except Exception as e:
130
+ logger.error(f"Error cargando modelos de visión: {str(e)}")
131
+
132
+ def _setup_dimensionality_reduction(self):
133
+ """Configuración de algoritmos de reducción dimensional"""
134
+ self.reducers = {
135
+ 'umap': umap.UMAP(
136
+ n_components=self.config['umap_n_components'],
137
+ random_state=42,
138
+ n_neighbors=15,
139
+ min_dist=0.1
140
+ ),
141
+ 'tsne': TSNE(
142
+ n_components=2,
143
+ perplexity=self.config['tsne_perplexity'],
144
+ random_state=42
145
+ ),
146
+ 'dbscan': DBSCAN(
147
+ eps=self.config['clustering_eps'],
148
+ min_samples=5
149
+ )
150
+ }
151
+
152
+ async def process_multimodal_input(
153
+ self,
154
+ text_input: str = None,
155
+ image_input = None,
156
+ audio_input = None
157
+ ) -> Dict:
158
+ """
159
+ Procesamiento asíncrono de entrada multimodal
160
+
161
+ Args:
162
+ text_input: Texto para procesar
163
+ image_input: Imagen PIL o path
164
+ audio_input: Array de audio o path
165
+
166
+ Returns:
167
+ Diccionario con resultados del procesamiento
168
+ """
169
+ results = {
170
+ 'timestamp': datetime.now().isoformat(),
171
+ 'processing_status': 'initiated',
172
+ 'embeddings': {},
173
+ 'analysis': {},
174
+ 'visualizations': {}
175
+ }
176
+
177
+ try:
178
+ # Procesar texto si está disponible
179
+ if text_input and text_input.strip():
180
+ text_results = await self._process_text(text_input)
181
+ results['embeddings']['text'] = text_results['embedding']
182
+ results['analysis']['text'] = text_results['analysis']
183
+
184
+ # Procesar imagen si está disponible
185
+ if image_input is not None:
186
+ image_results = await self._process_image(image_input)
187
+ results['embeddings']['image'] = image_results['embedding']
188
+ results['analysis']['image'] = image_results['analysis']
189
+
190
+ # Procesar audio si está disponible
191
+ if audio_input is not None:
192
+ audio_results = await self._process_audio(audio_input)
193
+ results['embeddings']['audio'] = audio_results['embedding']
194
+ results['analysis']['audio'] = audio_results['analysis']
195
+
196
+ # Generar visualizaciones si hay múltiples modalidades
197
+ if len(results['embeddings']) > 1:
198
+ vis_results = await self._generate_multimodal_visualizations(results['embeddings'])
199
+ results['visualizations'] = vis_results
200
+
201
+ results['processing_status'] = 'completed'
202
+ logger.info("Procesamiento multimodal completado exitosamente")
203
+
204
+ except Exception as e:
205
+ results['processing_status'] = 'error'
206
+ results['error'] = str(e)
207
+ logger.error(f"Error en procesamiento multimodal: {str(e)}")
208
+
209
+ return results
210
+
211
+ async def _process_text(self, text: str) -> Dict:
212
+ """Procesamiento avanzado de texto con múltiples análisis"""
213
+ try:
214
+ # Generar embedding del texto
215
+ embedding = self.models['text_embedder'].encode([text])[0]
216
+
217
+ # Análisis de sentimientos
218
+ sentiment_results = self.models['sentiment'](text)
219
+
220
+ # Análisis estadístico básico
221
+ text_stats = {
222
+ 'length': len(text),
223
+ 'words': len(text.split()),
224
+ 'sentences': len([s for s in text.split('.') if s.strip()]),
225
+ 'avg_word_length': np.mean([len(word) for word in text.split()])
226
+ }
227
+
228
+ return {
229
+ 'embedding': embedding.tolist(),
230
+ 'analysis': {
231
+ 'sentiment': sentiment_results,
232
+ 'statistics': text_stats,
233
+ 'processed_text': text[:200] + "..." if len(text) > 200 else text
234
+ }
235
+ }
236
+
237
+ except Exception as e:
238
+ logger.error(f"Error procesando texto: {str(e)}")
239
+ return {'embedding': None, 'analysis': {'error': str(e)}}
240
+
241
+ async def _process_image(self, image) -> Dict:
242
+ """Procesamiento avanzado de imágenes con múltiples técnicas"""
243
+ try:
244
+ # Convertir a PIL Image si es necesario
245
+ if isinstance(image, str):
246
+ image = Image.open(image)
247
+ elif isinstance(image, np.ndarray):
248
+ image = Image.fromarray(image)
249
+
250
+ # Generar caption con BLIP
251
+ inputs = self.processors['blip'](image, return_tensors="pt").to(self.device)
252
+ with torch.no_grad():
253
+ generated_ids = self.models['blip'].generate(**inputs, max_length=50)
254
+ caption = self.processors['blip'].decode(generated_ids[0], skip_special_tokens=True)
255
+
256
+ # Clasificación de imagen
257
+ classification_results = self.models['image_classifier'](image)
258
+
259
+ # Generar embedding de la imagen usando el caption
260
+ caption_embedding = self.models['text_embedder'].encode([caption])[0]
261
+
262
+ # Análisis de propiedades de imagen
263
+ img_array = np.array(image)
264
+ image_stats = {
265
+ 'size': image.size,
266
+ 'mode': image.mode,
267
+ 'mean_brightness': np.mean(img_array),
268
+ 'std_brightness': np.std(img_array),
269
+ 'aspect_ratio': image.size[0] / image.size[1]
270
+ }
271
+
272
+ return {
273
+ 'embedding': caption_embedding.tolist(),
274
+ 'analysis': {
275
+ 'caption': caption,
276
+ 'classification': classification_results,
277
+ 'statistics': image_stats
278
+ }
279
+ }
280
+
281
+ except Exception as e:
282
+ logger.error(f"Error procesando imagen: {str(e)}")
283
+ return {'embedding': None, 'analysis': {'error': str(e)}}
284
+
285
+ async def _process_audio(self, audio_input) -> Dict:
286
+ """Procesamiento básico de audio (placeholder para implementación futura)"""
287
+ try:
288
+ # Esta es una implementación básica
289
+ # En producción se implementarían modelos como Whisper para transcripción
290
+
291
+ # Simular procesamiento de audio
292
+ dummy_embedding = np.random.rand(768).tolist()
293
+
294
+ audio_analysis = {
295
+ 'transcription': 'Transcripción automática no disponible en esta versión',
296
+ 'duration': 'Desconocido',
297
+ 'sample_rate': self.config['audio_sample_rate']
298
+ }
299
+
300
+ return {
301
+ 'embedding': dummy_embedding,
302
+ 'analysis': audio_analysis
303
+ }
304
+
305
+ except Exception as e:
306
+ logger.error(f"Error procesando audio: {str(e)}")
307
+ return {'embedding': None, 'analysis': {'error': str(e)}}
308
+
309
+ async def _generate_multimodal_visualizations(self, embeddings: Dict) -> Dict:
310
+ """Generación de visualizaciones avanzadas para datos multimodales"""
311
+ try:
312
+ # Combinar embeddings de diferentes modalidades
313
+ combined_embeddings = []
314
+ modality_labels = []
315
+
316
+ for modality, embedding in embeddings.items():
317
+ if embedding is not None:
318
+ combined_embeddings.append(embedding)
319
+ modality_labels.append(modality)
320
+
321
+ if len(combined_embeddings) < 2:
322
+ return {'message': 'Se requieren al menos 2 modalidades para visualización'}
323
+
324
+ # Aplicar UMAP para reducción dimensional
325
+ embeddings_array = np.array(combined_embeddings)
326
+ umap_result = self.reducers['umap'].fit_transform(embeddings_array)
327
+
328
+ # Crear visualización con Plotly
329
+ fig = px.scatter(
330
+ x=umap_result[:, 0],
331
+ y=umap_result[:, 1],
332
+ color=modality_labels,
333
+ title="Proyección UMAP de Embeddings Multimodales",
334
+ labels={'x': 'UMAP 1', 'y': 'UMAP 2'},
335
+ width=800,
336
+ height=600
337
+ )
338
+
339
+ fig.update_traces(marker=dict(size=12, opacity=0.8))
340
+ fig.update_layout(
341
+ template='plotly_white',
342
+ title_font_size=16,
343
+ showlegend=True
344
+ )
345
+
346
+ return {
347
+ 'umap_projection': fig,
348
+ 'embedding_similarity': self._calculate_embedding_similarities(embeddings),
349
+ 'cluster_analysis': self._perform_clustering_analysis(embeddings_array)
350
+ }
351
+
352
+ except Exception as e:
353
+ logger.error(f"Error generando visualizaciones: {str(e)}")
354
+ return {'error': str(e)}
355
+
356
+ def _calculate_embedding_similarities(self, embeddings: Dict) -> Dict:
357
+ """Cálculo de similitudes entre embeddings de diferentes modalidades"""
358
+ from sklearn.metrics.pairwise import cosine_similarity
359
+
360
+ similarities = {}
361
+ modalities = list(embeddings.keys())
362
+
363
+ for i, mod1 in enumerate(modalities):
364
+ for j, mod2 in enumerate(modalities):
365
+ if i < j and embeddings[mod1] is not None and embeddings[mod2] is not None:
366
+ sim = cosine_similarity(
367
+ [embeddings[mod1]],
368
+ [embeddings[mod2]]
369
+ )[0][0]
370
+ similarities[f"{mod1}_vs_{mod2}"] = float(sim)
371
+
372
+ return similarities
373
+
374
+ def _perform_clustering_analysis(self, embeddings_array: np.ndarray) -> Dict:
375
+ """Análisis de clustering sobre embeddings multimodales"""
376
+ try:
377
+ # Normalizar embeddings
378
+ scaler = StandardScaler()
379
+ normalized_embeddings = scaler.fit_transform(embeddings_array)
380
+
381
+ # Aplicar DBSCAN
382
+ clusters = self.reducers['dbscan'].fit_predict(normalized_embeddings)
383
+
384
+ cluster_info = {
385
+ 'n_clusters': len(set(clusters)) - (1 if -1 in clusters else 0),
386
+ 'noise_points': list(clusters).count(-1),
387
+ 'cluster_labels': clusters.tolist()
388
+ }
389
+
390
+ return cluster_info
391
+
392
+ except Exception as e:
393
+ logger.error(f"Error en análisis de clustering: {str(e)}")
394
+ return {'error': str(e)}
395
+
396
+ # Instancia global del sistema
397
+ ai_system = MultimodalAISystem()
398
+
399
+ def create_gradio_interface():
400
+ """Creación de la interfaz Gradio avanzada con múltiples componentes"""
401
+
402
+ def process_inputs(text_input, image_input, audio_input):
403
+ """Función wrapper para procesamiento asíncrono en Gradio"""
404
+ loop = asyncio.new_event_loop()
405
+ asyncio.set_event_loop(loop)
406
+
407
+ try:
408
+ result = loop.run_until_complete(
409
+ ai_system.process_multimodal_input(text_input, image_input, audio_input)
410
+ )
411
+
412
+ # Formatear resultados para la interfaz
413
+ output_text = f"""
414
+ 🤖 **ANÁLISIS MULTIMODAL COMPLETADO**
415
 
416
+ **Timestamp**: {result['timestamp']}
417
+ 📊 **Estado**: {result['processing_status']}
 
 
 
 
 
 
 
 
 
418
 
419
+ """
420
+
421
+ # Agregar análisis de texto
422
+ if 'text' in result['analysis']:
423
+ text_analysis = result['analysis']['text']
424
+ output_text += f"""
425
+ 📝 **ANÁLISIS DE TEXTO**:
426
+ - Estadísticas: {text_analysis.get('statistics', {})}
427
+ - Sentimiento: {text_analysis.get('sentiment', 'No disponible')}
428
+ """
429
+
430
+ # Agregar análisis de imagen
431
+ if 'image' in result['analysis']:
432
+ image_analysis = result['analysis']['image']
433
+ output_text += f"""
434
+ 🖼️ **ANÁLISIS DE IMAGEN**:
435
+ - Caption generado: {image_analysis.get('caption', 'No disponible')}
436
+ - Clasificación: {image_analysis.get('classification', [])}
437
+ """
438
+
439
+ # Agregar similitudes si existen
440
+ if 'embedding_similarity' in result.get('visualizations', {}):
441
+ similarities = result['visualizations']['embedding_similarity']
442
+ output_text += f"""
443
+ 🔗 **SIMILITUDES ENTRE MODALIDADES**:
444
+ {json.dumps(similarities, indent=2)}
445
+ """
446
+
447
+ # Retornar visualización si existe
448
+ visualization = None
449
+ if 'umap_projection' in result.get('visualizations', {}):
450
+ visualization = result['visualizations']['umap_projection']
451
+
452
+ return output_text, visualization
453
+
454
+ except Exception as e:
455
+ error_msg = f"❌ **ERROR EN PROCESAMIENTO**: {str(e)}"
456
+ return error_msg, None
457
+
458
+ finally:
459
+ loop.close()
460
+
461
+ # Crear interfaz Gradio con tema personalizado
462
+ with gr.Blocks(
463
+ theme=gr.themes.Soft(),
464
+ title="🧠 Sistema de IA Multimodal Avanzado",
465
+ css="""
466
+ .gradio-container {
467
+ max-width: 1200px !important;
468
+ margin: auto;
469
+ }
470
+ .main-title {
471
+ text-align: center;
472
+ background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
473
+ -webkit-background-clip: text;
474
+ -webkit-text-fill-color: transparent;
475
+ font-size: 2.5em;
476
+ font-weight: bold;
477
+ margin-bottom: 1em;
478
+ }
479
+ """
480
+ ) as interface:
481
+
482
+ gr.HTML("""
483
+ <div class="main-title">
484
+ 🧠 Sistema de IA Multimodal Avanzado
485
+ </div>
486
+ <p style="text-align: center; font-size: 1.2em; color: #666;">
487
+ Procesamiento inteligente de texto, imágenes y audio con algoritmos de vanguardia
488
+ </p>
489
+ """)
490
+
491
+ with gr.Row():
492
+ with gr.Column(scale=1):
493
+ gr.Markdown("### 📊 **Panel de Entrada**")
494
+
495
+ text_input = gr.Textbox(
496
+ label="📝 Entrada de Texto",
497
+ placeholder="Ingrese texto para análisis semántico...",
498
+ lines=4,
499
+ max_lines=10
500
+ )
501
+
502
+ image_input = gr.Image(
503
+ label="🖼️ Entrada de Imagen",
504
+ type="pil",
505
+ sources=["upload", "webcam"]
506
+ )
507
+
508
+ audio_input = gr.Audio(
509
+ label="🎵 Entrada de Audio",
510
+ type="filepath",
511
+ sources=["upload", "microphone"]
512
+ )
513
+
514
+ process_btn = gr.Button(
515
+ "🚀 Procesar Entrada Multimodal",
516
+ variant="primary",
517
+ size="lg"
518
+ )
519
+
520
+ with gr.Column(scale=2):
521
+ gr.Markdown("### 📈 **Resultados del Análisis**")
522
+
523
+ output_text = gr.Textbox(
524
+ label="📊 Análisis Detallado",
525
+ lines=15,
526
+ max_lines=20,
527
+ interactive=False
528
+ )
529
+
530
+ output_plot = gr.Plot(
531
+ label="📈 Visualización de Embeddings",
532
+ visible=True
533
+ )
534
+
535
+ with gr.Row():
536
+ gr.Markdown("""
537
+ ### 🔧 **Características del Sistema**
538
+
539
+ - **🧠 Procesamiento de Lenguaje Natural**: Análisis semántico y de sentimientos
540
+ - **👁️ Visión Computacional**: Generación de captions y clasificación de imágenes
541
+ - **🎵 Procesamiento de Audio**: Transcripción y análisis acústico
542
+ - **📊 Reducción Dimensional**: UMAP, t-SNE y clustering con DBSCAN
543
+ - **🔗 Análisis Cross-Modal**: Similitudes entre diferentes modalidades
544
+ - **📈 Visualizaciones Interactivas**: Proyecciones y análisis visual
545
+ """)
546
+
547
+ # Conectar eventos
548
+ process_btn.click(
549
+ fn=process_inputs,
550
+ inputs=[text_input, image_input, audio_input],
551
+ outputs=[output_text, output_plot]
552
+ )
553
+
554
+ # Ejemplos predefinidos
555
+ gr.Examples(
556
+ examples=[
557
+ ["Analiza este texto sobre inteligencia artificial", None, None],
558
+ ["", "https://picsum.photos/400/300", None],
559
+ ["Combina análisis de texto e imagen", "https://picsum.photos/400/300", None]
560
+ ],
561
+ inputs=[text_input, image_input, audio_input]
562
+ )
563
+
564
+ return interface
565
 
566
+ # Lanzar aplicación
567
  if __name__ == "__main__":
568
+ demo = create_gradio_interface()
569
+ demo.launch(
570
+ server_name="0.0.0.0",
571
+ server_port=7860,
572
+ share=False,
573
+ debug=False,
574
+ show_error=True
575
+ )