Profiling page: per-turn phase timings, live in the web dashboard
The engine already tracks where each turn's wall time goes (expert-disk service, I/O wait, expert matmul, attention, lm_head) — it just only spoke at exit or under PROF=1. Stream it instead: - glm.c: mux serve emits a per-turn "PROF" protocol line next to TIERS/HITS (window deltas per request, same convention as the STAT hit%); the phase window base is now always captured (a few loads per request). - openai_server.py: parses PROF into a 120-turn rolling window and serves it at /profile (read-only, same trust level as /health). - web: new Profiling tab — stat tiles (tok/s, wall, tokens/forward, disk service), wall-time composition bars for the last turn and the window, per-turn throughput and stacked phase columns with hover readouts, and a table of recent turns. Disk service is shown apart from the stack: it overlaps with compute, so only the I/O wait the compute thread felt counts inside wall time. Phase colours are a CVD-validated set with gaps + legend + table so identity never rides on colour alone. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WhTmF8yvEBgSkUKSVfZF7P
This commit is contained in:
committed by
Nicholas Beerbower
parent
63a6824881
commit
6afffbcbf2
+5
-2
@@ -31,6 +31,7 @@ import { Textarea } from "@/components/ui/textarea"
|
||||
import { getHealth, listModels, streamChat, type ChatMessage, type HealthResponse, type StreamChatResult } from "@/lib/api"
|
||||
import { activeRequests, supportsCacheSlots } from "@/lib/runtime"
|
||||
import { Brain } from "./Brain"
|
||||
import { Profiling } from "./Profiling"
|
||||
import { persistPublicSettings, stored } from "@/lib/storage"
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
@@ -73,7 +74,7 @@ export default function App() {
|
||||
const [totalTokens, setTotalTokens] = useState({ prompt: 0, completion: 0 })
|
||||
const [connecting, setConnecting] = useState(false)
|
||||
const [connected, setConnected] = useState(false)
|
||||
const [view, setView] = useState<"chat" | "brain">("chat")
|
||||
const [view, setView] = useState<"chat" | "brain" | "profiling">("chat")
|
||||
const [error, setError] = useState("")
|
||||
const autoConnected = useRef(false)
|
||||
const abortRef = useRef<AbortController | null>(null)
|
||||
@@ -314,6 +315,7 @@ export default function App() {
|
||||
<div className="view-tabs">
|
||||
<button className={view === "chat" ? "active" : ""} onClick={() => setView("chat")}><MessageSquareText className="size-3.5" /> Chat</button>
|
||||
<button className={view === "brain" ? "active" : ""} onClick={() => setView("brain")}><BrainCircuit className="size-3.5" /> Brain</button>
|
||||
<button className={view === "profiling" ? "active" : ""} onClick={() => setView("profiling")}><Gauge className="size-3.5" /> Profiling</button>
|
||||
</div>
|
||||
<div className="top-actions">
|
||||
{loading && tokenCount > 0 ? <Badge className="badge-live"><Zap className="size-3 flash" /> {tokenCount} tokens</Badge> : null}
|
||||
@@ -326,7 +328,8 @@ export default function App() {
|
||||
</div>
|
||||
</header>
|
||||
|
||||
{view === "brain" ? <Brain baseUrl={baseUrl} apiKey={apiKey} connected={connected} /> : <>
|
||||
{view === "brain" ? <Brain baseUrl={baseUrl} apiKey={apiKey} connected={connected} />
|
||||
: view === "profiling" ? <Profiling baseUrl={baseUrl} apiKey={apiKey} connected={connected} /> : <>
|
||||
|
||||
<div className="conversation">
|
||||
{!messages.length ? (
|
||||
|
||||
Reference in New Issue
Block a user