Spaces:
Running
Running
Anton Malykhin
fix: stabilize benchmark leaders, model benchmark sorting, and HF bucket reads
644ba85 | import { average, geometricMean, sizeNumber } from '$lib/helpers/leaderboard'; | |
| import type { RankingDataset } from '$lib/types/ranking-data'; | |
| import type { BenchmarkScope, GuardModel } from '$lib/types/leaderboard'; | |
| import type { | |
| BenchmarkDetail, | |
| LanguageFilter, | |
| LeaderboardRow, | |
| SortDirection, | |
| SortKey | |
| } from '$lib/types/ranking'; | |
| function isFiniteNumber(value: number | null): value is number { | |
| return typeof value === 'number' && Number.isFinite(value); | |
| } | |
| export function rankingScopeGroups(scope: BenchmarkScope, dataset: RankingDataset) { | |
| if (scope === 'robust') return dataset.robustGroups; | |
| if (scope === 'en') { | |
| return dataset.allGroups.filter((group) => dataset.groupLanguages[group]?.includes('en')); | |
| } | |
| return [...dataset.allGroups]; | |
| } | |
| export function filterRankingGroups( | |
| groups: readonly string[], | |
| selectedGroups: readonly string[], | |
| allGroupsSelected: boolean, | |
| selectedLanguage: LanguageFilter, | |
| groupLanguages: RankingDataset['groupLanguages'] | |
| ) { | |
| let filtered = [...groups]; | |
| if (!allGroupsSelected) { | |
| filtered = filtered.filter((group) => selectedGroups.includes(group)); | |
| } | |
| if (selectedLanguage === 'en') { | |
| filtered = filtered.filter((group) => groupLanguages[group]?.includes('en')); | |
| } | |
| if (selectedLanguage === 'ru') { | |
| filtered = filtered.filter((group) => groupLanguages[group]?.includes('ru')); | |
| } | |
| return filtered.length ? filtered : [...groups]; | |
| } | |
| export function deriveRankingRow( | |
| model: GuardModel, | |
| groups: readonly string[], | |
| useOverall: boolean, | |
| allGroupCount: number | |
| ): LeaderboardRow { | |
| if (useOverall) { | |
| return { | |
| model, | |
| integral: model.integral, | |
| minGroup: model.minGroup, | |
| fpr: model.fpr, | |
| fnr: model.fnr, | |
| f1: model.f1, | |
| p95: model.p95, | |
| size: model.size, | |
| covered: allGroupCount | |
| }; | |
| } | |
| const selectedScores = groups.map((group) => model.groups[group]).filter(Boolean); | |
| const scores = selectedScores.map((group) => group.score).filter(isFiniteNumber); | |
| const scopedIntegral = geometricMean(scores); | |
| return { | |
| model, | |
| integral: scopedIntegral ?? model.integral, | |
| minGroup: scores.length ? Math.min(...scores) : model.minGroup, | |
| fpr: average(selectedScores.map((group) => group.fpr)), | |
| fnr: average(selectedScores.map((group) => group.fnr)), | |
| f1: model.f1, | |
| p95: model.p95, | |
| size: model.size, | |
| covered: selectedScores.length | |
| }; | |
| } | |
| export function buildRankingRows( | |
| groups: readonly string[], | |
| useOverall: boolean, | |
| sourceModels: readonly GuardModel[], | |
| allGroupCount: number | |
| ) { | |
| return sourceModels.map((model) => deriveRankingRow(model, groups, useOverall, allGroupCount)); | |
| } | |
| export function rankingSortValue(row: LeaderboardRow, key: SortKey) { | |
| if (key === 'integral') return row.integral; | |
| if (key === 'minGroup') return row.minGroup; | |
| if (key === 'fpr') return row.fpr; | |
| if (key === 'fnr') return row.fnr; | |
| if (key === 'p95') return row.p95; | |
| return sizeNumber(row.size); | |
| } | |
| export function compareRankingRows( | |
| a: LeaderboardRow, | |
| b: LeaderboardRow, | |
| key: SortKey, | |
| direction: SortDirection | |
| ) { | |
| const first = rankingSortValue(a, key); | |
| const second = rankingSortValue(b, key); | |
| const firstMissing = !Number.isFinite(first); | |
| const secondMissing = !Number.isFinite(second); | |
| if (firstMissing && secondMissing) return 0; | |
| if (firstMissing) return 1; | |
| if (secondMissing) return -1; | |
| const multiplier = direction === 'asc' ? 1 : -1; | |
| return (Number(first) - Number(second)) * multiplier; | |
| } | |
| export function benchmarkDetails(model: GuardModel, groups: readonly string[]): BenchmarkDetail[] { | |
| return groups | |
| .map((group) => ({ | |
| name: group, | |
| score: model.groups[group]?.score ?? null, | |
| minDatasetScore: model.groups[group]?.minDatasetScore ?? null, | |
| fpr: model.groups[group]?.fpr ?? null, | |
| fnr: model.groups[group]?.fnr ?? null, | |
| f1: model.groups[group]?.f1 ?? null | |
| })) | |
| .filter((group) => group.score !== null || group.fpr !== null || group.fnr !== null) | |
| .sort((a, b) => (b.score ?? -1) - (a.score ?? -1)); | |
| } | |
| export function rankingRowsToCsv(items: readonly LeaderboardRow[]) { | |
| const header = [ | |
| 'rank', | |
| 'model', | |
| 'size', | |
| 'integral', | |
| 'min_group', | |
| 'overall_fpr', | |
| 'overall_fnr', | |
| 'overall_f1', | |
| 'p95_ms', | |
| 'run_date' | |
| ]; | |
| const lines = items.map((row, index) => | |
| [ | |
| index + 1, | |
| row.model.name, | |
| row.size, | |
| row.integral.toFixed(4), | |
| row.minGroup.toFixed(4), | |
| row.fpr?.toFixed(4) ?? '', | |
| row.fnr?.toFixed(4) ?? '', | |
| row.f1.toFixed(4), | |
| row.p95.toFixed(1), | |
| row.model.runDate | |
| ] | |
| .map((cell) => `"${String(cell).replaceAll('"', '""')}"`) | |
| .join(',') | |
| ); | |
| return [header.join(','), ...lines].join('\n'); | |
| } | |