671 lines
39 KiB
HTML
671 lines
39 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en" class="dark">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>HYPERSWAP // Dual-Engine Model Orchestrator & Live Telemetry</title>
|
||
<script src="https://cdn.tailwindcss.com"></script>
|
||
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.1/dist/chart.umd.min.js"></script>
|
||
<link rel="stylesheet" href="/static/styles.css">
|
||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||
</head>
|
||
<body class="bg-slate-950 text-slate-100 min-h-screen font-sans antialiased selection:bg-cyan-500 selection:text-white">
|
||
|
||
<!-- TOP HEADER -->
|
||
<header class="border-b border-slate-800 bg-slate-900/80 backdrop-blur sticky top-0 z-50">
|
||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-3 flex flex-wrap items-center justify-between gap-4">
|
||
<div class="flex items-center space-x-3">
|
||
<div class="w-10 h-10 rounded-xl bg-gradient-to-tr from-cyan-500 via-indigo-500 to-purple-500 flex items-center justify-center shadow-lg shadow-cyan-500/20">
|
||
<i class="fa-solid fa-bolt-lightning text-white text-lg"></i>
|
||
</div>
|
||
<div>
|
||
<div class="flex items-center space-x-2">
|
||
<h1 class="text-xl font-bold tracking-tight bg-clip-text text-transparent bg-gradient-to-r from-cyan-400 via-sky-300 to-indigo-400">
|
||
HYPERSWAP
|
||
</h1>
|
||
<span class="text-xs uppercase tracking-widest px-2 py-0.5 rounded bg-cyan-950/80 text-cyan-400 border border-cyan-800 font-mono">
|
||
v1.0-DEPLOY
|
||
</span>
|
||
</div>
|
||
<p class="text-xs text-slate-400 font-mono">NVIDIA RTX 4080 SUPER 16GB // 64GB DDR5 RAM // Ubuntu Linux</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="flex items-center space-x-3">
|
||
<!-- Service Status Indicators -->
|
||
<div class="flex items-center space-x-2 px-3 py-1.5 rounded-lg bg-slate-800/80 border border-slate-700/60 text-xs">
|
||
<span class="relative flex h-2.5 w-2.5">
|
||
<span id="ollama-pulse" class="animate-ping absolute inline-flex h-full w-full rounded-full bg-emerald-400 opacity-75"></span>
|
||
<span id="ollama-dot" class="relative inline-flex rounded-full h-2.5 w-2.5 bg-emerald-500"></span>
|
||
</span>
|
||
<span class="font-medium text-slate-300">Ollama LLM:</span>
|
||
<span id="ollama-status-text" class="text-emerald-400 font-mono font-bold">ONLINE</span>
|
||
</div>
|
||
|
||
<div class="flex items-center space-x-2 px-3 py-1.5 rounded-lg bg-slate-800/80 border border-slate-700/60 text-xs">
|
||
<span class="relative flex h-2.5 w-2.5">
|
||
<span id="comfy-pulse" class="animate-ping absolute inline-flex h-full w-full rounded-full bg-emerald-400 opacity-75"></span>
|
||
<span id="comfy-dot" class="relative inline-flex rounded-full h-2.5 w-2.5 bg-emerald-500"></span>
|
||
</span>
|
||
<span class="font-medium text-slate-300">ComfyUI:</span>
|
||
<span id="comfy-status-text" class="text-emerald-400 font-mono font-bold">ONLINE</span>
|
||
</div>
|
||
|
||
<div class="flex items-center space-x-1.5 px-3 py-1.5 rounded-lg bg-slate-800/80 border border-slate-700/60 text-xs text-slate-400 font-mono">
|
||
<i class="fa-solid fa-satellite-dish text-cyan-400 text-xs animate-pulse"></i>
|
||
<span id="sse-badge">SSE 1Hz</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</header>
|
||
|
||
<!-- MAIN CONTAINER -->
|
||
<main class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6 space-y-6">
|
||
|
||
<!-- HERO MEMORY GAUGES -->
|
||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||
<!-- GPU VRAM ALLOCATION GAUGE -->
|
||
<div class="bg-slate-900/70 border border-slate-800 rounded-2xl p-5 relative overflow-hidden backdrop-blur">
|
||
<div class="flex justify-between items-start mb-3">
|
||
<div>
|
||
<div class="flex items-center space-x-2">
|
||
<i class="fa-solid fa-microchip text-cyan-400"></i>
|
||
<h2 class="text-sm font-semibold text-slate-200 tracking-wide uppercase">GPU VRAM (16 GB Dedicated)</h2>
|
||
</div>
|
||
<p class="text-xs text-slate-400 mt-0.5">Real-time allocation breakdown on RTX 4080 SUPER</p>
|
||
</div>
|
||
<div class="text-right font-mono">
|
||
<span id="vram-total-used" class="text-2xl font-bold text-slate-100">0.0</span>
|
||
<span class="text-xs text-slate-400">/ 16.0 GB</span>
|
||
<div id="vram-used-pct" class="text-xs text-cyan-400 font-bold">0% USED</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Segmented Bar -->
|
||
<div class="h-6 w-full bg-slate-950 rounded-lg overflow-hidden flex border border-slate-800 p-0.5">
|
||
<div id="bar-ollama" class="bg-gradient-to-r from-purple-600 to-indigo-500 h-full rounded-l transition-all duration-500 relative group" style="width: 0%">
|
||
<div class="opacity-0 group-hover:opacity-100 absolute -top-8 left-1/2 -translate-x-1/2 bg-slate-800 text-[10px] text-white px-2 py-0.5 rounded border border-slate-700 whitespace-nowrap z-20">
|
||
Ollama: <span id="tooltip-ollama">0 GB</span>
|
||
</div>
|
||
</div>
|
||
<div id="bar-comfy" class="bg-gradient-to-r from-cyan-500 to-sky-400 h-full transition-all duration-500 relative group" style="width: 0%">
|
||
<div class="opacity-0 group-hover:opacity-100 absolute -top-8 left-1/2 -translate-x-1/2 bg-slate-800 text-[10px] text-white px-2 py-0.5 rounded border border-slate-700 whitespace-nowrap z-20">
|
||
ComfyUI: <span id="tooltip-comfy">0 GB</span>
|
||
</div>
|
||
</div>
|
||
<div id="bar-system" class="bg-slate-600 h-full transition-all duration-500 relative group" style="width: 0%">
|
||
<div class="opacity-0 group-hover:opacity-100 absolute -top-8 left-1/2 -translate-x-1/2 bg-slate-800 text-[10px] text-white px-2 py-0.5 rounded border border-slate-700 whitespace-nowrap z-20">
|
||
System: <span id="tooltip-system">0 GB</span>
|
||
</div>
|
||
</div>
|
||
<div id="bar-free" class="bg-slate-900 h-full rounded-r transition-all duration-500" style="width: 100%"></div>
|
||
</div>
|
||
|
||
<!-- Legend -->
|
||
<div class="grid grid-cols-4 gap-2 mt-3 text-xs font-mono">
|
||
<div class="flex items-center space-x-1.5">
|
||
<span class="w-2.5 h-2.5 rounded-full bg-purple-500"></span>
|
||
<span class="text-slate-400">Ollama:</span>
|
||
<span id="legend-ollama" class="text-slate-200 font-bold">0 GB</span>
|
||
</div>
|
||
<div class="flex items-center space-x-1.5">
|
||
<span class="w-2.5 h-2.5 rounded-full bg-cyan-400"></span>
|
||
<span class="text-slate-400">Comfy:</span>
|
||
<span id="legend-comfy" class="text-slate-200 font-bold">0 GB</span>
|
||
</div>
|
||
<div class="flex items-center space-x-1.5">
|
||
<span class="w-2.5 h-2.5 rounded-full bg-slate-500"></span>
|
||
<span class="text-slate-400">System:</span>
|
||
<span id="legend-system" class="text-slate-200 font-bold">0 GB</span>
|
||
</div>
|
||
<div class="flex items-center space-x-1.5">
|
||
<span class="w-2.5 h-2.5 rounded-full bg-slate-800 border border-slate-700"></span>
|
||
<span class="text-slate-400">Free:</span>
|
||
<span id="legend-free" class="text-emerald-400 font-bold">0 GB</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- SYSTEM RAM & PAGE CACHE GAUGE -->
|
||
<div class="bg-slate-900/70 border border-slate-800 rounded-2xl p-5 relative overflow-hidden backdrop-blur">
|
||
<div class="flex justify-between items-start mb-3">
|
||
<div>
|
||
<div class="flex items-center space-x-2">
|
||
<i class="fa-solid fa-memory text-amber-400"></i>
|
||
<h2 class="text-sm font-semibold text-slate-200 tracking-wide uppercase">Host RAM & Model Page Cache (64 GB)</h2>
|
||
</div>
|
||
<p class="text-xs text-slate-400 mt-0.5">Models stay resident in RAM for instant PCIe hot-swaps</p>
|
||
</div>
|
||
<div class="text-right font-mono">
|
||
<span id="ram-cached-gb" class="text-2xl font-bold text-amber-400">0.0</span>
|
||
<span class="text-xs text-slate-400">GB CACHED</span>
|
||
<div id="ram-total-text" class="text-xs text-slate-400">60.3 GB Total</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Segmented Bar -->
|
||
<div class="h-6 w-full bg-slate-950 rounded-lg overflow-hidden flex border border-slate-800 p-0.5">
|
||
<div id="bar-ram-used" class="bg-gradient-to-r from-rose-600 to-orange-500 h-full rounded-l transition-all duration-500" style="width: 10%"></div>
|
||
<div id="bar-ram-cache" class="bg-gradient-to-r from-amber-500 to-yellow-400 h-full transition-all duration-500" style="width: 50%"></div>
|
||
<div id="bar-ram-free" class="bg-slate-900 h-full rounded-r transition-all duration-500" style="width: 40%"></div>
|
||
</div>
|
||
|
||
<!-- Legend -->
|
||
<div class="grid grid-cols-3 gap-2 mt-3 text-xs font-mono">
|
||
<div class="flex items-center space-x-1.5">
|
||
<span class="w-2.5 h-2.5 rounded-full bg-rose-500"></span>
|
||
<span class="text-slate-400">Apps Used:</span>
|
||
<span id="legend-ram-used" class="text-slate-200 font-bold">0 GB</span>
|
||
</div>
|
||
<div class="flex items-center space-x-1.5">
|
||
<span class="w-2.5 h-2.5 rounded-full bg-amber-400"></span>
|
||
<span class="text-slate-400">Models in RAM:</span>
|
||
<span id="legend-ram-cached" class="text-amber-400 font-bold">0 GB</span>
|
||
</div>
|
||
<div class="flex items-center space-x-1.5">
|
||
<span class="w-2.5 h-2.5 rounded-full bg-slate-800 border border-slate-700"></span>
|
||
<span class="text-slate-400">Free RAM:</span>
|
||
<span id="legend-ram-free" class="text-emerald-400 font-bold">0 GB</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 4-CARD CONTROL & TELEMETRY GRID -->
|
||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
||
|
||
<!-- CARD 1: OLLAMA LLM ENGINE -->
|
||
<div class="bg-slate-900/80 border border-slate-800 rounded-2xl p-5 flex flex-col justify-between space-y-4">
|
||
<div>
|
||
<div class="flex items-center justify-between pb-3 border-b border-slate-800">
|
||
<div class="flex items-center space-x-2">
|
||
<div class="p-2 rounded-lg bg-purple-950/80 border border-purple-800 text-purple-400">
|
||
<i class="fa-solid fa-brain text-sm"></i>
|
||
</div>
|
||
<div>
|
||
<h3 class="font-bold text-slate-100 text-sm">Ollama LLM Engine</h3>
|
||
<p class="text-xs text-slate-400">Port :11434 // FlashAttention + Q4 KV Cache</p>
|
||
</div>
|
||
</div>
|
||
<button onclick="freeOllamaVRAM()" class="px-2.5 py-1 text-xs font-semibold rounded-lg bg-rose-950/70 border border-rose-800 text-rose-300 hover:bg-rose-900 transition flex items-center space-x-1">
|
||
<i class="fa-solid fa-arrow-down-to-bracket"></i>
|
||
<span>Soft-Yield VRAM</span>
|
||
</button>
|
||
</div>
|
||
|
||
<!-- Active Model Box -->
|
||
<div class="mt-4 p-4 rounded-xl bg-slate-950 border border-slate-800/80 space-y-3">
|
||
<div class="flex justify-between items-center">
|
||
<span class="text-xs text-slate-400 uppercase font-mono">Active Model in VRAM</span>
|
||
<span id="ollama-vram-badge" class="px-2 py-0.5 text-[10px] font-mono rounded bg-purple-900/60 text-purple-300 border border-purple-700">
|
||
0.0 GB VRAM
|
||
</span>
|
||
</div>
|
||
<div class="flex items-center justify-between">
|
||
<div class="flex items-center space-x-2 overflow-hidden">
|
||
<i class="fa-solid fa-cube text-purple-400"></i>
|
||
<span id="ollama-active-model" class="text-base font-bold font-mono text-slate-100 truncate">None Loaded</span>
|
||
</div>
|
||
<span id="ollama-context" class="text-xs font-mono text-slate-400">0 ctx</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Quick Hot-Swap Control -->
|
||
<div class="mt-4 space-y-2">
|
||
<label class="text-xs font-semibold text-slate-300 flex items-center justify-between">
|
||
<span>Instant Model Hot-Swap:</span>
|
||
<span class="text-[10px] text-cyan-400 font-mono">RAM Cache Optimized</span>
|
||
</label>
|
||
<div class="flex space-x-2">
|
||
<select id="ollama-model-select" class="flex-1 bg-slate-950 border border-slate-700 rounded-lg px-3 py-2 text-xs font-mono text-slate-200 focus:outline-none focus:border-purple-500">
|
||
<option value="">Loading installed models...</option>
|
||
</select>
|
||
<button id="btn-switch-model" onclick="triggerModelSwitch()" class="px-4 py-2 bg-gradient-to-r from-purple-600 to-indigo-600 hover:from-purple-500 hover:to-indigo-500 text-white text-xs font-bold rounded-lg shadow-md transition flex items-center space-x-1.5">
|
||
<i class="fa-solid fa-shuffle"></i>
|
||
<span>Hot Swap</span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Ollama Stats Footer -->
|
||
<div class="pt-3 border-t border-slate-800 grid grid-cols-3 gap-2 text-center font-mono text-xs">
|
||
<div class="p-2 rounded bg-slate-950 border border-slate-800">
|
||
<span class="text-[10px] text-slate-500 block">LAST SWAP TIME</span>
|
||
<span id="ollama-last-swap" class="text-cyan-400 font-bold">-- ms</span>
|
||
</div>
|
||
<div class="p-2 rounded bg-slate-950 border border-slate-800">
|
||
<span class="text-[10px] text-slate-500 block">RAM HIT STATUS</span>
|
||
<span id="ollama-cache-hit" class="text-emerald-400 font-bold">--</span>
|
||
</div>
|
||
<div class="p-2 rounded bg-slate-950 border border-slate-800">
|
||
<span class="text-[10px] text-slate-500 block">TOTAL MODELS</span>
|
||
<span id="ollama-total-models" class="text-slate-300 font-bold">0</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- CARD 2: COMFYUI DIFFUSION PIPELINE -->
|
||
<div class="bg-slate-900/80 border border-slate-800 rounded-2xl p-5 flex flex-col justify-between space-y-4">
|
||
<div>
|
||
<div class="flex items-center justify-between pb-3 border-b border-slate-800">
|
||
<div class="flex items-center space-x-2">
|
||
<div class="p-2 rounded-lg bg-cyan-950/80 border border-cyan-800 text-cyan-400">
|
||
<i class="fa-solid fa-palette text-sm"></i>
|
||
</div>
|
||
<div>
|
||
<h3 class="font-bold text-slate-100 text-sm">ComfyUI Diffusion Engine</h3>
|
||
<p class="text-xs text-slate-400">Port :8188 // DynamicVRAM + Pinned Async Offload</p>
|
||
</div>
|
||
</div>
|
||
<button onclick="freeComfyVRAM()" class="px-2.5 py-1 text-xs font-semibold rounded-lg bg-rose-950/70 border border-rose-800 text-rose-300 hover:bg-rose-900 transition flex items-center space-x-1">
|
||
<i class="fa-solid fa-broom"></i>
|
||
<span>Purge VRAM</span>
|
||
</button>
|
||
</div>
|
||
|
||
<!-- Comfy Execution Box -->
|
||
<div class="mt-4 p-4 rounded-xl bg-slate-950 border border-slate-800/80 space-y-3">
|
||
<div class="flex justify-between items-center">
|
||
<span class="text-xs text-slate-400 uppercase font-mono">Pipeline Status</span>
|
||
<span id="comfy-exec-badge" class="px-2 py-0.5 text-[10px] font-mono rounded bg-emerald-950 text-emerald-300 border border-emerald-800">
|
||
IDLE / READY
|
||
</span>
|
||
</div>
|
||
<div class="flex items-center justify-between">
|
||
<div class="flex items-center space-x-2">
|
||
<i class="fa-solid fa-layer-group text-cyan-400"></i>
|
||
<span id="comfy-model-info" class="text-sm font-mono text-slate-200">Dynamic Model Offloader</span>
|
||
</div>
|
||
<div class="text-xs font-mono text-slate-400">
|
||
Queue: <span id="comfy-queue-count" class="text-cyan-400 font-bold">0</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Comfy Feature Checklist -->
|
||
<div class="mt-4 space-y-2 text-xs">
|
||
<div class="p-2.5 rounded-lg bg-slate-950 border border-slate-800 space-y-1.5">
|
||
<div class="flex items-center justify-between text-slate-300">
|
||
<span class="flex items-center space-x-1.5">
|
||
<i class="fa-solid fa-check text-emerald-400 text-xs"></i>
|
||
<span>Host Pinned Memory:</span>
|
||
</span>
|
||
<span class="font-mono font-bold text-emerald-400">53.6 GB Staging Buffer</span>
|
||
</div>
|
||
<div class="flex items-center justify-between text-slate-300">
|
||
<span class="flex items-center space-x-1.5">
|
||
<i class="fa-solid fa-check text-emerald-400 text-xs"></i>
|
||
<span>Async PCIe Offloading:</span>
|
||
</span>
|
||
<span class="font-mono font-bold text-cyan-400">Enabled (2 Streams)</span>
|
||
</div>
|
||
<div class="flex items-center justify-between text-slate-300">
|
||
<span class="flex items-center space-x-1.5">
|
||
<i class="fa-solid fa-check text-emerald-400 text-xs"></i>
|
||
<span>Fast Disk RAM Mmap:</span>
|
||
</span>
|
||
<span class="font-mono font-bold text-amber-400">Active</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Comfy Stats Footer -->
|
||
<div class="pt-3 border-t border-slate-800 grid grid-cols-2 gap-2 text-center font-mono text-xs">
|
||
<div class="p-2 rounded bg-slate-950 border border-slate-800">
|
||
<span class="text-[10px] text-slate-500 block">DISCOVERED MODELS</span>
|
||
<span id="comfy-discovered-count" class="text-cyan-400 font-bold">0 Files</span>
|
||
</div>
|
||
<div class="p-2 rounded bg-slate-950 border border-slate-800">
|
||
<span class="text-[10px] text-slate-500 block">VRAM AVAILABLE</span>
|
||
<span id="comfy-vram-avail" class="text-emerald-400 font-bold">15.9 GB</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- CARD 3: GPU HARDWARE TELEMETRY -->
|
||
<div class="bg-slate-900/80 border border-slate-800 rounded-2xl p-5 space-y-4">
|
||
<div class="flex items-center justify-between pb-3 border-b border-slate-800">
|
||
<div class="flex items-center space-x-2">
|
||
<div class="p-2 rounded-lg bg-emerald-950/80 border border-emerald-800 text-emerald-400">
|
||
<i class="fa-solid fa-gauge-high text-sm"></i>
|
||
</div>
|
||
<div>
|
||
<h3 class="font-bold text-slate-100 text-sm">GPU Live Telemetry (NVML)</h3>
|
||
<p class="text-xs text-slate-400" id="gpu-chip-name">NVIDIA GeForce RTX 4080 SUPER</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Quick Gauges Grid -->
|
||
<div class="grid grid-cols-2 sm:grid-cols-4 gap-3 font-mono">
|
||
<div class="p-3 rounded-xl bg-slate-950 border border-slate-800 text-center">
|
||
<span class="text-[10px] text-slate-400 uppercase block">GPU Util</span>
|
||
<span id="gpu-util-val" class="text-xl font-bold text-cyan-400">0%</span>
|
||
</div>
|
||
<div class="p-3 rounded-xl bg-slate-950 border border-slate-800 text-center">
|
||
<span class="text-[10px] text-slate-400 uppercase block">Temperature</span>
|
||
<span id="gpu-temp-val" class="text-xl font-bold text-emerald-400">0°C</span>
|
||
</div>
|
||
<div class="p-3 rounded-xl bg-slate-950 border border-slate-800 text-center">
|
||
<span class="text-[10px] text-slate-400 uppercase block">Power Draw</span>
|
||
<span id="gpu-power-val" class="text-xl font-bold text-amber-400">0 W</span>
|
||
</div>
|
||
<div class="p-3 rounded-xl bg-slate-950 border border-slate-800 text-center relative overflow-hidden">
|
||
<span class="text-[10px] text-slate-400 uppercase block">Fan Speed</span>
|
||
<div class="flex items-center justify-center space-x-1.5">
|
||
<i id="gpu-fan-icon" class="fa-solid fa-fan text-emerald-400 text-sm"></i>
|
||
<span id="gpu-fan-val" class="text-xl font-bold text-emerald-400">0%</span>
|
||
</div>
|
||
<span id="gpu-fan-sub" class="text-[9px] font-mono text-slate-500 block truncate">Fan 0: --% | Fan 1: --%</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Process Table -->
|
||
<div class="space-y-2">
|
||
<span class="text-xs font-semibold text-slate-400 uppercase font-mono">Active Compute Processes</span>
|
||
<div class="rounded-xl bg-slate-950 border border-slate-800 p-2 max-h-36 overflow-y-auto font-mono text-xs">
|
||
<table class="w-full text-left">
|
||
<thead>
|
||
<tr class="text-slate-500 border-b border-slate-800/80 text-[10px]">
|
||
<th class="pb-1">PID</th>
|
||
<th class="pb-1">Process</th>
|
||
<th class="pb-1 text-right">VRAM</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="gpu-proc-table" class="divide-y divide-slate-900">
|
||
<tr><td colspan="3" class="py-2 text-center text-slate-500">Scanning GPU processes...</td></tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- CARD 4: REAL-TIME SWITCH TIMELINE & OPTIMIZER -->
|
||
<div class="bg-slate-900/80 border border-slate-800 rounded-2xl p-5 flex flex-col justify-between space-y-4">
|
||
<div>
|
||
<div class="flex items-center justify-between pb-3 border-b border-slate-800">
|
||
<div class="flex items-center space-x-2">
|
||
<div class="p-2 rounded-lg bg-indigo-950/80 border border-indigo-800 text-indigo-400">
|
||
<i class="fa-solid fa-clock-rotate-left text-sm"></i>
|
||
</div>
|
||
<div>
|
||
<h3 class="font-bold text-slate-100 text-sm">Model Switch Timeline & Optimizer</h3>
|
||
<p class="text-xs text-slate-400">Real-time latency logger and memory warmer</p>
|
||
</div>
|
||
</div>
|
||
<button onclick="warmAllModels()" class="px-2.5 py-1 text-xs font-semibold rounded-lg bg-amber-950/70 border border-amber-800 text-amber-300 hover:bg-amber-900 transition flex items-center space-x-1">
|
||
<i class="fa-solid fa-fire text-amber-400"></i>
|
||
<span>Warm All to RAM</span>
|
||
</button>
|
||
</div>
|
||
|
||
<!-- Switch Events Log -->
|
||
<div class="mt-4 space-y-2">
|
||
<span class="text-xs font-semibold text-slate-400 uppercase font-mono">Recent Model Swaps</span>
|
||
<div id="switch-log-container" class="space-y-2 max-h-48 overflow-y-auto pr-1">
|
||
<div class="p-3 rounded-xl bg-slate-950 border border-slate-800 text-xs text-slate-400 text-center font-mono">
|
||
No recent model swaps recorded yet.
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Optimizer Banner -->
|
||
<div class="p-3 rounded-xl bg-gradient-to-r from-cyan-950/50 via-slate-950 to-purple-950/50 border border-slate-800 text-xs flex items-center justify-between">
|
||
<div class="flex items-center space-x-2">
|
||
<i class="fa-solid fa-wand-magic-sparkles text-cyan-400"></i>
|
||
<span class="text-slate-300">64GB RAM Cache holds all models in memory</span>
|
||
</div>
|
||
<span class="font-mono text-cyan-400 font-bold">PCIe x16 (~31.5 GB/s)</span>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<!-- OVERCLOCK CONTROL PANEL -->
|
||
<div class="bg-slate-900/80 border border-fuchsia-900/50 rounded-2xl p-5 space-y-4 shadow-lg shadow-fuchsia-950/30">
|
||
<div class="flex flex-wrap items-center justify-between gap-3 pb-3 border-b border-slate-800">
|
||
<div class="flex items-center space-x-2">
|
||
<div class="p-2 rounded-lg bg-fuchsia-950/80 border border-fuchsia-800 text-fuchsia-400">
|
||
<i class="fa-solid fa-rocket text-sm"></i>
|
||
</div>
|
||
<div>
|
||
<h3 class="font-bold text-slate-100 text-sm">GPU Overclock Control</h3>
|
||
<p class="text-xs text-slate-400">Per-app profiles auto-switch with the VRAM arbitrator</p>
|
||
</div>
|
||
</div>
|
||
<div class="flex items-center space-x-2">
|
||
<span id="oc-active-badge" class="px-2.5 py-1 text-xs font-mono rounded-lg bg-slate-800 border border-slate-700 text-slate-300">Active: --</span>
|
||
<span id="oc-x-badge" class="px-2.5 py-1 text-xs font-mono rounded-lg bg-slate-800 border border-slate-700 text-slate-400">X: --</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Profile quick-select -->
|
||
<div class="grid grid-cols-3 gap-3">
|
||
<button id="oc-btn-ollama" onclick="applyOverclock('ollama')" class="py-2.5 rounded-xl border text-xs font-bold transition flex items-center justify-center space-x-2 bg-purple-950/60 border-purple-800 text-purple-300 hover:bg-purple-900/60">
|
||
<i class="fa-solid fa-brain"></i><span>Ollama</span>
|
||
</button>
|
||
<button id="oc-btn-comfy" onclick="applyOverclock('comfy')" class="py-2.5 rounded-xl border text-xs font-bold transition flex items-center justify-center space-x-2 bg-cyan-950/60 border-cyan-800 text-cyan-300 hover:bg-cyan-900/60">
|
||
<i class="fa-solid fa-palette"></i><span>ComfyUI</span>
|
||
</button>
|
||
<button id="oc-btn-balanced" onclick="applyOverclock('balanced')" class="py-2.5 rounded-xl border text-xs font-bold transition flex items-center justify-center space-x-2 bg-slate-800/60 border-slate-700 text-slate-300 hover:bg-slate-700/60">
|
||
<i class="fa-solid fa-scale-balanced"></i><span>Balanced</span>
|
||
</button>
|
||
</div>
|
||
|
||
<!-- Live status readback -->
|
||
<div class="grid grid-cols-2 sm:grid-cols-4 gap-3 font-mono text-center">
|
||
<div class="p-3 rounded-xl bg-slate-950 border border-slate-800">
|
||
<span class="text-[10px] text-slate-400 uppercase block">Power Limit</span>
|
||
<span id="oc-power-limit" class="text-lg font-bold text-amber-400">-- W</span>
|
||
</div>
|
||
<div class="p-3 rounded-xl bg-slate-950 border border-slate-800">
|
||
<span class="text-[10px] text-slate-400 uppercase block">Core Clock</span>
|
||
<span id="oc-core" class="text-lg font-bold text-cyan-400">--</span>
|
||
</div>
|
||
<div class="p-3 rounded-xl bg-slate-950 border border-slate-800">
|
||
<span class="text-[10px] text-slate-400 uppercase block">Mem Clock</span>
|
||
<span id="oc-mem" class="text-lg font-bold text-purple-400">--</span>
|
||
</div>
|
||
<div class="p-3 rounded-xl bg-slate-950 border border-slate-800">
|
||
<span class="text-[10px] text-slate-400 uppercase block">Temp / Draw</span>
|
||
<span id="oc-temp-draw" class="text-lg font-bold text-emerald-400">--</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- GPU FAN COOLING CONTROL -->
|
||
<div class="p-4 rounded-xl bg-slate-950 border border-slate-800 space-y-4">
|
||
<div class="flex flex-wrap items-center justify-between gap-2">
|
||
<div class="flex items-center space-x-2">
|
||
<i id="oc-fan-card-icon" class="fa-solid fa-fan text-emerald-400 text-sm fan-spinning"></i>
|
||
<div>
|
||
<span class="text-xs font-semibold text-slate-200 uppercase font-mono block">GPU Fan Cooling Control</span>
|
||
<span class="text-[10px] text-slate-400 font-mono">Dual-fan PWM active speed regulation</span>
|
||
</div>
|
||
</div>
|
||
<span id="oc-fan-badge" class="px-2.5 py-1 text-xs font-mono rounded-lg bg-emerald-950/80 border border-emerald-700 text-emerald-300 font-bold">
|
||
AUTO (VBIOS)
|
||
</span>
|
||
</div>
|
||
|
||
<!-- Fan Presets -->
|
||
<div class="grid grid-cols-2 sm:grid-cols-5 gap-2">
|
||
<button onclick="setFanAuto()" class="py-1.5 px-2 rounded-lg bg-slate-900 hover:bg-slate-800 border border-slate-700 text-slate-300 text-xs font-mono font-semibold transition text-center flex items-center justify-center space-x-1">
|
||
<i class="fa-solid fa-wand-magic-sparkles text-cyan-400 text-[10px]"></i>
|
||
<span>Auto (VBIOS)</span>
|
||
</button>
|
||
<button onclick="setFanManual(50)" class="py-1.5 px-2 rounded-lg bg-slate-900 hover:bg-slate-800 border border-slate-700 text-slate-300 text-xs font-mono font-semibold transition text-center">
|
||
50% Quiet
|
||
</button>
|
||
<button onclick="setFanManual(65)" class="py-1.5 px-2 rounded-lg bg-slate-900 hover:bg-slate-800 border border-slate-700 text-slate-300 text-xs font-mono font-semibold transition text-center">
|
||
65% Balanced
|
||
</button>
|
||
<button onclick="setFanManual(80)" class="py-1.5 px-2 rounded-lg bg-slate-900 hover:bg-slate-800 border border-slate-700 text-slate-300 text-xs font-mono font-semibold transition text-center">
|
||
80% Heavy
|
||
</button>
|
||
<button onclick="setFanManual(100)" class="py-1.5 px-2 rounded-lg bg-rose-950/60 hover:bg-rose-900/80 border border-rose-800 text-rose-300 text-xs font-mono font-bold transition text-center flex items-center justify-center space-x-1">
|
||
<i class="fa-solid fa-gauge-max text-rose-400 text-[10px]"></i>
|
||
<span>100% Turbo</span>
|
||
</button>
|
||
</div>
|
||
|
||
<!-- Live Dual-Fan Meters -->
|
||
<div class="grid grid-cols-1 sm:grid-cols-2 gap-3 p-3 rounded-lg bg-slate-900/60 border border-slate-800/80 text-xs font-mono">
|
||
<div class="space-y-1">
|
||
<div class="flex justify-between text-slate-400">
|
||
<span class="flex items-center space-x-1"><i class="fa-solid fa-fan text-[10px] text-cyan-400"></i><span>Fan 0 (Intake/Core):</span></span>
|
||
<span id="oc-fan0-val" class="font-bold text-slate-100">--%</span>
|
||
</div>
|
||
<div class="w-full bg-slate-950 rounded-full h-2 overflow-hidden border border-slate-800">
|
||
<div id="oc-fan0-bar" class="bg-gradient-to-r from-cyan-500 to-emerald-400 h-full rounded-full transition-all duration-300" style="width: 0%"></div>
|
||
</div>
|
||
</div>
|
||
<div class="space-y-1">
|
||
<div class="flex justify-between text-slate-400">
|
||
<span class="flex items-center space-x-1"><i class="fa-solid fa-fan text-[10px] text-purple-400"></i><span>Fan 1 (Exhaust/VRM):</span></span>
|
||
<span id="oc-fan1-val" class="font-bold text-slate-100">--%</span>
|
||
</div>
|
||
<div class="w-full bg-slate-950 rounded-full h-2 overflow-hidden border border-slate-800">
|
||
<div id="oc-fan1-bar" class="bg-gradient-to-r from-purple-500 to-emerald-400 h-full rounded-full transition-all duration-300" style="width: 0%"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Custom Manual Slider -->
|
||
<div class="space-y-2">
|
||
<div class="flex justify-between items-center text-xs">
|
||
<span class="text-slate-400">Custom Manual Target:</span>
|
||
<span id="oc-fan-slider-label" class="font-mono text-emerald-400 font-bold">65%</span>
|
||
</div>
|
||
<div class="flex items-center space-x-3">
|
||
<input id="oc-fan-slider" type="range" min="30" max="100" step="1" value="65" oninput="document.getElementById('oc-fan-slider-label').textContent=this.value+'%'" class="flex-1 accent-emerald-500">
|
||
<button onclick="setFanManual(parseInt(document.getElementById('oc-fan-slider').value))" class="px-3.5 py-1.5 rounded-lg bg-gradient-to-r from-emerald-600 to-teal-600 hover:from-emerald-500 hover:to-teal-500 text-white text-xs font-bold font-mono shadow transition flex items-center space-x-1">
|
||
<i class="fa-solid fa-check"></i>
|
||
<span>Apply</span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- GPU SPECS STRIP -->
|
||
<div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-2 font-mono text-center">
|
||
<div class="p-2 rounded-lg bg-slate-950 border border-slate-800">
|
||
<span class="text-[9px] text-slate-500 uppercase block">GPU</span>
|
||
<span id="oc-spec-gpu" class="text-[11px] font-bold text-slate-200 block truncate">--</span>
|
||
</div>
|
||
<div class="p-2 rounded-lg bg-slate-950 border border-slate-800">
|
||
<span class="text-[9px] text-slate-500 uppercase block">Driver</span>
|
||
<span id="oc-spec-driver" class="text-[11px] font-bold text-cyan-400 block">--</span>
|
||
</div>
|
||
<div class="p-2 rounded-lg bg-slate-950 border border-slate-800">
|
||
<span class="text-[9px] text-slate-500 uppercase block">VRAM</span>
|
||
<span id="oc-spec-vram" class="text-[11px] font-bold text-purple-400 block">--</span>
|
||
</div>
|
||
<div class="p-2 rounded-lg bg-slate-950 border border-slate-800">
|
||
<span class="text-[9px] text-slate-500 uppercase block">Max Core</span>
|
||
<span id="oc-spec-maxcore" class="text-[11px] font-bold text-cyan-400 block">--</span>
|
||
</div>
|
||
<div class="p-2 rounded-lg bg-slate-950 border border-slate-800">
|
||
<span class="text-[9px] text-slate-500 uppercase block">Max Mem</span>
|
||
<span id="oc-spec-maxmem" class="text-[11px] font-bold text-purple-400 block">--</span>
|
||
</div>
|
||
<div class="p-2 rounded-lg bg-slate-950 border border-slate-800">
|
||
<span class="text-[9px] text-slate-500 uppercase block">Power</span>
|
||
<span id="oc-spec-power" class="text-[11px] font-bold text-amber-400 block">--</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- LIVE TIME-SERIES GRAPH (clocks + temp + fan) -->
|
||
<div class="rounded-xl bg-slate-950 border border-slate-800 p-3">
|
||
<div class="flex items-center justify-between mb-2">
|
||
<span class="text-xs font-semibold text-slate-300 uppercase font-mono">
|
||
<i class="fa-solid fa-chart-line text-fuchsia-400 mr-1"></i>Live Tuning Graph
|
||
</span>
|
||
<div class="flex flex-wrap items-center space-x-3 text-[10px] font-mono">
|
||
<span class="flex items-center space-x-1"><span class="w-2 h-2 rounded-full bg-cyan-400 inline-block"></span>Core MHz</span>
|
||
<span class="flex items-center space-x-1"><span class="w-2 h-2 rounded-full bg-purple-400 inline-block"></span>Mem MHz</span>
|
||
<span class="flex items-center space-x-1"><span class="w-2 h-2 rounded-full bg-rose-400 inline-block"></span>Temp °C</span>
|
||
<span class="flex items-center space-x-1"><span class="w-2 h-2 rounded-full bg-amber-400 inline-block"></span>Power W</span>
|
||
<span class="flex items-center space-x-1"><span class="w-2 h-2 rounded-full bg-emerald-400 inline-block"></span>Fan %</span>
|
||
</div>
|
||
</div>
|
||
<div class="relative h-64">
|
||
<canvas id="oc-chart"></canvas>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Fine-tune sliders for the selected profile -->
|
||
<div class="p-4 rounded-xl bg-slate-950 border border-slate-800 space-y-4">
|
||
<div class="flex items-center justify-between">
|
||
<span class="text-xs font-semibold text-slate-300 uppercase font-mono">Fine-tune profile</span>
|
||
<select id="oc-edit-profile" onchange="loadOverclockForProfile(this.value)" class="bg-slate-900 border border-slate-700 rounded-lg px-2 py-1 text-xs font-mono text-slate-200 focus:outline-none focus:border-fuchsia-500">
|
||
<option value="ollama">ollama</option>
|
||
<option value="comfy">comfy</option>
|
||
<option value="balanced">balanced</option>
|
||
</select>
|
||
</div>
|
||
|
||
<div class="grid grid-cols-1 md:grid-cols-3 gap-5">
|
||
<div>
|
||
<label class="text-xs text-slate-400 flex justify-between"><span>Power Limit</span><span id="oc-val-power" class="font-mono text-amber-400">370 W</span></label>
|
||
<input id="oc-slider-power" type="range" min="150" max="370" step="5" value="370" oninput="document.getElementById('oc-val-power').textContent=this.value+' W'" class="w-full accent-amber-500">
|
||
</div>
|
||
<div>
|
||
<label class="text-xs text-slate-400 flex justify-between"><span>Core Offset</span><span id="oc-val-core" class="font-mono text-cyan-400">+100 MHz</span></label>
|
||
<input id="oc-slider-core" type="range" min="0" max="200" step="5" value="100" oninput="document.getElementById('oc-val-core').textContent='+'+this.value+' MHz'" class="w-full accent-cyan-500">
|
||
</div>
|
||
<div>
|
||
<label class="text-xs text-slate-400 flex justify-between"><span>Memory Offset</span><span id="oc-val-mem" class="font-mono text-purple-400">+500 MHz</span></label>
|
||
<input id="oc-slider-mem" type="range" min="0" max="1000" step="25" value="500" oninput="document.getElementById('oc-val-mem').textContent='+'+this.value+' MHz'" class="w-full accent-purple-500">
|
||
</div>
|
||
</div>
|
||
|
||
<div class="grid grid-cols-1 md:grid-cols-2 gap-5">
|
||
<div>
|
||
<label class="text-xs text-slate-400 flex justify-between"><span>Core Clock Lock</span><span id="oc-val-lockcore" class="font-mono text-slate-400">Off</span></label>
|
||
<div class="flex items-center space-x-2">
|
||
<input id="oc-lockcore-toggle" type="checkbox" onchange="toggleCoreLock()" class="w-4 h-4 accent-cyan-500">
|
||
<span class="text-xs text-slate-500">Lock core to max boost (2900–3105 MHz)</span>
|
||
</div>
|
||
</div>
|
||
<div>
|
||
<label class="text-xs text-slate-400 flex justify-between"><span>Memory Clock Lock</span><span id="oc-val-lockmem" class="font-mono text-slate-400">Off</span></label>
|
||
<div class="flex items-center space-x-2">
|
||
<input id="oc-lockmem-toggle" type="checkbox" onchange="toggleMemLock()" class="w-4 h-4 accent-purple-500">
|
||
<span class="text-xs text-slate-500">Lock mem to max (11501 MHz)</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Per-Profile Fan Settings -->
|
||
<div class="grid grid-cols-1 md:grid-cols-2 gap-5 pt-3 border-t border-slate-900">
|
||
<div>
|
||
<label class="text-xs text-slate-400 flex justify-between"><span>Profile Fan Mode</span><span id="oc-val-prof-fanmode" class="font-mono text-emerald-400">Auto</span></label>
|
||
<select id="oc-prof-fanmode" onchange="toggleProfileFanMode()" class="w-full bg-slate-900 border border-slate-700 rounded-lg px-3 py-2 text-xs font-mono text-slate-200 mt-1 focus:outline-none focus:border-emerald-500">
|
||
<option value="auto">Auto (VBIOS Dynamic Curve)</option>
|
||
<option value="manual">Manual (Locked Target %)</option>
|
||
</select>
|
||
</div>
|
||
<div id="oc-prof-fanspeed-container" class="opacity-50 pointer-events-none transition">
|
||
<label class="text-xs text-slate-400 flex justify-between"><span>Profile Fan Target</span><span id="oc-val-prof-fanspeed" class="font-mono text-emerald-400">70%</span></label>
|
||
<input id="oc-slider-prof-fanspeed" type="range" min="30" max="100" step="5" value="70" oninput="document.getElementById('oc-val-prof-fanspeed').textContent=this.value+'%'" class="w-full accent-emerald-500 mt-2">
|
||
</div>
|
||
</div>
|
||
|
||
<div class="flex items-center justify-between pt-2">
|
||
<span id="oc-offset-note" class="text-[11px] font-mono text-slate-500"></span>
|
||
<button onclick="saveOverclockProfile()" class="px-4 py-2 bg-gradient-to-r from-fuchsia-600 to-purple-600 hover:from-fuchsia-500 hover:to-purple-500 text-white text-xs font-bold rounded-lg shadow-md transition flex items-center space-x-1.5">
|
||
<i class="fa-solid fa-floppy-disk"></i><span>Save Profile</span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
</main>
|
||
|
||
<script src="/static/app.js"></script>
|
||
</body>
|
||
</html>
|