Make label part of band identity; correct ASUS GPU attribution

Labels now define distinct sessions — different power-cap configs
(asus_210w, sapphire_210w, asus_uncapped) render as separate bands
instead of merging into one. The label badge displays alongside
quant/engine/config badges rather than replacing them.

Scenario drilldown filters by label to prevent cross-band mixing.

Data fix: runs 22-32 (asus_210w) and 43-46 (asus_uncapped) reassigned
from Sapphire (gpu_id=11) to ASUS (gpu_id=12) — they were run on the
ASUS card but imported with the Sapphire GPU identity.
This commit is contained in:
PeterChrz 2026-10-04 23:18:21 -04:00
parent f96fd1ad77
commit 9bf17dba6f
Signed by untrusted user who does not match committer: pch
GPG key ID: 8F0826ECF7302C63
3 changed files with 36 additions and 28 deletions

View file

@ -28,10 +28,15 @@ public function handle(): int
foreach ($runs as $run) { foreach ($runs as $run) {
// Grouping key: user + GPU + model + quant + visibility + engine // Grouping key: user + GPU + model + quant + visibility + engine
// + harness identity + named server config. Free-text labels are // + harness identity + named server config + label. The label is
// intentionally NOT part of identity: rerunning psychbench with // the run-wide experiment/config variant (e.g. a power-cap
// the same actual settings belongs in the same bubble even when // setting), so different labels are different sessions even when
// the user wrote a different run note. // every other dimension matches. Normalize null/empty to a
// single sentinel so unlabeled runs still group together.
$normalizedLabel = $run->label !== null && $run->label !== ''
? $run->label
: 'unlabeled';
$key = implode('|', [ $key = implode('|', [
$run->model_id ?? '-', $run->model_id ?? '-',
$run->model_quant ?? '-', $run->model_quant ?? '-',
@ -48,11 +53,12 @@ public function handle(): int
$run->harness_ver ?: '-', $run->harness_ver ?: '-',
$run->harness_mode ?: 'one-shot', $run->harness_mode ?: 'one-shot',
$run->config_id ?? 'none', $run->config_id ?? 'none',
$normalizedLabel,
]); ]);
$sessions[$key] ??= [ $sessions[$key] ??= [
'key' => $key, 'key' => $key,
'labels' => collect([$run->label])->filter(), 'label' => $run->label,
'model_id' => $run->model_id, 'model_id' => $run->model_id,
'model_quant' => $run->model_quant, 'model_quant' => $run->model_quant,
'gpu' => $run->gpu, 'gpu' => $run->gpu,
@ -71,10 +77,6 @@ public function handle(): int
'runs' => collect(), 'runs' => collect(),
]; ];
if ($run->label !== null && $run->label !== '') {
$sessions[$key]['labels']->push($run->label);
}
// Scenariobench is aggregated at band level (one row for all // Scenariobench is aggregated at band level (one row for all
// scenario runs in the band) rather than per-run, so collect the // scenario runs in the band) rather than per-run, so collect the
// run rows and defer to a second pass below. // run rows and defer to a second pass below.
@ -114,11 +116,7 @@ public function handle(): int
foreach (array_values($sessions) as $bandIndex => $band) { foreach (array_values($sessions) as $bandIndex => $band) {
$summaryId = DB::table('session_summaries')->insertGetId([ $summaryId = DB::table('session_summaries')->insertGetId([
'session_key' => $band['key'], 'session_key' => $band['key'],
// Keep a label only when every grouped run agrees. A 'label' => $band['label'],
// mixed label is a note, not a configuration split.
'label' => $band['labels']->unique()->count() === 1
? $band['labels']->first()
: null,
'model_id' => $band['model_id'], 'model_id' => $band['model_id'],
'model_quant' => $band['model_quant'], 'model_quant' => $band['model_quant'],
'gpu' => $band['gpu'], 'gpu' => $band['gpu'],

View file

@ -7,7 +7,8 @@
use Livewire\Attributes\Layout; use Livewire\Attributes\Layout;
use Livewire\Component; use Livewire\Component;
new #[Layout('components.layouts.app')] class extends Component { new #[Layout('components.layouts.app')] class extends Component
{
use IncludesSorting; use IncludesSorting;
private const SORTABLE = [ private const SORTABLE = [
@ -55,7 +56,16 @@ public function runs()
->where('engine', $band->engine) ->where('engine', $band->engine)
->where(function ($q) use ($band) { ->where(function ($q) use ($band) {
$q->whereNull('config_id') $q->whereNull('config_id')
->orWhere('config_id', $this->configIdFromName($band->config_name)); ->orWhere('config_id', $this->configIdFromName($band->config_name));
})
->where(function ($q) use ($band) {
if ($band->label !== null && $band->label !== '') {
$q->where('label', $band->label);
} else {
$q->where(function ($inner) {
$inner->whereNull('label')->orWhere('label', '');
});
}
}) })
->orderBy('ran_at') ->orderBy('ran_at')
->get(); ->get();
@ -82,7 +92,7 @@ public function results()
->whereIn('benchmark_run_id', $runIds); ->whereIn('benchmark_run_id', $runIds);
if ($column === 'gen_tps') { if ($column === 'gen_tps') {
$query->orderByRaw('gen_tokens / nullif(wall, 0) ' . $direction); $query->orderByRaw('gen_tokens / nullif(wall, 0) '.$direction);
} else { } else {
$query->orderBy($column, $direction); $query->orderBy($column, $direction);
} }

View file

@ -6,7 +6,8 @@
use Livewire\Component; use Livewire\Component;
use Livewire\WithPagination; use Livewire\WithPagination;
new class extends Component { new class extends Component
{
use WithPagination; use WithPagination;
public array $filters = [ public array $filters = [
@ -152,16 +153,15 @@ class="w-64"
<span class="text-sm">{{ $session->band->model_id ?? 'unknown model' }}</span> <span class="text-sm">{{ $session->band->model_id ?? 'unknown model' }}</span>
@if ($session->band->label) @if ($session->band->label)
<flux:badge size="xs" color="amber">{{ $session->band->label }}</flux:badge> <flux:badge size="xs" color="amber">{{ $session->band->label }}</flux:badge>
@else @endif
@if ($session->band->model_quant) @if ($session->band->model_quant)
<flux:badge size="xs" color="zinc">{{ $session->band->model_quant }}</flux:badge> <flux:badge size="xs" color="zinc">{{ $session->band->model_quant }}</flux:badge>
@endif @endif
@if ($session->band->engine) @if ($session->band->engine)
<flux:badge size="xs" color="sky">{{ $session->band->engine }}</flux:badge> <flux:badge size="xs" color="sky">{{ $session->band->engine }}</flux:badge>
@endif @endif
@if ($session->band->config_name) @if ($session->band->config_name)
<flux:badge size="xs" color="amber">{{ $session->band->config_name }}</flux:badge> <flux:badge size="xs" color="amber">{{ $session->band->config_name }}</flux:badge>
@endif
@endif @endif
<flux:spacer /> <flux:spacer />
<span class="text-sm text-zinc-500">{{ $session->band->runner_name ?? 'anonymous' }}</span> <span class="text-sm text-zinc-500">{{ $session->band->runner_name ?? 'anonymous' }}</span>