@mlbottleneck/engine 0.4.1 → 0.5.1
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 +7 -1
- package/localmaxxing-snapshot.json +1 -1
- package/mlbottleneck-engine.d.ts +33 -0
- package/mlbottleneck-engine.mjs +280 -5
- package/mlbottleneck-engine.umd.js +280 -5
- package/package.json +1 -1
package/mlbottleneck-engine.d.ts
CHANGED
|
@@ -95,6 +95,27 @@ export interface DeviceSummary {
|
|
|
95
95
|
} | null;
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
+
export interface MeasuredRun {
|
|
99
|
+
tokensPerSecond: number;
|
|
100
|
+
origin: 'community' | 'lab';
|
|
101
|
+
stack: 'stock' | 'lab-baseline' | 'tuned';
|
|
102
|
+
model: string;
|
|
103
|
+
hardware: string;
|
|
104
|
+
deviceCount: number;
|
|
105
|
+
runtime: string;
|
|
106
|
+
quantization: string;
|
|
107
|
+
depthTokens: number;
|
|
108
|
+
/** Concurrent requests in the measured run (always equals the request's batch size). */
|
|
109
|
+
concurrency: number;
|
|
110
|
+
/** tokensPerSecond is per request; this is the combined rate across the batch. */
|
|
111
|
+
aggregateTokensPerSecond: number;
|
|
112
|
+
speculation: { method: string; tokens: number | null } | null;
|
|
113
|
+
/** Same runtime, quantization family, and device count as the request. */
|
|
114
|
+
sameSetup: boolean;
|
|
115
|
+
url: string | null;
|
|
116
|
+
note: string | null;
|
|
117
|
+
}
|
|
118
|
+
|
|
98
119
|
export interface Prediction {
|
|
99
120
|
fits: boolean;
|
|
100
121
|
strategy: { key: Strategy; label: string; reasoning: string | null; auto: boolean };
|
|
@@ -118,6 +139,13 @@ export interface Prediction {
|
|
|
118
139
|
verifiedPeers: number;
|
|
119
140
|
} | null;
|
|
120
141
|
memory: { modelSizeGB: number | null; residentWeightsGB: number | null; kvCacheGB: number | null; availableGB: number | null };
|
|
142
|
+
/** Measured runs on the same model and hardware template (null when none exist). */
|
|
143
|
+
measured: {
|
|
144
|
+
/** Closest stock measurement: a community gold run or a lab stock/baseline row. */
|
|
145
|
+
nearest: MeasuredRun | null;
|
|
146
|
+
/** Closest tuned neural.download lab result: what a tuned stack reached, never a stock reference. */
|
|
147
|
+
labTuned: MeasuredRun | null;
|
|
148
|
+
};
|
|
121
149
|
bottleneck: string | null;
|
|
122
150
|
power: { watts: number | null; tdpWatts: number | null; costPerDay: number | null; costPer1KTokens: number | null } | null;
|
|
123
151
|
devices: DeviceSummary[];
|
|
@@ -142,7 +170,12 @@ export interface HardwareListing {
|
|
|
142
170
|
|
|
143
171
|
export interface EvidenceSnapshot {
|
|
144
172
|
generatedAt?: string;
|
|
173
|
+
/** Community gold rows: calibrate the engine (peer correction, optimized target). */
|
|
145
174
|
goldCases: any[];
|
|
175
|
+
/** neural.download lab rows (stock / lab-baseline / tuned): measured references only, never calibration. */
|
|
176
|
+
labCases?: any[];
|
|
177
|
+
labSource?: string;
|
|
178
|
+
labUpdated?: string;
|
|
146
179
|
}
|
|
147
180
|
|
|
148
181
|
export interface Engine {
|
package/mlbottleneck-engine.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! ML Bottleneck engine v0.
|
|
1
|
+
/*! ML Bottleneck engine v0.5.1 | https://mlbottleneck.com | MIT */
|
|
2
2
|
// Generated by scripts/build-sdk.mjs from engine.js and sdk/api.js. Do not edit.
|
|
3
3
|
|
|
4
4
|
function createEngine(options = {}) {
|
|
@@ -23,13 +23,22 @@ function createEngine(options = {}) {
|
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
// Benchmark evidence
|
|
27
|
-
|
|
26
|
+
// Benchmark evidence. Localmaxxing gold rows calibrate the engine (peer
|
|
27
|
+
// correction, optimized target). Lab rows (data/lab-evidence.json, the
|
|
28
|
+
// author's neural.download Intel lab) never calibrate it: they are shown
|
|
29
|
+
// beside a plan as measured references — stock / lab-baseline rows can be
|
|
30
|
+
// the nearest measured run, tuned rows show what a tuned stack reached.
|
|
31
|
+
const ENGINE_EVIDENCE = { goldCases: [], labCases: [] };
|
|
28
32
|
let goldValidationCache = null;
|
|
33
|
+
let labEvidenceCache = null;
|
|
34
|
+
let labValidationCache = null;
|
|
29
35
|
|
|
30
36
|
function setEngineEvidence(snapshot) {
|
|
31
37
|
ENGINE_EVIDENCE.goldCases = Array.isArray(snapshot?.goldCases) ? snapshot.goldCases : [];
|
|
38
|
+
ENGINE_EVIDENCE.labCases = Array.isArray(snapshot?.labCases) ? snapshot.labCases : [];
|
|
32
39
|
goldValidationCache = null;
|
|
40
|
+
labEvidenceCache = null;
|
|
41
|
+
labValidationCache = null;
|
|
33
42
|
}
|
|
34
43
|
|
|
35
44
|
// Nominal storage bytes per weight for each quantization family. Real
|
|
@@ -7357,6 +7366,244 @@ function createEngine(options = {}) {
|
|
|
7357
7366
|
}
|
|
7358
7367
|
|
|
7359
7368
|
|
|
7369
|
+
// ---- Lab evidence (neural.download) ------------------------------------
|
|
7370
|
+
const LAB_EVIDENCE_ORIGIN = 'neural.download';
|
|
7371
|
+
const TENSOR_CAPABLE_RUNTIMES = ['vllm', 'sglang', 'tensorrt_llm'];
|
|
7372
|
+
|
|
7373
|
+
// One measured lab point in the shape the gold helpers understand. Depth
|
|
7374
|
+
// sweeps and speculation ladders expand into one row per point so a plan
|
|
7375
|
+
// at 32K depth finds the 32K measurement, not the 128-token one.
|
|
7376
|
+
function normalizeLabEvidenceRow(row, overrides = {}) {
|
|
7377
|
+
const preset = MODEL_PRESETS[row.presetKey];
|
|
7378
|
+
const template = DEVICE_TEMPLATES[row.hardwareTemplate];
|
|
7379
|
+
if (!preset || !template) return null;
|
|
7380
|
+
const format = getQuantFormat(row.quantization);
|
|
7381
|
+
const quantKey = format ? format.family : String(row.quantization || 'q4').toLowerCase();
|
|
7382
|
+
const promptTokens = Number.isFinite(overrides.promptTokens) ? overrides.promptTokens : (Number.isFinite(row.promptTokens) ? row.promptTokens : 128);
|
|
7383
|
+
const outputTokens = Number.isFinite(row.outputTokens) && row.outputTokens > 0 ? row.outputTokens : 128;
|
|
7384
|
+
const speculation = overrides.speculation !== undefined ? overrides.speculation : (row.speculation || null);
|
|
7385
|
+
const observedTokS = Number.isFinite(overrides.observedTokS) ? overrides.observedTokS : row.observedTokS;
|
|
7386
|
+
if (!Number.isFinite(observedTokS) || observedTokS <= 0) return null;
|
|
7387
|
+
const batchSize = Math.max(1, Number(overrides.batchSize) || 1);
|
|
7388
|
+
const deviceCount = Math.max(1, Number(row.deviceCount) || 1);
|
|
7389
|
+
const runtime = FRAMEWORK_PROFILES[row.runtimeKey];
|
|
7390
|
+
const strategy = row.strategy || (deviceCount > 1 ? (TENSOR_CAPABLE_RUNTIMES.includes(row.runtimeKey) ? 'tensor' : 'pipeline') : 'pipeline');
|
|
7391
|
+
return {
|
|
7392
|
+
id: overrides.id || row.id,
|
|
7393
|
+
origin: LAB_EVIDENCE_ORIGIN,
|
|
7394
|
+
isLab: true,
|
|
7395
|
+
stack: row.stack || 'stock',
|
|
7396
|
+
source: row.url || '',
|
|
7397
|
+
url: row.url || '',
|
|
7398
|
+
note: row.note || '',
|
|
7399
|
+
model: preset.label || row.presetKey,
|
|
7400
|
+
hfId: preset.hfId || '',
|
|
7401
|
+
presetKey: row.presetKey,
|
|
7402
|
+
hardware: template.name || row.hardwareTemplate,
|
|
7403
|
+
hardwareTemplate: row.hardwareTemplate,
|
|
7404
|
+
deviceCount,
|
|
7405
|
+
runtimeKey: row.runtimeKey,
|
|
7406
|
+
engine: runtime ? runtime.label : row.runtimeKey,
|
|
7407
|
+
quantization: row.quantization || quantKey,
|
|
7408
|
+
quantKey,
|
|
7409
|
+
strategy,
|
|
7410
|
+
speculation,
|
|
7411
|
+
promptTokens,
|
|
7412
|
+
outputTokens,
|
|
7413
|
+
contextLength: promptTokens + outputTokens,
|
|
7414
|
+
decodeContextTokens: promptTokens + outputTokens / 2,
|
|
7415
|
+
// Per-request decode rate (one sequence's tokens per second); the
|
|
7416
|
+
// aggregate across a batched run is kept separately.
|
|
7417
|
+
observedTokS,
|
|
7418
|
+
batchSize,
|
|
7419
|
+
aggregateTokS: Number.isFinite(overrides.aggregateTokS) ? overrides.aggregateTokS : observedTokS * batchSize,
|
|
7420
|
+
prefillTokS: Number.isFinite(overrides.prefillTokS) ? overrides.prefillTokS : (Number.isFinite(row.prefillTokS) ? row.prefillTokS : null),
|
|
7421
|
+
reproducibility: 1
|
|
7422
|
+
};
|
|
7423
|
+
}
|
|
7424
|
+
|
|
7425
|
+
function getLabEvidenceRows() {
|
|
7426
|
+
if (labEvidenceCache) return labEvidenceCache;
|
|
7427
|
+
const rows = [];
|
|
7428
|
+
for (const row of ENGINE_EVIDENCE.labCases || []) {
|
|
7429
|
+
if (!row || typeof row !== 'object' || !row.id) continue;
|
|
7430
|
+
const base = normalizeLabEvidenceRow(row);
|
|
7431
|
+
if (base) rows.push(base);
|
|
7432
|
+
for (const point of Array.isArray(row.depthSweep) ? row.depthSweep : []) {
|
|
7433
|
+
const swept = normalizeLabEvidenceRow(row, {
|
|
7434
|
+
id: `${row.id}@${point.promptTokens}`,
|
|
7435
|
+
promptTokens: point.promptTokens,
|
|
7436
|
+
observedTokS: point.decodeTokS,
|
|
7437
|
+
prefillTokS: point.prefillTokS
|
|
7438
|
+
});
|
|
7439
|
+
if (swept) rows.push(swept);
|
|
7440
|
+
}
|
|
7441
|
+
for (const rung of Array.isArray(row.speculationLadder) ? row.speculationLadder : []) {
|
|
7442
|
+
const stepped = normalizeLabEvidenceRow(row, {
|
|
7443
|
+
id: `${row.id}@${rung.method}${rung.tokens}`,
|
|
7444
|
+
speculation: { method: rung.method, tokens: rung.tokens },
|
|
7445
|
+
observedTokS: rung.observedTokS
|
|
7446
|
+
});
|
|
7447
|
+
if (stepped) rows.push(stepped);
|
|
7448
|
+
}
|
|
7449
|
+
// Concurrency sweeps: { users, perUserTokS, aggregateTokS } per level
|
|
7450
|
+
// (llama-batched-bench -npl / vllm bench serve --max-concurrency).
|
|
7451
|
+
for (const level of Array.isArray(row.concurrencySweep) ? row.concurrencySweep : []) {
|
|
7452
|
+
const users = Math.max(1, Number(level.users) || 1);
|
|
7453
|
+
const perUser = Number.isFinite(level.perUserTokS) ? level.perUserTokS : (Number.isFinite(level.aggregateTokS) ? level.aggregateTokS / users : NaN);
|
|
7454
|
+
const batched = normalizeLabEvidenceRow(row, {
|
|
7455
|
+
id: `${row.id}@u${users}`,
|
|
7456
|
+
batchSize: users,
|
|
7457
|
+
observedTokS: perUser,
|
|
7458
|
+
aggregateTokS: Number.isFinite(level.aggregateTokS) ? level.aggregateTokS : perUser * users
|
|
7459
|
+
});
|
|
7460
|
+
if (batched) rows.push(batched);
|
|
7461
|
+
}
|
|
7462
|
+
}
|
|
7463
|
+
labEvidenceCache = rows;
|
|
7464
|
+
return rows;
|
|
7465
|
+
}
|
|
7466
|
+
|
|
7467
|
+
// Rows that can stand in as the plan's "nearest measured" run: community
|
|
7468
|
+
// gold runs plus the lab's stock / baseline rows without speculation. A
|
|
7469
|
+
// tuned stack is not a stock reference.
|
|
7470
|
+
function getMeasuredReferenceRows() {
|
|
7471
|
+
return getGoldValidationRows().concat(getLabEvidenceRows().filter(row => row.stack !== 'tuned' && !row.speculation));
|
|
7472
|
+
}
|
|
7473
|
+
|
|
7474
|
+
function describeSameSetup(target, row) {
|
|
7475
|
+
return row.runtimeKey === target.runtimeKey && row.quantKey === target.quantKey &&
|
|
7476
|
+
(row.deviceCount || 1) === (target.deviceCount || 1);
|
|
7477
|
+
}
|
|
7478
|
+
|
|
7479
|
+
// A reference run must serve the same number of concurrent requests as
|
|
7480
|
+
// the plan: per-request decode at 16 users says nothing about one user.
|
|
7481
|
+
function sameBatch(target, row) {
|
|
7482
|
+
return (row.batchSize || 1) === (target.batchSize || 1);
|
|
7483
|
+
}
|
|
7484
|
+
|
|
7485
|
+
function depthDistance(target, row) {
|
|
7486
|
+
const targetDepth = Math.max(64, Number.isFinite(target.decodeContextTokens) ? target.decodeContextTokens : (target.contextLength || 64));
|
|
7487
|
+
const rowDepth = Math.max(64, Number.isFinite(row.decodeContextTokens) ? row.decodeContextTokens : (row.contextLength || 64));
|
|
7488
|
+
return Math.abs(Math.log(targetDepth / rowDepth));
|
|
7489
|
+
}
|
|
7490
|
+
|
|
7491
|
+
// Closest measured run for the ladder: same preset and hardware template
|
|
7492
|
+
// are required; runtime, quantization, device count, and decode depth
|
|
7493
|
+
// refine the choice. Community runs and lab stock rows compete equally.
|
|
7494
|
+
function findNearestMeasuredRun(target) {
|
|
7495
|
+
if (!target?.presetKey || !target.hardwareTemplate) return null;
|
|
7496
|
+
const candidates = getMeasuredReferenceRows()
|
|
7497
|
+
.filter(row => row.presetKey === target.presetKey && row.hardwareTemplate === target.hardwareTemplate && sameBatch(target, row))
|
|
7498
|
+
.map(row => ({ row, score: getGoldSimilarity(target, row) }))
|
|
7499
|
+
.sort((a, b) => b.score - a.score ||
|
|
7500
|
+
depthDistance(target, a.row) - depthDistance(target, b.row) ||
|
|
7501
|
+
(b.row.reproducibility || 0) - (a.row.reproducibility || 0));
|
|
7502
|
+
const best = candidates[0];
|
|
7503
|
+
if (!best) return null;
|
|
7504
|
+
return { ...best.row, sameSetup: describeSameSetup(target, best.row), similarity: best.score };
|
|
7505
|
+
}
|
|
7506
|
+
|
|
7507
|
+
// The tuned lab result closest to this plan on the same machine (same
|
|
7508
|
+
// hardware template and device count — a different card count is a
|
|
7509
|
+
// different roofline); runtime, quantization, and depth refine the
|
|
7510
|
+
// choice and ties go to the faster run. Labeled as tuned, never used as
|
|
7511
|
+
// a stock reference.
|
|
7512
|
+
function findLabTunedRun(target) {
|
|
7513
|
+
if (!target?.presetKey || !target.hardwareTemplate) return null;
|
|
7514
|
+
const candidates = getLabEvidenceRows()
|
|
7515
|
+
.filter(row => row.stack === 'tuned' && row.presetKey === target.presetKey &&
|
|
7516
|
+
row.hardwareTemplate === target.hardwareTemplate && (row.deviceCount || 1) === (target.deviceCount || 1) && sameBatch(target, row))
|
|
7517
|
+
.map(row => ({ row, score: getGoldSimilarity(target, row) }))
|
|
7518
|
+
.sort((a, b) => b.score - a.score ||
|
|
7519
|
+
depthDistance(target, a.row) - depthDistance(target, b.row) ||
|
|
7520
|
+
b.row.observedTokS - a.row.observedTokS);
|
|
7521
|
+
const best = candidates[0];
|
|
7522
|
+
if (!best) return null;
|
|
7523
|
+
return { ...best.row, sameSetup: describeSameSetup(target, best.row), similarity: best.score };
|
|
7524
|
+
}
|
|
7525
|
+
|
|
7526
|
+
function buildEvidenceTarget(modelConfig, devicesArray, metrics = null) {
|
|
7527
|
+
return {
|
|
7528
|
+
hfId: modelConfig.hfId,
|
|
7529
|
+
presetKey: modelConfig.modelPreset,
|
|
7530
|
+
hardwareTemplate: devicesArray[0]?.template || '',
|
|
7531
|
+
runtimeKey: getFrameworkProfile(modelConfig, devicesArray).key,
|
|
7532
|
+
quantKey: modelConfig.quantizationType,
|
|
7533
|
+
quantization: modelConfig.quantFormat || '',
|
|
7534
|
+
deviceCount: devicesArray.length,
|
|
7535
|
+
contextLength: modelConfig.seqLength,
|
|
7536
|
+
decodeContextTokens: getDecodeContextTokens(modelConfig),
|
|
7537
|
+
hasOverflow: Array.isArray(metrics) ? metrics.some(metric => metric.hasOverflow) : false,
|
|
7538
|
+
batchSize: modelConfig.batchSize || 1
|
|
7539
|
+
};
|
|
7540
|
+
}
|
|
7541
|
+
|
|
7542
|
+
// The engine's view of one lab row in the row's own setup (speculation
|
|
7543
|
+
// included when the row used it): stock projection, optimized target, and
|
|
7544
|
+
// physical roofline. Stock rows show how the engine tracks the lab's
|
|
7545
|
+
// hardware; tuned rows show how much of the optimized target a tuned
|
|
7546
|
+
// stack actually reached.
|
|
7547
|
+
function calculateLabCaseProjection(row) {
|
|
7548
|
+
const preset = MODEL_PRESETS[row.presetKey];
|
|
7549
|
+
const template = DEVICE_TEMPLATES[row.hardwareTemplate];
|
|
7550
|
+
if (!preset || !template || !DTYPE_SIZES[row.quantKey]) return null;
|
|
7551
|
+
const devices = Array.from({ length: row.deviceCount }, (_, index) => ({
|
|
7552
|
+
id: index + 1,
|
|
7553
|
+
template: row.hardwareTemplate,
|
|
7554
|
+
name: `${template.name || row.hardwareTemplate}${row.deviceCount > 1 ? ` #${index + 1}` : ''}`,
|
|
7555
|
+
...JSON.parse(JSON.stringify(template))
|
|
7556
|
+
}));
|
|
7557
|
+
const strategy = row.strategy;
|
|
7558
|
+
const spec = row.speculation;
|
|
7559
|
+
const modelConfig = normalizeModelConfig({
|
|
7560
|
+
...preset,
|
|
7561
|
+
modelPreset: row.presetKey,
|
|
7562
|
+
quantizationType: row.quantKey,
|
|
7563
|
+
quantFormat: getQuantFormat(row.quantization) ? row.quantization : '',
|
|
7564
|
+
runtimeFramework: row.runtimeKey,
|
|
7565
|
+
parallelismStrategy: strategy,
|
|
7566
|
+
optimizationMode: spec ? 'speculative' : 'none',
|
|
7567
|
+
specMethod: spec ? spec.method : 'mtp',
|
|
7568
|
+
specTokens: spec ? spec.tokens : null,
|
|
7569
|
+
specAcceptance: null,
|
|
7570
|
+
specDraftRatio: spec && Number.isFinite(spec.draftRatio) ? spec.draftRatio : null,
|
|
7571
|
+
kvCacheCompression: 'none',
|
|
7572
|
+
batchSize: row.batchSize || 1,
|
|
7573
|
+
promptTokens: row.promptTokens,
|
|
7574
|
+
outputTokens: row.outputTokens,
|
|
7575
|
+
seqLength: row.promptTokens + row.outputTokens
|
|
7576
|
+
});
|
|
7577
|
+
const metrics = calculateMetricsForConfig(modelConfig, devices);
|
|
7578
|
+
const genericTokS = calculateSystemRateFromDeviceRates(metrics.map(metric => metric.decodeTokensPerSecond), strategy, row.batchSize || 1, devices, getSystemRateOptions(modelConfig));
|
|
7579
|
+
const prefillProjectedTokS = getSystemPrefillRateForMetrics(modelConfig, metrics, devices, strategy);
|
|
7580
|
+
const calibration = calculateCurrentCalibration(modelConfig, metrics, genericTokS, strategy, devices);
|
|
7581
|
+
if (!calibration || !Number.isFinite(genericTokS) || genericTokS <= 0) return null;
|
|
7582
|
+
return {
|
|
7583
|
+
...row,
|
|
7584
|
+
genericTokS,
|
|
7585
|
+
prefillProjectedTokS,
|
|
7586
|
+
expectedTokS: calibration.expectedTokS,
|
|
7587
|
+
optimizedTokS: calibration.optimizedTokS,
|
|
7588
|
+
physicalTokS: calibration.physicalTokS,
|
|
7589
|
+
latencyBoundTokS: calibration.latencyBoundTokS,
|
|
7590
|
+
calibrationPeers: calibration.peers,
|
|
7591
|
+
confidence: calibration.confidence,
|
|
7592
|
+
observedToGeneric: row.observedTokS / genericTokS,
|
|
7593
|
+
observedToExpected: row.observedTokS / calibration.expectedTokS,
|
|
7594
|
+
observedToOptimized: row.observedTokS / calibration.optimizedTokS,
|
|
7595
|
+
observedToPhysical: row.observedTokS / calibration.physicalTokS,
|
|
7596
|
+
hasOverflow: metrics.some(metric => metric.hasOverflow)
|
|
7597
|
+
};
|
|
7598
|
+
}
|
|
7599
|
+
|
|
7600
|
+
function getLabValidationRows() {
|
|
7601
|
+
if (labValidationCache) return labValidationCache;
|
|
7602
|
+
labValidationCache = getLabEvidenceRows().map(calculateLabCaseProjection).filter(Boolean);
|
|
7603
|
+
return labValidationCache;
|
|
7604
|
+
}
|
|
7605
|
+
|
|
7606
|
+
|
|
7360
7607
|
function calculateCurrentCalibration(modelConfig, metrics, genericSystemRate, strategy, devicesArray = null) {
|
|
7361
7608
|
const devices = devicesArray || defaultDevices();
|
|
7362
7609
|
if (!metrics?.length || !Number.isFinite(genericSystemRate)) return null;
|
|
@@ -7669,6 +7916,7 @@ function createEngine(options = {}) {
|
|
|
7669
7916
|
}
|
|
7670
7917
|
const power = calculatePowerAndCost(devices, aggregateDecode, metrics, request.usage || {});
|
|
7671
7918
|
const speculationActive = Boolean(primary?.speculation && primary.speculationMultiplier > 1);
|
|
7919
|
+
const evidenceTarget = buildEvidenceTarget(config, devices, metrics);
|
|
7672
7920
|
return {
|
|
7673
7921
|
fits,
|
|
7674
7922
|
strategy: { key: strategy, label: strategy, reasoning: strategyInfo?.reasoning || null, auto: Boolean(strategyInfo) },
|
|
@@ -7702,6 +7950,10 @@ function createEngine(options = {}) {
|
|
|
7702
7950
|
kvCacheGB: sdkRound(metrics.reduce((sum, metric) => sum + (metric.residentKvCacheGB || 0), 0), 2),
|
|
7703
7951
|
availableGB: sdkRound(devices.reduce((sum, device) => sum + (parseFloat(device.memoryGB) || 0), 0), 1)
|
|
7704
7952
|
},
|
|
7953
|
+
measured: {
|
|
7954
|
+
nearest: sdkSummarizeMeasuredRun(findNearestMeasuredRun(evidenceTarget)),
|
|
7955
|
+
labTuned: sdkSummarizeMeasuredRun(findLabTunedRun(evidenceTarget))
|
|
7956
|
+
},
|
|
7705
7957
|
bottleneck: primary?.decodeTimeBreakdown?.dominant || null,
|
|
7706
7958
|
power: power ? { watts: sdkRound(power.actualPowerWatts, 0), tdpWatts: sdkRound(power.totalTDP, 0), costPerDay: sdkRound(power.dailyCost, 3), costPer1KTokens: sdkRound(power.costPer1KTokens, 5) } : null,
|
|
7707
7959
|
devices: metrics.map((metric, index) => sdkSummarizeDevice(metric, devices[index])),
|
|
@@ -7731,6 +7983,29 @@ function createEngine(options = {}) {
|
|
|
7731
7983
|
};
|
|
7732
7984
|
}
|
|
7733
7985
|
|
|
7986
|
+
// A measured reference run (community gold row or neural.download lab row)
|
|
7987
|
+
// in a stable shape; null when nothing on the same model + hardware exists.
|
|
7988
|
+
function sdkSummarizeMeasuredRun(row) {
|
|
7989
|
+
if (!row) return null;
|
|
7990
|
+
return {
|
|
7991
|
+
tokensPerSecond: sdkRound(row.observedTokS, 2),
|
|
7992
|
+
origin: row.isLab ? 'lab' : 'community',
|
|
7993
|
+
stack: row.isLab ? row.stack : 'stock',
|
|
7994
|
+
model: row.model,
|
|
7995
|
+
hardware: row.hardware,
|
|
7996
|
+
deviceCount: row.deviceCount || 1,
|
|
7997
|
+
runtime: row.runtimeKey,
|
|
7998
|
+
quantization: row.quantization || row.quantKey,
|
|
7999
|
+
depthTokens: Math.round(row.decodeContextTokens || row.contextLength || 0),
|
|
8000
|
+
concurrency: row.batchSize || 1,
|
|
8001
|
+
aggregateTokensPerSecond: sdkRound(row.aggregateTokS || row.observedTokS * (row.batchSize || 1), 2),
|
|
8002
|
+
speculation: row.speculation ? { method: row.speculation.method, tokens: row.speculation.tokens ?? null } : null,
|
|
8003
|
+
sameSetup: Boolean(row.sameSetup),
|
|
8004
|
+
url: row.source || row.url || null,
|
|
8005
|
+
note: row.note || null
|
|
8006
|
+
};
|
|
8007
|
+
}
|
|
8008
|
+
|
|
7734
8009
|
function listModels() {
|
|
7735
8010
|
return Object.entries(MODEL_PRESETS).map(([key, preset]) => ({
|
|
7736
8011
|
key,
|
|
@@ -7792,11 +8067,11 @@ function createEngine(options = {}) {
|
|
|
7792
8067
|
|
|
7793
8068
|
if (options.snapshot) setEngineEvidence(options.snapshot);
|
|
7794
8069
|
const api = createApi();
|
|
7795
|
-
api.version = "0.
|
|
8070
|
+
api.version = "0.5.1";
|
|
7796
8071
|
api.evidenceGeneratedAt = options.snapshot?.generatedAt || null;
|
|
7797
8072
|
return api;
|
|
7798
8073
|
}
|
|
7799
8074
|
|
|
7800
|
-
const version = "0.
|
|
8075
|
+
const version = "0.5.1";
|
|
7801
8076
|
export { createEngine, version };
|
|
7802
8077
|
export default createEngine;
|