openvibers/openvibe.bench Commits

Add model quality picks and version comparison feeds (#199)

OP OpenVibers committed 2 days ago · 161f261d77 · 7 files, +189 −5

Changes

ddiff --git a/server/app.js b/server/app.js
iindex d096d62..0b40454 100644
---- a/server/app.js
++++ b/server/app.js
@@@ -147,6 +147,28 @@ async function createApp(opts = {}) {
],
responses: { '200': { description: 'The fitted rating board; sparse models are omitted' }, '404': { description: 'No public rating kind' }, '422': { description: 'Invalid category' } },
} };
++ paths['/api/v1/pick'] = { get: {
++ operationId: 'bench.pick.get', summary: 'Cheapest measured models that clear a quality bar', security: [],
++ parameters: [
++ { name: 'kind', in: 'query', schema: { type: 'string' } },
++ { name: 'min_score', in: 'query', description: 'Minimum Bench score from 0 to 100', schema: { type: 'number', minimum: 0, maximum: 100 } },
++ { name: 'max_cost', in: 'query', description: 'Maximum measured cost per solved task in USD', schema: { type: 'number', minimum: 0 } },
++ ],
++ responses: { '200': { description: 'Measured quality and cost frontier; unknown prices stay unknown' } },
++ } };
++ paths['/api/v1/local/runs'] = { get: {
++ operationId: 'bench.localRuns.get', summary: 'Measured public runs for a hardware description', security: [],
++ parameters: [{ name: 'hardware', in: 'query', required: true, schema: { type: 'string', maxLength: 120 } }],
++ responses: { '200': { description: 'Public verified runs with reported hardware, speed, score and frontier gap' } },
++ } };
++ paths['/api/v1/versions/diff'] = { get: {
++ operationId: 'bench.versionDiff.get', summary: 'Paired task-level comparison of two runs on one frozen benchmark version', security: [],
++ parameters: [
++ { name: 'baseline', in: 'query', required: true, schema: { type: 'string' } },
++ { name: 'candidate', in: 'query', required: true, schema: { type: 'string' } },
++ ],
++ responses: { '200': { description: 'Paired score deltas, 95% bootstrap interval, item changes and effect-size power estimate' }, '400': { description: 'Runs do not share a frozen benchmark version' }, '404': { description: 'No public verified run' } },
++ } };
res.set('Cache-Control', 'public, max-age=3600').set('Access-Control-Allow-Origin', '*').json({ ...doc, paths });
});
// /.well-known/agent.json (openvibe-shared/agent-layer, SEO-2): what this site serves, for agents.
ddiff --git a/server/bench/version-diff.js b/server/bench/version-diff.js
nnew file mode 100644
iindex 0000000..396cc77
---- /dev/null
++++ b/server/bench/version-diff.js
@@@ -0,0 +1,55 @@
++'use strict';
++
++/** Paired task-level comparison for two runs of the same frozen benchmark version. */
++function seeded(seed) {
++ let state = Number(seed) >>> 0;
++ return () => {
++ state = (Math.imul(state, 1664525) + 1013904223) >>> 0;
++ return state / 0x100000000;
++ };
++}
++
++function percentile(sorted, p) {
++ if (!sorted.length) return null;
++ return sorted[Math.min(sorted.length - 1, Math.floor(p * sorted.length))];
++}
++
++function compareRuns(baseline, candidate, { iterations = 10000, seed = 301 } = {}) {
++ const oldScores = new Map((baseline.tasks || []).filter((t) => t.score != null && !t.held_out).map((t) => [t.task_id, Number(t.score)]));
++ const newScores = new Map((candidate.tasks || []).filter((t) => t.score != null && !t.held_out).map((t) => [t.task_id, Number(t.score)]));
++ const rows = [...oldScores.keys()].filter((id) => newScores.has(id)).sort().map((task_id) => ({
++ task_id, baseline: oldScores.get(task_id), candidate: newScores.get(task_id),
++ delta: newScores.get(task_id) - oldScores.get(task_id),
++ }));
++ const diffs = rows.map((r) => r.delta);
++ const mean = diffs.length ? diffs.reduce((a, b) => a + b, 0) / diffs.length : null;
++ const sd = diffs.length > 1 ? Math.sqrt(diffs.reduce((sum, d) => sum + ((d - mean) ** 2), 0) / (diffs.length - 1)) : null;
++ const random = seeded(seed);
++ const samples = [];
++ for (let i = 0; i < iterations && diffs.length; i++) {
++ let total = 0;
++ for (let j = 0; j < diffs.length; j++) total += diffs[Math.floor(random() * diffs.length)];
++ samples.push(total / diffs.length);
++ }
++ samples.sort((a, b) => a - b);
++ const lower = percentile(samples, 0.025);
++ const upper = percentile(samples, 0.975);
++ const better = diffs.filter((d) => d > 0).length;
++ const worse = diffs.filter((d) => d < 0).length;
++ return {
++ schema: 'bench.version-diff@1',
++ method: { design: 'paired by identical task_id on the same frozen benchmark version', interval: '95% percentile bootstrap of paired mean score differences', iterations, seed, held_out: 'excluded from public rows and statistics' },
++ baseline: { run_id: baseline.id, model: baseline.model, benchmark: baseline.benchmark, created_at: baseline.created_at, score: baseline.score, cost_usd: baseline.cost_usd, ms: baseline.ms },
++ candidate: { run_id: candidate.id, model: candidate.model, benchmark: candidate.benchmark, created_at: candidate.created_at, score: candidate.score, cost_usd: candidate.cost_usd, ms: candidate.ms },
++ paired_tasks: rows.length,
++ mean_delta: mean,
++ ci95: { lower, upper },
++ significant: rows.length >= 2 && (lower > 0 || upper < 0),
++ minimum_detectable_effect_80pct_power: sd == null ? null : (1.96 + 0.84) * sd / Math.sqrt(rows.length),
++ changes: { better, worse, unchanged: rows.length - better - worse },
++ rows,
++ caveat: 'A task bootstrap describes these paired items; it does not correct judge bias or benchmark contamination.',
++ };
++}
++
++module.exports = { compareRuns };
ddiff --git a/server/http/pick.js b/server/http/pick.js
iindex 57cbca9..d8636b3 100644
---- a/server/http/pick.js
++++ b/server/http/pick.js
@@@ -16,9 +16,12 @@ const str = (v) => (typeof v === 'string' ? v : '');
function readControls(query) {
const maxCost = str(query.max_cost);
++ const rawScore = str(query.min_score);
++ const score = rawScore === '' ? null : Number(rawScore);
return {
kind: str(query.kind).slice(0, 80),
maxCost: maxCost === '' ? null : Number(maxCost),
++ minScore: Number.isFinite(score) && score >= 0 && score <= 100 ? score : null,
fast: str(query.fast) === '1' || str(query.fast) === 'true',
q: str(query.q).slice(0, 200),
};
ddiff --git a/server/http/registry.js b/server/http/registry.js
iindex 93f04c3..df6cb28 100644
---- a/server/http/registry.js
++++ b/server/http/registry.js
@@@ -21,6 +21,7 @@
const express = require('express');
const { http } = require('openvibe-contracts');
const { asyncRouter } = require('./router');
++const { compareRuns: compareVersionRuns } = require('../bench/version-diff');
const { sameOrigin } = require('./same-origin');
const { validateBenchmark, validateRun } = require('../bench/validate');
const { canViewBenchmark } = require('../bench/registry');
@@@ -362,6 +363,54 @@ function createRegistryApi(ctx) {
} catch (err) { return failed(res, err); }
});
++ // A paired release diff: both runs must be public, verified, and on the identical frozen task set.
++ r.get('/versions/diff', async (req, res) => {
++ const baselineId = String(req.query.baseline || '');
++ const candidateId = String(req.query.candidate || '');
++ if (!baselineId || !candidateId || baselineId === candidateId) return invalid(res, 'baseline and candidate must name two distinct run ids');
++ try {
++ const [baseline, candidate] = await Promise.all([registry.getRun(baselineId), registry.getRun(candidateId)]);
++ if (!baseline || !candidate) return problem(res, 404, 'bench.run_not_found', 'No such run.');
++ const [baseBenchmark, candidateBenchmark] = await Promise.all([
++ registry.getBenchmark(baseline.benchmark_id), registry.getBenchmark(candidate.benchmark_id),
++ ]);
++ if (!baseBenchmark || !candidateBenchmark || baseBenchmark.visibility !== 'public' || candidateBenchmark.visibility !== 'public'
++ || baseline.provenance !== 'verified' || candidate.provenance !== 'verified') {
++ return problem(res, 404, 'bench.run_not_found', 'No such public verified run.');
++ }
++ if (baseline.benchmark_id !== candidate.benchmark_id || baseline.benchmark_version !== candidate.benchmark_version) {
++ return invalid(res, 'version diffs require the same public benchmark and frozen version');
++ }
++ const diff = compareVersionRuns(baseline, candidate);
++ res.set('Cache-Control', 'public, max-age=60');
++ return res.json({ diff });
++ } catch (err) { return failed(res, err); }
++ });
++
++ // Hardware results are measured runs only. No speed or fit estimates are inferred from model names.
++ r.get('/local/runs', async (req, res) => {
++ const hardwareQuery = String(req.query.hardware || '').trim().slice(0, 120);
++ if (!hardwareQuery) return invalid(res, 'hardware is required, for example ?hardware=RTX%204090');
++ const limit = Math.min(100, Math.max(1, Number(req.query.limit) || 50));
++ try {
++ const runs = await registry.listRuns({ publicOnly: true, verifiedOnly: true, limit: 100 });
++ const matching = runs.filter((run) => run.hardware && JSON.stringify(run.hardware).toLowerCase().includes(hardwareQuery.toLowerCase()));
++ const bestByBenchmark = new Map();
++ for (const run of runs) {
++ const key = `${run.benchmark_id}@${run.benchmark_version}`;
++ bestByBenchmark.set(key, Math.max(bestByBenchmark.get(key) ?? -Infinity, Number(run.score) || 0));
++ }
++ res.set('Cache-Control', 'public, max-age=60');
++ return res.json({ schema: 'bench.local-runs@1', hardware_query: hardwareQuery, source: 'public verified Bench runs', count: Math.min(limit, matching.length), runs: matching.slice(0, limit).map((run) => ({
++ id: run.id, benchmark: run.benchmark, model: run.model, hardware: run.hardware,
++ score: run.score, frontier_score: bestByBenchmark.get(`${run.benchmark_id}@${run.benchmark_version}`) ?? null,
++ gap_to_frontier: run.score == null ? null : (bestByBenchmark.get(`${run.benchmark_id}@${run.benchmark_version}`) - run.score),
++ cost_usd: run.cost_usd, ms: run.ms, tokens: run.tokens, aggregate_tokens_per_second: run.ms > 0 ? Number((run.tokens * 1000 / run.ms).toFixed(3)) : null,
++ created_at: run.created_at,
++ })) });
++ } catch (err) { return failed(res, err); }
++ });
++
r.get('/rankings', async (req, res) => {
const benchmark = req.query.benchmark ? String(req.query.benchmark) : '';
if (!benchmark) return invalid(res, 'benchmark is required: ?benchmark=bmk_…');
ddiff --git a/server/pick/pick.js b/server/pick/pick.js
iindex 27cbf35..aaf2a99 100644
---- a/server/pick/pick.js
++++ b/server/pick/pick.js
@@@ -104,18 +104,27 @@ function whySentence(rows, kindName) {
* The answer. Reads the controls (with the free text read first, so the words can set them), and returns the frontier
* with every number that made it.
*/
--async function answer(ctx, { kind = '', maxCost = null, fast = false, q = '', kinds = KINDS } = {}) {
++async function answer(ctx, { kind = '', maxCost = null, minScore = null, fast = false, q = '', kinds = KINDS } = {}) {
const parsed = q ? parsePick(q, { kinds }) : { kind: null, max_cost: null, fast: false, notes: [] };
const kindId = parsed.kind || (kind && kindById(kind) ? kind : null) || await busiestKind(ctx);
const price = parsed.max_cost != null ? parsed.max_cost : (maxCost == null || maxCost === '' ? null : Number(maxCost));
++ const qualityBar = minScore == null || minScore === '' ? null : Number(minScore);
const wantFast = parsed.fast || !!fast;
const all = await ctx.bench.valueRows(kindId);
++ let exchangeOffers = [];
++ if (ctx.ai && typeof ctx.ai.market === 'function') {
++ try {
++ const market = await ctx.ai.market({ openWeights: false, limit: 500 });
++ exchangeOffers = Array.isArray(market && market.offers) ? market.offers : [];
++ } catch { /* Exchange prices may be temporarily unavailable; measured Bench costs remain available. */ }
++ }
const fit = await boardForKind(ctx, kindId);
const bands = bandMap(fit && fit.fit);
// The price comes first: a model over it is out whatever else it does.
-- const priced = price == null ? all : all.filter((r) => r.cost_per_solved != null && r.cost_per_solved <= price + 1e-9);
++ const qualified = qualityBar == null ? all : all.filter((r) => r.score >= qualityBar);
++ const priced = price == null ? qualified : qualified.filter((r) => r.cost_per_solved != null && r.cost_per_solved <= price + 1e-9);
// "Fast" is a time cap taken from the run data: the middle of the models' median times.
const fastCap = wantFast ? median(priced.map((r) => r.median_ms).filter((v) => v > 0)) : null;
@@@ -126,7 +135,8 @@ async function answer(ctx, { kind = '', maxCost = null, fast = false, q = '', ki
.map((r) => ({ ...r, model: r.subject, cost: r.cost_per_solved }));
const front = frontier(comparable);
const order = new Map(comparable.map((r, i) => [r.subject, i]));
-- front.sort((a, b) => (b.score - a.score)
++ front.sort((a, b) => (qualityBar == null ? b.score - a.score : (a.cost_per_solved - b.cost_per_solved))
++ || (b.score - a.score)
|| ((a.cost_per_solved == null ? Infinity : a.cost_per_solved) - (b.cost_per_solved == null ? Infinity : b.cost_per_solved))
|| a.subject.localeCompare(b.subject));
@@@ -141,6 +151,8 @@ async function answer(ctx, { kind = '', maxCost = null, fast = false, q = '', ki
median_ms: r.median_ms,
runs: r.runs,
thin: r.runs < MIN_RUNS,
++ exchange_offers: exchangeOffers.filter((offer) => String(offer.model || '').toLowerCase() === r.subject.toLowerCase())
++ .map((offer) => ({ provider: offer.provider || null, provider_model: offer.provider_model || null, price: offer.price ?? null, checked_at: offer.checked_at || offer.updated_at || null })),
sample: await sampleFor(ctx, kindId, r.subject),
});
}
@@@ -163,15 +175,17 @@ async function answer(ctx, { kind = '', maxCost = null, fast = false, q = '', ki
controls: {
kind: kindId,
max_cost: price == null ? null : price,
++ min_score: qualityBar,
fast: wantFast,
q: String(q || ''),
notes: parsed.notes || [],
},
-- filters: { max_cost: price == null ? null : price, fast: wantFast, fast_cap_ms: fastCap, min_runs: MIN_RUNS },
++ filters: { max_cost: price == null ? null : price, min_score: qualityBar, fast: wantFast, fast_cap_ms: fastCap, min_runs: MIN_RUNS },
rows,
also_ran: alsoRan,
why: whySentence(rows, kindInfo.name),
-- counts: { models: all.length, priced: priced.length, timed: timed.length, frontier: rows.length, others, thin_elsewhere: thinElsewhere },
++ counts: { models: all.length, qualified: qualified.length, priced: priced.length, timed: timed.length, frontier: rows.length, others, thin_elsewhere: thinElsewhere },
++ price_source: 'frontier order uses measured cost_per_solved from Bench; current Exchange offer prices are attached when available but are not treated as per-task cost',
generated_at: new Date().toISOString(),
};
}
ddiff --git a/test/pick.test.js b/test/pick.test.js
iindex 704ae99..4f07618 100644
---- a/test/pick.test.js
++++ b/test/pick.test.js
@@@ -10,6 +10,7 @@ const { boot, check, done } = require('./helpers/boot');
const { frontier } = require('../server/pick/frontier');
const { parsePick } = require('../server/pick/parser');
const { KINDS } = require('../server/kinds');
++const { compareRuns: compareVersionRuns } = require('../server/bench/version-diff');
(async () => {
await check('the frontier drops the models another model beats on score and on cost', () => {
@@@ -23,6 +24,20 @@ const { KINDS } = require('../server/kinds');
assert.deepStrictEqual(frontier(rows).map((r) => r.model), ['a', 'b', 'c']);
});
++ await check('the version diff pairs identical tasks and reports a seeded confidence interval', () => {
++ const baseline = { id: 'old', model: 'model@1', benchmark: 'bench@1', tasks: [
++ { task_id: 'a', score: 0.5 }, { task_id: 'b', score: 0.6 }, { task_id: 'held', score: 1, held_out: true },
++ ] };
++ const candidate = { id: 'new', model: 'model@2', benchmark: 'bench@1', tasks: [
++ { task_id: 'a', score: 0.7 }, { task_id: 'b', score: 0.6 }, { task_id: 'c', score: 0.9 },
++ ] };
++ const out = compareVersionRuns(baseline, candidate, { iterations: 1000 });
++ assert.strictEqual(out.paired_tasks, 2, 'only common public task ids are paired');
++ assert.deepStrictEqual(out.changes, { better: 1, worse: 0, unchanged: 1 });
++ assert.deepStrictEqual(out.ci95, compareVersionRuns(baseline, candidate, { iterations: 1000 }).ci95, 'bootstrap is reproducible');
++ assert.ok(out.ci95.lower <= out.mean_delta && out.ci95.upper >= out.mean_delta);
++ });
++
await check('a tie keeps both models on the frontier', () => {
const rows = [{ model: 'a', score: 90, cost: 0.02 }, { model: 'b', score: 90, cost: 0.02 }];
assert.deepStrictEqual(frontier(rows).map((r) => r.model), ['a', 'b']);
@@@ -97,6 +112,12 @@ const { KINDS } = require('../server/kinds');
assert.ok(ok.rows.some((r) => r.model === 'alpha-1'), 'alpha-1 is under two cents');
});
++ await check('the quality floor returns only models that clear the requested score', async () => {
++ const json = (await t.get('/api/v1/pick?kind=design.page&min_score=99')).json();
++ assert.strictEqual(json.filters.min_score, 99);
++ assert.ok(json.rows.every((r) => r.score >= 99), 'every pick clears the quality floor');
++ });
++
await check('fast takes its time cap from the run data', async () => {
const json = (await t.get('/api/v1/pick?kind=design.page&fast=1')).json();
assert.ok(json.filters.fast_cap_ms > 0, 'a cap from the run times');
ddiff --git a/test/registry.test.js b/test/registry.test.js
iindex 6af940c..89ab21b 100644
---- a/test/registry.test.js
++++ b/test/registry.test.js
@@@ -58,6 +58,8 @@ function runDoc(benchmark, over = {}) {
let benchmarkId;
let version;
++ let baselineRunId;
++ let candidateRunId;
await check('a benchmark is created, drafted and frozen into a version', async () => {
const created = await t.get('/api/v1/benchmarks', { bearer: writer, json: definition() });
@@@ -96,10 +98,28 @@ function runDoc(benchmark, over = {}) {
const verified = await t.get('/api/v1/runs', { bearer: publisher, json: runDoc(`${benchmarkId}@${version}`) });
assert.strictEqual(verified.status, 201, verified.text);
assert.strictEqual(verified.json().run.provenance, 'verified');
++ baselineRunId = verified.json().run.id;
const submitted = await t.get('/api/v1/runs', { as: alice, json: runDoc(`${benchmarkId}@${version}`, { model: 'gpt-5' }) });
assert.strictEqual(submitted.status, 201, submitted.text);
assert.strictEqual(submitted.json().run.provenance, 'submitted');
assert.strictEqual(submitted.json().run.executor.kind, 'submitted');
++ const candidate = await t.get('/api/v1/runs', { bearer: publisher, json: runDoc(`${benchmarkId}@${version}`, {
++ model: 'claude-opus-4.1', score: 95, hardware: { gpu: 'RTX 4090', vram_gb: 24 }, tokens: 1000, ms: 2000,
++ tasks: [{ task_id: 't1', score: 95, cost_usd: 0.01, ms: 2000, tokens: 1000, artifacts: [] }],
++ }) });
++ assert.strictEqual(candidate.status, 201, candidate.text);
++ candidateRunId = candidate.json().run.id;
++ });
++
++ await check('the version feed returns a paired bootstrap diff and local hardware measurements', async () => {
++ const diff = await t.get(`/api/v1/versions/diff?baseline=${baselineRunId}&candidate=${candidateRunId}`);
++ assert.strictEqual(diff.status, 200, diff.text);
++ assert.strictEqual(diff.json().diff.paired_tasks, 1);
++ assert.strictEqual(diff.json().diff.mean_delta, 5);
++ const local = await t.get('/api/v1/local/runs?hardware=RTX%204090');
++ assert.strictEqual(local.status, 200, local.text);
++ assert.ok(local.json().runs.some((run) => run.model === 'claude-opus-4.1'));
++ assert.strictEqual(local.json().runs[0].aggregate_tokens_per_second, 500);
});
await check('a human judged run publishes null scores and keeps its output on the framed render path', async () => {