teszenofficial commited on
Commit
cda7b0a
·
verified ·
1 Parent(s): 82bb8af

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +141 -116
app.py CHANGED
@@ -36,12 +36,12 @@ print(f"📦 Descargando modelo desde {MODEL_REPO}...")
36
  repo_path = snapshot_download(
37
  repo_id=MODEL_REPO,
38
  repo_type="model",
39
- local_dir="mtptz_repo"
40
  )
41
 
42
  sys.path.insert(0, repo_path)
43
 
44
- # Importar modelo mejorado compatible
45
  from model import MTPMiniModel
46
  from tokenizer import MTPTokenizer
47
 
@@ -56,7 +56,7 @@ config = model_data["config"]
56
  # Detectar si el modelo usa SwiGLU
57
  use_swiglu = config["model"].get("use_swiglu", False)
58
 
59
- print(f"🧠 Inicializando modelo...")
60
  print(f" → Vocabulario: {VOCAB_SIZE}")
61
  print(f" → Dimensión: {config['model']['d_model']}")
62
  print(f" → Capas: {config['model']['n_layers']}")
@@ -95,9 +95,9 @@ print(f"✅ Modelo cargado: {param_count:,} parámetros ({param_count/1e6:.1f}M)
95
  # API CONFIG
96
  # ======================
97
  app = FastAPI(
98
- title="MTP-3.5 API",
99
- description="API para modelo de lenguaje MTP-3.5 mejorado con RoPE, RMSNorm y SwiGLU",
100
- version="3.5"
101
  )
102
 
103
  app.add_middleware(
@@ -201,7 +201,7 @@ async def generate(req: PromptRequest):
201
  "tokens_generated": len(safe_tokens),
202
  "generation_time": round(generation_time, 2),
203
  "tokens_per_second": round(tokens_per_second, 1),
204
- "model": "MTP-3.5",
205
  "device": DEVICE
206
  }
207
 
@@ -336,7 +336,7 @@ def health_check():
336
 
337
  return {
338
  "status": "healthy",
339
- "model": "MTP-3.5",
340
  "device": DEVICE,
341
  "active_requests": ACTIVE_REQUESTS,
342
  "max_concurrent_requests": MAX_CONCURRENT_REQUESTS,
@@ -363,8 +363,8 @@ def model_info():
363
  improvements.append("SwiGLU Activation")
364
 
365
  return {
366
- "model_name": "MTP-3.5",
367
- "version": "3.5",
368
  "architecture": {
369
  "d_model": config["model"]["d_model"],
370
  "n_layers": config["model"]["n_layers"],
@@ -409,21 +409,21 @@ def chat_ui():
409
  <head>
410
  <meta charset="UTF-8">
411
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
412
- <title>MTP 3.5 - Chat Interface</title>
413
  <link rel="preconnect" href="https://fonts.googleapis.com">
414
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
415
  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600&display=swap" rel="stylesheet">
416
  <style>
417
  :root {
418
- --bg-color: #131314;
419
- --surface-color: #1E1F20;
420
- --accent-color: #4a9eff;
421
- --text-primary: #e3e3e3;
422
- --text-secondary: #9aa0a6;
423
- --user-bubble: #282a2c;
424
- --success-color: #34a853;
425
- --warning-color: #fbbc04;
426
- --error-color: #ea4335;
427
  --logo-url: url('https://i.postimg.cc/yxS54PF3/IMG-3082.jpg');
428
  }
429
  * {
@@ -433,7 +433,7 @@ def chat_ui():
433
  }
434
  body {
435
  margin: 0;
436
- background-color: var(--bg-color);
437
  font-family: 'Inter', sans-serif;
438
  color: var(--text-primary);
439
  height: 100dvh;
@@ -442,174 +442,184 @@ body {
442
  overflow: hidden;
443
  }
444
  header {
445
- padding: 12px 20px;
446
  display: flex;
447
  align-items: center;
448
  justify-content: space-between;
449
- background: rgba(19, 19, 20, 0.85);
450
- backdrop-filter: blur(12px);
451
  position: fixed;
452
  top: 0;
453
  width: 100%;
454
  z-index: 50;
455
- border-bottom: 1px solid rgba(255,255,255,0.05);
456
  }
457
  .brand-wrapper {
458
  display: flex;
459
  align-items: center;
460
- gap: 12px;
461
  cursor: pointer;
462
  }
463
  .brand-logo {
464
- width: 32px;
465
- height: 32px;
466
  border-radius: 50%;
467
  background-image: var(--logo-url);
468
  background-size: cover;
469
  background-position: center;
470
- border: 1px solid rgba(255,255,255,0.1);
 
471
  }
472
  .brand-text {
473
- font-weight: 500;
474
- font-size: 1.05rem;
475
  display: flex;
476
  align-items: center;
477
- gap: 8px;
 
 
 
 
478
  }
479
  .version-badge {
480
  font-size: 0.75rem;
481
- background: rgba(74, 158, 255, 0.15);
482
- color: #8ab4f8;
483
- padding: 2px 8px;
484
- border-radius: 12px;
485
- font-weight: 600;
 
486
  }
487
  .status-indicator {
488
- width: 8px;
489
- height: 8px;
490
  border-radius: 50%;
491
  background: var(--success-color);
492
  animation: pulse 2s infinite;
 
493
  }
494
  @keyframes pulse {
495
- 0%, 100% { opacity: 1; }
496
- 50% { opacity: 0.5; }
497
  }
498
  .chat-scroll {
499
  flex: 1;
500
  overflow-y: auto;
501
- padding: 80px 20px 40px 20px;
502
  display: flex;
503
  flex-direction: column;
504
- gap: 30px;
505
- max-width: 850px;
506
  margin: 0 auto;
507
  width: 100%;
508
  scroll-behavior: smooth;
509
  }
510
  .msg-row {
511
  display: flex;
512
- gap: 16px;
513
  width: 100%;
514
  opacity: 0;
515
- transform: translateY(10px);
516
- animation: slideUpFade 0.4s cubic-bezier(0.2, 0.8, 0.2, 1) forwards;
517
  }
518
  .msg-row.user { justify-content: flex-end; }
519
  .msg-row.bot { justify-content: flex-start; align-items: flex-start; }
520
  .msg-content {
521
- line-height: 1.6;
522
  font-size: 1rem;
523
  word-wrap: break-word;
524
  max-width: 85%;
525
  }
526
  .user .msg-content {
527
- background-color: var(--user-bubble);
528
- padding: 10px 18px;
529
- border-radius: 18px;
530
- border-top-right-radius: 4px;
531
  color: #fff;
 
532
  }
533
  .bot .msg-content-wrapper {
534
  display: flex;
535
  flex-direction: column;
536
- gap: 8px;
537
  width: 100%;
538
  }
539
  .bot .msg-text {
540
- padding-top: 6px;
541
  color: var(--text-primary);
542
  white-space: pre-wrap;
543
  }
544
  .bot-avatar {
545
- width: 34px;
546
- height: 34px;
547
- min-width: 34px;
548
  border-radius: 50%;
549
  background-image: var(--logo-url);
550
  background-size: cover;
551
- box-shadow: 0 2px 6px rgba(0,0,0,0.2);
 
552
  }
553
  .bot-actions {
554
  display: flex;
555
- gap: 10px;
556
  opacity: 0;
557
  transition: opacity 0.3s;
558
- margin-top: 5px;
559
  }
560
  .action-btn {
561
- background: transparent;
562
- border: none;
563
  color: var(--text-secondary);
564
  cursor: pointer;
565
- padding: 4px;
566
- border-radius: 4px;
567
  display: flex;
568
  align-items: center;
569
- transition: color 0.2s, background 0.2s;
570
  font-size: 0.85rem;
571
  }
572
  .action-btn:hover {
573
- color: var(--text-primary);
574
- background: rgba(255,255,255,0.08);
 
575
  }
576
  .action-btn svg {
577
  width: 16px;
578
  height: 16px;
579
  fill: currentColor;
580
- margin-right: 4px;
581
  }
582
  .typing-cursor::after {
583
  content: '';
584
  display: inline-block;
585
- width: 10px;
586
- height: 10px;
587
  background: var(--accent-color);
588
- border-radius: 50%;
589
- margin-left: 5px;
590
  vertical-align: middle;
591
- animation: blink 1s infinite;
592
  }
593
  .footer-container {
594
- padding: 0 20px 20px 20px;
595
- background: linear-gradient(to top, var(--bg-color) 85%, transparent);
596
  position: relative;
597
  z-index: 60;
598
  }
599
  .input-box {
600
- max-width: 850px;
601
  margin: 0 auto;
602
  background: var(--surface-color);
603
- border-radius: 28px;
604
- padding: 8px 10px 8px 20px;
605
  display: flex;
606
  align-items: center;
607
- border: 1px solid rgba(255,255,255,0.1);
608
- transition: border-color 0.2s, box-shadow 0.2s;
 
609
  }
610
  .input-box:focus-within {
611
- border-color: rgba(74, 158, 255, 0.5);
612
- box-shadow: 0 0 0 2px rgba(74, 158, 255, 0.1);
613
  }
614
  #userInput {
615
  flex: 1;
@@ -623,60 +633,74 @@ header {
623
  max-height: 120px;
624
  }
625
  #mainBtn {
626
- background: white;
627
- color: black;
628
  border: none;
629
- width: 36px;
630
- height: 36px;
631
  border-radius: 50%;
632
  display: flex;
633
  align-items: center;
634
  justify-content: center;
635
  cursor: pointer;
636
- margin-left: 8px;
637
- transition: transform 0.2s;
 
 
 
 
 
638
  }
639
- #mainBtn:hover { transform: scale(1.05); }
640
  #mainBtn:disabled {
641
- opacity: 0.5;
642
  cursor: not-allowed;
 
643
  }
644
  .disclaimer {
645
  text-align: center;
646
  font-size: 0.75rem;
647
- color: #666;
648
- margin-top: 12px;
649
  }
650
  .stats-badge {
651
  font-size: 0.7rem;
652
  color: var(--text-secondary);
653
- margin-top: 4px;
654
  font-family: 'Monaco', monospace;
 
 
 
 
655
  }
656
  @keyframes slideUpFade {
657
- from { opacity: 0; transform: translateY(15px); }
658
  to { opacity: 1; transform: translateY(0); }
659
  }
660
  @keyframes blink {
661
  0%, 100% { opacity: 1; }
662
- 50% { opacity: 0; }
663
  }
664
  @keyframes pulseAvatar {
665
- 0% { box-shadow: 0 0 0 0 rgba(74, 158, 255, 0.4); }
666
- 70% { box-shadow: 0 0 0 8px rgba(74, 158, 255, 0); }
667
- 100% { box-shadow: 0 0 0 0 rgba(74, 158, 255, 0); }
668
  }
669
  .pulsing { animation: pulseAvatar 1.5s infinite; }
670
- ::-webkit-scrollbar { width: 8px; }
671
  ::-webkit-scrollbar-track { background: transparent; }
672
- ::-webkit-scrollbar-thumb { background: #333; border-radius: 4px; }
 
 
 
 
673
  .error-message {
674
  color: var(--error-color);
675
- font-size: 0.85rem;
676
- padding: 8px 12px;
677
- background: rgba(234, 67, 53, 0.1);
678
- border-radius: 8px;
679
- margin-top: 8px;
 
680
  }
681
  </style>
682
  </head>
@@ -685,7 +709,7 @@ header {
685
  <div class="brand-wrapper" onclick="location.reload()">
686
  <div class="brand-logo"></div>
687
  <div class="brand-text">
688
- MTP <span class="version-badge">3.5</span>
689
  </div>
690
  </div>
691
  <div class="status-indicator" title="Sistema operativo"></div>
@@ -695,13 +719,14 @@ header {
695
  <div class="bot-avatar"></div>
696
  <div class="msg-content-wrapper">
697
  <div class="msg-text">
698
- ¡Hola! Soy MTP 3.5, un modelo de lenguaje mejorado con arquitectura Transformer avanzada.
699
 
700
- Características:
701
- • RoPE (Rotary Position Embedding)
702
- • RMSNorm para estabilidad
703
- Control de repetición inteligente
704
- Generación coherente y fluida
 
705
 
706
  ¿En qué puedo ayudarte hoy?
707
  </div>
@@ -714,7 +739,7 @@ Características:
714
  <button id="mainBtn" onclick="handleBtnClick()"></button>
715
  </div>
716
  <div class="disclaimer">
717
- MTP 3.5 puede cometer errores. Considera verificar la información importante.
718
  </div>
719
  </div>
720
  <script>
@@ -726,7 +751,7 @@ let abortController = null;
726
  let typingTimeout = null;
727
  let lastUserPrompt = "";
728
  const ICON_SEND = `<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M22 2L11 13M22 2l-7 20-4-9-9-4 20-7z"></path></svg>`;
729
- const ICON_STOP = `<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="0"><rect x="2" y="2" width="20" height="20" rx="4" ry="4"></rect></svg>`;
730
  mainBtn.innerHTML = ICON_SEND;
731
 
732
  // Auto-resize textarea
@@ -950,7 +975,7 @@ window.onload = () => {
950
  fetch('/info')
951
  .then(r => r.json())
952
  .then(data => {
953
- console.log('Modelo cargado:', data);
954
  })
955
  .catch(e => console.error('Error cargando info:', e));
956
  };
@@ -961,7 +986,7 @@ window.onload = () => {
961
 
962
  if __name__ == "__main__":
963
  port = int(os.environ.get("PORT", 7860))
964
- print(f"\n🚀 Iniciando servidor MTP-3.5...")
965
  print(f"🌐 Interfaz web: http://0.0.0.0:{port}")
966
  print(f"📡 API docs: http://0.0.0.0:{port}/docs")
967
  print(f"📊 Health check: http://0.0.0.0:{port}/health")
 
36
  repo_path = snapshot_download(
37
  repo_id=MODEL_REPO,
38
  repo_type="model",
39
+ local_dir="mtp_repo"
40
  )
41
 
42
  sys.path.insert(0, repo_path)
43
 
44
+ # Importar modelo y tokenizer
45
  from model import MTPMiniModel
46
  from tokenizer import MTPTokenizer
47
 
 
56
  # Detectar si el modelo usa SwiGLU
57
  use_swiglu = config["model"].get("use_swiglu", False)
58
 
59
+ print(f"🧠 Inicializando modelo MTP 4...")
60
  print(f" → Vocabulario: {VOCAB_SIZE}")
61
  print(f" → Dimensión: {config['model']['d_model']}")
62
  print(f" → Capas: {config['model']['n_layers']}")
 
95
  # API CONFIG
96
  # ======================
97
  app = FastAPI(
98
+ title="MTP 4 API",
99
+ description="API para modelo de lenguaje MTP 4 con RoPE, RMSNorm y SwiGLU",
100
+ version="4.0"
101
  )
102
 
103
  app.add_middleware(
 
201
  "tokens_generated": len(safe_tokens),
202
  "generation_time": round(generation_time, 2),
203
  "tokens_per_second": round(tokens_per_second, 1),
204
+ "model": "MTP-4",
205
  "device": DEVICE
206
  }
207
 
 
336
 
337
  return {
338
  "status": "healthy",
339
+ "model": "MTP-4",
340
  "device": DEVICE,
341
  "active_requests": ACTIVE_REQUESTS,
342
  "max_concurrent_requests": MAX_CONCURRENT_REQUESTS,
 
363
  improvements.append("SwiGLU Activation")
364
 
365
  return {
366
+ "model_name": "MTP-4",
367
+ "version": "4.0",
368
  "architecture": {
369
  "d_model": config["model"]["d_model"],
370
  "n_layers": config["model"]["n_layers"],
 
409
  <head>
410
  <meta charset="UTF-8">
411
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
412
+ <title>MTP 4 - Chat Interface</title>
413
  <link rel="preconnect" href="https://fonts.googleapis.com">
414
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
415
  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600&display=swap" rel="stylesheet">
416
  <style>
417
  :root {
418
+ --bg-color: #0a0a0b;
419
+ --surface-color: #1a1a1c;
420
+ --accent-color: #6366f1;
421
+ --text-primary: #e8e8ea;
422
+ --text-secondary: #9ca3af;
423
+ --user-bubble: #2d2d30;
424
+ --success-color: #10b981;
425
+ --warning-color: #f59e0b;
426
+ --error-color: #ef4444;
427
  --logo-url: url('https://i.postimg.cc/yxS54PF3/IMG-3082.jpg');
428
  }
429
  * {
 
433
  }
434
  body {
435
  margin: 0;
436
+ background: linear-gradient(135deg, #0a0a0b 0%, #1a1a1c 100%);
437
  font-family: 'Inter', sans-serif;
438
  color: var(--text-primary);
439
  height: 100dvh;
 
442
  overflow: hidden;
443
  }
444
  header {
445
+ padding: 14px 24px;
446
  display: flex;
447
  align-items: center;
448
  justify-content: space-between;
449
+ background: rgba(26, 26, 28, 0.9);
450
+ backdrop-filter: blur(16px);
451
  position: fixed;
452
  top: 0;
453
  width: 100%;
454
  z-index: 50;
455
+ border-bottom: 1px solid rgba(99, 102, 241, 0.1);
456
  }
457
  .brand-wrapper {
458
  display: flex;
459
  align-items: center;
460
+ gap: 14px;
461
  cursor: pointer;
462
  }
463
  .brand-logo {
464
+ width: 36px;
465
+ height: 36px;
466
  border-radius: 50%;
467
  background-image: var(--logo-url);
468
  background-size: cover;
469
  background-position: center;
470
+ border: 2px solid rgba(99, 102, 241, 0.3);
471
+ box-shadow: 0 0 12px rgba(99, 102, 241, 0.2);
472
  }
473
  .brand-text {
474
+ font-weight: 600;
475
+ font-size: 1.15rem;
476
  display: flex;
477
  align-items: center;
478
+ gap: 10px;
479
+ background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);
480
+ -webkit-background-clip: text;
481
+ -webkit-text-fill-color: transparent;
482
+ background-clip: text;
483
  }
484
  .version-badge {
485
  font-size: 0.75rem;
486
+ background: linear-gradient(135deg, rgba(99, 102, 241, 0.2) 0%, rgba(139, 92, 246, 0.2) 100%);
487
+ color: #a5b4fc;
488
+ padding: 3px 10px;
489
+ border-radius: 14px;
490
+ font-weight: 700;
491
+ border: 1px solid rgba(99, 102, 241, 0.3);
492
  }
493
  .status-indicator {
494
+ width: 10px;
495
+ height: 10px;
496
  border-radius: 50%;
497
  background: var(--success-color);
498
  animation: pulse 2s infinite;
499
+ box-shadow: 0 0 8px var(--success-color);
500
  }
501
  @keyframes pulse {
502
+ 0%, 100% { opacity: 1; transform: scale(1); }
503
+ 50% { opacity: 0.7; transform: scale(0.95); }
504
  }
505
  .chat-scroll {
506
  flex: 1;
507
  overflow-y: auto;
508
+ padding: 90px 24px 50px 24px;
509
  display: flex;
510
  flex-direction: column;
511
+ gap: 32px;
512
+ max-width: 900px;
513
  margin: 0 auto;
514
  width: 100%;
515
  scroll-behavior: smooth;
516
  }
517
  .msg-row {
518
  display: flex;
519
+ gap: 18px;
520
  width: 100%;
521
  opacity: 0;
522
+ transform: translateY(12px);
523
+ animation: slideUpFade 0.5s cubic-bezier(0.2, 0.8, 0.2, 1) forwards;
524
  }
525
  .msg-row.user { justify-content: flex-end; }
526
  .msg-row.bot { justify-content: flex-start; align-items: flex-start; }
527
  .msg-content {
528
+ line-height: 1.65;
529
  font-size: 1rem;
530
  word-wrap: break-word;
531
  max-width: 85%;
532
  }
533
  .user .msg-content {
534
+ background: linear-gradient(135deg, #2d2d30 0%, #3a3a3d 100%);
535
+ padding: 12px 20px;
536
+ border-radius: 20px;
537
+ border-top-right-radius: 6px;
538
  color: #fff;
539
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
540
  }
541
  .bot .msg-content-wrapper {
542
  display: flex;
543
  flex-direction: column;
544
+ gap: 10px;
545
  width: 100%;
546
  }
547
  .bot .msg-text {
548
+ padding-top: 8px;
549
  color: var(--text-primary);
550
  white-space: pre-wrap;
551
  }
552
  .bot-avatar {
553
+ width: 38px;
554
+ height: 38px;
555
+ min-width: 38px;
556
  border-radius: 50%;
557
  background-image: var(--logo-url);
558
  background-size: cover;
559
+ box-shadow: 0 0 16px rgba(99, 102, 241, 0.4);
560
+ border: 2px solid rgba(99, 102, 241, 0.3);
561
  }
562
  .bot-actions {
563
  display: flex;
564
+ gap: 12px;
565
  opacity: 0;
566
  transition: opacity 0.3s;
567
+ margin-top: 6px;
568
  }
569
  .action-btn {
570
+ background: rgba(99, 102, 241, 0.1);
571
+ border: 1px solid rgba(99, 102, 241, 0.2);
572
  color: var(--text-secondary);
573
  cursor: pointer;
574
+ padding: 6px 12px;
575
+ border-radius: 8px;
576
  display: flex;
577
  align-items: center;
578
+ transition: all 0.2s;
579
  font-size: 0.85rem;
580
  }
581
  .action-btn:hover {
582
+ color: var(--accent-color);
583
+ background: rgba(99, 102, 241, 0.15);
584
+ border-color: rgba(99, 102, 241, 0.4);
585
  }
586
  .action-btn svg {
587
  width: 16px;
588
  height: 16px;
589
  fill: currentColor;
590
+ margin-right: 5px;
591
  }
592
  .typing-cursor::after {
593
  content: '';
594
  display: inline-block;
595
+ width: 3px;
596
+ height: 18px;
597
  background: var(--accent-color);
598
+ margin-left: 3px;
 
599
  vertical-align: middle;
600
+ animation: blink 0.8s infinite;
601
  }
602
  .footer-container {
603
+ padding: 0 24px 24px 24px;
604
+ background: linear-gradient(to top, rgba(10, 10, 11, 0.95) 85%, transparent);
605
  position: relative;
606
  z-index: 60;
607
  }
608
  .input-box {
609
+ max-width: 900px;
610
  margin: 0 auto;
611
  background: var(--surface-color);
612
+ border-radius: 30px;
613
+ padding: 10px 12px 10px 24px;
614
  display: flex;
615
  align-items: center;
616
+ border: 1px solid rgba(99, 102, 241, 0.2);
617
+ transition: all 0.3s;
618
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
619
  }
620
  .input-box:focus-within {
621
+ border-color: rgba(99, 102, 241, 0.6);
622
+ box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.15), 0 4px 20px rgba(0, 0, 0, 0.4);
623
  }
624
  #userInput {
625
  flex: 1;
 
633
  max-height: 120px;
634
  }
635
  #mainBtn {
636
+ background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);
637
+ color: white;
638
  border: none;
639
+ width: 40px;
640
+ height: 40px;
641
  border-radius: 50%;
642
  display: flex;
643
  align-items: center;
644
  justify-content: center;
645
  cursor: pointer;
646
+ margin-left: 10px;
647
+ transition: all 0.2s;
648
+ box-shadow: 0 4px 12px rgba(99, 102, 241, 0.3);
649
+ }
650
+ #mainBtn:hover {
651
+ transform: scale(1.05);
652
+ box-shadow: 0 6px 16px rgba(99, 102, 241, 0.5);
653
  }
 
654
  #mainBtn:disabled {
655
+ opacity: 0.6;
656
  cursor: not-allowed;
657
+ transform: scale(1);
658
  }
659
  .disclaimer {
660
  text-align: center;
661
  font-size: 0.75rem;
662
+ color: #6b7280;
663
+ margin-top: 14px;
664
  }
665
  .stats-badge {
666
  font-size: 0.7rem;
667
  color: var(--text-secondary);
668
+ margin-top: 6px;
669
  font-family: 'Monaco', monospace;
670
+ background: rgba(99, 102, 241, 0.05);
671
+ padding: 4px 8px;
672
+ border-radius: 6px;
673
+ display: inline-block;
674
  }
675
  @keyframes slideUpFade {
676
+ from { opacity: 0; transform: translateY(18px); }
677
  to { opacity: 1; transform: translateY(0); }
678
  }
679
  @keyframes blink {
680
  0%, 100% { opacity: 1; }
681
+ 50% { opacity: 0.3; }
682
  }
683
  @keyframes pulseAvatar {
684
+ 0% { box-shadow: 0 0 0 0 rgba(99, 102, 241, 0.5); }
685
+ 70% { box-shadow: 0 0 0 10px rgba(99, 102, 241, 0); }
686
+ 100% { box-shadow: 0 0 0 0 rgba(99, 102, 241, 0); }
687
  }
688
  .pulsing { animation: pulseAvatar 1.5s infinite; }
689
+ ::-webkit-scrollbar { width: 10px; }
690
  ::-webkit-scrollbar-track { background: transparent; }
691
+ ::-webkit-scrollbar-thumb {
692
+ background: rgba(99, 102, 241, 0.3);
693
+ border-radius: 5px;
694
+ }
695
+ ::-webkit-scrollbar-thumb:hover { background: rgba(99, 102, 241, 0.5); }
696
  .error-message {
697
  color: var(--error-color);
698
+ font-size: 0.9rem;
699
+ padding: 10px 14px;
700
+ background: rgba(239, 68, 68, 0.1);
701
+ border-radius: 10px;
702
+ margin-top: 10px;
703
+ border: 1px solid rgba(239, 68, 68, 0.2);
704
  }
705
  </style>
706
  </head>
 
709
  <div class="brand-wrapper" onclick="location.reload()">
710
  <div class="brand-logo"></div>
711
  <div class="brand-text">
712
+ MTP <span class="version-badge">4.0</span>
713
  </div>
714
  </div>
715
  <div class="status-indicator" title="Sistema operativo"></div>
 
719
  <div class="bot-avatar"></div>
720
  <div class="msg-content-wrapper">
721
  <div class="msg-text">
722
+ ¡Hola! Soy MTP 4, un modelo de lenguaje avanzado con arquitectura Transformer optimizada.
723
 
724
+ Características principales:
725
+ • RoPE - Rotary Position Embedding para mejor contexto
726
+ • RMSNorm - Normalización estable y eficiente
727
+ SwiGLU - Función de activación mejorada
728
+ Control inteligente de repetición y coherencia
729
+ • Generación fluida y natural
730
 
731
  ¿En qué puedo ayudarte hoy?
732
  </div>
 
739
  <button id="mainBtn" onclick="handleBtnClick()"></button>
740
  </div>
741
  <div class="disclaimer">
742
+ MTP 4 puede cometer errores. Considera verificar la información importante.
743
  </div>
744
  </div>
745
  <script>
 
751
  let typingTimeout = null;
752
  let lastUserPrompt = "";
753
  const ICON_SEND = `<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M22 2L11 13M22 2l-7 20-4-9-9-4 20-7z"></path></svg>`;
754
+ const ICON_STOP = `<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="0"><rect x="2" y="2" width="20" height="20" rx="4" ry="4"></rect></svg>`;
755
  mainBtn.innerHTML = ICON_SEND;
756
 
757
  // Auto-resize textarea
 
975
  fetch('/info')
976
  .then(r => r.json())
977
  .then(data => {
978
+ console.log('MTP 4 cargado:', data);
979
  })
980
  .catch(e => console.error('Error cargando info:', e));
981
  };
 
986
 
987
  if __name__ == "__main__":
988
  port = int(os.environ.get("PORT", 7860))
989
+ print(f"\n🚀 Iniciando servidor MTP 4...")
990
  print(f"🌐 Interfaz web: http://0.0.0.0:{port}")
991
  print(f"📡 API docs: http://0.0.0.0:{port}/docs")
992
  print(f"📊 Health check: http://0.0.0.0:{port}/health")