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:
parent
f96fd1ad77
commit
9bf17dba6f
3 changed files with 36 additions and 28 deletions
|
|
@ -28,10 +28,15 @@ public function handle(): int
|
|||
|
||||
foreach ($runs as $run) {
|
||||
// Grouping key: user + GPU + model + quant + visibility + engine
|
||||
// + harness identity + named server config. Free-text labels are
|
||||
// intentionally NOT part of identity: rerunning psychbench with
|
||||
// the same actual settings belongs in the same bubble even when
|
||||
// the user wrote a different run note.
|
||||
// + harness identity + named server config + label. The label is
|
||||
// the run-wide experiment/config variant (e.g. a power-cap
|
||||
// setting), so different labels are different sessions even when
|
||||
// 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('|', [
|
||||
$run->model_id ?? '-',
|
||||
$run->model_quant ?? '-',
|
||||
|
|
@ -48,11 +53,12 @@ public function handle(): int
|
|||
$run->harness_ver ?: '-',
|
||||
$run->harness_mode ?: 'one-shot',
|
||||
$run->config_id ?? 'none',
|
||||
$normalizedLabel,
|
||||
]);
|
||||
|
||||
$sessions[$key] ??= [
|
||||
'key' => $key,
|
||||
'labels' => collect([$run->label])->filter(),
|
||||
'label' => $run->label,
|
||||
'model_id' => $run->model_id,
|
||||
'model_quant' => $run->model_quant,
|
||||
'gpu' => $run->gpu,
|
||||
|
|
@ -71,10 +77,6 @@ public function handle(): int
|
|||
'runs' => collect(),
|
||||
];
|
||||
|
||||
if ($run->label !== null && $run->label !== '') {
|
||||
$sessions[$key]['labels']->push($run->label);
|
||||
}
|
||||
|
||||
// Scenariobench is aggregated at band level (one row for all
|
||||
// scenario runs in the band) rather than per-run, so collect the
|
||||
// run rows and defer to a second pass below.
|
||||
|
|
@ -114,11 +116,7 @@ public function handle(): int
|
|||
foreach (array_values($sessions) as $bandIndex => $band) {
|
||||
$summaryId = DB::table('session_summaries')->insertGetId([
|
||||
'session_key' => $band['key'],
|
||||
// Keep a label only when every grouped run agrees. A
|
||||
// mixed label is a note, not a configuration split.
|
||||
'label' => $band['labels']->unique()->count() === 1
|
||||
? $band['labels']->first()
|
||||
: null,
|
||||
'label' => $band['label'],
|
||||
'model_id' => $band['model_id'],
|
||||
'model_quant' => $band['model_quant'],
|
||||
'gpu' => $band['gpu'],
|
||||
|
|
|
|||
|
|
@ -7,7 +7,8 @@
|
|||
use Livewire\Attributes\Layout;
|
||||
use Livewire\Component;
|
||||
|
||||
new #[Layout('components.layouts.app')] class extends Component {
|
||||
new #[Layout('components.layouts.app')] class extends Component
|
||||
{
|
||||
use IncludesSorting;
|
||||
|
||||
private const SORTABLE = [
|
||||
|
|
@ -55,7 +56,16 @@ public function runs()
|
|||
->where('engine', $band->engine)
|
||||
->where(function ($q) use ($band) {
|
||||
$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')
|
||||
->get();
|
||||
|
|
@ -82,7 +92,7 @@ public function results()
|
|||
->whereIn('benchmark_run_id', $runIds);
|
||||
|
||||
if ($column === 'gen_tps') {
|
||||
$query->orderByRaw('gen_tokens / nullif(wall, 0) ' . $direction);
|
||||
$query->orderByRaw('gen_tokens / nullif(wall, 0) '.$direction);
|
||||
} else {
|
||||
$query->orderBy($column, $direction);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@
|
|||
use Livewire\Component;
|
||||
use Livewire\WithPagination;
|
||||
|
||||
new class extends Component {
|
||||
new class extends Component
|
||||
{
|
||||
use WithPagination;
|
||||
|
||||
public array $filters = [
|
||||
|
|
@ -152,16 +153,15 @@ class="w-64"
|
|||
<span class="text-sm">{{ $session->band->model_id ?? 'unknown model' }}</span>
|
||||
@if ($session->band->label)
|
||||
<flux:badge size="xs" color="amber">{{ $session->band->label }}</flux:badge>
|
||||
@else
|
||||
@if ($session->band->model_quant)
|
||||
<flux:badge size="xs" color="zinc">{{ $session->band->model_quant }}</flux:badge>
|
||||
@endif
|
||||
@if ($session->band->engine)
|
||||
<flux:badge size="xs" color="sky">{{ $session->band->engine }}</flux:badge>
|
||||
@endif
|
||||
@if ($session->band->config_name)
|
||||
<flux:badge size="xs" color="amber">{{ $session->band->config_name }}</flux:badge>
|
||||
@endif
|
||||
@endif
|
||||
@if ($session->band->model_quant)
|
||||
<flux:badge size="xs" color="zinc">{{ $session->band->model_quant }}</flux:badge>
|
||||
@endif
|
||||
@if ($session->band->engine)
|
||||
<flux:badge size="xs" color="sky">{{ $session->band->engine }}</flux:badge>
|
||||
@endif
|
||||
@if ($session->band->config_name)
|
||||
<flux:badge size="xs" color="amber">{{ $session->band->config_name }}</flux:badge>
|
||||
@endif
|
||||
<flux:spacer />
|
||||
<span class="text-sm text-zinc-500">{{ $session->band->runner_name ?? 'anonymous' }}</span>
|
||||
|
|
|
|||
Loading…
Reference in a new issue