Skip to content

feat(inference): default to the best line per SKU / feat(inference):默认显示每个 SKU 的最佳曲线 - #713

Merged
adibarra merged 4 commits into
masterfrom
agent/best-line-per-sku
Aug 10, 2026
Merged

feat(inference): default to the best line per SKU / feat(inference):默认显示每个 SKU 的最佳曲线#713
adibarra merged 4 commits into
masterfrom
agent/best-line-per-sku

Conversation

@Oseltamivir

@Oseltamivir Oseltamivir commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Summary

  • rank configuration Pareto frontiers within each physical hardware SKU using nine-point normalized AUC over the candidates' shared measured x-domain
  • default /inference to the winning configuration while preserving manual legend selection and a shareable Best per SKU toggle
  • apply the same selection policy to official data and ?unofficialrun= overlays, including overlay scope changes
  • add Simplified Chinese UI copy (每个 SKU 仅显示最佳配置) and focused official/overlay tests

Why

Several frameworks, deployment modes, and speculative-decoding variants can produce many lines for the same chip. Showing one representative winner per SKU makes the initial comparison readable without removing access to the other configurations.

Validation

  • bun run typecheck
  • bun run lint
  • bun run fmt
  • focused Vitest: 44 passing
  • Cypress component smoke suite: 25 passing, including unofficial overlay rendering
  • full unit suite: 3,233 passing; one unrelated existing time-zone-sensitive failure in visit-tracking.test.ts (2026-05-15T22:00:00Z is the next local calendar day in Asia/Singapore)
  • Cypress integration suite requires DATABASE_READONLY_URL; the local run was stopped after availability returned 500 because that variable is not configured

Works for both official runs and ?unofficialrun= overlays; verified through the component overlay suite.


Note

Medium Risk
Changes default legend selection and URL semantics on /inference, but manual toggles and i_best=0 preserve prior behavior; ranking is localized to chart filtering, not auth or data APIs.

Overview
Adds a Best per SKU mode on the inference dashboard so the legend starts with one winning hwKey per physical chip instead of every framework/deployment variant.

Selection uses a new bestSeriesPerSku helper: group series by SKU, build each candidate’s Pareto frontier for the active chart roofline direction, then pick the winner by normalized AUC over the shared measured x-range (so wider curves don’t win by span alone). Ties break on hwKey.

InferenceContext owns bestPerSku (on by default on the inference tab unless i_best=0), computes bestHwTypes from the current interactivity/e2e graph and y-metric, and uses that set for automatic hardware resets when model/sequence/metric/x-mode changes. Manual legend edits, select-all, or presets turn the mode off. Share URLs gain i_best.

ScatterGraph exposes a legend switch (EN + zh copy) that reapplies best selection for official + overlay preview runs. ChartDisplay applies the same policy when unofficial overlay scope changes so tables/charts stay aligned.

Vitest coverage for the ranking helper; Cypress mocks updated; visit-tracking.test fixes flaky calendar-day handling under non-UTC timezones.

Reviewed by Cursor Bugbot for commit 0aaf379. Bugbot is set up for automated code reviews on this repo. Configure here.

@vercel

vercel Bot commented Aug 10, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
inferencemax-app Ready Ready Preview Aug 10, 2026 1:47pm

Request Review

Rank configuration frontiers over each SKU's shared measured domain, default the inference legend to the winner, and keep a bilingual toggle plus unofficial-run overlay support.

中文:推理图表默认按每个 SKU 的共同实测区间评选并展示最佳配置曲线,同时提供中英文切换控件,并支持非官方运行覆盖。
@Oseltamivir
Oseltamivir force-pushed the agent/best-line-per-sku branch from 9044b80 to d842914 Compare August 10, 2026 04:54
@Oseltamivir
Oseltamivir marked this pull request as ready for review August 10, 2026 05:17
@Oseltamivir
Oseltamivir requested a review from adibarra as a code owner August 10, 2026 05:17

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 3 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit b269baa. Configure here.

