Bonsai-Chat-WebGPU / src /bench /BenchApp.tsx
Valeriy Selitskiy
Release v1.2.2 interactive chat workspace
21ad36a
Raw
History Blame Contribute Delete
33.4 kB
import { useEffect, useMemo, useRef, useState } from 'react';
import {
BrowserEngineClient,
EngineClientError,
evaluateModelContextPolicy,
evaluateModelGate,
loadModelManifestV2,
type BenchmarkFlashMode,
type BenchmarkKvCacheType,
type BenchmarkWasmFlavor,
type EngineCapabilities,
type GenerateParams,
type ModelManifestV2,
type ModelTierId,
type RequestedBackend,
} from '../engine';
import { formatBytes } from '../lib/format';
import {
BENCHMARK_WORKLOADS,
DEFAULT_BENCHMARK_WORKLOAD_ID,
benchmarkReportFilename,
buildBenchmarkReport,
serializeBenchmarkReport,
type BenchmarkReport,
type BenchmarkWorkloadId,
type TeacherForcedReferenceScoreEvidence,
} from './report';
import {
STATE_DRIFT_REFERENCE_PATH,
validateStateDriftReferenceFixture,
} from './state-drift-reference';
const MANIFEST_PATH = 'manifest/models.json';
const DEFAULT_MODEL: ModelTierId = '1_7b';
const MAX_GLUE_INT = 2_147_483_647;
interface RunProgress {
label: string;
loadedBytes: number;
totalBytes: number;
}
let sharedBenchClient: BrowserEngineClient | null = null;
function getBenchClient(): BrowserEngineClient {
sharedBenchClient ??= new BrowserEngineClient();
return sharedBenchClient;
}
function manifestUrl(): string {
return new URL(`${import.meta.env.BASE_URL}${MANIFEST_PATH}`, document.baseURI).href;
}
function stateDriftReferenceUrl(): string {
return new URL(
`${import.meta.env.BASE_URL}${STATE_DRIFT_REFERENCE_PATH}`,
document.baseURI,
).href;
}
function errorMessage(error: unknown): string {
if (error instanceof EngineClientError) return `${error.code}: ${error.message}`;
return error instanceof Error ? error.message : String(error);
}
function isAbort(error: unknown, signal: AbortSignal): boolean {
return signal.aborted
|| (error instanceof DOMException && error.name === 'AbortError')
|| (error instanceof EngineClientError && ['ABORTED', 'SHARD_DOWNLOAD_ABORTED'].includes(error.code));
}
function throwIfAborted(signal: AbortSignal): void {
if (signal.aborted) throw new DOMException('Benchmark stopped by operator.', 'AbortError');
}
function parseOptionalInteger(value: string): number | null {
if (value.trim() === '') return null;
const parsed = Number(value);
return Number.isSafeInteger(parsed) && parsed > 0 && parsed <= MAX_GLUE_INT ? parsed : null;
}
function formatDuration(value: number | null | undefined): string {
if (value === null || value === undefined) return '—';
return value >= 1_000 ? `${(value / 1_000).toFixed(2)} s` : `${value.toFixed(1)} ms`;
}
function formatRate(value: number | null | undefined): string {
return value === null || value === undefined ? '—' : `${value.toFixed(2)} t/s`;
}
function downloadReport(report: BenchmarkReport): void {
const blob = new Blob([serializeBenchmarkReport(report)], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const anchor = document.createElement('a');
anchor.href = url;
anchor.download = benchmarkReportFilename(report);
document.body.append(anchor);
anchor.click();
anchor.remove();
window.setTimeout(() => URL.revokeObjectURL(url), 0);
}
export function BenchApp() {
const [client] = useState(getBenchClient);
const [manifest, setManifest] = useState<ModelManifestV2 | null>(null);
const [capabilities, setCapabilities] = useState<EngineCapabilities | null>(null);
const [workloadId, setWorkloadId] = useState<BenchmarkWorkloadId>(DEFAULT_BENCHMARK_WORKLOAD_ID);
const [modelId, setModelId] = useState<ModelTierId>(DEFAULT_MODEL);
const [backend, setBackend] = useState<RequestedBackend>('auto');
const [contextSize, setContextSize] = useState(4_096);
const [maxTokens, setMaxTokens] = useState(64);
const [nBatchInput, setNBatchInput] = useState('');
const [nUbatchInput, setNUbatchInput] = useState('');
const [flashMode, setFlashMode] = useState<BenchmarkFlashMode>('off');
const [kvCacheType, setKvCacheType] = useState<BenchmarkKvCacheType>('f16');
const [wasmFlavor, setWasmFlavor] = useState<BenchmarkWasmFlavor>('auto');
const [running, setRunning] = useState(false);
const [progress, setProgress] = useState<RunProgress>({
label: 'Waiting for an operator-initiated run',
loadedBytes: 0,
totalBytes: 0,
});
const [report, setReport] = useState<BenchmarkReport | null>(null);
const [output, setOutput] = useState('');
const [bootstrapError, setBootstrapError] = useState<string | null>(null);
const [runError, setRunError] = useState<string | null>(null);
const operationRef = useRef<AbortController | null>(null);
useEffect(() => {
let cancelled = false;
const controller = new AbortController();
setProgress((current) => ({ ...current, label: 'Inspecting manifest and browser runtime' }));
void Promise.all([
loadModelManifestV2(manifestUrl(), controller.signal),
client.capabilities(),
]).then(([loadedManifest, loadedCapabilities]) => {
if (cancelled) return;
const initial = loadedManifest.models.find((model) => model.id === DEFAULT_MODEL)
?? loadedManifest.models[0];
if (!initial) throw new Error('The benchmark manifest contains no model tiers.');
setManifest(loadedManifest);
setCapabilities(loadedCapabilities);
setModelId(initial.id);
setContextSize(initial.defaultContext);
setProgress({
label: 'Ready · no model is loaded until Run benchmark is pressed',
loadedBytes: 0,
totalBytes: 0,
});
}).catch((bootstrapError) => {
if (cancelled || controller.signal.aborted) return;
setBootstrapError(errorMessage(bootstrapError));
setProgress((current) => ({ ...current, label: 'Runtime inspection failed' }));
});
return () => {
cancelled = true;
controller.abort();
};
}, [client]);
const model = useMemo(
() => manifest?.models.find((candidate) => candidate.id === modelId) ?? null,
[manifest, modelId],
);
const workload = BENCHMARK_WORKLOADS[workloadId];
const deviceGate = useMemo(() => {
if (!model || !capabilities) return null;
return evaluateModelGate(model, backend, capabilities.webgpu, {
usageBytes: null,
quotaBytes: null,
persisted: capabilities.storage.persisted,
});
}, [backend, capabilities, model]);
const storageGate = useMemo(() => {
if (!model || !capabilities) return null;
return evaluateModelGate(model, backend, capabilities.webgpu, capabilities.storage);
}, [backend, capabilities, model]);
const contextPolicy = model
? evaluateModelContextPolicy(model, contextSize, {
tuningScope: 'benchmark',
requestedBackend: backend,
flashMode,
kvCacheType,
})
: null;
const contextLimit = contextPolicy?.limit ?? 4_096;
const nBatch = parseOptionalInteger(nBatchInput);
const nUbatch = parseOptionalInteger(nUbatchInput);
const batchTuningError = nBatchInput.trim() !== '' && nBatch === null
? `nBatch must be an integer from 1 to ${MAX_GLUE_INT.toLocaleString()}.`
: nUbatchInput.trim() !== '' && nUbatch === null
? `nUbatch must be an integer from 1 to ${MAX_GLUE_INT.toLocaleString()}.`
: nBatch !== null && nUbatch !== null && nUbatch > nBatch
? 'nUbatch must not exceed nBatch.'
: null;
const runtimeTuningError = flashMode === 'off' && kvCacheType !== 'f16'
? 'Quantized KV requires Flash Attention auto.'
: flashMode === 'auto' && backend !== 'webgpu'
? 'Flash Attention experiments require the explicit WebGPU backend.'
: null;
const wasmTuningError = wasmFlavor === 'jspi' && capabilities?.runtime.wasmFlavor === 'compat'
? 'JSPI is unavailable in this browser; use auto or compat.'
: null;
const workloadError = workload.requiredMaxTokens !== null && maxTokens !== workload.requiredMaxTokens
? `${workload.id} requires exactly ${workload.requiredMaxTokens.toLocaleString()} max tokens.`
: null;
const stateDriftReferenceError = workload.id === 'state-drift-1k-v1' && (
model?.id !== '27b'
|| backend !== 'webgpu'
|| contextSize !== 2_048
|| nBatch !== 32
|| nUbatch !== 16
)
? 'state-drift-1k-v1 reference scoring requires 27B, explicit WebGPU, context 2,048, nBatch 32, and nUbatch 16.'
: null;
const configurationTuningError = batchTuningError
?? runtimeTuningError
?? wasmTuningError
?? workloadError
?? stateDriftReferenceError;
const configurationValid = contextPolicy?.allowed === true
&& Number.isSafeInteger(maxTokens)
&& maxTokens >= 8
&& maxTokens <= 1_024
&& configurationTuningError === null;
const canRun = Boolean(manifest && capabilities && model && deviceGate?.allowed && configurationValid);
const clearPreviousRun = () => {
setReport(null);
setOutput('');
setRunError(null);
if (manifest && capabilities) {
setProgress({
label: 'Ready · settings changed; run again to produce matching evidence',
loadedBytes: 0,
totalBytes: 0,
});
}
};
const handleModelChange = (nextId: ModelTierId) => {
if (running || !manifest) return;
const next = manifest.models.find((candidate) => candidate.id === nextId);
if (!next) return;
setModelId(nextId);
setContextSize(next.defaultContext);
if (!next.cpuFallback && backend === 'wasm') setBackend('auto');
clearPreviousRun();
};
const runBenchmark = () => {
if (!canRun || !manifest || !capabilities || !model || operationRef.current) return;
const controller = new AbortController();
operationRef.current = controller;
setRunning(true);
setReport(null);
setOutput('');
setRunError(null);
const startedAt = new Date().toISOString();
const run = async () => {
let storagePersistent = capabilities.storage.persisted;
setProgress({ label: 'Requesting persistent browser storage', loadedBytes: 0, totalBytes: 0 });
try {
const storage = await client.storagePersist();
storagePersistent = storage.persisted;
setCapabilities((current) => current ? { ...current, storage } : current);
} catch {
// Persistence is a browser policy choice. The runtime storage gate remains authoritative.
}
throwIfAborted(controller.signal);
await client.unload();
throwIfAborted(controller.signal);
let coldCachedBytes: number | null = null;
const loadParams = {
manifest,
modelId: model.id,
backend,
contextSize,
benchmarkTuning: {
...(nBatch === null ? {} : { nBatch }),
...(nUbatch === null ? {} : { nUbatch }),
flashMode,
kvCacheType,
wasmFlavor,
},
};
const coldStarted = performance.now();
const coldLoad = await client.loadModel(loadParams, {
signal: controller.signal,
onProgress: (event) => {
if (event.phase === 'download' && coldCachedBytes === null) {
coldCachedBytes = event.loadedBytes;
}
const shard = event.shardIndex === null ? '' : ` · shard ${event.shardIndex + 1}/${event.shardCount}`;
setProgress({
label: `Cold load · ${event.phase}${shard}`,
loadedBytes: event.loadedBytes,
totalBytes: event.totalBytes,
});
},
});
const coldLoadMs = performance.now() - coldStarted;
throwIfAborted(controller.signal);
setProgress({ label: 'Unloading model before verified-cache reload', loadedBytes: 0, totalBytes: 0 });
await client.unload();
throwIfAborted(controller.signal);
const warmStarted = performance.now();
const warmLoad = await client.loadModel(loadParams, {
signal: controller.signal,
onProgress: (event) => {
const shard = event.shardIndex === null ? '' : ` · shard ${event.shardIndex + 1}/${event.shardCount}`;
setProgress({
label: `Warm load · ${event.phase}${shard}`,
loadedBytes: event.loadedBytes,
totalBytes: event.totalBytes,
});
},
});
const warmLoadMs = performance.now() - warmStarted;
if (coldLoad.backend !== warmLoad.backend) {
throw new Error(`Backend changed between cold and warm loads (${coldLoad.backend}${warmLoad.backend}).`);
}
if (coldLoad.tuning.observed.wasmFlavor !== warmLoad.tuning.observed.wasmFlavor) {
throw new Error(
`WASM flavor changed between cold and warm loads (${coldLoad.tuning.observed.wasmFlavor}${warmLoad.tuning.observed.wasmFlavor}).`,
);
}
throwIfAborted(controller.signal);
let firstTokenAt: number | null = null;
let streamedTokenEvents = 0;
const generationStarted = performance.now();
const generationRequest = {
messages: workload.messages.map((message) => ({ ...message })),
maxTokens,
temperature: 0,
topK: 1,
topP: 1,
seed: 42,
toolChoice: 'none',
cachePrompt: false,
returnTokenIds: true,
} satisfies GenerateParams;
setProgress({ label: `Generating fixed workload · ${workload.id}`, loadedBytes: 0, totalBytes: maxTokens });
const generationResult = await client.generate(generationRequest, {
signal: controller.signal,
onToken: (text, reasoningDelta) => {
if (!text && !reasoningDelta) return;
if (firstTokenAt === null) firstTokenAt = performance.now();
streamedTokenEvents += 1;
setProgress({
label: `Generating fixed prompt · ${streamedTokenEvents} stream event${streamedTokenEvents === 1 ? '' : 's'}`,
loadedBytes: streamedTokenEvents,
totalBytes: maxTokens,
});
},
});
const generationCompleted = performance.now();
throwIfAborted(controller.signal);
let teacherForcedReferenceScore: TeacherForcedReferenceScoreEvidence | null = null;
if (workload.id === 'state-drift-1k-v1') {
setProgress({
label: 'Loading and validating pinned CPU reference',
loadedBytes: 0,
totalBytes: 1,
});
const fixtureResponse = await fetch(stateDriftReferenceUrl(), {
signal: controller.signal,
cache: 'no-cache',
});
if (!fixtureResponse.ok) {
throw new Error(
`CPU reference fixture request failed with HTTP ${fixtureResponse.status}.`,
);
}
const fixture = validateStateDriftReferenceFixture(
await fixtureResponse.json() as unknown,
{ model, capabilities, loadResult: warmLoad },
);
throwIfAborted(controller.signal);
setProgress({
label: 'Teacher-forcing the 1,024-token CPU reference',
loadedBytes: 0,
totalBytes: fixture.referenceTokenIds.length,
});
const score = await client.scoreSequence({
promptTokenIds: fixture.promptTokenIds,
referenceTokenIds: fixture.referenceTokenIds,
topK: 5,
}, { signal: controller.signal });
teacherForcedReferenceScore = { fixture, score };
throwIfAborted(controller.signal);
}
const backendReport = await client.backendReport();
throwIfAborted(controller.signal);
const nextReport = buildBenchmarkReport({
startedAt,
completedAt: new Date().toISOString(),
manifest,
model,
capabilities,
requestedBackend: backend,
contextSize: warmLoad.context.size,
workloadId,
generationRequest,
coldLoadMs,
warmLoadMs,
coldCachedBytes,
storagePersistent,
loadResult: warmLoad,
generationResult,
generationElapsedMs: generationCompleted - generationStarted,
timeToFirstTokenMs: firstTokenAt === null ? null : firstTokenAt - generationStarted,
streamedTokenEvents,
backendReport,
teacherForcedReferenceScore,
});
setReport(nextReport);
setOutput(generationResult.text || generationResult.reasoningText);
setProgress({
label: 'Benchmark complete · JSON report is ready',
loadedBytes: 1,
totalBytes: 1,
});
};
void run().catch((runError) => {
if (isAbort(runError, controller.signal)) {
setProgress({ label: 'Benchmark stopped by operator', loadedBytes: 0, totalBytes: 0 });
return;
}
setRunError(errorMessage(runError));
setProgress({ label: 'Benchmark failed safely · no report exported', loadedBytes: 0, totalBytes: 0 });
}).finally(() => {
if (operationRef.current === controller) operationRef.current = null;
setRunning(false);
});
};
const progressPercent = progress.totalBytes > 0
? Math.min(100, Math.max(0, progress.loadedBytes / progress.totalBytes * 100))
: 0;
const fullGateStorageOnly = storageGate && !storageGate.allowed && deviceGate?.allowed;
return (
<div className="bench-page station-frame">
<header className="bench-masthead">
<div className="brand-block" aria-label="Bonsai browser benchmark">
<span className="brand-mark" aria-hidden="true"><span /></span>
<div>
<p className="eyebrow">Repeatable local inference</p>
<h1>Bonsai <i>browser benchmark</i></h1>
</div>
</div>
<div className="bench-masthead-note">
<strong>Nothing runs on arrival</strong>
<span>One click performs two loads, one fixed prompt, and no network call beyond model assets.</span>
</div>
<a className="bench-return" href={import.meta.env.BASE_URL}>Open chat <span aria-hidden="true"></span></a>
</header>
<div className="bench-layout">
<aside className="bench-controls">
<p className="eyebrow">Benchmark settings</p>
<h2>Configure one run</h2>
<p className="bench-control-intro">The fixed prompt and temperature stay locked so exported runs remain comparable.</p>
<form onSubmit={(event) => { event.preventDefault(); runBenchmark(); }}>
<label className="bench-field">
<span>Workload</span>
<select
value={workloadId}
disabled={running}
onChange={(event) => {
const nextId = event.target.value as BenchmarkWorkloadId;
const next = BENCHMARK_WORKLOADS[nextId];
setWorkloadId(nextId);
setMaxTokens(next.requiredMaxTokens ?? 64);
clearPreviousRun();
}}
>
{Object.values(BENCHMARK_WORKLOADS).map((candidate) => (
<option key={candidate.id} value={candidate.id}>{candidate.label}</option>
))}
</select>
<small>{workload.description}</small>
</label>
<label className="bench-field">
<span>Model tier</span>
<select
value={modelId}
disabled={running || !manifest}
onChange={(event) => handleModelChange(event.target.value as ModelTierId)}
>
{(manifest?.models ?? []).map((candidate) => (
<option key={candidate.id} value={candidate.id}>{candidate.displayName}</option>
))}
</select>
<small>{model ? `${formatBytes(model.downloadBytes)} verified weights` : 'Loading manifest…'}</small>
</label>
<label className="bench-field">
<span>Backend</span>
<select
value={backend}
disabled={running}
onChange={(event) => {
setBackend(event.target.value as RequestedBackend);
clearPreviousRun();
}}
>
<option value="auto">Auto · gated</option>
<option value="webgpu">WebGPU · explicit</option>
<option value="wasm" disabled={model?.cpuFallback === false}>CPU-WASM</option>
</select>
<small>{deviceGate?.selectedBackend ? `Preflight selects ${deviceGate.selectedBackend}` : 'No backend selected'}</small>
</label>
<div className="bench-field-pair">
<label className="bench-field">
<span>Context</span>
<input
type="number"
min="256"
max={contextLimit}
step="256"
value={contextSize}
disabled={running}
onChange={(event) => {
setContextSize(Number(event.target.value));
clearPreviousRun();
}}
/>
<small>Max {contextLimit.toLocaleString()}</small>
</label>
<label className="bench-field">
<span>Max tokens</span>
<input
type="number"
min="8"
max="1024"
step="8"
value={maxTokens}
disabled={running}
onChange={(event) => {
setMaxTokens(Number(event.target.value));
clearPreviousRun();
}}
/>
<small>8–1,024</small>
</label>
</div>
<details className="bench-experimental">
<summary>Experimental runtime tuning</summary>
<p>Blank batch fields use the pinned runtime defaults. Every option is exported as an experiment, not a release recommendation.</p>
<div className="bench-field-pair">
<label className="bench-field">
<span>nBatch</span>
<input
type="number"
min="1"
max={MAX_GLUE_INT}
step="1"
placeholder="runtime default"
value={nBatchInput}
disabled={running}
onChange={(event) => {
setNBatchInput(event.target.value);
clearPreviousRun();
}}
/>
</label>
<label className="bench-field">
<span>nUbatch</span>
<input
type="number"
min="1"
max={MAX_GLUE_INT}
step="1"
placeholder="runtime default"
value={nUbatchInput}
disabled={running}
onChange={(event) => {
setNUbatchInput(event.target.value);
clearPreviousRun();
}}
/>
</label>
</div>
<div className="bench-field-pair">
<label className="bench-field">
<span>Flash Attention request</span>
<select
value={flashMode}
disabled={running}
onChange={(event) => {
setFlashMode(event.target.value as BenchmarkFlashMode);
clearPreviousRun();
}}
>
<option value="off">Off · default</option>
<option value="auto">Auto · observed on</option>
</select>
</label>
<label className="bench-field">
<span>KV cache K / V</span>
<select
value={kvCacheType}
disabled={running}
onChange={(event) => {
setKvCacheType(event.target.value as BenchmarkKvCacheType);
clearPreviousRun();
}}
>
<option value="f16">f16 / f16 · default</option>
<option value="q8_0">q8_0 / q8_0 · exp.</option>
<option value="q4_0">q4_0 / q4_0 · exp.</option>
</select>
</label>
</div>
<label className="bench-field">
<span>WASM runtime</span>
<select
value={wasmFlavor}
disabled={running}
onChange={(event) => {
setWasmFlavor(event.target.value as BenchmarkWasmFlavor);
clearPreviousRun();
}}
>
<option value="auto">Auto · browser-selected</option>
<option value="jspi">JSPI · explicit</option>
<option value="compat">Compat / Asyncify · explicit</option>
</select>
<small>Current auto path: {capabilities?.runtime.wasmFlavor ?? 'inspecting'}</small>
</label>
<dl className="bench-locks">
<div><dt>Chat release</dt><dd>Flash off · KV f16/f16</dd></div>
<div><dt>Evidence rule</dt><dd>native log must match or the run fails</dd></div>
</dl>
</details>
{configurationTuningError && (
<p className="bench-inline-warning" role="alert">{configurationTuningError}</p>
)}
<div className={`bench-gate ${deviceGate?.allowed ? 'pass' : 'fail'}`}>
<strong>{deviceGate?.allowed ? 'Device preflight passed' : 'Device preflight blocked'}</strong>
<span>
{deviceGate?.reasons[0]
?? (fullGateStorageOnly
? 'Storage cannot be proven before cache inspection; the worker repeats the authoritative gate.'
: deviceGate?.warnings[0] ?? 'Waiting for capability inspection.')}
</span>
</div>
<div className="bench-run-actions">
<button className="bench-run-button" type="submit" disabled={!canRun || running}>
{running ? 'Run in progress' : 'Run benchmark'}
</button>
{running && (
<button
className="bench-stop-button"
type="button"
onClick={() => {
setProgress((current) => ({ ...current, label: 'Stopping benchmark…' }));
operationRef.current?.abort();
}}
>
Stop
</button>
)}
</div>
</form>
</aside>
<main className="bench-workbench">
<section className="bench-hero">
<div>
<p className="eyebrow ink">Phase 5 · operator evidence</p>
<h2>Measure the whole <em>growth cycle.</em></h2>
</div>
<p>Cold load includes cache inspection and any missing download. Warm load repeats initialization after unload with verified shards retained. Generation uses one public, fixed prompt.</p>
</section>
<section className="bench-progress" aria-live="polite">
<div><strong>{progress.label}</strong><span>{progress.totalBytes > 1 ? `${Math.round(progressPercent)}%` : ''}</span></div>
<span className="bench-progress-track"><i style={{ width: `${progressPercent}%` }} /></span>
</section>
{bootstrapError && <div className="bench-error" role="alert"><strong>Runtime inspection failed</strong><span>{bootstrapError}</span></div>}
{runError && <div className="bench-error" role="alert"><strong>Run rejected</strong><span>{runError}</span></div>}
<section className="bench-core-section" aria-label="Benchmark measurements">
<div className="bench-section-heading">
<div><p className="eyebrow ink">Core sample</p><h3>Four boundaries, one run</h3></div>
{report && <button type="button" onClick={() => downloadReport(report)}>Export JSON</button>}
</div>
<div className="bench-core-sample">
<article>
<span>Cold load</span>
<strong>{formatDuration(report?.load.cold.durationMs)}</strong>
<small>{report ? `${report.load.cold.cacheState} at start` : 'first boundary'}</small>
</article>
<article>
<span>Warm load</span>
<strong>{formatDuration(report?.load.warm.durationMs)}</strong>
<small>verified cache retained</small>
</article>
<article>
<span>TTFT</span>
<strong>{formatDuration(report?.generation.timeToFirstTokenMs)}</strong>
<small>request to first stream</small>
</article>
<article>
<span>Decode</span>
<strong>{formatRate(report?.generation.decodeTokensPerSecond)}</strong>
<small>{report ? `${report.generation.completionTokens} completion tokens` : 'engine timing'}</small>
</article>
</div>
</section>
<section className="bench-detail-grid">
<article className="bench-data-card">
<p className="eyebrow ink">Throughput</p>
<dl>
<div><dt>Prompt</dt><dd>{formatRate(report?.generation.promptTokensPerSecond)}</dd></div>
<div><dt>Decode</dt><dd>{formatRate(report?.generation.decodeTokensPerSecond)}</dd></div>
<div><dt>Token count</dt><dd>{report?.generation.completionTokens ?? '—'}</dd></div>
<div><dt>Finish</dt><dd>{report?.generation.finishReason ?? '—'}</dd></div>
<div><dt>CPU-ref PPL</dt><dd>{report?.generation.teacherForcedReferenceScore?.score.summary.perplexity.toFixed(4) ?? '—'}</dd></div>
<div><dt>CPU-ref mean NLL</dt><dd>{report?.generation.teacherForcedReferenceScore?.score.summary.meanNll.toFixed(6) ?? '—'}</dd></div>
</dl>
</article>
<article className="bench-data-card">
<p className="eyebrow ink">Graph tripwire</p>
<dl>
<div><dt>Graph splits</dt><dd>{report?.execution.graphSplits ?? '—'}</dd></div>
<div><dt>CPU ops</dt><dd>{report?.execution.opsOnCpu ?? '—'}</dd></div>
<div><dt>GPU layers</dt><dd>{report?.execution.gpuLayers ? `${report.execution.gpuLayers.offloaded}/${report.execution.gpuLayers.total}` : '—'}</dd></div>
<div><dt>Backend</dt><dd>{report?.execution.selectedBackend.toUpperCase() ?? '—'}</dd></div>
</dl>
</article>
<article className="bench-data-card bench-runtime-card">
<p className="eyebrow ink">Runtime pins</p>
<dl>
<div><dt>Device</dt><dd>{report?.execution.device ?? capabilities?.webgpu.name ?? 'Inspecting…'}</dd></div>
<div><dt>wllama</dt><dd title={report?.runtime.wllamaRevision}>{report?.runtime.wllamaRevision.slice(0, 12) ?? '—'}</dd></div>
<div><dt>llama.cpp</dt><dd title={report?.runtime.llamaCppRevision}>{report?.runtime.llamaCppRevision.slice(0, 12) ?? '—'}</dd></div>
<div><dt>Weights</dt><dd title={report?.runtime.manifestRevision ?? undefined}>{report?.runtime.manifestRevision?.slice(0, 12) ?? '—'}</dd></div>
<div><dt>WASM</dt><dd>{report?.runtime.wasmFlavor.toUpperCase() ?? '—'}</dd></div>
</dl>
</article>
<article className="bench-data-card bench-tuning-card">
<p className="eyebrow ink">Native tuning</p>
<dl>
<div><dt>Applied</dt><dd>{report ? (report.load.tuning.applied ? 'yes' : 'no') : '—'}</dd></div>
<div><dt>Flash</dt><dd>{report ? `${report.load.tuning.requested.flashMode} → ${String(report.load.tuning.observed.flashAttention)}` : '—'}</dd></div>
<div><dt>K/V</dt><dd>{report ? `${report.load.tuning.observed.cacheTypeK}/${report.load.tuning.observed.cacheTypeV}` : '—'}</dd></div>
<div><dt>KV bytes</dt><dd>{report?.load.tuning.observed.kvBufferBytes === null || report?.load.tuning.observed.kvBufferBytes === undefined ? '—' : formatBytes(report.load.tuning.observed.kvBufferBytes)}</dd></div>
</dl>
</article>
</section>
<section className="bench-output">
<div>
<p className="eyebrow ink">Fixed prompt</p>
<h3>{workload.id}</h3>
<p>{workload.messages.map((message) => message.content ?? '').join('\n')}</p>
</div>
<div>
<p className="eyebrow ink">Generated output · visible text, or reasoning trace</p>
<p data-testid="bench-generated-output">{output || 'Run the benchmark to inspect generated output.'}</p>
</div>
</section>
</main>
</div>
</div>
);
}