@localmode/bench 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +90 -0
- package/dist/index.cjs +39 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +901 -0
- package/dist/index.d.ts +901 -0
- package/dist/index.js +39 -0
- package/dist/index.js.map +1 -0
- package/package.json +75 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,901 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Protocol types for the LocalMode LocalMode Bench — the cross-runtime in-browser
|
|
3
|
+
* AI benchmark. A `BenchRunResult` is the unit of submission: it carries raw
|
|
4
|
+
* per-chunk timing traces (never just client-computed aggregates) so that all
|
|
5
|
+
* published statistics can be recomputed and audited server-side.
|
|
6
|
+
*/
|
|
7
|
+
/** Protocol identifier embedded in every result. Bump only with a spec change. */
|
|
8
|
+
declare const BENCH_PROTOCOL_VERSION = "localmode-bench/1";
|
|
9
|
+
/** Result JSON schema version (independent of the protocol semantics version). */
|
|
10
|
+
declare const BENCH_SCHEMA_VERSION = 1;
|
|
11
|
+
/** Benchmark suite presets. `custom` = user-picked cells. */
|
|
12
|
+
type BenchSuiteId = 'quick' | 'standard' | 'thorough' | 'custom';
|
|
13
|
+
/**
|
|
14
|
+
* A benchmark runtime lane. Transformers.js is split into two lanes because
|
|
15
|
+
* WebGPU vs WASM is the paper's core comparison axis.
|
|
16
|
+
*/
|
|
17
|
+
type BenchRuntimeId = 'transformers-webgpu' | 'transformers-wasm' | 'webllm' | 'wllama' | 'litert' | 'chrome-ai' | 'mediapipe';
|
|
18
|
+
/** Workload kinds. Quality lanes are separate from timed performance lanes. */
|
|
19
|
+
type BenchWorkloadKind = 'llm-generate' | 'embed-single' | 'embed-batch' | 'quality-mmlu' | 'quality-sts';
|
|
20
|
+
/** A fixed LLM generation workload (public prompt, deterministic settings). */
|
|
21
|
+
interface LLMWorkloadSpec {
|
|
22
|
+
id: string;
|
|
23
|
+
kind: 'llm-generate';
|
|
24
|
+
/** Human-readable label, e.g. "Chat pp128/tg128". */
|
|
25
|
+
label: string;
|
|
26
|
+
prompt: string;
|
|
27
|
+
systemPrompt?: string;
|
|
28
|
+
/**
|
|
29
|
+
* Approximate prompt token count (reference estimate; exact counts are
|
|
30
|
+
* tokenizer-specific and computed post-hoc from the stored prompt).
|
|
31
|
+
*/
|
|
32
|
+
approxPromptTokens: number;
|
|
33
|
+
/** Generation budget. Decode metrics use the actual generated length. */
|
|
34
|
+
maxTokens: number;
|
|
35
|
+
/** Always 0 for performance runs (deterministic where the runtime allows). */
|
|
36
|
+
temperature: number;
|
|
37
|
+
}
|
|
38
|
+
/** A fixed embedding workload over deterministic public texts. */
|
|
39
|
+
interface EmbedWorkloadSpec {
|
|
40
|
+
id: string;
|
|
41
|
+
kind: 'embed-single' | 'embed-batch';
|
|
42
|
+
label: string;
|
|
43
|
+
/** Fixed input texts. Length 1 for single-latency, N for batch throughput. */
|
|
44
|
+
texts: string[];
|
|
45
|
+
}
|
|
46
|
+
/** Quality-fidelity workloads (temp 0, scored, untimed-region rules relaxed). */
|
|
47
|
+
interface QualityWorkloadSpec {
|
|
48
|
+
id: string;
|
|
49
|
+
kind: 'quality-mmlu' | 'quality-sts';
|
|
50
|
+
label: string;
|
|
51
|
+
/** Number of items to evaluate (subset of the bundled dataset). */
|
|
52
|
+
items: number;
|
|
53
|
+
}
|
|
54
|
+
type BenchWorkloadSpec = LLMWorkloadSpec | EmbedWorkloadSpec | QualityWorkloadSpec;
|
|
55
|
+
/** Static reference to a model as benchmarked in one runtime lane. */
|
|
56
|
+
interface BenchModelRef {
|
|
57
|
+
/** Cross-runtime pairing id, e.g. "qwen3-0.6b" — same weights family. */
|
|
58
|
+
benchModelId: string;
|
|
59
|
+
runtimeId: BenchRuntimeId;
|
|
60
|
+
/** The provider-native model id passed to the runtime. */
|
|
61
|
+
providerModelId: string;
|
|
62
|
+
displayName: string;
|
|
63
|
+
/** "llm" or "embedding". */
|
|
64
|
+
task: 'llm' | 'embedding';
|
|
65
|
+
parameterCount?: string;
|
|
66
|
+
quantization?: string;
|
|
67
|
+
sizeBytes?: number;
|
|
68
|
+
contextLength?: number;
|
|
69
|
+
/** Direct model URL when applicable (wllama GGUF, litert). */
|
|
70
|
+
url?: string;
|
|
71
|
+
requiresWebGPU?: boolean;
|
|
72
|
+
}
|
|
73
|
+
/** One recorded stream chunk: wall-clock timestamp + delta length in chars. */
|
|
74
|
+
interface BenchChunk {
|
|
75
|
+
/** `performance.now()` at chunk receipt (ms, page-relative). */
|
|
76
|
+
t: number;
|
|
77
|
+
/** Character length of this chunk's text delta. */
|
|
78
|
+
c: number;
|
|
79
|
+
}
|
|
80
|
+
/** Provider-reported usage, recorded as auxiliary data (often estimated). */
|
|
81
|
+
interface ProviderUsage {
|
|
82
|
+
inputTokens: number;
|
|
83
|
+
outputTokens: number;
|
|
84
|
+
totalTokens: number;
|
|
85
|
+
durationMs: number;
|
|
86
|
+
/** How trustworthy the provider counts are for this runtime. */
|
|
87
|
+
fidelity: 'measured' | 'estimated' | 'chunk-count';
|
|
88
|
+
}
|
|
89
|
+
/** One timed LLM generation iteration with its raw trace. */
|
|
90
|
+
interface LLMIteration {
|
|
91
|
+
/** `performance.now()` just before the stream is requested. */
|
|
92
|
+
startT: number;
|
|
93
|
+
/** Per-chunk receipt trace. TTFT derives from the first entry with c > 0. */
|
|
94
|
+
chunks: BenchChunk[];
|
|
95
|
+
/** `performance.now()` after the terminal chunk. */
|
|
96
|
+
endT: number;
|
|
97
|
+
/** Full generated text (enables post-hoc exact tokenization + auditing). */
|
|
98
|
+
text: string;
|
|
99
|
+
providerUsage?: ProviderUsage;
|
|
100
|
+
finishReason?: string;
|
|
101
|
+
/** Validity-gate events that fired during this iteration (empty = valid). */
|
|
102
|
+
gates: string[];
|
|
103
|
+
}
|
|
104
|
+
/** One timed embedding iteration. */
|
|
105
|
+
interface EmbedIteration {
|
|
106
|
+
startT: number;
|
|
107
|
+
endT: number;
|
|
108
|
+
/** Number of texts embedded in this iteration. */
|
|
109
|
+
count: number;
|
|
110
|
+
/** Embedding dimensions reported by the model. */
|
|
111
|
+
dimensions: number;
|
|
112
|
+
gates: string[];
|
|
113
|
+
}
|
|
114
|
+
/** Model-load phase record for a cell (null when the cell reused a live model). */
|
|
115
|
+
interface LoadRecord {
|
|
116
|
+
/** Provider cache probe before load: true=warm, false=cold, undefined=unknown. */
|
|
117
|
+
cached: boolean | undefined;
|
|
118
|
+
startT: number;
|
|
119
|
+
endT: number;
|
|
120
|
+
/** Progress milestones (coarse, at most ~50 samples). */
|
|
121
|
+
progress?: Array<{
|
|
122
|
+
t: number;
|
|
123
|
+
pct: number;
|
|
124
|
+
}>;
|
|
125
|
+
/** Catalog-declared download size, when known. */
|
|
126
|
+
declaredBytes?: number;
|
|
127
|
+
}
|
|
128
|
+
/** Memory sampling at protocol points (Chromium-only APIs; absent elsewhere). */
|
|
129
|
+
interface MemorySample {
|
|
130
|
+
/** Bytes reported at suite baseline, after load, after timed runs. */
|
|
131
|
+
baseline?: number;
|
|
132
|
+
postLoad?: number;
|
|
133
|
+
postRun?: number;
|
|
134
|
+
api: 'uaSpecific' | 'legacyHeap' | 'none';
|
|
135
|
+
}
|
|
136
|
+
/** Quality lane outcome attached to a cell. */
|
|
137
|
+
interface QualityResult {
|
|
138
|
+
taskId: string;
|
|
139
|
+
/** Primary score: accuracy (MMLU) or Spearman rho (STS). */
|
|
140
|
+
score: number;
|
|
141
|
+
n: number;
|
|
142
|
+
/** Per-item correctness or per-pair cosine, for auditability. */
|
|
143
|
+
details?: number[];
|
|
144
|
+
}
|
|
145
|
+
type BenchCellStatus = 'ok' | 'invalid' | 'error' | 'skipped';
|
|
146
|
+
/** One benchmark cell: (runtime x model x workload) with its raw iterations. */
|
|
147
|
+
interface BenchCellResult {
|
|
148
|
+
/** `${runtimeId}/${benchModelId}/${workloadId}` */
|
|
149
|
+
cellId: string;
|
|
150
|
+
runtimeId: BenchRuntimeId;
|
|
151
|
+
runtimeVersion?: string;
|
|
152
|
+
model: BenchModelRef;
|
|
153
|
+
workloadId: string;
|
|
154
|
+
workloadKind: BenchWorkloadKind;
|
|
155
|
+
/** Backend actually used (probed, never the requested one). */
|
|
156
|
+
resolvedBackend: string;
|
|
157
|
+
load: LoadRecord | null;
|
|
158
|
+
/** Untimed warmup duration (ms), when a warmup ran. */
|
|
159
|
+
warmupMs?: number;
|
|
160
|
+
iterations: LLMIteration[] | EmbedIteration[];
|
|
161
|
+
memory?: MemorySample;
|
|
162
|
+
quality?: QualityResult;
|
|
163
|
+
status: BenchCellStatus;
|
|
164
|
+
invalidReasons?: string[];
|
|
165
|
+
error?: {
|
|
166
|
+
name: string;
|
|
167
|
+
message: string;
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
/** Trace events global to the suite run (validity accounting). */
|
|
171
|
+
interface TraceEvent {
|
|
172
|
+
t: number;
|
|
173
|
+
type: 'suite-start' | 'suite-end' | 'visibility-hidden' | 'visibility-visible' | 'wakelock-acquired' | 'wakelock-released' | 'pressure-change' | 'gpu-device-lost' | 'cooldown-start' | 'cooldown-end' | 'abort';
|
|
174
|
+
detail?: string;
|
|
175
|
+
}
|
|
176
|
+
/** Browser identification with its provenance. */
|
|
177
|
+
interface BrowserInfo {
|
|
178
|
+
name: string;
|
|
179
|
+
version: string;
|
|
180
|
+
source: 'ua-ch' | 'ua-parse';
|
|
181
|
+
brands?: Array<{
|
|
182
|
+
brand: string;
|
|
183
|
+
version: string;
|
|
184
|
+
}>;
|
|
185
|
+
}
|
|
186
|
+
/** OS identification. Version is 'unknown-frozen' on engines with frozen UAs. */
|
|
187
|
+
interface OSInfo {
|
|
188
|
+
platform: string;
|
|
189
|
+
version: string;
|
|
190
|
+
architecture?: string;
|
|
191
|
+
bitness?: string;
|
|
192
|
+
model?: string;
|
|
193
|
+
}
|
|
194
|
+
/** WebGPU adapter identity + selected limits (all fields may be empty strings). */
|
|
195
|
+
interface GPUInfo {
|
|
196
|
+
available: boolean;
|
|
197
|
+
vendor?: string;
|
|
198
|
+
architecture?: string;
|
|
199
|
+
device?: string;
|
|
200
|
+
description?: string;
|
|
201
|
+
isFallbackAdapter?: boolean;
|
|
202
|
+
features?: string[];
|
|
203
|
+
limits?: Record<string, number>;
|
|
204
|
+
}
|
|
205
|
+
/** Full environment capture for a run. Clamped fields are labeled as such. */
|
|
206
|
+
interface EnvironmentCapture {
|
|
207
|
+
capturedAt: string;
|
|
208
|
+
browser: BrowserInfo;
|
|
209
|
+
os: OSInfo;
|
|
210
|
+
hardware: {
|
|
211
|
+
/** navigator.hardwareConcurrency — clamped/randomized on Gecko/WebKit. */
|
|
212
|
+
cores: number | null;
|
|
213
|
+
coresClamped: boolean;
|
|
214
|
+
/** navigator.deviceMemory (GB) — Chromium-only, capped at 8. */
|
|
215
|
+
deviceMemoryGB: number | null;
|
|
216
|
+
deviceMemoryCapped: boolean;
|
|
217
|
+
};
|
|
218
|
+
gpu: GPUInfo;
|
|
219
|
+
/** WebGL renderer string, a secondary GPU identity signal. */
|
|
220
|
+
webglRenderer: string | null;
|
|
221
|
+
flags: {
|
|
222
|
+
crossOriginIsolated: boolean;
|
|
223
|
+
sharedArrayBuffer: boolean;
|
|
224
|
+
wasmSimd: boolean;
|
|
225
|
+
};
|
|
226
|
+
storage: {
|
|
227
|
+
quotaBytes?: number;
|
|
228
|
+
usageBytes?: number;
|
|
229
|
+
} | null;
|
|
230
|
+
power: {
|
|
231
|
+
batterySupported: boolean;
|
|
232
|
+
charging?: boolean;
|
|
233
|
+
level?: number;
|
|
234
|
+
};
|
|
235
|
+
pressure: {
|
|
236
|
+
supported: boolean;
|
|
237
|
+
lastState?: string;
|
|
238
|
+
};
|
|
239
|
+
/** Inferred performance.now() quantum in microseconds (grid inference). */
|
|
240
|
+
timerResolutionUs: number | null;
|
|
241
|
+
screen: {
|
|
242
|
+
width: number;
|
|
243
|
+
height: number;
|
|
244
|
+
dpr: number;
|
|
245
|
+
} | null;
|
|
246
|
+
languages?: string[];
|
|
247
|
+
/** Free-text device self-report — displayed as "user-reported", never trusted. */
|
|
248
|
+
userReportedDevice?: string;
|
|
249
|
+
}
|
|
250
|
+
/** Deterministic JS matmul microbenchmark result (hardware fingerprint). */
|
|
251
|
+
interface FingerprintResult {
|
|
252
|
+
/** Millions of fused multiply-adds per second. */
|
|
253
|
+
mflops: number;
|
|
254
|
+
n: number;
|
|
255
|
+
iterations: number;
|
|
256
|
+
durationMs: number;
|
|
257
|
+
/** Checksum of the final matrix — proves the work actually ran. */
|
|
258
|
+
checksum: number;
|
|
259
|
+
}
|
|
260
|
+
/** Statistical summary of one metric across iterations. */
|
|
261
|
+
interface MetricSummary {
|
|
262
|
+
n: number;
|
|
263
|
+
median: number;
|
|
264
|
+
mean: number;
|
|
265
|
+
sd: number;
|
|
266
|
+
iqr: number;
|
|
267
|
+
min: number;
|
|
268
|
+
max: number;
|
|
269
|
+
/** 95% confidence interval half-width (Student-t). */
|
|
270
|
+
ci95: number;
|
|
271
|
+
/** Coefficient of variation (sd/mean), 0 when mean is 0. */
|
|
272
|
+
cv: number;
|
|
273
|
+
}
|
|
274
|
+
/** Derived per-cell summary (recomputable from the raw trace by anyone). */
|
|
275
|
+
interface CellSummary {
|
|
276
|
+
cellId: string;
|
|
277
|
+
status: BenchCellStatus;
|
|
278
|
+
/** LLM lanes. */
|
|
279
|
+
ttftMs?: MetricSummary;
|
|
280
|
+
decodeCharsPerSec?: MetricSummary;
|
|
281
|
+
decodeChunksPerSec?: MetricSummary;
|
|
282
|
+
prefillTokPerSecApprox?: MetricSummary;
|
|
283
|
+
generatedChars?: MetricSummary;
|
|
284
|
+
/** Embedding lanes. */
|
|
285
|
+
singleLatencyMs?: MetricSummary;
|
|
286
|
+
batchTextsPerSec?: MetricSummary;
|
|
287
|
+
/** Load phase. */
|
|
288
|
+
loadMs?: number;
|
|
289
|
+
loadCached?: boolean;
|
|
290
|
+
qualityScore?: number;
|
|
291
|
+
highVariance: boolean;
|
|
292
|
+
}
|
|
293
|
+
/** The unit of submission: one full suite run on one device. */
|
|
294
|
+
interface BenchRunResult {
|
|
295
|
+
protocol: typeof BENCH_PROTOCOL_VERSION;
|
|
296
|
+
schemaVersion: typeof BENCH_SCHEMA_VERSION;
|
|
297
|
+
runId: string;
|
|
298
|
+
createdAt: string;
|
|
299
|
+
harness: {
|
|
300
|
+
name: string;
|
|
301
|
+
version: string;
|
|
302
|
+
appVersion?: string;
|
|
303
|
+
};
|
|
304
|
+
suite: BenchSuiteId;
|
|
305
|
+
environment: EnvironmentCapture;
|
|
306
|
+
fingerprint: FingerprintResult | null;
|
|
307
|
+
cells: BenchCellResult[];
|
|
308
|
+
events: TraceEvent[];
|
|
309
|
+
/** Client-computed summaries (advisory; server recomputes from the trace). */
|
|
310
|
+
clientSummaries?: CellSummary[];
|
|
311
|
+
/** Server-issued anti-forgery nonce (verified tier only). */
|
|
312
|
+
nonce?: string;
|
|
313
|
+
/** SHA-256 of the canonical JSON of this object without `digest`. */
|
|
314
|
+
digest?: string;
|
|
315
|
+
}
|
|
316
|
+
/** A plausibility/integrity finding attached by validation. */
|
|
317
|
+
interface PlausibilityFlag {
|
|
318
|
+
code: string;
|
|
319
|
+
cellId?: string;
|
|
320
|
+
message: string;
|
|
321
|
+
severity: 'warn' | 'reject';
|
|
322
|
+
}
|
|
323
|
+
/** Outcome of full validation (shape + recompute + plausibility). */
|
|
324
|
+
interface ValidationReport {
|
|
325
|
+
ok: boolean;
|
|
326
|
+
shapeErrors: string[];
|
|
327
|
+
flags: PlausibilityFlag[];
|
|
328
|
+
summaries: CellSummary[];
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Protocol constants: fixed public workloads and the run policy. These are
|
|
333
|
+
* part of the versioned benchmark spec — any change to prompts, token budgets,
|
|
334
|
+
* or policy numbers requires a protocol version bump (see BENCH_PROTOCOL_VERSION).
|
|
335
|
+
*
|
|
336
|
+
* Metric naming follows llama-bench conventions (ppN = prefill on an
|
|
337
|
+
* N-token prompt, tgN = token generation over N tokens) and MLPerf Client
|
|
338
|
+
* definitions (TTFT; decode rate excludes the first token).
|
|
339
|
+
*/
|
|
340
|
+
|
|
341
|
+
/** Fixed generation budget for timed lanes (tg128, MLPerf-Client-sized). */
|
|
342
|
+
declare const GENERATION_BUDGET = 128;
|
|
343
|
+
/** LLM performance workloads. */
|
|
344
|
+
declare const LLM_WORKLOADS: readonly LLMWorkloadSpec[];
|
|
345
|
+
/** Embedding performance workloads. */
|
|
346
|
+
declare const EMBED_WORKLOADS: readonly EmbedWorkloadSpec[];
|
|
347
|
+
/** Quality-fidelity workloads (separate lane, temperature 0). */
|
|
348
|
+
declare const QUALITY_WORKLOADS: readonly QualityWorkloadSpec[];
|
|
349
|
+
/** All workloads indexed by id. */
|
|
350
|
+
declare const WORKLOADS_BY_ID: ReadonlyMap<string, LLMWorkloadSpec | EmbedWorkloadSpec | QualityWorkloadSpec>;
|
|
351
|
+
/** Run policy for a suite (part of the versioned protocol). */
|
|
352
|
+
interface RunPolicy {
|
|
353
|
+
/** Untimed warmup generations per cell (absorbs shader compile/JIT). */
|
|
354
|
+
warmupRuns: number;
|
|
355
|
+
/** Timed iterations per cell. */
|
|
356
|
+
timedRuns: number;
|
|
357
|
+
/** Idle cool-down between cells (thermal recovery), ms. */
|
|
358
|
+
cooldownMs: number;
|
|
359
|
+
/** Gate the next cell on Compute Pressure <= 'fair' when available. */
|
|
360
|
+
pressureGate: boolean;
|
|
361
|
+
/** Max wait for the pressure gate before proceeding anyway, ms. */
|
|
362
|
+
pressureGateTimeoutMs: number;
|
|
363
|
+
/** After a cold load, dispose + reload to also measure the warm load. */
|
|
364
|
+
measureWarmReload: boolean;
|
|
365
|
+
/** CV above this fraction marks a summary metric as high-variance. */
|
|
366
|
+
highVarianceCv: number;
|
|
367
|
+
}
|
|
368
|
+
/** Policies per suite preset. */
|
|
369
|
+
declare const RUN_POLICIES: Record<'quick' | 'standard' | 'thorough', RunPolicy>;
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* Runtime adapter contract. Adapters wire a browser ML runtime (Transformers.js,
|
|
373
|
+
* WebLLM, wllama, LiteRT, Chrome Built-in AI, MediaPipe) to the runner. They are
|
|
374
|
+
* injected by the harness host (e.g. the localmode.ai bench page) so this
|
|
375
|
+
* package stays free of provider dependencies — the same pattern the LocalMode
|
|
376
|
+
* blocks use for provider wiring.
|
|
377
|
+
*
|
|
378
|
+
* The runner consumes the `@localmode/core` model interfaces structurally
|
|
379
|
+
* (type-only peer dependency): any object with a compatible `doStream`/`doEmbed`
|
|
380
|
+
* works, including models from other libraries.
|
|
381
|
+
*/
|
|
382
|
+
|
|
383
|
+
/** Structural subset of `@localmode/core`'s StreamChunk. */
|
|
384
|
+
interface BenchStreamChunk {
|
|
385
|
+
text: string;
|
|
386
|
+
done: boolean;
|
|
387
|
+
finishReason?: string;
|
|
388
|
+
usage?: {
|
|
389
|
+
inputTokens: number;
|
|
390
|
+
outputTokens: number;
|
|
391
|
+
totalTokens: number;
|
|
392
|
+
durationMs: number;
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
/** Structural subset of `@localmode/core`'s LanguageModel. */
|
|
396
|
+
interface BenchLanguageModel {
|
|
397
|
+
readonly modelId: string;
|
|
398
|
+
readonly provider: string;
|
|
399
|
+
doStream?(options: {
|
|
400
|
+
prompt: string;
|
|
401
|
+
systemPrompt?: string;
|
|
402
|
+
maxTokens?: number;
|
|
403
|
+
temperature?: number;
|
|
404
|
+
abortSignal?: AbortSignal;
|
|
405
|
+
}): AsyncIterable<BenchStreamChunk>;
|
|
406
|
+
doGenerate(options: {
|
|
407
|
+
prompt: string;
|
|
408
|
+
systemPrompt?: string;
|
|
409
|
+
maxTokens?: number;
|
|
410
|
+
temperature?: number;
|
|
411
|
+
abortSignal?: AbortSignal;
|
|
412
|
+
}): Promise<{
|
|
413
|
+
text: string;
|
|
414
|
+
finishReason: string;
|
|
415
|
+
usage: ProviderUsage | Omit<ProviderUsage, 'fidelity'>;
|
|
416
|
+
}>;
|
|
417
|
+
}
|
|
418
|
+
/** Structural subset of `@localmode/core`'s EmbeddingModel. */
|
|
419
|
+
interface BenchEmbeddingModel {
|
|
420
|
+
readonly modelId: string;
|
|
421
|
+
readonly provider: string;
|
|
422
|
+
readonly dimensions: number;
|
|
423
|
+
doEmbed(options: {
|
|
424
|
+
values: string[];
|
|
425
|
+
abortSignal?: AbortSignal;
|
|
426
|
+
}): Promise<{
|
|
427
|
+
embeddings: Float32Array[];
|
|
428
|
+
}>;
|
|
429
|
+
}
|
|
430
|
+
/** Availability probe result for a runtime lane on this device. */
|
|
431
|
+
interface AdapterAvailability {
|
|
432
|
+
ok: boolean;
|
|
433
|
+
/** Human-readable reason when not available ('no WebGPU adapter', ...). */
|
|
434
|
+
reason?: string;
|
|
435
|
+
}
|
|
436
|
+
/** Load-progress callback payload (normalized percent when known). */
|
|
437
|
+
interface AdapterLoadProgress {
|
|
438
|
+
pct?: number;
|
|
439
|
+
}
|
|
440
|
+
/** A loaded LLM handle: the model plus its resolved execution backend. */
|
|
441
|
+
interface LoadedLLM {
|
|
442
|
+
model: BenchLanguageModel;
|
|
443
|
+
/** Backend actually in use — 'webgpu' | 'wasm' | 'gpu' | 'cpu' | 'chrome-builtin'. */
|
|
444
|
+
resolvedBackend: string;
|
|
445
|
+
dispose(): Promise<void>;
|
|
446
|
+
}
|
|
447
|
+
/** A loaded embedding-model handle. */
|
|
448
|
+
interface LoadedEmbedder {
|
|
449
|
+
model: BenchEmbeddingModel;
|
|
450
|
+
resolvedBackend: string;
|
|
451
|
+
dispose(): Promise<void>;
|
|
452
|
+
}
|
|
453
|
+
/** Adapter for an LLM runtime lane. */
|
|
454
|
+
interface LLMRuntimeAdapter {
|
|
455
|
+
readonly runtimeId: BenchRuntimeId;
|
|
456
|
+
readonly displayName: string;
|
|
457
|
+
/** Underlying runtime library version, when known (recorded per cell). */
|
|
458
|
+
readonly runtimeVersion?: string;
|
|
459
|
+
/** Is this lane usable on the current device/browser? */
|
|
460
|
+
isAvailable(): Promise<AdapterAvailability>;
|
|
461
|
+
/** Provider cache probe — true=warm, false=cold, undefined=unknown. */
|
|
462
|
+
isModelCached(model: BenchModelRef): Promise<boolean | undefined>;
|
|
463
|
+
/** Load (download + compile) the model. Must NOT run any inference. */
|
|
464
|
+
load(model: BenchModelRef, options: {
|
|
465
|
+
onProgress?: (p: AdapterLoadProgress) => void;
|
|
466
|
+
abortSignal?: AbortSignal;
|
|
467
|
+
}): Promise<LoadedLLM>;
|
|
468
|
+
}
|
|
469
|
+
/** Adapter for an embedding runtime lane. */
|
|
470
|
+
interface EmbeddingRuntimeAdapter {
|
|
471
|
+
readonly runtimeId: BenchRuntimeId;
|
|
472
|
+
readonly displayName: string;
|
|
473
|
+
readonly runtimeVersion?: string;
|
|
474
|
+
isAvailable(): Promise<AdapterAvailability>;
|
|
475
|
+
isModelCached(model: BenchModelRef): Promise<boolean | undefined>;
|
|
476
|
+
load(model: BenchModelRef, options: {
|
|
477
|
+
onProgress?: (p: AdapterLoadProgress) => void;
|
|
478
|
+
abortSignal?: AbortSignal;
|
|
479
|
+
}): Promise<LoadedEmbedder>;
|
|
480
|
+
}
|
|
481
|
+
/** Usage fidelity per runtime — how trustworthy provider token counts are. */
|
|
482
|
+
declare const USAGE_FIDELITY: Record<BenchRuntimeId, ProviderUsage['fidelity']>;
|
|
483
|
+
|
|
484
|
+
/**
|
|
485
|
+
* The suite runner: executes (runtime x model x workload) cells under the
|
|
486
|
+
* versioned run policy — cache probe, load, untimed warmup, N timed runs with
|
|
487
|
+
* raw per-chunk traces, validity gates, memory protocol points, cool-downs —
|
|
488
|
+
* and assembles the submittable BenchRunResult.
|
|
489
|
+
*/
|
|
490
|
+
|
|
491
|
+
/** One planned cell. Cells sharing (runtimeId, model) reuse the loaded model. */
|
|
492
|
+
interface PlannedCell {
|
|
493
|
+
model: BenchModelRef;
|
|
494
|
+
workload: LLMWorkloadSpec | EmbedWorkloadSpec | QualityWorkloadSpec;
|
|
495
|
+
}
|
|
496
|
+
/** Progress callbacks for a host UI. */
|
|
497
|
+
interface RunnerHooks {
|
|
498
|
+
onCellStart?(cellId: string, index: number, total: number): void;
|
|
499
|
+
onCellFinish?(cell: BenchCellResult): void;
|
|
500
|
+
onLoadProgress?(cellId: string, pct: number | undefined): void;
|
|
501
|
+
onIteration?(cellId: string, iteration: number, total: number): void;
|
|
502
|
+
onPhase?(phase: string): void;
|
|
503
|
+
}
|
|
504
|
+
/** Inputs to a suite run. */
|
|
505
|
+
interface RunSuiteOptions {
|
|
506
|
+
suite: BenchSuiteId;
|
|
507
|
+
cells: PlannedCell[];
|
|
508
|
+
policy: RunPolicy;
|
|
509
|
+
llmAdapters: ReadonlyMap<string, LLMRuntimeAdapter>;
|
|
510
|
+
embedAdapters: ReadonlyMap<string, EmbeddingRuntimeAdapter>;
|
|
511
|
+
harness: {
|
|
512
|
+
name: string;
|
|
513
|
+
version: string;
|
|
514
|
+
appVersion?: string;
|
|
515
|
+
};
|
|
516
|
+
hooks?: RunnerHooks;
|
|
517
|
+
abortSignal?: AbortSignal;
|
|
518
|
+
/** Skip the fingerprint microbenchmark (tests only; submissions require it). */
|
|
519
|
+
skipFingerprint?: boolean;
|
|
520
|
+
userReportedDevice?: string;
|
|
521
|
+
}
|
|
522
|
+
/**
|
|
523
|
+
* Run a benchmark suite and return the full, submittable result (raw traces
|
|
524
|
+
* included; `clientSummaries` computed with the same code the server uses).
|
|
525
|
+
*
|
|
526
|
+
* Cells are grouped by (runtime, model): the model loads once, its workloads
|
|
527
|
+
* run back-to-back, then it is disposed before the next model (peak-memory
|
|
528
|
+
* hygiene). Validity gates never retry silently — affected iterations carry
|
|
529
|
+
* their gate events and the cell is marked invalid.
|
|
530
|
+
*
|
|
531
|
+
* @throws {DOMException} AbortError when `abortSignal` aborts.
|
|
532
|
+
* @example
|
|
533
|
+
* const result = await runBenchmarkSuite({ suite: 'quick', cells, policy, ... });
|
|
534
|
+
*/
|
|
535
|
+
declare function runBenchmarkSuite(options: RunSuiteOptions): Promise<BenchRunResult>;
|
|
536
|
+
|
|
537
|
+
/**
|
|
538
|
+
* Environment capture. Records identity + capability signals with honest
|
|
539
|
+
* provenance: UA Client Hints on Chromium; UA parsing elsewhere with the OS
|
|
540
|
+
* version marked 'unknown-frozen' (UA strings are frozen by design on Gecko
|
|
541
|
+
* and WebKit). Clamped fields (cores, deviceMemory) are labeled clamped.
|
|
542
|
+
*/
|
|
543
|
+
|
|
544
|
+
/**
|
|
545
|
+
* Capture the full benchmark environment. Never throws — every probe is
|
|
546
|
+
* individually guarded and absent signals are recorded as absent.
|
|
547
|
+
*
|
|
548
|
+
* @param options.userReportedDevice - Optional free-text device self-report
|
|
549
|
+
* (displayed as "user-reported", never treated as ground truth).
|
|
550
|
+
* @example
|
|
551
|
+
* const env = await captureEnvironment();
|
|
552
|
+
*/
|
|
553
|
+
declare function captureEnvironment(options?: {
|
|
554
|
+
userReportedDevice?: string;
|
|
555
|
+
}): Promise<EnvironmentCapture>;
|
|
556
|
+
|
|
557
|
+
/**
|
|
558
|
+
* Memory sampling at protocol points (baseline / post-load / post-run).
|
|
559
|
+
* Uses `performance.measureUserAgentSpecificMemory()` (Chromium, requires
|
|
560
|
+
* cross-origin isolation, resolves at the next GC — up to ~20 s), with the
|
|
561
|
+
* legacy Chromium JS-heap as fallback. Never call inside a timed region.
|
|
562
|
+
*/
|
|
563
|
+
/** Which memory API is usable in this context. */
|
|
564
|
+
declare function memoryApiAvailable(): 'uaSpecific' | 'legacyHeap' | 'none';
|
|
565
|
+
/**
|
|
566
|
+
* Sample total page memory in bytes, or null when unavailable / timed out.
|
|
567
|
+
* The UA-specific measurement is raced against `timeoutMs` because it only
|
|
568
|
+
* resolves at the next garbage collection.
|
|
569
|
+
*
|
|
570
|
+
* @param timeoutMs - Max wait for the GC-gated measurement (default 25000).
|
|
571
|
+
* @example
|
|
572
|
+
* const bytes = await sampleMemoryBytes(); // 734003200 | null
|
|
573
|
+
*/
|
|
574
|
+
declare function sampleMemoryBytes(timeoutMs?: number): Promise<number | null>;
|
|
575
|
+
|
|
576
|
+
/**
|
|
577
|
+
* Wall-clock timing helpers. All benchmark timestamps use `performance.now()`
|
|
578
|
+
* (5 µs resolution on cross-origin-isolated Chromium, coarser elsewhere);
|
|
579
|
+
* decode rates are derived from endpoint timestamps, never from averaged
|
|
580
|
+
* per-token deltas, because per-token gaps sit at or below timer quantization.
|
|
581
|
+
*/
|
|
582
|
+
/** Monotonic high-resolution timestamp in ms (performance.now, Date fallback). */
|
|
583
|
+
declare function hrNow(): number;
|
|
584
|
+
/**
|
|
585
|
+
* Infer the effective `performance.now()` quantum by sampling timer deltas.
|
|
586
|
+
* Genuine traces sit on this grid; the value is recorded in the environment
|
|
587
|
+
* capture and used by the timer-grid integrity check.
|
|
588
|
+
*
|
|
589
|
+
* @param samples - Number of distinct increments to observe (default 64).
|
|
590
|
+
* @returns Inferred quantum in microseconds, or null outside a browser.
|
|
591
|
+
* @example
|
|
592
|
+
* const q = inferTimerResolutionUs(); // 5 on isolated Chromium
|
|
593
|
+
*/
|
|
594
|
+
declare function inferTimerResolutionUs(samples?: number): number | null;
|
|
595
|
+
/** Await a real delay (setTimeout) — used for cool-downs between cells. */
|
|
596
|
+
declare function sleep(ms: number, abortSignal?: AbortSignal): Promise<void>;
|
|
597
|
+
|
|
598
|
+
/**
|
|
599
|
+
* Deterministic single-thread JS matmul microbenchmark. Every submission runs
|
|
600
|
+
* it; the resulting MFLOPS is a hardware fingerprint that claimed inference
|
|
601
|
+
* rates must plausibly correlate with, and the checksum proves the work ran.
|
|
602
|
+
*/
|
|
603
|
+
|
|
604
|
+
/**
|
|
605
|
+
* Run the fingerprint microbenchmark: repeated n x n f32 matmuls for at least
|
|
606
|
+
* `minDurationMs`, single-threaded, deterministic inputs.
|
|
607
|
+
*
|
|
608
|
+
* @param options.n - Matrix dimension (default 160; ~8.2 MFLOP per iteration).
|
|
609
|
+
* @param options.minDurationMs - Minimum wall time to run (default 600).
|
|
610
|
+
* @returns MFLOPS, iteration count, and a checksum of the final product.
|
|
611
|
+
* @example
|
|
612
|
+
* const fp = await runFingerprint(); // { mflops: 1800.4, ... }
|
|
613
|
+
*/
|
|
614
|
+
declare function runFingerprint(options?: {
|
|
615
|
+
n?: number;
|
|
616
|
+
minDurationMs?: number;
|
|
617
|
+
}): Promise<FingerprintResult>;
|
|
618
|
+
|
|
619
|
+
/**
|
|
620
|
+
* Suite-level trace recorder: validity-relevant events (tab visibility, wake
|
|
621
|
+
* lock, compute pressure, GPU device loss, aborts) with wall-clock timestamps.
|
|
622
|
+
* Iterations that overlap a hidden period are invalidated, never retried
|
|
623
|
+
* silently — the trace is part of the submitted, auditable record.
|
|
624
|
+
*/
|
|
625
|
+
|
|
626
|
+
/** Records trace events and tracks the current validity-gate state. */
|
|
627
|
+
declare class TraceRecorder {
|
|
628
|
+
private readonly events;
|
|
629
|
+
private disposers;
|
|
630
|
+
private hidden;
|
|
631
|
+
private lastPressureState;
|
|
632
|
+
private wakeLockSentinel;
|
|
633
|
+
/** Append an event at the current timestamp. */
|
|
634
|
+
record(type: TraceEvent['type'], detail?: string): void;
|
|
635
|
+
/** True while the page is hidden (timed regions overlapping this are invalid). */
|
|
636
|
+
get isHidden(): boolean;
|
|
637
|
+
/** Last observed compute-pressure state ('nominal'|'fair'|'serious'|'critical'). */
|
|
638
|
+
get pressureState(): string | undefined;
|
|
639
|
+
/** All recorded events (live reference; snapshot with `[...events]`). */
|
|
640
|
+
get all(): readonly TraceEvent[];
|
|
641
|
+
/**
|
|
642
|
+
* Attach browser listeners (visibility, compute pressure) and request a
|
|
643
|
+
* screen wake lock. Safe to call outside a browser (records nothing).
|
|
644
|
+
*/
|
|
645
|
+
attach(): Promise<void>;
|
|
646
|
+
/** Release listeners and the wake lock. */
|
|
647
|
+
dispose(): Promise<void>;
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
/**
|
|
651
|
+
* Statistics for benchmark reporting: median headline, mean ± SD, IQR, 95% CI
|
|
652
|
+
* (Student-t for the small n this protocol uses), CV, and geometric mean for
|
|
653
|
+
* cross-workload aggregation (never across devices).
|
|
654
|
+
*/
|
|
655
|
+
|
|
656
|
+
/**
|
|
657
|
+
* Linear-interpolated quantile (type-7, the R/NumPy default).
|
|
658
|
+
*
|
|
659
|
+
* @param values - Sample values (need not be sorted).
|
|
660
|
+
* @param q - Quantile in [0, 1].
|
|
661
|
+
* @returns The interpolated quantile.
|
|
662
|
+
* @throws {RangeError} When `values` is empty or `q` is out of range.
|
|
663
|
+
* @example
|
|
664
|
+
* quantile([1, 2, 3, 4], 0.5); // 2.5
|
|
665
|
+
*/
|
|
666
|
+
declare function quantile(values: readonly number[], q: number): number;
|
|
667
|
+
/** Median of a sample. @see quantile */
|
|
668
|
+
declare function median(values: readonly number[]): number;
|
|
669
|
+
/** Arithmetic mean. @throws {RangeError} on an empty sample. */
|
|
670
|
+
declare function mean(values: readonly number[]): number;
|
|
671
|
+
/** Sample standard deviation (n-1 denominator). Returns 0 for n < 2. */
|
|
672
|
+
declare function stddev(values: readonly number[]): number;
|
|
673
|
+
/**
|
|
674
|
+
* Geometric mean. Used to aggregate across workloads within one device run
|
|
675
|
+
* (Speedometer/JetStream convention). All values must be positive.
|
|
676
|
+
*
|
|
677
|
+
* @throws {RangeError} on an empty sample or non-positive values.
|
|
678
|
+
*/
|
|
679
|
+
declare function geomean(values: readonly number[]): number;
|
|
680
|
+
/**
|
|
681
|
+
* Full summary of one metric across timed iterations.
|
|
682
|
+
*
|
|
683
|
+
* @param values - One value per timed iteration (ms, tok/s, ...).
|
|
684
|
+
* @returns Median headline plus dispersion measures; `ci95` is the Student-t
|
|
685
|
+
* 95% half-width (0 when n < 2).
|
|
686
|
+
* @example
|
|
687
|
+
* summarize([102, 99, 104]).median; // 102
|
|
688
|
+
*/
|
|
689
|
+
declare function summarize(values: readonly number[]): MetricSummary;
|
|
690
|
+
/**
|
|
691
|
+
* Spearman rank correlation between two equal-length samples, with average
|
|
692
|
+
* ranks for ties. Used by the STS embedding-quality lane.
|
|
693
|
+
*
|
|
694
|
+
* @returns rho in [-1, 1].
|
|
695
|
+
* @throws {RangeError} when lengths differ or n < 2.
|
|
696
|
+
*/
|
|
697
|
+
declare function spearman(a: readonly number[], b: readonly number[]): number;
|
|
698
|
+
|
|
699
|
+
/**
|
|
700
|
+
* Validation: structural schema checks, deterministic summary recomputation
|
|
701
|
+
* from raw traces (the same code runs client- and server-side), and versioned
|
|
702
|
+
* plausibility/integrity checks for community submissions. Flags are attached,
|
|
703
|
+
* never silently dropped — flagged runs are quarantined publicly.
|
|
704
|
+
*/
|
|
705
|
+
|
|
706
|
+
/** Version of the plausibility rule set (recorded alongside moderation). */
|
|
707
|
+
declare const PLAUSIBILITY_RULES_VERSION = 1;
|
|
708
|
+
/**
|
|
709
|
+
* Structural validation of a submitted result. Returns human-readable errors
|
|
710
|
+
* (empty array = shape ok). Deliberately hand-rolled: this package is
|
|
711
|
+
* zero-dependency and the checks double as executable schema documentation.
|
|
712
|
+
*/
|
|
713
|
+
declare function validateRunShape(value: unknown): string[];
|
|
714
|
+
/**
|
|
715
|
+
* Recompute a cell's summary purely from its raw iteration traces.
|
|
716
|
+
* This function IS the metric definition:
|
|
717
|
+
* - TTFT = first non-empty chunk timestamp − startT
|
|
718
|
+
* - decode rate = (chars after first chunk) / (endT_lastChunk − t_firstChunk)
|
|
719
|
+
* - prefill tok/s ≈ approxPromptTokens / TTFT (approximate by construction)
|
|
720
|
+
*/
|
|
721
|
+
declare function summarizeCell(cell: BenchCellResult, highVarianceCv?: number, approxPromptTokens?: number): CellSummary;
|
|
722
|
+
/** Recompute all cell summaries for a run (workload prompt sizes looked up). */
|
|
723
|
+
declare function summarizeRun(run: BenchRunResult, highVarianceCv?: number, promptTokensByWorkload?: ReadonlyMap<string, number>): CellSummary[];
|
|
724
|
+
/**
|
|
725
|
+
* Versioned plausibility/integrity checks over a submitted run. Returns flags;
|
|
726
|
+
* `severity: 'reject'` flags route the run to quarantine, `warn` flags are
|
|
727
|
+
* displayed. Rules (v1): timestamp monotonicity, decode-rate envelopes,
|
|
728
|
+
* duration consistency, timer-grid conformance, fingerprint sanity,
|
|
729
|
+
* environment cross-field consistency.
|
|
730
|
+
*/
|
|
731
|
+
declare function checkPlausibility(run: BenchRunResult): PlausibilityFlag[];
|
|
732
|
+
/**
|
|
733
|
+
* Full validation pipeline for a submission: shape, digest-independent
|
|
734
|
+
* summary recompute, client-summary agreement (>1% relative disagreement on
|
|
735
|
+
* medians is flagged), and plausibility rules.
|
|
736
|
+
*/
|
|
737
|
+
declare function validateSubmission(run: BenchRunResult): ValidationReport;
|
|
738
|
+
|
|
739
|
+
/**
|
|
740
|
+
* Canonical JSON serialization + SHA-256 digest for run results. The digest
|
|
741
|
+
* covers the canonical form of the result WITHOUT its `digest` field, so any
|
|
742
|
+
* party can recompute and verify it (isomorphic: browser and Node).
|
|
743
|
+
*/
|
|
744
|
+
|
|
745
|
+
/**
|
|
746
|
+
* Deterministic JSON: object keys sorted lexicographically at every level,
|
|
747
|
+
* arrays in order, no whitespace. Non-finite numbers serialize as null
|
|
748
|
+
* (JSON.stringify semantics) so digests stay portable.
|
|
749
|
+
*
|
|
750
|
+
* @example
|
|
751
|
+
* canonicalJson({ b: 1, a: [2, { d: 3, c: 4 }] }); // '{"a":[2,{"c":4,"d":3}],"b":1}'
|
|
752
|
+
*/
|
|
753
|
+
declare function canonicalJson(value: unknown): string;
|
|
754
|
+
/** SHA-256 hex of a UTF-8 string via Web Crypto (browser + Node >= 19). */
|
|
755
|
+
declare function sha256Hex(text: string): Promise<string>;
|
|
756
|
+
/**
|
|
757
|
+
* Compute the run digest: SHA-256 of the canonical JSON of the result with
|
|
758
|
+
* `digest` removed.
|
|
759
|
+
*
|
|
760
|
+
* @example
|
|
761
|
+
* result.digest = await computeRunDigest(result);
|
|
762
|
+
*/
|
|
763
|
+
declare function computeRunDigest(result: BenchRunResult): Promise<string>;
|
|
764
|
+
/** Verify a result's embedded digest. Returns false when absent or wrong. */
|
|
765
|
+
declare function verifyRunDigest(result: BenchRunResult): Promise<boolean>;
|
|
766
|
+
|
|
767
|
+
/**
|
|
768
|
+
* Aggregation for the public leaderboard and for paper analysis. Runs group
|
|
769
|
+
* into device-class rows; medians are taken per submission first, then across
|
|
770
|
+
* submissions (median-of-medians). Nothing is ever averaged across devices.
|
|
771
|
+
*/
|
|
772
|
+
|
|
773
|
+
/** Device class derived from environment identity signals. */
|
|
774
|
+
declare function deviceClassOf(run: BenchRunResult): string;
|
|
775
|
+
/** One leaderboard row: a (deviceClass, runtime, model, workload) group. */
|
|
776
|
+
interface LeaderboardRow {
|
|
777
|
+
deviceClass: string;
|
|
778
|
+
runtimeId: string;
|
|
779
|
+
benchModelId: string;
|
|
780
|
+
modelName: string;
|
|
781
|
+
workloadId: string;
|
|
782
|
+
/** Number of distinct submissions contributing. */
|
|
783
|
+
submissions: number;
|
|
784
|
+
/** Median-of-medians metrics (only those applicable to the workload). */
|
|
785
|
+
ttftMs?: number;
|
|
786
|
+
decodeCharsPerSec?: number;
|
|
787
|
+
singleLatencyMs?: number;
|
|
788
|
+
batchTextsPerSec?: number;
|
|
789
|
+
loadColdMs?: number;
|
|
790
|
+
loadWarmMs?: number;
|
|
791
|
+
qualityScore?: number;
|
|
792
|
+
resolvedBackends: string[];
|
|
793
|
+
browsers: string[];
|
|
794
|
+
/** True when any contributing submission had a high-variance metric. */
|
|
795
|
+
highVariance: boolean;
|
|
796
|
+
/** Rows below the min-N threshold are provisional. */
|
|
797
|
+
provisional: boolean;
|
|
798
|
+
}
|
|
799
|
+
/** Minimum concordant submissions for a non-provisional headline row. */
|
|
800
|
+
declare const HEADLINE_MIN_SUBMISSIONS = 3;
|
|
801
|
+
/**
|
|
802
|
+
* Aggregate validated runs into leaderboard rows.
|
|
803
|
+
*
|
|
804
|
+
* @param runs - Validated (non-quarantined) run results.
|
|
805
|
+
* @param minSubmissions - Min submissions before a row loses `provisional`.
|
|
806
|
+
* @example
|
|
807
|
+
* const rows = aggregateRuns(allRuns);
|
|
808
|
+
*/
|
|
809
|
+
declare function aggregateRuns(runs: readonly BenchRunResult[], minSubmissions?: number): LeaderboardRow[];
|
|
810
|
+
/** Leaderboard rows as CSV. */
|
|
811
|
+
declare function rowsToCSV(rows: readonly LeaderboardRow[]): string;
|
|
812
|
+
/**
|
|
813
|
+
* Long-format per-iteration CSV for paper analysis (one row per timed
|
|
814
|
+
* iteration, with full environment identity columns) — feed to R/pandas.
|
|
815
|
+
*/
|
|
816
|
+
declare function runsToLongCSV(runs: readonly BenchRunResult[]): string;
|
|
817
|
+
|
|
818
|
+
/**
|
|
819
|
+
* tinyMMLU — 100 IRT-anchored items from the MMLU benchmark, selected by the
|
|
820
|
+
* tinyBenchmarks project (Maia Polo et al., "tinyBenchmarks: evaluating LLMs
|
|
821
|
+
* with fewer examples", arXiv:2402.14992). Source dataset:
|
|
822
|
+
* https://huggingface.co/datasets/tinyBenchmarks/tinyMMLU (test split, 100 rows).
|
|
823
|
+
* Upstream MMLU (cais/mmlu) and the tinyBenchmarks repository are MIT-licensed.
|
|
824
|
+
*
|
|
825
|
+
* Used by the quality-fidelity lane: scores measure runtime/quantization
|
|
826
|
+
* fidelity of a model build, not model capability (public sets are assumed
|
|
827
|
+
* to be in training data).
|
|
828
|
+
*/
|
|
829
|
+
/** One multiple-choice item: four choices, `answer` is the 0-based correct index. */
|
|
830
|
+
interface MMLUItem {
|
|
831
|
+
question: string;
|
|
832
|
+
subject: string;
|
|
833
|
+
choices: [string, string, string, string];
|
|
834
|
+
answer: 0 | 1 | 2 | 3;
|
|
835
|
+
}
|
|
836
|
+
/** The 100-item tinyMMLU test split (order preserved from the source dataset). */
|
|
837
|
+
declare const TINY_MMLU: readonly MMLUItem[];
|
|
838
|
+
|
|
839
|
+
/**
|
|
840
|
+
* Quality-fidelity lane. Scores measure runtime/quantization fidelity of a
|
|
841
|
+
* model build (do this runtime's weights + kernels reproduce expected answers),
|
|
842
|
+
* NOT model capability — the bundled public sets are assumed to be in every
|
|
843
|
+
* model's training data. Always run at temperature 0, outside timed regions.
|
|
844
|
+
*/
|
|
845
|
+
|
|
846
|
+
/** Fixed MCQ prompt template (part of the versioned protocol). */
|
|
847
|
+
declare function formatMMLUPrompt(item: (typeof TINY_MMLU)[number]): string;
|
|
848
|
+
/**
|
|
849
|
+
* Parse the answer letter from a model response. Accepts "B", "B.", "(B)",
|
|
850
|
+
* "Answer: B", or a response beginning with the exact choice text.
|
|
851
|
+
*
|
|
852
|
+
* @returns 0-3, or null when no unambiguous answer is present.
|
|
853
|
+
*/
|
|
854
|
+
declare function parseMMLUAnswer(response: string, choices: readonly string[]): number | null;
|
|
855
|
+
/**
|
|
856
|
+
* Run the tinyMMLU fidelity task on a language model (temperature 0,
|
|
857
|
+
* `maxTokens` 8, greedy answer parsing). Unparseable answers count as wrong.
|
|
858
|
+
*
|
|
859
|
+
* @param model - Any structurally-compatible LanguageModel.
|
|
860
|
+
* @param items - Number of items from the 100-item set (25 or 100 in v1).
|
|
861
|
+
* @returns Accuracy in [0,1] with per-item correctness details.
|
|
862
|
+
*/
|
|
863
|
+
declare function runMMLUFidelity(model: BenchLanguageModel, items: number, options?: {
|
|
864
|
+
abortSignal?: AbortSignal;
|
|
865
|
+
onProgress?: (done: number, total: number) => void;
|
|
866
|
+
}): Promise<QualityResult>;
|
|
867
|
+
/**
|
|
868
|
+
* Run the STS-B embedding-quality task: Spearman correlation of cosine
|
|
869
|
+
* similarities against human scores over the bundled pair subset.
|
|
870
|
+
*
|
|
871
|
+
* @param model - Any structurally-compatible EmbeddingModel.
|
|
872
|
+
* @param pairs - Number of pairs from the 100-pair set.
|
|
873
|
+
* @returns Spearman rho with per-pair cosine details.
|
|
874
|
+
*/
|
|
875
|
+
declare function runSTSQuality(model: BenchEmbeddingModel, pairs: number, options?: {
|
|
876
|
+
abortSignal?: AbortSignal;
|
|
877
|
+
onProgress?: (done: number, total: number) => void;
|
|
878
|
+
}): Promise<QualityResult>;
|
|
879
|
+
|
|
880
|
+
/**
|
|
881
|
+
* STS Benchmark subset — the first 100 pairs of the STS-B test split
|
|
882
|
+
* (semantic textual similarity; human scores 0-5). Source:
|
|
883
|
+
* https://huggingface.co/datasets/mteb/stsbenchmark-sts (test split).
|
|
884
|
+
*
|
|
885
|
+
* LICENSE: CC BY-SA 4.0 (share-alike). This file and any redistribution of the
|
|
886
|
+
* pairs below remain under CC BY-SA 4.0 — see LICENSE-CC-BY-SA.md in this
|
|
887
|
+
* directory. Kept isolated from the MIT-licensed code and datasets on purpose.
|
|
888
|
+
*
|
|
889
|
+
* Used by the embedding quality lane: Spearman correlation of cosine
|
|
890
|
+
* similarities against the human scores.
|
|
891
|
+
*/
|
|
892
|
+
/** One sentence pair with its human similarity score (0-5). */
|
|
893
|
+
interface STSPair {
|
|
894
|
+
s1: string;
|
|
895
|
+
s2: string;
|
|
896
|
+
score: number;
|
|
897
|
+
}
|
|
898
|
+
/** 100-pair STS-B test subset (order preserved from the source dataset). */
|
|
899
|
+
declare const STSB_SUBSET: readonly STSPair[];
|
|
900
|
+
|
|
901
|
+
export { type AdapterAvailability, type AdapterLoadProgress, BENCH_PROTOCOL_VERSION, BENCH_SCHEMA_VERSION, type BenchCellResult, type BenchCellStatus, type BenchChunk, type BenchEmbeddingModel, type BenchLanguageModel, type BenchModelRef, type BenchRunResult, type BenchRuntimeId, type BenchStreamChunk, type BenchSuiteId, type BenchWorkloadKind, type BenchWorkloadSpec, type BrowserInfo, type CellSummary, EMBED_WORKLOADS, type EmbedIteration, type EmbedWorkloadSpec, type EmbeddingRuntimeAdapter, type EnvironmentCapture, type FingerprintResult, GENERATION_BUDGET, type GPUInfo, HEADLINE_MIN_SUBMISSIONS, type LLMIteration, type LLMRuntimeAdapter, type LLMWorkloadSpec, LLM_WORKLOADS, type LeaderboardRow, type LoadRecord, type LoadedEmbedder, type LoadedLLM, type MMLUItem, type MemorySample, type MetricSummary, type OSInfo, PLAUSIBILITY_RULES_VERSION, type PlannedCell, type PlausibilityFlag, type ProviderUsage, QUALITY_WORKLOADS, type QualityResult, type QualityWorkloadSpec, RUN_POLICIES, type RunPolicy, type RunSuiteOptions, type RunnerHooks, STSB_SUBSET, type STSPair, TINY_MMLU, type TraceEvent, TraceRecorder, USAGE_FIDELITY, type ValidationReport, WORKLOADS_BY_ID, aggregateRuns, canonicalJson, captureEnvironment, checkPlausibility, computeRunDigest, deviceClassOf, formatMMLUPrompt, geomean, hrNow, inferTimerResolutionUs, mean, median, memoryApiAvailable, parseMMLUAnswer, quantile, rowsToCSV, runBenchmarkSuite, runFingerprint, runMMLUFidelity, runSTSQuality, runsToLongCSV, sampleMemoryBytes, sha256Hex, sleep, spearman, stddev, summarize, summarizeCell, summarizeRun, validateRunShape, validateSubmission, verifyRunDigest };
|