Revamp Web UI: Added Tailwind CSS CDN, cyberpunk glassmorphism layout, glowing neon visualizers, and enhanced telemetry gauges
This commit is contained in:
@@ -1,89 +1,104 @@
|
|||||||
/* Cyberpunk Glassmorphism Design Token System */
|
/* Cyberpunk Design System & Styling Rules */
|
||||||
@tailwind base;
|
|
||||||
@tailwind components;
|
|
||||||
@tailwind utilities;
|
|
||||||
|
|
||||||
:root {
|
/* Cyber Card Glassmorphism */
|
||||||
--bg-dark: #07090E;
|
.cyber-card {
|
||||||
--panel-bg: rgba(15, 23, 42, 0.75);
|
background: rgba(13, 18, 30, 0.85);
|
||||||
--cyan-glow: #00F0FF;
|
backdrop-filter: blur(20px);
|
||||||
--violet-glow: #8A2BE2;
|
-webkit-backdrop-filter: blur(20px);
|
||||||
--emerald-glow: #00FF9D;
|
|
||||||
--amber-glow: #FFB800;
|
|
||||||
--rose-glow: #FF3366;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
background-color: var(--bg-dark);
|
|
||||||
background-image:
|
|
||||||
radial-gradient(at 0% 0%, rgba(0, 240, 255, 0.08) 0px, transparent 50%),
|
|
||||||
radial-gradient(at 100% 0%, rgba(138, 43, 226, 0.08) 0px, transparent 50%),
|
|
||||||
radial-gradient(at 50% 100%, rgba(0, 255, 157, 0.04) 0px, transparent 50%);
|
|
||||||
font-family: 'Inter', sans-serif;
|
|
||||||
color: #F8FAFC;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Glassmorphism Panel Component */
|
|
||||||
.glass-panel {
|
|
||||||
background: rgba(15, 23, 42, 0.7);
|
|
||||||
backdrop-filter: blur(16px);
|
|
||||||
-webkit-backdrop-filter: blur(16px);
|
|
||||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||||
box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.37);
|
box-shadow: 0 10px 30px -10px rgba(0, 0, 0, 0.5);
|
||||||
|
transition: all 0.3s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.glass-panel:hover {
|
.cyber-card:hover {
|
||||||
border-color: rgba(0, 240, 255, 0.2);
|
border-color: rgba(0, 240, 255, 0.25);
|
||||||
|
box-shadow: 0 15px 35px -10px rgba(0, 240, 255, 0.15);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Buttons */
|
/* Neon Buttons */
|
||||||
.btn {
|
.btn-neon {
|
||||||
@apply px-4 py-2 rounded-xl text-xs font-bold font-mono tracking-wider transition-all duration-200 flex items-center gap-2 cursor-pointer border shadow-lg;
|
padding: 0.5rem 1rem;
|
||||||
|
border-radius: 0.75rem;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
font-weight: 800;
|
||||||
|
font-family: 'Fira Code', monospace;
|
||||||
|
letter-spacing: 0.05em;
|
||||||
|
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
display: inline-flex;
|
||||||
|
items-center: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
cursor: pointer;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-emerald {
|
.btn-emerald {
|
||||||
background: linear-gradient(135deg, rgba(0, 255, 157, 0.2), rgba(0, 200, 120, 0.1));
|
background: linear-gradient(135deg, rgba(0, 255, 157, 0.2), rgba(0, 200, 120, 0.1));
|
||||||
border-color: rgba(0, 255, 157, 0.4);
|
border-color: rgba(0, 255, 157, 0.4);
|
||||||
color: #00FF9D;
|
color: #00FF9D;
|
||||||
|
box-shadow: 0 0 15px rgba(0, 255, 157, 0.15);
|
||||||
}
|
}
|
||||||
.btn-emerald:hover {
|
.btn-emerald:hover:not(:disabled) {
|
||||||
background: rgba(0, 255, 157, 0.3);
|
background: rgba(0, 255, 157, 0.3);
|
||||||
box-shadow: 0 0 20px rgba(0, 255, 157, 0.4);
|
box-shadow: 0 0 25px rgba(0, 255, 157, 0.5);
|
||||||
|
transform: translateY(-1px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-rose {
|
.btn-rose {
|
||||||
background: linear-gradient(135deg, rgba(255, 51, 102, 0.2), rgba(200, 40, 80, 0.1));
|
background: linear-gradient(135deg, rgba(255, 51, 102, 0.2), rgba(200, 40, 80, 0.1));
|
||||||
border-color: rgba(255, 51, 102, 0.4);
|
border-color: rgba(255, 51, 102, 0.4);
|
||||||
color: #FF3366;
|
color: #FF3366;
|
||||||
|
box-shadow: 0 0 15px rgba(255, 51, 102, 0.15);
|
||||||
}
|
}
|
||||||
.btn-rose:hover {
|
.btn-rose:hover:not(:disabled) {
|
||||||
background: rgba(255, 51, 102, 0.3);
|
background: rgba(255, 51, 102, 0.3);
|
||||||
box-shadow: 0 0 20px rgba(255, 51, 102, 0.4);
|
box-shadow: 0 0 25px rgba(255, 51, 102, 0.5);
|
||||||
|
transform: translateY(-1px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-ghost {
|
.btn-ghost {
|
||||||
background: rgba(30, 41, 59, 0.6);
|
background: rgba(30, 41, 59, 0.7);
|
||||||
border-color: rgba(255, 255, 255, 0.1);
|
border-color: rgba(255, 255, 255, 0.1);
|
||||||
color: #94A3B8;
|
color: #94A3B8;
|
||||||
}
|
}
|
||||||
.btn-ghost:hover {
|
.btn-ghost:hover:not(:disabled) {
|
||||||
background: rgba(51, 65, 85, 0.8);
|
background: rgba(51, 65, 85, 0.9);
|
||||||
color: #FFF;
|
color: #FFFFFF;
|
||||||
|
border-color: rgba(0, 240, 255, 0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-purple {
|
.btn-purple {
|
||||||
background: linear-gradient(135deg, rgba(138, 43, 226, 0.25), rgba(100, 30, 180, 0.15));
|
background: linear-gradient(135deg, rgba(138, 43, 226, 0.25), rgba(100, 30, 180, 0.15));
|
||||||
border-color: rgba(138, 43, 226, 0.5);
|
border-color: rgba(138, 43, 226, 0.5);
|
||||||
color: #C084FC;
|
color: #C084FC;
|
||||||
|
box-shadow: 0 0 15px rgba(138, 43, 226, 0.15);
|
||||||
}
|
}
|
||||||
.btn-purple:hover {
|
.btn-purple:hover:not(:disabled) {
|
||||||
background: rgba(138, 43, 226, 0.35);
|
background: rgba(138, 43, 226, 0.35);
|
||||||
box-shadow: 0 0 20px rgba(138, 43, 226, 0.4);
|
box-shadow: 0 0 25px rgba(138, 43, 226, 0.5);
|
||||||
|
transform: translateY(-1px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-neon:disabled {
|
||||||
|
opacity: 0.4;
|
||||||
|
cursor: not-allowed;
|
||||||
|
transform: none !important;
|
||||||
|
box-shadow: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Status Badges */
|
/* Status Badges */
|
||||||
.status-badge {
|
.status-badge {
|
||||||
@apply px-3 py-1 rounded-full text-[11px] font-bold font-mono tracking-widest border uppercase inline-flex items-center gap-1.5;
|
padding: 0.25rem 0.75rem;
|
||||||
|
border-radius: 9999px;
|
||||||
|
font-size: 0.6875rem;
|
||||||
|
font-weight: 800;
|
||||||
|
font-family: 'Fira Code', monospace;
|
||||||
|
letter-spacing: 0.05em;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.375rem;
|
||||||
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
|
|
||||||
.status-idle {
|
.status-idle {
|
||||||
@@ -96,12 +111,13 @@ body {
|
|||||||
background: rgba(0, 240, 255, 0.15);
|
background: rgba(0, 240, 255, 0.15);
|
||||||
border-color: rgba(0, 240, 255, 0.4);
|
border-color: rgba(0, 240, 255, 0.4);
|
||||||
color: #00F0FF;
|
color: #00F0FF;
|
||||||
animation: pulse-glow 2s infinite;
|
box-shadow: 0 0 15px rgba(0, 240, 255, 0.3);
|
||||||
|
animation: badge-pulse 2s infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes pulse-glow {
|
@keyframes badge-pulse {
|
||||||
0%, 100% { box-shadow: 0 0 10px rgba(0, 240, 255, 0.3); }
|
0%, 100% { box-shadow: 0 0 10px rgba(0, 240, 255, 0.2); }
|
||||||
50% { box-shadow: 0 0 25px rgba(0, 240, 255, 0.7); }
|
50% { box-shadow: 0 0 25px rgba(0, 240, 255, 0.6); }
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes spin-reverse {
|
@keyframes spin-reverse {
|
||||||
@@ -112,25 +128,35 @@ body {
|
|||||||
animation: spin-reverse 3s linear infinite;
|
animation: spin-reverse 3s linear infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Scrollbar Customization */
|
/* Custom Scrollbar */
|
||||||
.custom-scrollbar::-webkit-scrollbar {
|
.custom-scrollbar::-webkit-scrollbar {
|
||||||
width: 6px;
|
width: 6px;
|
||||||
height: 6px;
|
height: 6px;
|
||||||
}
|
}
|
||||||
.custom-scrollbar::-webkit-scrollbar-track {
|
.custom-scrollbar::-webkit-scrollbar-track {
|
||||||
background: rgba(15, 23, 42, 0.6);
|
background: rgba(7, 9, 14, 0.8);
|
||||||
}
|
}
|
||||||
.custom-scrollbar::-webkit-scrollbar-thumb {
|
.custom-scrollbar::-webkit-scrollbar-thumb {
|
||||||
background: rgba(51, 65, 85, 0.8);
|
background: rgba(51, 65, 85, 0.8);
|
||||||
border-radius: 3px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
.custom-scrollbar::-webkit-scrollbar-thumb:hover {
|
.custom-scrollbar::-webkit-scrollbar-thumb:hover {
|
||||||
background: rgba(0, 240, 255, 0.5);
|
background: rgba(0, 240, 255, 0.6);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Terminal Log Badges */
|
/* Terminal Log Stream Elements */
|
||||||
.log-line {
|
.log-line {
|
||||||
@apply font-mono text-xs flex items-start gap-2 py-0.5 border-b border-slate-900/40 hover:bg-slate-900/50 px-1 rounded transition;
|
font-family: 'Fira Code', monospace;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 0.5rem;
|
||||||
|
padding: 0.25rem 0.5rem;
|
||||||
|
border-radius: 0.375rem;
|
||||||
|
transition: background 0.15s ease;
|
||||||
|
}
|
||||||
|
.log-line:hover {
|
||||||
|
background: rgba(30, 41, 59, 0.4);
|
||||||
}
|
}
|
||||||
.log-timestamp {
|
.log-timestamp {
|
||||||
color: #64748B;
|
color: #64748B;
|
||||||
@@ -143,8 +169,19 @@ body {
|
|||||||
.badge-error { background: rgba(255, 51, 102, 0.15); color: #FF3366; border: 1px solid rgba(255, 51, 102, 0.3); }
|
.badge-error { background: rgba(255, 51, 102, 0.15); color: #FF3366; border: 1px solid rgba(255, 51, 102, 0.3); }
|
||||||
|
|
||||||
.log-filter-btn {
|
.log-filter-btn {
|
||||||
@apply px-2 py-0.5 rounded text-[10px] font-bold text-slate-400 hover:text-white transition;
|
padding: 0.2rem 0.5rem;
|
||||||
|
border-radius: 0.375rem;
|
||||||
|
font-size: 0.625rem;
|
||||||
|
font-weight: 700;
|
||||||
|
font-family: 'Fira Code', monospace;
|
||||||
|
color: #94A3B8;
|
||||||
|
transition: all 0.15s ease;
|
||||||
|
}
|
||||||
|
.log-filter-btn:hover {
|
||||||
|
color: #FFFFFF;
|
||||||
}
|
}
|
||||||
.log-filter-btn.active {
|
.log-filter-btn.active {
|
||||||
@apply bg-cyan-500/20 text-cyan-400 border border-cyan-500/40;
|
background: rgba(0, 240, 255, 0.2);
|
||||||
|
color: #00F0FF;
|
||||||
|
border: 1px solid rgba(0, 240, 255, 0.4);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,300 +1,338 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en" class="dark">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>AI-Trainer | Unsloth MoE & GRPO Control Center</title>
|
<title>AI-Trainer | Unsloth MoE & GRPO Control Center</title>
|
||||||
|
|
||||||
<!-- Google Fonts & FontAwesome / Lucide -->
|
<!-- Google Fonts: Outfit, Inter, Fira Code -->
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600;700&family=Inter:wght@300;400;500;600;700;800;900&family=Outfit:wght@400;600;700;800;900&display=swap" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600;700&family=Inter:wght@300;400;500;600;700;800;900&family=Outfit:wght@400;600;700;800;900&display=swap" rel="stylesheet">
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
|
|
||||||
|
|
||||||
|
<!-- FontAwesome Icons -->
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
|
||||||
|
|
||||||
|
<!-- Tailwind CSS CDN -->
|
||||||
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
|
<script>
|
||||||
|
tailwind.config = {
|
||||||
|
darkMode: 'class',
|
||||||
|
theme: {
|
||||||
|
extend: {
|
||||||
|
colors: {
|
||||||
|
cyberDark: '#07090E',
|
||||||
|
cyberCard: 'rgba(13, 18, 30, 0.85)',
|
||||||
|
cyberBorder: 'rgba(255, 255, 255, 0.08)',
|
||||||
|
neonCyan: '#00F0FF',
|
||||||
|
neonViolet: '#8A2BE2',
|
||||||
|
neonEmerald: '#00FF9D',
|
||||||
|
neonAmber: '#FFB800',
|
||||||
|
neonRose: '#FF3366'
|
||||||
|
},
|
||||||
|
fontFamily: {
|
||||||
|
sans: ['Inter', 'sans-serif'],
|
||||||
|
outfit: ['Outfit', 'sans-serif'],
|
||||||
|
mono: ['Fira Code', 'monospace']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
<!-- Chart.js CDN -->
|
<!-- Chart.js CDN -->
|
||||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||||
|
|
||||||
|
<!-- Custom Styles -->
|
||||||
<link rel="stylesheet" href="css/style.css">
|
<link rel="stylesheet" href="css/style.css">
|
||||||
</head>
|
</head>
|
||||||
<body class="bg-dark text-light antialiased overflow-x-hidden">
|
<body class="bg-cyberDark text-slate-100 font-sans antialiased overflow-x-hidden min-h-screen flex flex-col">
|
||||||
|
|
||||||
<!-- Loading Screen Overlay -->
|
<!-- Fullscreen Animated Loading Overlay -->
|
||||||
<div id="loadingOverlay" class="fixed inset-0 z-50 bg-black/90 backdrop-blur-md flex flex-col items-center justify-center transition-opacity duration-500 opacity-0 pointer-events-none">
|
<div id="loadingOverlay" class="fixed inset-0 z-50 bg-cyberDark/95 backdrop-blur-xl flex flex-col items-center justify-center transition-all duration-500 opacity-0 pointer-events-none">
|
||||||
<div class="relative flex items-center justify-center">
|
<div class="relative flex items-center justify-center">
|
||||||
<div class="w-24 h-24 border-4 border-cyan-500/20 border-t-cyan-400 rounded-full animate-spin"></div>
|
<div class="w-28 h-28 border-4 border-cyan-500/20 border-t-cyan-400 rounded-full animate-spin"></div>
|
||||||
<div class="absolute w-16 h-16 border-4 border-violet-500/20 border-b-violet-400 rounded-full animate-spin-reverse"></div>
|
<div class="absolute w-20 h-20 border-4 border-violet-500/20 border-b-violet-400 rounded-full animate-spin-reverse"></div>
|
||||||
|
<div class="absolute w-12 h-12 border-4 border-emerald-500/20 border-t-emerald-400 rounded-full animate-spin"></div>
|
||||||
<i class="fa-solid fa-brain text-2xl text-cyan-400 animate-pulse"></i>
|
<i class="fa-solid fa-brain text-2xl text-cyan-400 animate-pulse"></i>
|
||||||
</div>
|
</div>
|
||||||
<h3 class="mt-6 text-xl font-bold tracking-wider text-cyan-400 uppercase font-outfit" id="loadingTitle">Initializing Neural Environment...</h3>
|
<h3 class="mt-8 text-2xl font-black tracking-widest text-transparent bg-clip-text bg-gradient-to-r from-cyan-400 via-violet-400 to-emerald-400 uppercase font-outfit" id="loadingTitle">INITIALIZING NEURAL HARNESS...</h3>
|
||||||
<p class="text-sm text-slate-400 mt-2 font-mono" id="loadingSubtext">Loading Unsloth Triton Kernels & MoE Router Maps</p>
|
<p class="text-xs text-slate-400 mt-2 font-mono" id="loadingSubtext">Loading Unsloth Triton Kernels & MoE Layer Router Maps</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Main Container Layout -->
|
<!-- Top Navigation Bar -->
|
||||||
<div class="min-h-screen flex flex-col">
|
<header class="border-b border-cyberBorder bg-slate-950/80 backdrop-blur-2xl sticky top-0 z-40 px-6 py-3.5 flex flex-wrap items-center justify-between gap-4">
|
||||||
|
<!-- Left: Brand Logo & Title -->
|
||||||
<!-- Top Navigation & Status Bar -->
|
<div class="flex items-center gap-4">
|
||||||
<header class="border-b border-slate-800 bg-slate-950/80 backdrop-blur-xl sticky top-0 z-40 px-6 py-3 flex flex-wrap items-center justify-between gap-4">
|
<div class="relative group cursor-pointer">
|
||||||
<div class="flex items-center gap-4">
|
<div class="absolute -inset-0.5 bg-gradient-to-r from-cyan-500 via-violet-600 to-emerald-500 rounded-xl blur opacity-60 group-hover:opacity-100 transition duration-300"></div>
|
||||||
<div class="w-10 h-10 rounded-xl bg-gradient-to-br from-cyan-500 via-violet-600 to-fuchsia-600 p-[1px] shadow-lg shadow-cyan-500/20">
|
<div class="relative w-11 h-11 bg-slate-950 rounded-xl flex items-center justify-center border border-white/10">
|
||||||
<div class="w-full h-full bg-slate-950 rounded-[11px] flex items-center justify-center">
|
<i class="fa-solid fa-bolt text-cyan-400 text-xl group-hover:scale-110 transition duration-300"></i>
|
||||||
<i class="fa-solid fa-microchip text-cyan-400 text-lg"></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="flex items-center gap-2.5">
|
||||||
|
<h1 class="text-xl font-black tracking-tight font-outfit text-white">AI-TRAINER</h1>
|
||||||
|
<span class="px-2.5 py-0.5 text-[10px] font-black tracking-widest bg-cyan-500/10 border border-cyan-500/30 text-cyan-400 rounded-full uppercase shadow-[0_0_10px_rgba(0,240,255,0.2)]">UNSLOTH GRPO MOE</span>
|
||||||
|
</div>
|
||||||
|
<p class="text-xs text-slate-400 font-mono">Proxify-ADB Autonomous Fleet Router & MoE Weight Shedder</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Middle: Live Telemetry Gauges -->
|
||||||
|
<div class="flex items-center gap-5 bg-slate-900/80 border border-cyberBorder px-5 py-2 rounded-2xl text-xs font-mono shadow-inner">
|
||||||
|
<div class="flex items-center gap-2.5">
|
||||||
|
<div class="w-2 h-2 rounded-full bg-cyan-400 animate-pulse"></div>
|
||||||
|
<span class="text-slate-400">GPU VRAM:</span>
|
||||||
|
<strong class="text-cyan-300" id="gaugeVram">6.2 / 16.0 GB</strong>
|
||||||
|
</div>
|
||||||
|
<div class="w-px h-4 bg-slate-800"></div>
|
||||||
|
<div class="flex items-center gap-2.5">
|
||||||
|
<div class="w-2 h-2 rounded-full bg-violet-400 animate-pulse"></div>
|
||||||
|
<span class="text-slate-400">MoE Stream RAM:</span>
|
||||||
|
<strong class="text-violet-300" id="gaugeRam">34.5 / 64.0 GB</strong>
|
||||||
|
</div>
|
||||||
|
<div class="w-px h-4 bg-slate-800"></div>
|
||||||
|
<div class="flex items-center gap-2.5">
|
||||||
|
<div class="w-2 h-2 rounded-full bg-emerald-400 animate-pulse"></div>
|
||||||
|
<span class="text-slate-400">ADB Fleet:</span>
|
||||||
|
<strong class="text-emerald-400" id="gaugeAdb">14 / 14 Connected</strong>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Right: Header Controls -->
|
||||||
|
<div class="flex items-center gap-3">
|
||||||
|
<button id="btnStartPipeline" class="btn-neon btn-emerald">
|
||||||
|
<i class="fa-solid fa-play"></i> RUN PIPELINE
|
||||||
|
</button>
|
||||||
|
<button id="btnStopPipeline" class="btn-neon btn-rose" disabled>
|
||||||
|
<i class="fa-solid fa-square"></i> STOP
|
||||||
|
</button>
|
||||||
|
<button id="btnOpenKnobs" class="btn-neon btn-ghost">
|
||||||
|
<i class="fa-solid fa-sliders"></i> TUNING KNOBS
|
||||||
|
</button>
|
||||||
|
<button id="btnSyncGitea" class="btn-neon btn-purple">
|
||||||
|
<i class="fa-solid fa-code-branch"></i> PUSH TO GITEA
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<!-- Main Content Layout -->
|
||||||
|
<main class="flex-1 p-6 space-y-6 max-w-[1920px] mx-auto w-full pb-80">
|
||||||
|
|
||||||
|
<!-- Pipeline Canvas Stage Section -->
|
||||||
|
<section class="cyber-card p-6 rounded-2xl relative overflow-hidden">
|
||||||
|
<div class="flex flex-wrap items-center justify-between gap-4 mb-4">
|
||||||
<div>
|
<div>
|
||||||
<div class="flex items-center gap-2">
|
<h2 class="text-lg font-black font-outfit text-white flex items-center gap-2.5">
|
||||||
<h1 class="text-lg font-black tracking-tight font-outfit text-white">AI-TRAINER</h1>
|
<i class="fa-solid fa-diagram-project text-cyan-400"></i>
|
||||||
<span class="px-2 py-0.5 text-[10px] font-extrabold tracking-wider bg-cyan-500/10 border border-cyan-500/30 text-cyan-400 rounded-full uppercase">UNSLOTH GRPO MOE</span>
|
AUTONOMOUS UN SLOTH GRPO PIPELINE MAP
|
||||||
|
</h2>
|
||||||
|
<p class="text-xs text-slate-400">Real-time dynamic expert pruning, hard execution sandbox evaluation, and GGUF quant deployment</p>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center gap-4 text-xs font-mono">
|
||||||
|
<span class="status-badge status-idle" id="pipelineStatusBadge">STATUS: IDLE</span>
|
||||||
|
<div class="flex items-center gap-2 bg-slate-900/90 px-3 py-1 rounded-xl border border-slate-800">
|
||||||
|
<span class="text-slate-400">Overall Progress:</span>
|
||||||
|
<strong class="text-cyan-400 text-sm" id="overallProgressText">0%</strong>
|
||||||
</div>
|
</div>
|
||||||
<p class="text-xs text-slate-400 font-mono">Proxify-ADB Fleet Orchestrator & MoE Pruner</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Live Telemetry Quick Gauges -->
|
<!-- Interactive Canvas Graph -->
|
||||||
<div class="flex items-center gap-6 bg-slate-900/60 border border-slate-800 px-4 py-1.5 rounded-xl text-xs font-mono">
|
<div class="relative w-full h-[240px] bg-slate-950/80 rounded-xl border border-slate-800/80 overflow-hidden shadow-2xl">
|
||||||
<div class="flex items-center gap-2">
|
<canvas id="pipelineCanvas" class="w-full h-full block"></canvas>
|
||||||
<i class="fa-solid fa-memory text-cyan-400"></i>
|
|
||||||
<span class="text-slate-400">VRAM:</span>
|
|
||||||
<span class="font-bold text-cyan-300" id="gaugeVram">6.2 / 16.0 GB</span>
|
|
||||||
</div>
|
|
||||||
<div class="w-px h-4 bg-slate-800"></div>
|
|
||||||
<div class="flex items-center gap-2">
|
|
||||||
<i class="fa-solid fa-server text-violet-400"></i>
|
|
||||||
<span class="text-slate-400">RAM:</span>
|
|
||||||
<span class="font-bold text-violet-300" id="gaugeRam">34.5 / 64.0 GB</span>
|
|
||||||
</div>
|
|
||||||
<div class="w-px h-4 bg-slate-800"></div>
|
|
||||||
<div class="flex items-center gap-2">
|
|
||||||
<i class="fa-solid fa-[#00FF9D] fa-mobile-screen-button text-emerald-400"></i>
|
|
||||||
<span class="text-slate-400">ADB Fleet:</span>
|
|
||||||
<span class="font-bold text-emerald-400" id="gaugeAdb">14 / 14 Online</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
<!-- Action Button Group -->
|
<!-- Telemetry & Controls Grid -->
|
||||||
<div class="flex items-center gap-3">
|
<div class="grid grid-cols-1 lg:grid-cols-12 gap-6">
|
||||||
<button id="btnStartPipeline" class="btn btn-emerald">
|
|
||||||
<i class="fa-solid fa-play"></i> Run Pipeline
|
|
||||||
</button>
|
|
||||||
<button id="btnStopPipeline" class="btn btn-rose" disabled>
|
|
||||||
<i class="fa-solid fa-square"></i> Stop
|
|
||||||
</button>
|
|
||||||
<button id="btnOpenKnobs" class="btn btn-ghost">
|
|
||||||
<i class="fa-solid fa-sliders"></i> Tuning Knobs
|
|
||||||
</button>
|
|
||||||
<button id="btnSyncGitea" class="btn btn-purple">
|
|
||||||
<i class="fa-solid fa-code-branch"></i> Push to Gitea
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<!-- Main Workspace Grid -->
|
<!-- Column 1: Charts & Expert Distributions (7 cols) -->
|
||||||
<main class="flex-1 p-6 space-y-6 max-w-[1920px] mx-auto w-full pb-72">
|
<div class="lg:col-span-7 space-y-6">
|
||||||
|
|
||||||
<!-- Visual Pipeline Flow Canvas Container -->
|
<!-- GRPO Reward Convergence Card -->
|
||||||
<section class="glass-panel p-6 rounded-2xl relative overflow-hidden">
|
<div class="cyber-card p-5 rounded-2xl">
|
||||||
<div class="flex items-center justify-between mb-4">
|
<div class="flex items-center justify-between mb-4">
|
||||||
<div>
|
<div>
|
||||||
<h2 class="text-base font-bold font-outfit text-white flex items-center gap-2">
|
|
||||||
<i class="fa-solid fa-diagram-project text-cyan-400"></i>
|
|
||||||
AUTONOMOUS FINE-TUNING PIPELINE VISUALIZER
|
|
||||||
</h2>
|
|
||||||
<p class="text-xs text-slate-400">Interactive execution path with dynamic layer pruning & execution rewards</p>
|
|
||||||
</div>
|
|
||||||
<div class="flex items-center gap-3 text-xs font-mono">
|
|
||||||
<span class="status-badge status-idle" id="pipelineStatusBadge">STATUS: IDLE</span>
|
|
||||||
<span class="text-slate-400">Progress: <strong class="text-white" id="overallProgressText">0%</strong></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Interactive Canvas Pipeline Graph -->
|
|
||||||
<div class="relative w-full h-[220px] bg-slate-950/60 rounded-xl border border-slate-800/80 overflow-hidden">
|
|
||||||
<canvas id="pipelineCanvas" class="w-full h-full block"></canvas>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<!-- Dashboard Telemetry Grid (2 Columns) -->
|
|
||||||
<div class="grid grid-cols-1 lg:grid-cols-12 gap-6">
|
|
||||||
|
|
||||||
<!-- Column 1: GRPO Reward Convergence Chart & MoE Distribution (7 cols) -->
|
|
||||||
<div class="lg:col-span-7 space-y-6">
|
|
||||||
|
|
||||||
<!-- GRPO Reward Convergence Card -->
|
|
||||||
<div class="glass-panel p-5 rounded-2xl">
|
|
||||||
<div class="flex items-center justify-between mb-4">
|
|
||||||
<h3 class="text-sm font-bold font-outfit text-white flex items-center gap-2">
|
<h3 class="text-sm font-bold font-outfit text-white flex items-center gap-2">
|
||||||
<i class="fa-solid fa-chart-line text-emerald-400"></i>
|
<i class="fa-solid fa-chart-line text-emerald-400"></i>
|
||||||
UNSLOTH GRPO HARD EXECUTION REWARD CONVERGENCE
|
UNSLOTH GRPO HARD EXECUTION REWARD CONVERGENCE
|
||||||
</h3>
|
</h3>
|
||||||
<span class="text-xs font-mono text-emerald-400 bg-emerald-500/10 px-2 py-0.5 rounded border border-emerald-500/20">
|
<p class="text-[11px] text-slate-400">Multi-vector reward curve ($R_{exec} = +3.0$, $R_{anti-hesit} = +2.0$, Safety = $-10.0$)</p>
|
||||||
Step <span id="grpoStepVal">0</span> / 300
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="h-[220px] w-full">
|
|
||||||
<canvas id="grpoChart"></canvas>
|
|
||||||
</div>
|
</div>
|
||||||
|
<span class="text-xs font-mono text-emerald-400 bg-emerald-500/10 px-3 py-1 rounded-xl border border-emerald-500/30 font-bold">
|
||||||
|
Step <span id="grpoStepVal">0</span> / 300
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="h-[220px] w-full">
|
||||||
|
<canvas id="grpoChart"></canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- MoE Expert Pruning Distribution Card -->
|
<!-- MoE Expert Pruning Distribution Card -->
|
||||||
<div class="glass-panel p-5 rounded-2xl">
|
<div class="cyber-card p-5 rounded-2xl">
|
||||||
<div class="flex items-center justify-between mb-4">
|
<div class="flex items-center justify-between mb-4">
|
||||||
|
<div>
|
||||||
<h3 class="text-sm font-bold font-outfit text-white flex items-center gap-2">
|
<h3 class="text-sm font-bold font-outfit text-white flex items-center gap-2">
|
||||||
<i class="fa-solid fa-scissors text-amber-400"></i>
|
<i class="fa-solid fa-scissors text-amber-400"></i>
|
||||||
DOMAIN MoE EXPERT RETENTION VS PRUNED TRIVIA EXPERTS
|
DOMAIN MoE EXPERT RETENTION VS PRUNED TRIVIA EXPERTS
|
||||||
</h3>
|
</h3>
|
||||||
<span class="text-xs font-mono text-amber-400 bg-amber-500/10 px-2 py-0.5 rounded border border-amber-500/20">
|
<p class="text-[11px] text-slate-400">Dropping ~68.75% dormant botany/history experts across 61 layers</p>
|
||||||
Retained: <strong id="retainedExpertsVal">64</strong> / 256
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="h-[180px] w-full">
|
|
||||||
<canvas id="moeChart"></canvas>
|
|
||||||
</div>
|
</div>
|
||||||
|
<span class="text-xs font-mono text-amber-400 bg-amber-500/10 px-3 py-1 rounded-xl border border-amber-500/30 font-bold">
|
||||||
|
Retained: <span id="retainedExpertsVal">64</span> / 256
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="h-[180px] w-full">
|
||||||
|
<canvas id="moeChart"></canvas>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Column 2: Fleet Topology & Script Code Inspector (5 cols) -->
|
</div>
|
||||||
<div class="lg:col-span-5 space-y-6">
|
|
||||||
|
|
||||||
<!-- Fleet & Proxmox Bridge Network Status Card -->
|
<!-- Column 2: Fleet Topology & Script Code Inspector (5 cols) -->
|
||||||
<div class="glass-panel p-5 rounded-2xl">
|
<div class="lg:col-span-5 space-y-6">
|
||||||
<h3 class="text-sm font-bold font-outfit text-white flex items-center gap-2 mb-3">
|
|
||||||
|
<!-- Proxmox Fleet Topology Card -->
|
||||||
|
<div class="cyber-card p-5 rounded-2xl">
|
||||||
|
<div class="flex items-center justify-between mb-3">
|
||||||
|
<h3 class="text-sm font-bold font-outfit text-white flex items-center gap-2">
|
||||||
<i class="fa-solid fa-network-wired text-cyan-400"></i>
|
<i class="fa-solid fa-network-wired text-cyan-400"></i>
|
||||||
10.30.20.0/24 PROXMOX FLEET TOPOLOGY
|
10.30.20.0/24 PROXMOX FLEET TOPOLOGY
|
||||||
</h3>
|
</h3>
|
||||||
|
<span class="text-[10px] font-mono text-cyan-400 bg-cyan-500/10 px-2 py-0.5 rounded border border-cyan-500/30">vmbr1 Isolated</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="grid grid-cols-2 gap-3 text-xs font-mono mb-4">
|
<div class="grid grid-cols-2 gap-3 text-xs font-mono mb-4">
|
||||||
<div class="bg-slate-900/80 border border-slate-800 p-3 rounded-xl">
|
<div class="bg-slate-950/80 border border-slate-800 p-3 rounded-xl">
|
||||||
<span class="text-slate-400 block text-[11px]">Control Gateway</span>
|
<span class="text-slate-400 block text-[10px]">Gateway Control Node</span>
|
||||||
<strong class="text-cyan-300 text-sm">10.30.20.1</strong>
|
<strong class="text-cyan-300 text-sm">10.30.20.1</strong>
|
||||||
<div class="mt-1 text-[10px] text-slate-500">vmbr1 (Isolated Bridge)</div>
|
<div class="mt-1 text-[10px] text-slate-500">Port 5555 / REST API</div>
|
||||||
</div>
|
|
||||||
<div class="bg-slate-900/80 border border-slate-800 p-3 rounded-xl">
|
|
||||||
<span class="text-slate-400 block text-[11px]">DHCP Pool</span>
|
|
||||||
<strong class="text-violet-300 text-sm">.100 - .254</strong>
|
|
||||||
<div class="mt-1 text-[10px] text-slate-500">dnsmasq 12h Leases</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="bg-slate-950/80 border border-slate-800 p-3 rounded-xl">
|
||||||
<!-- Active VM Fleet Node Grid -->
|
<span class="text-slate-400 block text-[10px]">Dynamic DHCP Pool</span>
|
||||||
<div class="space-y-2 max-h-[180px] overflow-y-auto custom-scrollbar pr-1" id="fleetNodeList">
|
<strong class="text-violet-300 text-sm">.100 ──► .254</strong>
|
||||||
<!-- Dynamically Populated Fleet Cards -->
|
<div class="mt-1 text-[10px] text-slate-500">dnsmasq 12h Leases</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Python Script Viewer & Sandbox Card -->
|
<!-- Active VM Nodes Grid -->
|
||||||
<div class="glass-panel p-5 rounded-2xl flex flex-col h-[280px]">
|
<div class="space-y-2 max-h-[190px] overflow-y-auto custom-scrollbar pr-1" id="fleetNodeList">
|
||||||
<div class="flex items-center justify-between mb-3">
|
<!-- Dynamically Rendered Cards -->
|
||||||
<h3 class="text-sm font-bold font-outfit text-white flex items-center gap-2">
|
|
||||||
<i class="fa-brands fa-python text-yellow-400"></i>
|
|
||||||
PIPELINE SCRIPT INSPECTOR
|
|
||||||
</h3>
|
|
||||||
<select id="scriptSelector" class="bg-slate-900 border border-slate-800 text-xs font-mono text-cyan-400 px-2 py-1 rounded">
|
|
||||||
<option value="harvester.py">harvester.py</option>
|
|
||||||
<option value="prune_moe.py">prune_moe.py</option>
|
|
||||||
<option value="harness_env.py">harness_env.py</option>
|
|
||||||
<option value="train_grpo.py">train_grpo.py</option>
|
|
||||||
<option value="deploy.py">deploy.py</option>
|
|
||||||
<option value="state_eye.py">state_eye.py</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<pre class="flex-1 bg-slate-950 p-3 rounded-xl border border-slate-900 text-xs font-mono text-slate-300 overflow-auto custom-scrollbar leading-relaxed" id="scriptCodeView"># Loading script content...</pre>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</main>
|
|
||||||
|
|
||||||
<!-- Bottom Collapsible Rolling Cyber Terminal -->
|
|
||||||
<div id="terminalContainer" class="fixed bottom-0 left-0 right-0 z-30 bg-slate-950/95 border-t border-slate-800/90 shadow-2xl backdrop-blur-2xl transition-all duration-300">
|
|
||||||
|
|
||||||
<!-- Terminal Controls & Header Bar -->
|
|
||||||
<div class="px-6 py-2.5 bg-slate-900/90 border-b border-slate-800 flex items-center justify-between gap-4 text-xs font-mono">
|
|
||||||
<div class="flex items-center gap-3">
|
|
||||||
<button id="btnToggleTerminal" class="text-slate-400 hover:text-white transition">
|
|
||||||
<i class="fa-solid fa-chevron-down" id="terminalChevron"></i>
|
|
||||||
</button>
|
|
||||||
<span class="font-bold text-cyan-400 flex items-center gap-2">
|
|
||||||
<i class="fa-solid fa-terminal"></i> LIVE LOG STREAM
|
|
||||||
</span>
|
|
||||||
<span class="bg-slate-800 px-2 py-0.5 rounded text-[10px] text-slate-400" id="logCountBadge">0 Logs</span>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Filter & Search Controls -->
|
<!-- Python Script Viewer Card -->
|
||||||
<div class="flex items-center gap-3">
|
<div class="cyber-card p-5 rounded-2xl flex flex-col h-[280px]">
|
||||||
<div class="flex items-center gap-1 bg-slate-950 px-2 py-1 rounded border border-slate-800">
|
<div class="flex items-center justify-between mb-3">
|
||||||
<span class="text-slate-500 text-[10px]">Filter:</span>
|
<h3 class="text-sm font-bold font-outfit text-white flex items-center gap-2">
|
||||||
<button class="log-filter-btn active" data-filter="ALL">ALL</button>
|
<i class="fa-brands fa-python text-yellow-400"></i>
|
||||||
<button class="log-filter-btn" data-filter="INFO">INFO</button>
|
PIPELINE SCRIPT INSPECTOR
|
||||||
<button class="log-filter-btn" data-filter="HARNESS">HARNESS</button>
|
</h3>
|
||||||
<button class="log-filter-btn" data-filter="REWARD">REWARD</button>
|
<select id="scriptSelector" class="bg-slate-950 border border-slate-800 text-xs font-mono text-cyan-400 px-3 py-1 rounded-xl focus:outline-none focus:border-cyan-500">
|
||||||
<button class="log-filter-btn" data-filter="WARN">WARN</button>
|
<option value="harvester.py">harvester.py</option>
|
||||||
|
<option value="prune_moe.py">prune_moe.py</option>
|
||||||
|
<option value="harness_env.py">harness_env.py</option>
|
||||||
|
<option value="train_grpo.py">train_grpo.py</option>
|
||||||
|
<option value="deploy.py">deploy.py</option>
|
||||||
|
<option value="state_eye.py">state_eye.py</option>
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
<pre class="flex-1 bg-slate-950 p-4 rounded-xl border border-slate-900 text-xs font-mono text-slate-300 overflow-auto custom-scrollbar leading-relaxed" id="scriptCodeView"># Select a script to view source code...</pre>
|
||||||
<button id="btnAutoScroll" class="px-2 py-1 rounded bg-cyan-500/10 text-cyan-400 border border-cyan-500/30 text-[11px] font-bold">
|
|
||||||
<i class="fa-solid fa-angles-down"></i> Auto-Scroll
|
|
||||||
</button>
|
|
||||||
<button id="btnClearLogs" class="px-2 py-1 rounded bg-slate-800 text-slate-400 hover:text-white text-[11px]">
|
|
||||||
<i class="fa-solid fa-trash-can"></i> Clear
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Log Output Scroll Container -->
|
|
||||||
<div id="terminalBody" class="h-56 p-4 font-mono text-xs overflow-y-auto space-y-1 custom-scrollbar bg-slate-950/90 select-text">
|
|
||||||
<!-- Log Lines Streamed Here -->
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Tuning Knobs Modal -->
|
</main>
|
||||||
<div id="knobsModal" class="fixed inset-0 z-50 bg-black/80 backdrop-blur-md flex items-center justify-center p-4 opacity-0 pointer-events-none transition-opacity duration-300">
|
|
||||||
<div class="glass-panel max-w-lg w-full p-6 rounded-2xl border border-slate-800 space-y-6">
|
<!-- Sticky Collapsible Cyber Terminal Log Console at Bottom -->
|
||||||
<div class="flex items-center justify-between border-b border-slate-800 pb-3">
|
<div id="terminalContainer" class="fixed bottom-0 left-0 right-0 z-30 bg-slate-950/95 border-t border-slate-800 shadow-2xl backdrop-blur-2xl transition-all duration-300">
|
||||||
<h3 class="text-lg font-bold font-outfit text-white flex items-center gap-2">
|
|
||||||
<i class="fa-solid fa-sliders text-cyan-400"></i> TUNING KNOBS & REWARD WEIGHTS
|
<!-- Terminal Header & Action Bar -->
|
||||||
</h3>
|
<div class="px-6 py-2.5 bg-slate-900/90 border-b border-slate-800 flex flex-wrap items-center justify-between gap-4 text-xs font-mono">
|
||||||
<button id="btnCloseKnobs" class="text-slate-400 hover:text-white"><i class="fa-solid fa-xmark text-lg"></i></button>
|
<div class="flex items-center gap-3">
|
||||||
|
<button id="btnToggleTerminal" class="w-7 h-7 rounded-lg bg-slate-800 hover:bg-slate-700 text-slate-300 hover:text-white flex items-center justify-center transition">
|
||||||
|
<i class="fa-solid fa-chevron-down text-xs" id="terminalChevron"></i>
|
||||||
|
</button>
|
||||||
|
<span class="font-bold text-cyan-400 flex items-center gap-2 text-sm">
|
||||||
|
<i class="fa-solid fa-terminal"></i> LIVE LOG STREAM CONSOLE
|
||||||
|
</span>
|
||||||
|
<span class="bg-cyan-500/10 border border-cyan-500/30 text-cyan-400 px-2.5 py-0.5 rounded-full text-[10px] font-bold" id="logCountBadge">0 Logs</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Filter Buttons & Controls -->
|
||||||
|
<div class="flex items-center gap-3">
|
||||||
|
<div class="flex items-center gap-1 bg-slate-950 px-2 py-1 rounded-xl border border-slate-800">
|
||||||
|
<span class="text-slate-500 text-[10px] px-1 font-bold">LEVEL:</span>
|
||||||
|
<button class="log-filter-btn active" data-filter="ALL">ALL</button>
|
||||||
|
<button class="log-filter-btn" data-filter="INFO">INFO</button>
|
||||||
|
<button class="log-filter-btn" data-filter="HARNESS">HARNESS</button>
|
||||||
|
<button class="log-filter-btn" data-filter="REWARD">REWARD</button>
|
||||||
|
<button class="log-filter-btn" data-filter="WARN">WARN</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="space-y-4 text-xs font-mono">
|
<button id="btnAutoScroll" class="px-3 py-1 rounded-xl bg-cyan-500/20 text-cyan-400 border border-cyan-500/40 text-[11px] font-bold hover:bg-cyan-500/30 transition">
|
||||||
<div>
|
<i class="fa-solid fa-angles-down"></i> Auto-Scroll
|
||||||
<label class="flex justify-between text-slate-300 mb-1">
|
</button>
|
||||||
<span>Retained MoE Experts per Layer:</span>
|
<button id="btnClearLogs" class="px-3 py-1 rounded-xl bg-slate-800 text-slate-400 hover:text-white text-[11px] border border-slate-700 transition">
|
||||||
<strong class="text-cyan-400" id="knobExpertsVal">64 / 256</strong>
|
<i class="fa-solid fa-trash-can"></i> Clear
|
||||||
</label>
|
</button>
|
||||||
<input type="range" id="knobExperts" min="16" max="128" step="16" value="64" class="w-full accent-cyan-400">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<label class="flex justify-between text-slate-300 mb-1">
|
|
||||||
<span>Hard Execution Reward Weight ($w_1$):</span>
|
|
||||||
<strong class="text-emerald-400" id="knobExecVal">3.0</strong>
|
|
||||||
</label>
|
|
||||||
<input type="range" id="knobExec" min="1.0" max="5.0" step="0.5" value="3.0" class="w-full accent-emerald-400">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<label class="flex justify-between text-slate-300 mb-1">
|
|
||||||
<span>Anti-Hesitation Penalty Weight ($w_2$):</span>
|
|
||||||
<strong class="text-amber-400" id="knobHesitVal">2.0</strong>
|
|
||||||
</label>
|
|
||||||
<input type="range" id="knobHesit" min="0.5" max="4.0" step="0.5" value="2.0" class="w-full accent-amber-400">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<label class="flex justify-between text-slate-300 mb-1">
|
|
||||||
<span>Target VRAM Footprint:</span>
|
|
||||||
<strong class="text-violet-400">16.0 GB (NVIDIA CUDA)</strong>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="flex justify-end gap-3 pt-3 border-t border-slate-800">
|
|
||||||
<button id="btnSaveKnobs" class="btn btn-emerald w-full">Save & Apply Parameters</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Rolling Terminal Stream Body -->
|
||||||
|
<div id="terminalBody" class="h-60 p-4 font-mono text-xs overflow-y-auto space-y-1 custom-scrollbar bg-slate-950 select-text">
|
||||||
|
<!-- Live Stream Logs Added Here -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Tuning Knobs Modal -->
|
||||||
|
<div id="knobsModal" class="fixed inset-0 z-50 bg-black/80 backdrop-blur-xl flex items-center justify-center p-4 opacity-0 pointer-events-none transition-opacity duration-300">
|
||||||
|
<div class="cyber-card max-w-lg w-full p-6 rounded-2xl border border-slate-800 space-y-6 shadow-2xl">
|
||||||
|
<div class="flex items-center justify-between border-b border-slate-800 pb-3">
|
||||||
|
<h3 class="text-lg font-black font-outfit text-white flex items-center gap-2">
|
||||||
|
<i class="fa-solid fa-sliders text-cyan-400"></i> TUNING KNOBS & REWARD WEIGHTS
|
||||||
|
</h3>
|
||||||
|
<button id="btnCloseKnobs" class="text-slate-400 hover:text-white text-lg"><i class="fa-solid fa-xmark"></i></button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="space-y-5 text-xs font-mono">
|
||||||
|
<div>
|
||||||
|
<label class="flex justify-between text-slate-300 mb-1.5">
|
||||||
|
<span>Retained MoE Experts per Layer:</span>
|
||||||
|
<strong class="text-cyan-400 text-sm" id="knobExpertsVal">64 / 256</strong>
|
||||||
|
</label>
|
||||||
|
<input type="range" id="knobExperts" min="16" max="128" step="16" value="64" class="w-full accent-cyan-400">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label class="flex justify-between text-slate-300 mb-1.5">
|
||||||
|
<span>Hard Execution Reward Weight ($w_1$):</span>
|
||||||
|
<strong class="text-emerald-400 text-sm" id="knobExecVal">3.0</strong>
|
||||||
|
</label>
|
||||||
|
<input type="range" id="knobExec" min="1.0" max="5.0" step="0.5" value="3.0" class="w-full accent-emerald-400">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label class="flex justify-between text-slate-300 mb-1.5">
|
||||||
|
<span>Anti-Hesitation Penalty Weight ($w_2$):</span>
|
||||||
|
<strong class="text-amber-400 text-sm" id="knobHesitVal">2.0</strong>
|
||||||
|
</label>
|
||||||
|
<input type="range" id="knobHesit" min="0.5" max="4.0" step="0.5" value="2.0" class="w-full accent-amber-400">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bg-slate-950 p-3 rounded-xl border border-slate-800">
|
||||||
|
<span class="text-slate-400 block text-[11px]">Hardware Memory Target:</span>
|
||||||
|
<strong class="text-violet-300">16.0 GB VRAM + 64.0 GB System RAM Streaming</strong>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-end gap-3 pt-3 border-t border-slate-800">
|
||||||
|
<button id="btnSaveKnobs" class="btn-neon btn-emerald w-full justify-center">SAVE & APPLY PARAMETERS</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Scripts -->
|
<!-- Scripts -->
|
||||||
|
|||||||
@@ -1,20 +1,22 @@
|
|||||||
/**
|
/**
|
||||||
* pipeline.js - Interactive Canvas Pipeline Visualizer
|
* pipeline.js - Interactive HTML5 Canvas Pipeline Visualizer
|
||||||
* Renders nodes, dynamic connections, glowing particle pulses, and interactive states.
|
* Renders glowing neon nodes, animated pulse particles, laser beams, and stage cards.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class PipelineVisualizer {
|
class PipelineVisualizer {
|
||||||
constructor(canvasId) {
|
constructor(canvasId) {
|
||||||
this.canvas = document.getElementById(canvasId);
|
this.canvas = document.getElementById(canvasId);
|
||||||
this.ctx = this.canvas.getContext('2d');
|
this.ctx = this.canvas.getContext('2d');
|
||||||
|
|
||||||
this.nodes = [
|
this.nodes = [
|
||||||
{ id: 'harvester', name: '1. Config Harvester', icon: '⚡', x: 0.12, y: 0.5, status: 'idle', desc: 'Scrapes /etc/dnsmasq.d & ADB nodes' },
|
{ id: 'harvester', name: '1. Config Harvester', icon: '⚡', x: 0.10, y: 0.5, status: 'idle', color: '#00F0FF', desc: 'Scrapes /etc/dnsmasq.d & ADB nodes' },
|
||||||
{ id: 'pruner', name: '2. MoE Expert Pruner', icon: '✂️', x: 0.28, y: 0.5, status: 'idle', desc: 'Drops 70% dormant trivia experts (256->64)' },
|
{ id: 'pruner', name: '2. MoE Expert Pruner', icon: '✂️', x: 0.26, y: 0.5, status: 'idle', color: '#FFB800', desc: 'Drops 70% dormant trivia experts (256->64)' },
|
||||||
{ id: 'harness', name: '3. Execution Gym', icon: '🛡️', x: 0.44, y: 0.5, status: 'idle', desc: 'Command safety sandbox & STDERR check' },
|
{ id: 'harness', name: '3. Execution Gym', icon: '🛡️', x: 0.42, y: 0.5, status: 'idle', color: '#8A2BE2', desc: 'Command safety sandbox & STDERR check' },
|
||||||
{ id: 'grpo', name: '4. Unsloth GRPO', icon: '🧠', x: 0.60, y: 0.5, status: 'idle', desc: 'Hard execution & anti-hesitation rewards' },
|
{ id: 'grpo', name: '4. Unsloth GRPO', icon: '🧠', x: 0.58, y: 0.5, status: 'idle', color: '#00FF9D', desc: 'Hard execution & anti-hesitation rewards' },
|
||||||
{ id: 'export', name: '5. GGUF Quantizer', icon: '📦', x: 0.76, y: 0.5, status: 'idle', desc: 'Dual-offload Q4_K_M GGUF packaging' },
|
{ id: 'export', name: '5. GGUF Quantizer', icon: '📦', x: 0.74, y: 0.5, status: 'idle', color: '#C084FC', desc: 'Dual-offload Q4_K_M GGUF packaging' },
|
||||||
{ id: 'telemetry', name: '6. State Eye Daemon', icon: '👁️', x: 0.90, y: 0.5, status: 'idle', desc: '10.30.20.1 live state context injector' }
|
{ id: 'telemetry', name: '6. State Eye Daemon', icon: '👁️', x: 0.90, y: 0.5, status: 'idle', color: '#00F0FF', desc: '10.30.20.1 live state context injector' }
|
||||||
];
|
];
|
||||||
|
|
||||||
this.particles = [];
|
this.particles = [];
|
||||||
this.activeStage = null;
|
this.activeStage = null;
|
||||||
this.animId = null;
|
this.animId = null;
|
||||||
@@ -27,17 +29,20 @@ class PipelineVisualizer {
|
|||||||
|
|
||||||
resize() {
|
resize() {
|
||||||
const parent = this.canvas.parentElement;
|
const parent = this.canvas.parentElement;
|
||||||
this.canvas.width = parent.clientWidth;
|
if (parent) {
|
||||||
this.canvas.height = parent.clientHeight;
|
this.canvas.width = parent.clientWidth;
|
||||||
|
this.canvas.height = parent.clientHeight;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
initParticles() {
|
initParticles() {
|
||||||
this.particles = [];
|
this.particles = [];
|
||||||
for (let i = 0; i < 20; i++) {
|
for (let i = 0; i < 25; i++) {
|
||||||
this.particles.push({
|
this.particles.push({
|
||||||
progress: Math.random(),
|
progress: Math.random(),
|
||||||
speed: 0.003 + Math.random() * 0.004,
|
speed: 0.003 + Math.random() * 0.004,
|
||||||
size: 3 + Math.random() * 2
|
size: 3 + Math.random() * 2,
|
||||||
|
alpha: 0.5 + Math.random() * 0.5
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -74,7 +79,7 @@ class PipelineVisualizer {
|
|||||||
const h = this.canvas.height;
|
const h = this.canvas.height;
|
||||||
this.ctx.clearRect(0, 0, w, h);
|
this.ctx.clearRect(0, 0, w, h);
|
||||||
|
|
||||||
// 1. Draw Connecting Lines
|
// 1. Draw Connecting Laser Beams
|
||||||
for (let i = 0; i < this.nodes.length - 1; i++) {
|
for (let i = 0; i < this.nodes.length - 1; i++) {
|
||||||
const n1 = this.nodes[i];
|
const n1 = this.nodes[i];
|
||||||
const n2 = this.nodes[i + 1];
|
const n2 = this.nodes[i + 1];
|
||||||
@@ -85,17 +90,31 @@ class PipelineVisualizer {
|
|||||||
|
|
||||||
const isPassed = this.activeStage && this.getStageIndex(n1.id) <= this.getStageIndex(this.activeStage);
|
const isPassed = this.activeStage && this.getStageIndex(n1.id) <= this.getStageIndex(this.activeStage);
|
||||||
|
|
||||||
|
// Base Beam
|
||||||
this.ctx.beginPath();
|
this.ctx.beginPath();
|
||||||
this.ctx.moveTo(x1, y1);
|
this.ctx.moveTo(x1, y1);
|
||||||
this.ctx.lineTo(x2, y2);
|
this.ctx.lineTo(x2, y2);
|
||||||
this.ctx.strokeStyle = isPassed ? 'rgba(0, 240, 255, 0.6)' : 'rgba(51, 65, 85, 0.5)';
|
this.ctx.strokeStyle = isPassed ? 'rgba(0, 240, 255, 0.4)' : 'rgba(30, 41, 59, 0.6)';
|
||||||
this.ctx.lineWidth = isPassed ? 3 : 2;
|
this.ctx.lineWidth = isPassed ? 4 : 2;
|
||||||
this.ctx.setLineDash(isPassed ? [] : [5, 5]);
|
if (!isPassed) this.ctx.setLineDash([6, 6]);
|
||||||
this.ctx.stroke();
|
this.ctx.stroke();
|
||||||
this.ctx.setLineDash([]);
|
this.ctx.setLineDash([]);
|
||||||
|
|
||||||
|
// Neon Glow Line
|
||||||
|
if (isPassed) {
|
||||||
|
this.ctx.beginPath();
|
||||||
|
this.ctx.moveTo(x1, y1);
|
||||||
|
this.ctx.lineTo(x2, y2);
|
||||||
|
this.ctx.strokeStyle = 'rgba(0, 240, 255, 0.8)';
|
||||||
|
this.ctx.lineWidth = 2;
|
||||||
|
this.ctx.shadowColor = '#00F0FF';
|
||||||
|
this.ctx.shadowBlur = 15;
|
||||||
|
this.ctx.stroke();
|
||||||
|
this.ctx.shadowBlur = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Draw Moving Data Particles
|
// 2. Draw Animated Particles on Active Segment
|
||||||
if (this.activeStage) {
|
if (this.activeStage) {
|
||||||
this.particles.forEach(p => {
|
this.particles.forEach(p => {
|
||||||
p.progress += p.speed;
|
p.progress += p.speed;
|
||||||
@@ -114,40 +133,44 @@ class PipelineVisualizer {
|
|||||||
|
|
||||||
this.ctx.beginPath();
|
this.ctx.beginPath();
|
||||||
this.ctx.arc(px, py, p.size, 0, Math.PI * 2);
|
this.ctx.arc(px, py, p.size, 0, Math.PI * 2);
|
||||||
this.ctx.fillStyle = '#00F0FF';
|
this.ctx.fillStyle = '#00FF9D';
|
||||||
this.ctx.shadowColor = '#00F0FF';
|
this.ctx.shadowColor = '#00FF9D';
|
||||||
this.ctx.shadowBlur = 10;
|
this.ctx.shadowBlur = 12;
|
||||||
this.ctx.fill();
|
this.ctx.fill();
|
||||||
this.ctx.shadowBlur = 0;
|
this.ctx.shadowBlur = 0;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Draw Nodes
|
// 3. Draw Nodes & Cards
|
||||||
this.nodes.forEach(node => {
|
this.nodes.forEach(node => {
|
||||||
const nx = node.x * w;
|
const nx = node.x * w;
|
||||||
const ny = node.y * h;
|
const ny = node.y * h;
|
||||||
|
|
||||||
// Glow effect for active/completed nodes
|
// Pulsing outer aura ring for active node
|
||||||
if (node.status === 'running') {
|
if (node.status === 'running') {
|
||||||
|
const pulse = 34 + Math.sin(Date.now() * 0.006) * 6;
|
||||||
this.ctx.beginPath();
|
this.ctx.beginPath();
|
||||||
this.ctx.arc(nx, ny, 32, 0, Math.PI * 2);
|
this.ctx.arc(nx, ny, pulse, 0, Math.PI * 2);
|
||||||
this.ctx.fillStyle = 'rgba(0, 240, 255, 0.15)';
|
this.ctx.fillStyle = 'rgba(0, 240, 255, 0.15)';
|
||||||
|
this.ctx.strokeStyle = 'rgba(0, 240, 255, 0.6)';
|
||||||
|
this.ctx.lineWidth = 2;
|
||||||
this.ctx.shadowColor = '#00F0FF';
|
this.ctx.shadowColor = '#00F0FF';
|
||||||
this.ctx.shadowBlur = 20;
|
this.ctx.shadowBlur = 25;
|
||||||
this.ctx.fill();
|
this.ctx.fill();
|
||||||
|
this.ctx.stroke();
|
||||||
this.ctx.shadowBlur = 0;
|
this.ctx.shadowBlur = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Outer Circle
|
// Outer Node Circle
|
||||||
this.ctx.beginPath();
|
this.ctx.beginPath();
|
||||||
this.ctx.arc(nx, ny, 24, 0, Math.PI * 2);
|
this.ctx.arc(nx, ny, 26, 0, Math.PI * 2);
|
||||||
if (node.status === 'running') {
|
if (node.status === 'running') {
|
||||||
this.ctx.fillStyle = '#0F172A';
|
this.ctx.fillStyle = '#090D16';
|
||||||
this.ctx.strokeStyle = '#00F0FF';
|
this.ctx.strokeStyle = node.color;
|
||||||
this.ctx.lineWidth = 3;
|
this.ctx.lineWidth = 3;
|
||||||
} else if (node.status === 'completed') {
|
} else if (node.status === 'completed') {
|
||||||
this.ctx.fillStyle = 'rgba(0, 255, 157, 0.2)';
|
this.ctx.fillStyle = 'rgba(0, 255, 157, 0.15)';
|
||||||
this.ctx.strokeStyle = '#00FF9D';
|
this.ctx.strokeStyle = '#00FF9D';
|
||||||
this.ctx.lineWidth = 2;
|
this.ctx.lineWidth = 2;
|
||||||
} else {
|
} else {
|
||||||
@@ -158,8 +181,8 @@ class PipelineVisualizer {
|
|||||||
this.ctx.fill();
|
this.ctx.fill();
|
||||||
this.ctx.stroke();
|
this.ctx.stroke();
|
||||||
|
|
||||||
// Icon
|
// Node Icon Emoji
|
||||||
this.ctx.font = '16px sans-serif';
|
this.ctx.font = '18px sans-serif';
|
||||||
this.ctx.textAlign = 'center';
|
this.ctx.textAlign = 'center';
|
||||||
this.ctx.textBaseline = 'middle';
|
this.ctx.textBaseline = 'middle';
|
||||||
this.ctx.fillText(node.icon, nx, ny);
|
this.ctx.fillText(node.icon, nx, ny);
|
||||||
@@ -167,12 +190,12 @@ class PipelineVisualizer {
|
|||||||
// Node Name Label
|
// Node Name Label
|
||||||
this.ctx.font = 'bold 11px Outfit, sans-serif';
|
this.ctx.font = 'bold 11px Outfit, sans-serif';
|
||||||
this.ctx.fillStyle = node.status === 'running' ? '#00F0FF' : node.status === 'completed' ? '#00FF9D' : '#94A3B8';
|
this.ctx.fillStyle = node.status === 'running' ? '#00F0FF' : node.status === 'completed' ? '#00FF9D' : '#94A3B8';
|
||||||
this.ctx.fillText(node.name, nx, ny + 42);
|
this.ctx.fillText(node.name, nx, ny + 46);
|
||||||
|
|
||||||
// Status Badge
|
// Status Badge Sub-label
|
||||||
this.ctx.font = '9px Fira Code, monospace';
|
this.ctx.font = '9px Fira Code, monospace';
|
||||||
this.ctx.fillStyle = '#64748B';
|
this.ctx.fillStyle = node.status === 'running' ? '#00FF9D' : '#64748B';
|
||||||
this.ctx.fillText(node.status.toUpperCase(), nx, ny + 56);
|
this.ctx.fillText(node.status.toUpperCase(), nx, ny + 62);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user