Comment thread packages/app/src/components/inference/InferenceContext.tsx
Comment thread packages/app/src/components/inference/ui/ScatterGraph.tsx
Comment thread packages/app/src/components/inference/ui/ChartDisplay.tsx
@adibarra

Copy link
Copy Markdown
Contributor

@claude fix the failing time zone sensitive test

@github-actions

github-actions Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Claude finished @adibarra's task in 1m 35s —— View job


Fix failing time-zone-sensitive test

  • Read visit-tracking.test.ts and locate the TZ-sensitive assertion
  • Fix the test so it passes regardless of local time zone
  • Run the focused unit test to confirm (default and TZ=Asia/Singapore)
  • Commit & push

Root cause: visit-tracking.ts computes calendar days in local time (getFullYear/getMonth/getDate), but the test fed UTC ISO strings (…Z). In UTC+8, 2026-05-15T22:00:00Z rolls over to 2026-05-16 local, so the "does NOT increment when a new session happens on the same calendar day" case saw a different day and incremented — failing only in non-UTC zones.

Fix: setNow now strips the trailing Z so timestamps are parsed in the local zone, matching the code under test. No production code touched, and every ISO literal in the test bodies is unchanged.

function setNow(iso: string) {
  // …parse as local time to match visit-tracking's local-calendar-day logic…
  vi.setSystemTime(new Date(iso.replace(/Z$/u, '')));
}

Verificationbunx vitest run packages/app/src/lib/visit-tracking.test.ts:

  • default TZ → 13 passed
  • TZ=Asia/Singapore (the zone that reproduced the failure) → 13 passed

Pushed as 53215a9 to agent/best-line-per-sku.
· branch agent/best-line-per-sku

Interpret the fake-timer timestamps as local time so the day/month
boundary assertions match visit-tracking's local-calendar-day logic.
The trailing 'Z' forced UTC parsing, which shifted 2026-05-15T22:00:00Z
to 2026-05-16 in UTC+8 (Asia/Singapore), flaking the "same day, new
session" case.

中文:将假定时器时间戳按本地时区解析,使日期/月份边界断言与
visit-tracking 的本地日历日逻辑一致,修复在 Asia/Singapore(UTC+8)
时区下因末尾 'Z' 触发 UTC 解析导致的时区敏感测试失败。

Co-authored-by: Alec Ibarra <93070681+adibarra@users.noreply.github.com>
@adibarra
adibarra enabled auto-merge (squash) August 10, 2026 13:44
@adibarra

Copy link
Copy Markdown
Contributor

@claude also resolve the cursor pr comments

@github-actions

github-actions Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Claude finished @adibarra's task in 7m 52s —— View job


Re-review + resolve Cursor Bugbot comments

All three Bugbot findings are valid. I implemented and verified fixes for each — but this run is the read-only review job, and its token is denied push access (403 … denied to github-actions[bot]). The commit is ready locally (6d90d09, verified below); the full patch is at the bottom so you can apply it directly, or re-trigger an implement-capable job (@claude frontend) to push it.


What each fix does

#1 — Ranking ignores selected precision (best-series-per-sku.ts, all 4 call sites)
bestSeriesPerSku now takes an optional isVisible(point) predicate and skips points that fail it, so a config can no longer win a SKU from a hidden precision / quick-filtered row and default the chart to a line with no visible series.

  • InferenceContext.bestHwTypeseffectivePrecisions.includes(point.precision) (mirrors hwFilteredPoints).
  • ChartDisplay.scopedBestSelections (official + overlay) → selectedPrecisions.includes(...) && matchesQuickFilters(...) (mirrors visibleComparisonRows).
  • ScatterGraph toggle-on handler (official + overlay) → same predicate.

#2 — Overlay toggle keeps Best per SKU (ScatterGraph.tsx)
handleToggleHwType / handleRemoveHwType now call setBestPerSku(false) on the overlay (unified-selection) branch, matching the official path (toggleHwType/removeHwType already did). A manual overlay selection is no longer silently reseeded by a later scope change. The programmatic toggle-on path still sets bestPerSku (it calls commitUnifiedSelection directly, not the handlers), so it's unaffected.

