@localmode/bench 0.1.0 → 0.3.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/README.md +87 -5
- package/dist/index.cjs +7 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +398 -21
- package/dist/index.d.ts +398 -21
- package/dist/index.js +7 -7
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
* published statistics can be recomputed and audited server-side.
|
|
6
6
|
*/
|
|
7
7
|
/** Protocol identifier embedded in every result. Bump only with a spec change. */
|
|
8
|
-
declare const BENCH_PROTOCOL_VERSION = "localmode-bench/
|
|
8
|
+
declare const BENCH_PROTOCOL_VERSION = "localmode-bench/2";
|
|
9
9
|
/** Result JSON schema version (independent of the protocol semantics version). */
|
|
10
|
-
declare const BENCH_SCHEMA_VERSION =
|
|
10
|
+
declare const BENCH_SCHEMA_VERSION = 2;
|
|
11
11
|
/** Benchmark suite presets. `custom` = user-picked cells. */
|
|
12
12
|
type BenchSuiteId = 'quick' | 'standard' | 'thorough' | 'custom';
|
|
13
13
|
/**
|
|
@@ -69,6 +69,12 @@ interface BenchModelRef {
|
|
|
69
69
|
/** Direct model URL when applicable (wllama GGUF, litert). */
|
|
70
70
|
url?: string;
|
|
71
71
|
requiresWebGPU?: boolean;
|
|
72
|
+
/**
|
|
73
|
+
* Appended to the quality-lane instruction line for every runtime of this
|
|
74
|
+
* pairing (e.g. " /no_think" to hold Qwen3 in non-thinking mode). Uniform
|
|
75
|
+
* across runtimes by construction, so fidelity comparisons stay valid.
|
|
76
|
+
*/
|
|
77
|
+
qualityPromptSuffix?: string;
|
|
72
78
|
}
|
|
73
79
|
/** One recorded stream chunk: wall-clock timestamp + delta length in chars. */
|
|
74
80
|
interface BenchChunk {
|
|
@@ -131,6 +137,8 @@ interface MemorySample {
|
|
|
131
137
|
baseline?: number;
|
|
132
138
|
postLoad?: number;
|
|
133
139
|
postRun?: number;
|
|
140
|
+
/** Bytes at the moment a cell errored (load or workload failure). */
|
|
141
|
+
atError?: number;
|
|
134
142
|
api: 'uaSpecific' | 'legacyHeap' | 'none';
|
|
135
143
|
}
|
|
136
144
|
/** Quality lane outcome attached to a cell. */
|
|
@@ -141,6 +149,13 @@ interface QualityResult {
|
|
|
141
149
|
n: number;
|
|
142
150
|
/** Per-item correctness or per-pair cosine, for auditability. */
|
|
143
151
|
details?: number[];
|
|
152
|
+
/**
|
|
153
|
+
* Raw model outputs per item (MMLU lanes; capped at 400 chars each) so the
|
|
154
|
+
* score is recomputable server-side and parse failures are auditable.
|
|
155
|
+
*/
|
|
156
|
+
outputs?: string[];
|
|
157
|
+
/** Fraction of items whose answer was parseable (MMLU lanes). */
|
|
158
|
+
parseRate?: number;
|
|
144
159
|
}
|
|
145
160
|
type BenchCellStatus = 'ok' | 'invalid' | 'error' | 'skipped';
|
|
146
161
|
/** One benchmark cell: (runtime x model x workload) with its raw iterations. */
|
|
@@ -162,9 +177,11 @@ interface BenchCellResult {
|
|
|
162
177
|
quality?: QualityResult;
|
|
163
178
|
status: BenchCellStatus;
|
|
164
179
|
invalidReasons?: string[];
|
|
180
|
+
/** Error that ended the cell; `cause` carries the wrapped provider error's message when present. */
|
|
165
181
|
error?: {
|
|
166
182
|
name: string;
|
|
167
183
|
message: string;
|
|
184
|
+
cause?: string;
|
|
168
185
|
};
|
|
169
186
|
}
|
|
170
187
|
/** Trace events global to the suite run (validity accounting). */
|
|
@@ -182,6 +199,14 @@ interface BrowserInfo {
|
|
|
182
199
|
brand: string;
|
|
183
200
|
version: string;
|
|
184
201
|
}>;
|
|
202
|
+
/** Rendering engine, derived from the UA (Blink / Gecko / WebKit). */
|
|
203
|
+
engine?: 'Blink' | 'Gecko' | 'WebKit' | 'unknown';
|
|
204
|
+
/** `navigator.vendor` (e.g. "Google Inc.", "Apple Computer, Inc."). */
|
|
205
|
+
vendor?: string;
|
|
206
|
+
/** `navigator.webdriver` — true under browser automation. */
|
|
207
|
+
webdriver?: boolean;
|
|
208
|
+
/** `navigator.pdfViewerEnabled`, a cheap headless/kiosk signal. */
|
|
209
|
+
pdfViewerEnabled?: boolean;
|
|
185
210
|
}
|
|
186
211
|
/** OS identification. Version is 'unknown-frozen' on engines with frozen UAs. */
|
|
187
212
|
interface OSInfo {
|
|
@@ -189,7 +214,30 @@ interface OSInfo {
|
|
|
189
214
|
version: string;
|
|
190
215
|
architecture?: string;
|
|
191
216
|
bitness?: string;
|
|
217
|
+
/** Device model from UA-CH (Android only; empty elsewhere by spec). */
|
|
192
218
|
model?: string;
|
|
219
|
+
/** Whether the OS is running in a WoW64-style emulation layer (UA-CH `wow64`). */
|
|
220
|
+
wow64?: boolean;
|
|
221
|
+
/** `navigator.platform` (legacy, frozen but still informative: "MacIntel", "Win32", "iPhone"). */
|
|
222
|
+
navigatorPlatform?: string;
|
|
223
|
+
}
|
|
224
|
+
/** Form-factor classification, derived from UA-CH form factors, the UA, and touch. */
|
|
225
|
+
type DeviceType = 'phone' | 'tablet' | 'desktop' | 'xr' | 'tv' | 'unknown';
|
|
226
|
+
/** Device / form-factor signals. */
|
|
227
|
+
interface DeviceInfo {
|
|
228
|
+
type: DeviceType;
|
|
229
|
+
/** UA-CH `mobile` bit (Chromium) or a UA-derived guess elsewhere. */
|
|
230
|
+
mobile: boolean;
|
|
231
|
+
/** UA-CH `formFactors` (Chromium 125+): Desktop / Mobile / Tablet / XR / EInk / Watch / Automotive. */
|
|
232
|
+
formFactors?: string[];
|
|
233
|
+
/** `navigator.maxTouchPoints`. */
|
|
234
|
+
maxTouchPoints: number;
|
|
235
|
+
/** `(pointer: coarse)` media query — primary input is a touch surface. */
|
|
236
|
+
pointerCoarse?: boolean;
|
|
237
|
+
/** `(hover: none)` media query — no hover-capable primary input. */
|
|
238
|
+
hoverNone?: boolean;
|
|
239
|
+
/** Standalone / fullscreen display mode (installed PWA or kiosk). */
|
|
240
|
+
displayMode?: string;
|
|
193
241
|
}
|
|
194
242
|
/** WebGPU adapter identity + selected limits (all fields may be empty strings). */
|
|
195
243
|
interface GPUInfo {
|
|
@@ -198,11 +246,155 @@ interface GPUInfo {
|
|
|
198
246
|
architecture?: string;
|
|
199
247
|
device?: string;
|
|
200
248
|
description?: string;
|
|
249
|
+
/** Adapter-reported subgroup sizes (Chromium 130+ `info.subgroupMinSize/MaxSize`). */
|
|
250
|
+
subgroupMinSize?: number;
|
|
251
|
+
subgroupMaxSize?: number;
|
|
201
252
|
isFallbackAdapter?: boolean;
|
|
202
253
|
features?: string[];
|
|
203
254
|
limits?: Record<string, number>;
|
|
255
|
+
/** `navigator.gpu.getPreferredCanvasFormat()`. */
|
|
256
|
+
preferredCanvasFormat?: string;
|
|
257
|
+
/** WGSL language features the implementation reports (`navigator.gpu.wgslLanguageFeatures`). */
|
|
258
|
+
wgslLanguageFeatures?: string[];
|
|
259
|
+
}
|
|
260
|
+
/** WebGL identity + capacity signals (a second, older GPU identity channel). */
|
|
261
|
+
interface WebGLInfo {
|
|
262
|
+
/** Best context available: 'webgl2', 'webgl', or null when neither creates. */
|
|
263
|
+
contextKind: 'webgl2' | 'webgl' | null;
|
|
264
|
+
/** UNMASKED_VENDOR_WEBGL when the debug extension exists, else VENDOR. */
|
|
265
|
+
vendor?: string;
|
|
266
|
+
/** UNMASKED_RENDERER_WEBGL when the debug extension exists, else RENDERER. */
|
|
267
|
+
renderer?: string;
|
|
268
|
+
version?: string;
|
|
269
|
+
shadingLanguageVersion?: string;
|
|
270
|
+
maxTextureSize?: number;
|
|
271
|
+
maxRenderbufferSize?: number;
|
|
272
|
+
maxVertexUniformVectors?: number;
|
|
273
|
+
maxFragmentUniformVectors?: number;
|
|
274
|
+
/** Number of extensions exposed (identity signal without shipping the whole list). */
|
|
275
|
+
extensionCount?: number;
|
|
276
|
+
/** Whether the renderer string names a software rasterizer (SwiftShader, llvmpipe, ...). */
|
|
277
|
+
softwareRenderer?: boolean;
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* WebAssembly proposal support, each probed by validating a canonical module
|
|
281
|
+
* (the same byte sequences `wasm-feature-detect` uses). Missing keys mean the
|
|
282
|
+
* probe itself failed, not that the feature is absent.
|
|
283
|
+
*/
|
|
284
|
+
interface WasmFeatureSupport {
|
|
285
|
+
simd: boolean;
|
|
286
|
+
relaxedSimd: boolean;
|
|
287
|
+
threads: boolean;
|
|
288
|
+
bulkMemory: boolean;
|
|
289
|
+
exceptions: boolean;
|
|
290
|
+
/** Exception handling with `exnref` (the newer, standardized form). */
|
|
291
|
+
exceptionsFinal: boolean;
|
|
292
|
+
extendedConst: boolean;
|
|
293
|
+
gc: boolean;
|
|
294
|
+
memory64: boolean;
|
|
295
|
+
multiMemory: boolean;
|
|
296
|
+
multiValue: boolean;
|
|
297
|
+
mutableGlobals: boolean;
|
|
298
|
+
referenceTypes: boolean;
|
|
299
|
+
saturatedFloatToInt: boolean;
|
|
300
|
+
signExtensions: boolean;
|
|
301
|
+
tailCall: boolean;
|
|
302
|
+
typedFunctionReferences: boolean;
|
|
303
|
+
/** 128-bit wide arithmetic (`i64.add128` family). */
|
|
304
|
+
wideArithmetic: boolean;
|
|
305
|
+
/** JavaScript Promise Integration (`WebAssembly.Suspending`). */
|
|
306
|
+
jspi: boolean;
|
|
307
|
+
/** Type reflection (`WebAssembly.Function`). */
|
|
308
|
+
typeReflection: boolean;
|
|
309
|
+
/** `WebAssembly.compileStreaming` exists. */
|
|
310
|
+
streamingCompilation: boolean;
|
|
311
|
+
/** JS String Builtins (`js-string` import module), probed via the imports/builtins option. */
|
|
312
|
+
jsStringBuiltins: boolean;
|
|
313
|
+
/** Type-level `WebAssembly.Memory` growth limit reachable in this engine (pages of 64 KiB). */
|
|
314
|
+
maxMemoryPages?: number;
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Availability of the browser APIs the runtimes and the paper care about.
|
|
318
|
+
* Each entry is a plain presence check (the feature exists on this page),
|
|
319
|
+
* not a functional test. Chrome Built-in AI is reported by its
|
|
320
|
+
* `availability()` string where the API exists.
|
|
321
|
+
*/
|
|
322
|
+
interface APIAvailability {
|
|
323
|
+
webgpu: boolean;
|
|
324
|
+
webgl2: boolean;
|
|
325
|
+
webnn: boolean;
|
|
326
|
+
/** OPFS: `navigator.storage.getDirectory` exists AND resolved. */
|
|
327
|
+
opfs: boolean;
|
|
328
|
+
/** Result of `navigator.storage.persisted()` where supported. */
|
|
329
|
+
persistedStorage?: boolean;
|
|
330
|
+
indexedDB: boolean;
|
|
331
|
+
cacheApi: boolean;
|
|
332
|
+
serviceWorker: boolean;
|
|
333
|
+
webWorkers: boolean;
|
|
334
|
+
offscreenCanvas: boolean;
|
|
335
|
+
webLocks: boolean;
|
|
336
|
+
broadcastChannel: boolean;
|
|
337
|
+
wakeLock: boolean;
|
|
338
|
+
computePressure: boolean;
|
|
339
|
+
performanceMemory: boolean;
|
|
340
|
+
measureUserAgentSpecificMemory: boolean;
|
|
341
|
+
schedulerYield: boolean;
|
|
342
|
+
webCodecs: boolean;
|
|
343
|
+
audioWorklet: boolean;
|
|
344
|
+
mediaDevices: boolean;
|
|
345
|
+
webTransport: boolean;
|
|
346
|
+
/** Chrome Built-in AI (Gemini Nano) surfaces, by `availability()` verdict when reachable. */
|
|
347
|
+
promptApi?: string;
|
|
348
|
+
summarizerApi?: string;
|
|
349
|
+
translatorApi?: string;
|
|
350
|
+
languageDetectorApi?: string;
|
|
204
351
|
}
|
|
205
|
-
/**
|
|
352
|
+
/** Network Information API (Chromium + Android) snapshot at capture time. */
|
|
353
|
+
interface NetworkInfo {
|
|
354
|
+
supported: boolean;
|
|
355
|
+
effectiveType?: string;
|
|
356
|
+
/** Connection type (wifi / cellular / ethernet / ...) where the UA exposes it. */
|
|
357
|
+
type?: string;
|
|
358
|
+
downlinkMbps?: number;
|
|
359
|
+
rttMs?: number;
|
|
360
|
+
saveData?: boolean;
|
|
361
|
+
online?: boolean;
|
|
362
|
+
}
|
|
363
|
+
/** Display / viewport snapshot. */
|
|
364
|
+
interface DisplayInfo {
|
|
365
|
+
width: number;
|
|
366
|
+
height: number;
|
|
367
|
+
availWidth?: number;
|
|
368
|
+
availHeight?: number;
|
|
369
|
+
dpr: number;
|
|
370
|
+
colorDepth?: number;
|
|
371
|
+
orientation?: string;
|
|
372
|
+
viewportWidth?: number;
|
|
373
|
+
viewportHeight?: number;
|
|
374
|
+
/** `(dynamic-range: high)` media query. */
|
|
375
|
+
hdr?: boolean;
|
|
376
|
+
/** `(color-gamut: p3)` media query. */
|
|
377
|
+
wideGamut?: boolean;
|
|
378
|
+
/** `screen.isExtended` (Window Management API) — more than one display attached. */
|
|
379
|
+
isExtended?: boolean;
|
|
380
|
+
/** Reduced-motion / forced-colors preferences, cheap OS-level signals. */
|
|
381
|
+
prefersReducedMotion?: boolean;
|
|
382
|
+
prefersColorScheme?: 'light' | 'dark' | 'no-preference';
|
|
383
|
+
}
|
|
384
|
+
/** Locale / clock signals. */
|
|
385
|
+
interface LocaleInfo {
|
|
386
|
+
timeZone?: string;
|
|
387
|
+
/** Minutes offset from UTC at capture time (`Date#getTimezoneOffset`). */
|
|
388
|
+
timeZoneOffsetMinutes?: number;
|
|
389
|
+
locale?: string;
|
|
390
|
+
/** `Intl.DateTimeFormat().resolvedOptions().calendar`. */
|
|
391
|
+
calendar?: string;
|
|
392
|
+
}
|
|
393
|
+
/**
|
|
394
|
+
* Full environment capture for a run. Every field beyond the first block is
|
|
395
|
+
* additive and best-effort: a probe that fails records nothing for its key and
|
|
396
|
+
* never affects the others. Clamped or capped fields are labeled as such.
|
|
397
|
+
*/
|
|
206
398
|
interface EnvironmentCapture {
|
|
207
399
|
capturedAt: string;
|
|
208
400
|
browser: BrowserInfo;
|
|
@@ -214,23 +406,46 @@ interface EnvironmentCapture {
|
|
|
214
406
|
/** navigator.deviceMemory (GB) — Chromium-only, capped at 8. */
|
|
215
407
|
deviceMemoryGB: number | null;
|
|
216
408
|
deviceMemoryCapped: boolean;
|
|
409
|
+
/** `performance.memory.jsHeapSizeLimit` (Chromium) — the V8 heap ceiling for this tab. */
|
|
410
|
+
jsHeapSizeLimitBytes?: number;
|
|
411
|
+
/** `performance.memory.usedJSHeapSize` at capture (the idle baseline). */
|
|
412
|
+
jsHeapUsedBytes?: number;
|
|
217
413
|
};
|
|
218
414
|
gpu: GPUInfo;
|
|
219
415
|
/** WebGL renderer string, a secondary GPU identity signal. */
|
|
220
416
|
webglRenderer: string | null;
|
|
417
|
+
/** Detailed WebGL identity + capacity (superset of `webglRenderer`). */
|
|
418
|
+
webgl?: WebGLInfo;
|
|
419
|
+
/**
|
|
420
|
+
* GPU model parsed from the WebGL renderer string (ANGLE unwrapped),
|
|
421
|
+
* e.g. "Apple M4", "NVIDIA GeForce RTX 4070", "Mali-G78 MP20". Absent when
|
|
422
|
+
* no WebGL context could be created.
|
|
423
|
+
*/
|
|
424
|
+
gpuModel?: string;
|
|
221
425
|
flags: {
|
|
222
426
|
crossOriginIsolated: boolean;
|
|
223
427
|
sharedArrayBuffer: boolean;
|
|
224
428
|
wasmSimd: boolean;
|
|
429
|
+
/** `window.isSecureContext`. */
|
|
430
|
+
secureContext?: boolean;
|
|
431
|
+
/** Full WebAssembly proposal matrix (superset of `wasmSimd`). */
|
|
432
|
+
wasm?: WasmFeatureSupport;
|
|
225
433
|
};
|
|
434
|
+
/** Presence checks for the APIs the runtimes depend on. */
|
|
435
|
+
apis?: APIAvailability;
|
|
436
|
+
device?: DeviceInfo;
|
|
226
437
|
storage: {
|
|
227
438
|
quotaBytes?: number;
|
|
228
439
|
usageBytes?: number;
|
|
440
|
+
usageDetails?: Record<string, number>;
|
|
229
441
|
} | null;
|
|
230
442
|
power: {
|
|
231
443
|
batterySupported: boolean;
|
|
232
444
|
charging?: boolean;
|
|
233
445
|
level?: number;
|
|
446
|
+
/** Seconds until full / empty (Infinity serialized as absent). */
|
|
447
|
+
chargingTimeSec?: number;
|
|
448
|
+
dischargingTimeSec?: number;
|
|
234
449
|
};
|
|
235
450
|
pressure: {
|
|
236
451
|
supported: boolean;
|
|
@@ -243,7 +458,17 @@ interface EnvironmentCapture {
|
|
|
243
458
|
height: number;
|
|
244
459
|
dpr: number;
|
|
245
460
|
} | null;
|
|
461
|
+
/** Detailed display snapshot (superset of `screen`). */
|
|
462
|
+
display?: DisplayInfo;
|
|
463
|
+
network?: NetworkInfo;
|
|
464
|
+
locale?: LocaleInfo;
|
|
246
465
|
languages?: string[];
|
|
466
|
+
/** Raw `navigator.userAgent` — kept verbatim so future parsers can re-derive fields. */
|
|
467
|
+
userAgent?: string;
|
|
468
|
+
/** Page origin the run executed on (distinguishes production from local/staging). */
|
|
469
|
+
pageOrigin?: string;
|
|
470
|
+
/** `document.visibilityState` at capture; a hidden tab is throttled. */
|
|
471
|
+
visibilityState?: string;
|
|
247
472
|
/** Free-text device self-report — displayed as "user-reported", never trusted. */
|
|
248
473
|
userReportedDevice?: string;
|
|
249
474
|
}
|
|
@@ -281,6 +506,16 @@ interface CellSummary {
|
|
|
281
506
|
decodeChunksPerSec?: MetricSummary;
|
|
282
507
|
prefillTokPerSecApprox?: MetricSummary;
|
|
283
508
|
generatedChars?: MetricSummary;
|
|
509
|
+
/** Request wall time (startT → endT), all LLM lanes. */
|
|
510
|
+
totalMs?: MetricSummary;
|
|
511
|
+
/** End-to-end chars/s over the whole request (prefill + decode conflated). */
|
|
512
|
+
overallCharsPerSec?: MetricSummary;
|
|
513
|
+
/**
|
|
514
|
+
* False when the chunk trace is not genuinely incremental (single chunk, or
|
|
515
|
+
* the visible stream spans <20% of the request) — TTFT and decode metrics
|
|
516
|
+
* are then omitted because they would be timing artifacts, not measurements.
|
|
517
|
+
*/
|
|
518
|
+
streamIncremental?: boolean;
|
|
284
519
|
/** Embedding lanes. */
|
|
285
520
|
singleLatencyMs?: MetricSummary;
|
|
286
521
|
batchTextsPerSec?: MetricSummary;
|
|
@@ -288,19 +523,32 @@ interface CellSummary {
|
|
|
288
523
|
loadMs?: number;
|
|
289
524
|
loadCached?: boolean;
|
|
290
525
|
qualityScore?: number;
|
|
526
|
+
/** Fraction of MMLU items whose answer parsed; a low value marks a format failure, not a fidelity one. */
|
|
527
|
+
qualityParseRate?: number;
|
|
291
528
|
highVariance: boolean;
|
|
292
529
|
}
|
|
530
|
+
/** Identity of the software that produced a run. */
|
|
531
|
+
interface HarnessInfo {
|
|
532
|
+
name: string;
|
|
533
|
+
version: string;
|
|
534
|
+
appVersion?: string;
|
|
535
|
+
/**
|
|
536
|
+
* Versions of the runtime packages bundled into the harness at build time
|
|
537
|
+
* (e.g. `{ "@huggingface/transformers": "4.2.0", "@wllama/wllama": "3.5.1" }`),
|
|
538
|
+
* keyed by npm package name. Per-cell `runtimeVersion` names the same value
|
|
539
|
+
* for the runtime that produced that cell.
|
|
540
|
+
*/
|
|
541
|
+
runtimeVersions?: Record<string, string>;
|
|
542
|
+
/** Git commit of the harness build where the host exposes it. */
|
|
543
|
+
commit?: string;
|
|
544
|
+
}
|
|
293
545
|
/** The unit of submission: one full suite run on one device. */
|
|
294
546
|
interface BenchRunResult {
|
|
295
547
|
protocol: typeof BENCH_PROTOCOL_VERSION;
|
|
296
548
|
schemaVersion: typeof BENCH_SCHEMA_VERSION;
|
|
297
549
|
runId: string;
|
|
298
550
|
createdAt: string;
|
|
299
|
-
harness:
|
|
300
|
-
name: string;
|
|
301
|
-
version: string;
|
|
302
|
-
appVersion?: string;
|
|
303
|
-
};
|
|
551
|
+
harness: HarnessInfo;
|
|
304
552
|
suite: BenchSuiteId;
|
|
305
553
|
environment: EnvironmentCapture;
|
|
306
554
|
fingerprint: FingerprintResult | null;
|
|
@@ -340,6 +588,14 @@ interface ValidationReport {
|
|
|
340
588
|
|
|
341
589
|
/** Fixed generation budget for timed lanes (tg128, MLPerf-Client-sized). */
|
|
342
590
|
declare const GENERATION_BUDGET = 128;
|
|
591
|
+
/**
|
|
592
|
+
* Minimum generated characters for a timed iteration to count as a decode
|
|
593
|
+
* measurement (part of the versioned protocol). An instruct model that emits
|
|
594
|
+
* EOS after a handful of characters - typically an untemplated prompt or a
|
|
595
|
+
* tokenizer mismatch - produces no decode phase to time; such iterations are
|
|
596
|
+
* gated `degenerate-output` and the cell is marked invalid rather than scored.
|
|
597
|
+
*/
|
|
598
|
+
declare const MIN_GENERATED_CHARS = 16;
|
|
343
599
|
/** LLM performance workloads. */
|
|
344
600
|
declare const LLM_WORKLOADS: readonly LLMWorkloadSpec[];
|
|
345
601
|
/** Embedding performance workloads. */
|
|
@@ -348,6 +604,25 @@ declare const EMBED_WORKLOADS: readonly EmbedWorkloadSpec[];
|
|
|
348
604
|
declare const QUALITY_WORKLOADS: readonly QualityWorkloadSpec[];
|
|
349
605
|
/** All workloads indexed by id. */
|
|
350
606
|
declare const WORKLOADS_BY_ID: ReadonlyMap<string, LLMWorkloadSpec | EmbedWorkloadSpec | QualityWorkloadSpec>;
|
|
607
|
+
/**
|
|
608
|
+
* Fixed runtime execution order (part of the versioned protocol). This makes
|
|
609
|
+
* the order deterministic so runtime interleaving is not a confounder across
|
|
610
|
+
* runs; it is a reproducibility measure, not a correctness fix. (The
|
|
611
|
+
* Transformers.js ORT-web lanes fail during session creation regardless of
|
|
612
|
+
* where they run in the order - a separate open runtime/adapter issue.) The
|
|
613
|
+
* order runs the WASM-arena runtimes first and the multi-GB-heap runtimes last.
|
|
614
|
+
* Within a runtime, catalog order is preserved.
|
|
615
|
+
*/
|
|
616
|
+
declare const RUNTIME_EXECUTION_ORDER: readonly BenchRuntimeId[];
|
|
617
|
+
/**
|
|
618
|
+
* Sort planned cells into the protocol execution order (stable within a
|
|
619
|
+
* runtime). The runner applies this itself; exported for hosts and tests.
|
|
620
|
+
*/
|
|
621
|
+
declare function orderCells<T extends {
|
|
622
|
+
model: {
|
|
623
|
+
runtimeId: BenchRuntimeId;
|
|
624
|
+
};
|
|
625
|
+
}>(cells: readonly T[]): T[];
|
|
351
626
|
/** Run policy for a suite (part of the versioned protocol). */
|
|
352
627
|
interface RunPolicy {
|
|
353
628
|
/** Untimed warmup generations per cell (absorbs shader compile/JIT). */
|
|
@@ -508,11 +783,7 @@ interface RunSuiteOptions {
|
|
|
508
783
|
policy: RunPolicy;
|
|
509
784
|
llmAdapters: ReadonlyMap<string, LLMRuntimeAdapter>;
|
|
510
785
|
embedAdapters: ReadonlyMap<string, EmbeddingRuntimeAdapter>;
|
|
511
|
-
harness:
|
|
512
|
-
name: string;
|
|
513
|
-
version: string;
|
|
514
|
-
appVersion?: string;
|
|
515
|
-
};
|
|
786
|
+
harness: HarnessInfo;
|
|
516
787
|
hooks?: RunnerHooks;
|
|
517
788
|
abortSignal?: AbortSignal;
|
|
518
789
|
/** Skip the fingerprint microbenchmark (tests only; submissions require it). */
|
|
@@ -539,6 +810,11 @@ declare function runBenchmarkSuite(options: RunSuiteOptions): Promise<BenchRunRe
|
|
|
539
810
|
* provenance: UA Client Hints on Chromium; UA parsing elsewhere with the OS
|
|
540
811
|
* version marked 'unknown-frozen' (UA strings are frozen by design on Gecko
|
|
541
812
|
* and WebKit). Clamped fields (cores, deviceMemory) are labeled clamped.
|
|
813
|
+
*
|
|
814
|
+
* Everything a browser will disclose is recorded, whether or not the current
|
|
815
|
+
* analysis uses it: WebGPU + WebGL identity, the WebAssembly proposal matrix,
|
|
816
|
+
* API availability, form factor, display, network, locale, power. Every probe
|
|
817
|
+
* is individually guarded; a failing probe records nothing for its key.
|
|
542
818
|
*/
|
|
543
819
|
|
|
544
820
|
/**
|
|
@@ -553,6 +829,64 @@ declare function runBenchmarkSuite(options: RunSuiteOptions): Promise<BenchRunRe
|
|
|
553
829
|
declare function captureEnvironment(options?: {
|
|
554
830
|
userReportedDevice?: string;
|
|
555
831
|
}): Promise<EnvironmentCapture>;
|
|
832
|
+
/**
|
|
833
|
+
* UA-string fallback for browsers without UA Client Hints (every WebKit
|
|
834
|
+
* browser). Conservative: browser name + version token, platform, and the OS
|
|
835
|
+
* version only where the UA genuinely carries one.
|
|
836
|
+
*
|
|
837
|
+
* @example
|
|
838
|
+
* parseUserAgent('... CriOS/145.0.7632.72 Mobile/15E148 Safari/604.1').browser.name; // 'Chrome iOS'
|
|
839
|
+
*/
|
|
840
|
+
declare function parseUserAgent(ua: string): {
|
|
841
|
+
browser: BrowserInfo;
|
|
842
|
+
os: OSInfo;
|
|
843
|
+
};
|
|
844
|
+
/**
|
|
845
|
+
* Rendering engine from the UA. Every iOS browser is WebKit regardless of its
|
|
846
|
+
* brand (App Store policy), so the iOS check comes first.
|
|
847
|
+
*
|
|
848
|
+
* @example
|
|
849
|
+
* detectEngine('... CriOS/145.0 ...'); // 'WebKit'
|
|
850
|
+
*/
|
|
851
|
+
declare function detectEngine(ua: string): BrowserInfo['engine'];
|
|
852
|
+
/** Inputs to the form-factor derivation, each optional. */
|
|
853
|
+
interface DeviceTypeSignals {
|
|
854
|
+
ua: string;
|
|
855
|
+
maxTouchPoints: number;
|
|
856
|
+
/** UA-CH `formFactors` high-entropy hint (Chromium 125+). */
|
|
857
|
+
formFactors?: string[];
|
|
858
|
+
/** UA-CH `mobile` bit. */
|
|
859
|
+
mobile?: boolean;
|
|
860
|
+
}
|
|
861
|
+
/**
|
|
862
|
+
* Derive a form factor. UA-CH form factors win when present; otherwise the UA
|
|
863
|
+
* decides, with `maxTouchPoints` unmasking an iPad that reports itself as a
|
|
864
|
+
* Mac (iPadOS 13+ default) and separating Android tablets (no `Mobile` token)
|
|
865
|
+
* from phones.
|
|
866
|
+
*
|
|
867
|
+
* @example
|
|
868
|
+
* deriveDeviceType({ ua: navigator.userAgent, maxTouchPoints: navigator.maxTouchPoints });
|
|
869
|
+
*/
|
|
870
|
+
declare function deriveDeviceType(signals: DeviceTypeSignals): DeviceType;
|
|
871
|
+
/**
|
|
872
|
+
* GPU model from a WebGL renderer string. ANGLE wraps the model as
|
|
873
|
+
* `ANGLE (<vendor>, <model>[ (0x...)] <backend...>, <api>)`; Metal adds a
|
|
874
|
+
* `ANGLE Metal Renderer: ` prefix. Native strings are returned as-is.
|
|
875
|
+
*
|
|
876
|
+
* @example
|
|
877
|
+
* parseGpuModel('ANGLE (Apple, ANGLE Metal Renderer: Apple M4, Unspecified Version)'); // 'Apple M4'
|
|
878
|
+
*/
|
|
879
|
+
declare function parseGpuModel(renderer: string | null | undefined): string | undefined;
|
|
880
|
+
/**
|
|
881
|
+
* WebAssembly proposal support, probed the way `wasm-feature-detect` does:
|
|
882
|
+
* validate or compile the smallest module that uses each feature. The byte
|
|
883
|
+
* sequences are those of wasm-feature-detect 1.9.0, inlined so the harness
|
|
884
|
+
* keeps its zero-dependency contract.
|
|
885
|
+
*
|
|
886
|
+
* @example
|
|
887
|
+
* const wasm = await detectWasmFeatures(); // { simd: true, threads: true, ... }
|
|
888
|
+
*/
|
|
889
|
+
declare function detectWasmFeatures(): Promise<WasmFeatureSupport>;
|
|
556
890
|
|
|
557
891
|
/**
|
|
558
892
|
* Memory sampling at protocol points (baseline / post-load / post-run).
|
|
@@ -704,19 +1038,40 @@ declare function spearman(a: readonly number[], b: readonly number[]): number;
|
|
|
704
1038
|
*/
|
|
705
1039
|
|
|
706
1040
|
/** Version of the plausibility rule set (recorded alongside moderation). */
|
|
707
|
-
declare const PLAUSIBILITY_RULES_VERSION =
|
|
1041
|
+
declare const PLAUSIBILITY_RULES_VERSION = 2;
|
|
1042
|
+
/**
|
|
1043
|
+
* Minimum fraction of the request that the visible chunk stream must span for
|
|
1044
|
+
* the trace to count as incremental. LiteRT-LM's web surface delivers every
|
|
1045
|
+
* chunk in a terminal burst (~0.8ms of a 30s request), so TTFT/decode derived
|
|
1046
|
+
* from such a trace are timing artifacts; a real token stream spans most of
|
|
1047
|
+
* the request by construction.
|
|
1048
|
+
*/
|
|
1049
|
+
declare const STREAM_COHERENCE_MIN_SPAN_RATIO = 0.2;
|
|
708
1050
|
/**
|
|
709
1051
|
* Structural validation of a submitted result. Returns human-readable errors
|
|
710
1052
|
* (empty array = shape ok). Deliberately hand-rolled: this package is
|
|
711
1053
|
* zero-dependency and the checks double as executable schema documentation.
|
|
712
1054
|
*/
|
|
713
1055
|
declare function validateRunShape(value: unknown): string[];
|
|
1056
|
+
/**
|
|
1057
|
+
* True when an iteration's chunk trace is genuinely incremental: at least two
|
|
1058
|
+
* chunks, and the visible stream spans at least
|
|
1059
|
+
* `STREAM_COHERENCE_MIN_SPAN_RATIO` of the request wall time. Anything else
|
|
1060
|
+
* (a doGenerate fallback's single chunk, or a runtime that computes the whole
|
|
1061
|
+
* generation and flushes it in a terminal burst) carries no usable TTFT or
|
|
1062
|
+
* decode timing.
|
|
1063
|
+
*/
|
|
1064
|
+
declare function isIncrementalStream(it: LLMIteration): boolean;
|
|
714
1065
|
/**
|
|
715
1066
|
* Recompute a cell's summary purely from its raw iteration traces.
|
|
716
1067
|
* This function IS the metric definition:
|
|
717
1068
|
* - TTFT = first non-empty chunk timestamp − startT
|
|
718
1069
|
* - decode rate = (chars after first chunk) / (endT_lastChunk − t_firstChunk)
|
|
719
1070
|
* - prefill tok/s ≈ approxPromptTokens / TTFT (approximate by construction)
|
|
1071
|
+
* - overall rate = total chars / (endT − startT), always derivable
|
|
1072
|
+
* TTFT/decode/prefill are derived only when EVERY iteration passes the
|
|
1073
|
+
* stream-coherence test (`streamIncremental`); overall rate and total wall
|
|
1074
|
+
* time are reported for all LLM lanes.
|
|
720
1075
|
*/
|
|
721
1076
|
declare function summarizeCell(cell: BenchCellResult, highVarianceCv?: number, approxPromptTokens?: number): CellSummary;
|
|
722
1077
|
/** Recompute all cell summaries for a run (workload prompt sizes looked up). */
|
|
@@ -784,11 +1139,15 @@ interface LeaderboardRow {
|
|
|
784
1139
|
/** Median-of-medians metrics (only those applicable to the workload). */
|
|
785
1140
|
ttftMs?: number;
|
|
786
1141
|
decodeCharsPerSec?: number;
|
|
1142
|
+
/** End-to-end chars/s (prefill + decode); the only rate for lanes whose stream is not incremental. */
|
|
1143
|
+
overallCharsPerSec?: number;
|
|
787
1144
|
singleLatencyMs?: number;
|
|
788
1145
|
batchTextsPerSec?: number;
|
|
789
1146
|
loadColdMs?: number;
|
|
790
1147
|
loadWarmMs?: number;
|
|
791
1148
|
qualityScore?: number;
|
|
1149
|
+
/** Median MMLU parse rate; below 1 the quality score is format-limited. */
|
|
1150
|
+
qualityParseRate?: number;
|
|
792
1151
|
resolvedBackends: string[];
|
|
793
1152
|
browsers: string[];
|
|
794
1153
|
/** True when any contributing submission had a high-variance metric. */
|
|
@@ -843,26 +1202,44 @@ declare const TINY_MMLU: readonly MMLUItem[];
|
|
|
843
1202
|
* model's training data. Always run at temperature 0, outside timed regions.
|
|
844
1203
|
*/
|
|
845
1204
|
|
|
1205
|
+
/**
|
|
1206
|
+
* Generation budget for MMLU items (part of the versioned protocol). Large
|
|
1207
|
+
* enough to absorb an empty Qwen3-style `<think></think>` block plus a
|
|
1208
|
+
* verbose "The answer is B." — the v1 budget of 8 truncated before any
|
|
1209
|
+
* parseable letter on thinking-mode builds, scoring fidelity as 0.
|
|
1210
|
+
*/
|
|
1211
|
+
declare const MMLU_MAX_TOKENS = 48;
|
|
1212
|
+
/** Cap on each stored raw output (auditability without payload bloat). */
|
|
1213
|
+
declare const MMLU_OUTPUT_CAP = 400;
|
|
846
1214
|
/** Fixed MCQ prompt template (part of the versioned protocol). */
|
|
847
|
-
declare function formatMMLUPrompt(item: (typeof TINY_MMLU)[number]): string;
|
|
1215
|
+
declare function formatMMLUPrompt(item: (typeof TINY_MMLU)[number], promptSuffix?: string): string;
|
|
848
1216
|
/**
|
|
849
|
-
* Parse the answer letter from a model response.
|
|
850
|
-
*
|
|
1217
|
+
* Parse the answer letter from a model response. Reasoning blocks are
|
|
1218
|
+
* stripped first; markdown emphasis around the letter is ignored. Accepts
|
|
1219
|
+
* "B", "B.", "(B)", "**B**", "Answer: B", "Option C", "choice (B)", or a
|
|
1220
|
+
* response beginning with the exact choice text. Letters are matched
|
|
1221
|
+
* case-sensitively after a keyword so the article "a" ("the answer is a
|
|
1222
|
+
* bit unclear") is never read as answer A; a lowercase letter counts only
|
|
1223
|
+
* when it is the whole reply or leads it as "b." / "b)".
|
|
851
1224
|
*
|
|
852
1225
|
* @returns 0-3, or null when no unambiguous answer is present.
|
|
853
1226
|
*/
|
|
854
1227
|
declare function parseMMLUAnswer(response: string, choices: readonly string[]): number | null;
|
|
855
1228
|
/**
|
|
856
1229
|
* Run the tinyMMLU fidelity task on a language model (temperature 0,
|
|
857
|
-
* `
|
|
1230
|
+
* `MMLU_MAX_TOKENS` budget, greedy answer parsing). Unparseable answers count
|
|
1231
|
+
* as wrong; raw outputs and the parse rate are recorded so the score is
|
|
1232
|
+
* auditable and recomputable server-side.
|
|
858
1233
|
*
|
|
859
1234
|
* @param model - Any structurally-compatible LanguageModel.
|
|
860
|
-
* @param items - Number of items from the 100-item set (25 or 100
|
|
861
|
-
* @returns Accuracy in [0,1] with per-item correctness details.
|
|
1235
|
+
* @param items - Number of items from the 100-item set (25 or 100).
|
|
1236
|
+
* @returns Accuracy in [0,1] with per-item correctness details and outputs.
|
|
862
1237
|
*/
|
|
863
1238
|
declare function runMMLUFidelity(model: BenchLanguageModel, items: number, options?: {
|
|
864
1239
|
abortSignal?: AbortSignal;
|
|
865
1240
|
onProgress?: (done: number, total: number) => void;
|
|
1241
|
+
/** Appended to the instruction line of every item (from the model catalog). */
|
|
1242
|
+
promptSuffix?: string;
|
|
866
1243
|
}): Promise<QualityResult>;
|
|
867
1244
|
/**
|
|
868
1245
|
* Run the STS-B embedding-quality task: Spearman correlation of cosine
|
|
@@ -898,4 +1275,4 @@ interface STSPair {
|
|
|
898
1275
|
/** 100-pair STS-B test subset (order preserved from the source dataset). */
|
|
899
1276
|
declare const STSB_SUBSET: readonly STSPair[];
|
|
900
1277
|
|
|
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 };
|
|
1278
|
+
export { type APIAvailability, 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, type DeviceInfo, type DeviceType, type DeviceTypeSignals, type DisplayInfo, EMBED_WORKLOADS, type EmbedIteration, type EmbedWorkloadSpec, type EmbeddingRuntimeAdapter, type EnvironmentCapture, type FingerprintResult, GENERATION_BUDGET, type GPUInfo, HEADLINE_MIN_SUBMISSIONS, type HarnessInfo, type LLMIteration, type LLMRuntimeAdapter, type LLMWorkloadSpec, LLM_WORKLOADS, type LeaderboardRow, type LoadRecord, type LoadedEmbedder, type LoadedLLM, type LocaleInfo, MIN_GENERATED_CHARS, type MMLUItem, MMLU_MAX_TOKENS, MMLU_OUTPUT_CAP, type MemorySample, type MetricSummary, type NetworkInfo, type OSInfo, PLAUSIBILITY_RULES_VERSION, type PlannedCell, type PlausibilityFlag, type ProviderUsage, QUALITY_WORKLOADS, type QualityResult, type QualityWorkloadSpec, RUNTIME_EXECUTION_ORDER, RUN_POLICIES, type RunPolicy, type RunSuiteOptions, type RunnerHooks, STREAM_COHERENCE_MIN_SPAN_RATIO, STSB_SUBSET, type STSPair, TINY_MMLU, type TraceEvent, TraceRecorder, USAGE_FIDELITY, type ValidationReport, WORKLOADS_BY_ID, type WasmFeatureSupport, type WebGLInfo, aggregateRuns, canonicalJson, captureEnvironment, checkPlausibility, computeRunDigest, deriveDeviceType, detectEngine, detectWasmFeatures, deviceClassOf, formatMMLUPrompt, geomean, hrNow, inferTimerResolutionUs, isIncrementalStream, mean, median, memoryApiAvailable, orderCells, parseGpuModel, parseMMLUAnswer, parseUserAgent, quantile, rowsToCSV, runBenchmarkSuite, runFingerprint, runMMLUFidelity, runSTSQuality, runsToLongCSV, sampleMemoryBytes, sha256Hex, sleep, spearman, stddev, summarize, summarizeCell, summarizeRun, validateRunShape, validateSubmission, verifyRunDigest };
|