#3 — Overlay misses default best selection (ChartDisplay.tsx)
scopedActiveOverlayHwTypes now returns scopedBestSelections.overlay whenever bestPerSku is on — not only during a scope change — so first loads no longer leave overlays fully selected while the official side already narrowed. This is safe because of #2: any manual overlay change clears bestPerSku, so forcing best here never overrides an explicit choice. selectedOfficialHwTypes also uses scopedBestSelections.official on the scope-change frame instead of the full officialScope.

Verification

  • bun run typecheck → clean
  • bun run lint → clean · bun run fmt → clean
  • bunx vitest run …/best-series-per-sku.test.ts6 passed (added ignores points the chart does not render when picking a winner)

Patch (apply on agent/best-line-per-sku)

git apply this patch — resolves all three findings
diff --git a/packages/app/src/components/inference/InferenceContext.tsx b/packages/app/src/components/inference/InferenceContext.tsx
index 23ddf01..33b5f62 100644
--- a/packages/app/src/components/inference/InferenceContext.tsx
+++ b/packages/app/src/components/inference/InferenceContext.tsx
@@ -913,9 +913,13 @@ export function InferenceProvider({
     ) {
       return hwTypesWithData;
     }
-    const best = bestSeriesPerSku(graph.data, direction);
+    // Rank over the points the chart actually renders (the active precisions),
+    // matching hwFilteredPoints — otherwise a hidden-precision line could win.
+    const best = bestSeriesPerSku(graph.data, direction, (point) =>
+      effectivePrecisions.includes(point.precision),
+    );
     return best.size > 0 ? best : hwTypesWithData;
-  }, [graphs, hwTypesWithData, selectedXAxisMode, selectedYAxisMetric]);
+  }, [graphs, hwTypesWithData, selectedXAxisMode, selectedYAxisMetric, effectivePrecisions]);
 
   const setBestPerSkuAndApply = useCallback(
     (enabled: boolean) => {
diff --git a/packages/app/src/components/inference/ui/ChartDisplay.tsx b/packages/app/src/components/inference/ui/ChartDisplay.tsx
index f80f823..962a19c 100644
--- a/packages/app/src/components/inference/ui/ChartDisplay.tsx
+++ b/packages/app/src/components/inference/ui/ChartDisplay.tsx
@@ -464,8 +464,12 @@ export default function ChartDisplay() {
       return { official: officialScope, overlay: overlayScope };
     }
     const overlay = overlayDataByChartType[wantedType];
-    const officialBest = bestSeriesPerSku(graph.data, direction);
-    const overlayBest = bestSeriesPerSku(overlay?.data ?? [], direction);
+    // Rank only over rendered points so a hidden precision / filtered-out row
+    // cannot win the SKU (mirrors visibleComparisonRows' eligibility).
+    const isVisible = (point: InferenceData) =>
+      selectedPrecisions.includes(point.precision) && matchesQuickFilters(point, quickFilters);
+    const officialBest = bestSeriesPerSku(graph.data, direction, isVisible);
+    const overlayBest = bestSeriesPerSku(overlay?.data ?? [], direction, isVisible);
     return {
       official: officialBest.size > 0 ? officialBest : officialScope,
       overlay: overlayBest.size > 0 ? overlayBest : overlayScope,
@@ -478,6 +482,8 @@ export default function ChartDisplay() {
     overlayScope,
     selectedXAxisMode,
     selectedYAxisMetric,
+    selectedPrecisions,
+    quickFilters,
   ]);
   const overlayRowsScopeKey = `${selectedModel}|${selectedSequence}|${selectedPrecisions.join(
     ',',
@@ -486,7 +492,7 @@ export default function ChartDisplay() {
   const overlayRowsScopeChanged =
     isUnofficialRun && appliedOverlayRowsScopeKey !== overlayRowsScopeKey;
   const selectedOfficialHwTypes = overlayRowsScopeChanged
-    ? officialScope
+    ? scopedBestSelections.official
     : isUnofficialRun
       ? (localOfficialOverride ?? activeHwTypes)
       : activeHwTypes;
@@ -496,8 +502,21 @@ export default function ChartDisplay() {
     const activeScopedOverlayKeys = new Set(
       [...activeOverlayHwTypes].filter((key) => overlayScope.has(key)),
     );
+    // With Best per SKU on, default overlays to the winning line even on the
+    // first load — not only on a scope change. The provider seeds every overlay
+    // key on load; without this the overlay stays fully selected while the
+    // official side already narrowed. A manual overlay toggle clears bestPerSku
+    // (see handleToggleHwType / handleRemoveHwType), so forcing best here never
+    // overrides a user's explicit choice.
+    if (bestPerSku) return scopedBestSelections.overlay;
     return overlayRowsScopeChanged ? scopedBestSelections.overlay : activeScopedOverlayKeys;
-  }, [activeOverlayHwTypes, overlayScope, overlayRowsScopeChanged, scopedBestSelections.overlay]);
+  }, [
+    activeOverlayHwTypes,
+    overlayScope,
+    overlayRowsScopeChanged,
+    scopedBestSelections.overlay,
+    bestPerSku,
+  ]);
   useEffect(() => {
     const merged = new Set(activeOverlayHwTypes);
     overlayScope.forEach((key) => merged.delete(key));
diff --git a/packages/app/src/components/inference/ui/ScatterGraph.tsx b/packages/app/src/components/inference/ui/ScatterGraph.tsx
index 921bda5..69e20b2 100644
--- a/packages/app/src/components/inference/ui/ScatterGraph.tsx
+++ b/packages/app/src/components/inference/ui/ScatterGraph.tsx
@@ -685,10 +685,21 @@ const ScatterGraph = React.memo(
       commitUnifiedSelection,
     ]);
 
-    // When no overlay data, delegate to context's toggleHwType (preserves setActivePresetId)
+    // When no overlay data, delegate to context's toggleHwType (preserves
+    // setActivePresetId and clears bestPerSku). With an overlay loaded the
+    // toggle goes through the unified selection, which never touches bestPerSku,
+    // so clear it here — otherwise a later scope change reseeds the best set and
+    // wipes this manual choice.
     const handleToggleHwType = useCallback(
-      (key: string) => (overlayData ? unifiedToggle(key, false) : toggleHwType(key)),
-      [overlayData, unifiedToggle, toggleHwType],
+      (key: string) => {
+        if (!overlayData) {
+          toggleHwType(key);
+          return;
+        }
+        setBestPerSku(false);
+        unifiedToggle(key, false);
+      },
+      [overlayData, unifiedToggle, toggleHwType, setBestPerSku],
     );
 
     // Legend "X" (remove) — same overlay split as handleToggleHwType. With an
@@ -704,11 +715,12 @@ const ScatterGraph = React.memo(
           removeHwType(key);
           return;
         }
+        setBestPerSku(false);
         const next = new Set(resolvedUnifiedSelection);
         next.delete(key);
         commitUnifiedSelection(next);
       },
-      [overlayData, removeHwType, resolvedUnifiedSelection, commitUnifiedSelection],
+      [overlayData, removeHwType, resolvedUnifiedSelection, commitUnifiedSelection, setBestPerSku],
     );
 
     // --- Theme ---
@@ -3282,8 +3294,15 @@ const ScatterGraph = React.memo(
                           direction === 'lower_left' ||
                           direction === 'lower_right'
                         ) {
-                          const selection = bestSeriesPerSku(data, direction);
-                          for (const key of bestSeriesPerSku(overlayData.data, direction)) {
+                          const isVisible = (point: InferenceData) =>
+                            selectedPrecisions.includes(point.precision) &&
+                            matchesQuickFilters(point, quickFilters);
+                          const selection = bestSeriesPerSku(data, direction, isVisible);
+                          for (const key of bestSeriesPerSku(
+                            overlayData.data,
+                            direction,
+                            isVisible,
+                          )) {
                             selection.add(`overlay:${key}`);
                           }
                           commitUnifiedSelection(selection);
diff --git a/packages/app/src/components/inference/utils/best-series-per-sku.test.ts b/packages/app/src/components/inference/utils/best-series-per-sku.test.ts
index 266b757..305acbb 100644
--- a/packages/app/src/components/inference/utils/best-series-per-sku.test.ts
+++ b/packages/app/src/components/inference/utils/best-series-per-sku.test.ts
@@ -57,6 +57,25 @@ describe('bestSeriesPerSku', () => {
     expect(baseSku(point('GB200-NVL72', 'gb200_dynamo-trt', 1, 1))).toBe('GB200');
   });
 
+  it('ignores points the chart does not render when picking a winner', () => {
+    const withPrecision = (hwKey: string, x: number, y: number, precision: string) =>
+      ({ ...point('B200-8', hwKey, x, y), precision }) as InferenceData;
+    // b200_hidden scores higher but only on a precision the chart hides, so the
+    // visible predicate must exclude it and pick the best visible series.
+    const selected = bestSeriesPerSku(
+      [
+        withPrecision('b200_hidden', 10, 100, 'fp4'),
+        withPrecision('b200_hidden', 20, 90, 'fp4'),
+        withPrecision('b200_visible', 10, 80, 'fp8'),
+        withPrecision('b200_visible', 20, 60, 'fp8'),
+      ],
+      'upper_left',
+      (candidate) => candidate.precision === 'fp8',
+    );
+
+    expect(selected).toEqual(new Set(['b200_visible']));
+  });
+
   it('ranks unofficial-run overlay series with the same SKU policy', () => {
     const overlayPoint = (hwKey: string, x: number, y: number) =>
       ({
diff --git a/packages/app/src/components/inference/utils/best-series-per-sku.ts b/packages/app/src/components/inference/utils/best-series-per-sku.ts
index db863e0..dc34c02 100644
--- a/packages/app/src/components/inference/utils/best-series-per-sku.ts
+++ b/packages/app/src/components/inference/utils/best-series-per-sku.ts
@@ -28,10 +28,19 @@ interface ScoredSeries {
  * so a curve cannot win merely because it spans a wider range. The chart's
  * existing Pareto direction and monotone interpolation are reused to keep the
  * ranking aligned with the line users see. Ties are deterministic by hwKey.
+ *
+ * `isVisible` restricts scoring to the points the chart actually renders (e.g.
+ * the selected precisions and quick filters). Without it, a configuration could
+ * win from hidden-precision points and default to a line with no visible series.
  */
-export function bestSeriesPerSku(points: InferenceData[], direction: Direction): Set<string> {
+export function bestSeriesPerSku(
+  points: InferenceData[],
+  direction: Direction,
+  isVisible: (point: InferenceData) => boolean = () => true,
+): Set<string> {
   const bySku = new Map<string, Map<string, InferenceData[]>>();
   for (const point of points) {
+    if (!isVisible(point)) continue;
     if (!isFrontierEligible(point) || !Number.isFinite(point.y)) continue;
     const sku = baseSku(point);
     const key = String(point.hwKey);

中文说明
Cursor Bugbot 的三个问题均属实,已实现并本地验证修复(提交 6d90d09),但当前是只读的 review 任务,其 token 无推送权限(403),因此无法推送。请直接应用上方补丁,或用 @claude frontend 重新触发可写任务来推送。

@adibarra
adibarra merged commit 6323304 into master Aug 10, 2026
24 checks passed
@adibarra
adibarra disabled auto-merge August 10, 2026 13:58
@adibarra
adibarra deleted the agent/best-line-per-sku branch August 10, 2026 13:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants