From a2fcc9716658be2f6d654358c6784ba89492dc38 Mon Sep 17 00:00:00 2001
From: Oseltamivir <58582368+Oseltamivir@users.noreply.github.com>
Date: Sun, 9 Aug 2026 20:37:10 +0800
Subject: [PATCH] fix(inference): retain clipped rows in table view
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Restore cost- and latency-clipped points when rendering inference tables while preserving chart display limits. Include clipped official and unofficial rows in visibility scopes and add component regression coverage.
中文:修复推理表格遗漏超出图表显示上限的数据行。表格恢复成本和延迟裁剪点,同时保留图表显示限制;官方与 unofficial overlay 路径均纳入可见范围并补充组件回归测试。
---
.../cypress/component/scatter-graph.cy.tsx | 104 ++++++++++++++++++
.../components/inference/ui/ChartDisplay.tsx | 34 +++++-
2 files changed, 133 insertions(+), 5 deletions(-)
diff --git a/packages/app/cypress/component/scatter-graph.cy.tsx b/packages/app/cypress/component/scatter-graph.cy.tsx
index d041b9a8..a4b6c380 100644
--- a/packages/app/cypress/component/scatter-graph.cy.tsx
+++ b/packages/app/cypress/component/scatter-graph.cy.tsx
@@ -938,6 +938,110 @@ describe('ScatterGraph', () => {
});
describe('ChartDisplay engine comparison guard', () => {
+ it('includes cost-clipped official and unofficial points in table mode', () => {
+ const chartDefinition = createMockChartDefinition({
+ chartType: 'interactivity',
+ x: 'median_intvty',
+ x_label: 'Interactivity (tok/s/user)',
+ y_costhOutput: 'costhOutput.y',
+ y_costhOutput_label: 'Cost per Million Output Tokens ($)',
+ y_costhOutput_roofline: 'lower_right',
+ y_cost_limit: 5,
+ });
+ const officialVisible = createMockInferenceData({
+ hwKey: 'b200_sglang',
+ precision: Precision.FP4,
+ tp: 4,
+ median_intvty: 134.7,
+ costhOutput: { y: 4, roof: true },
+ });
+ const officialClipped = createMockInferenceData({
+ hwKey: 'b200_sglang',
+ precision: Precision.FP4,
+ tp: 8,
+ median_intvty: 142.1,
+ costhOutput: { y: 7.016, roof: true },
+ });
+ const runUrl = 'https://github.com/x/y/actions/runs/707';
+ const overlayVisible = createMockInferenceData({
+ hwKey: 'h100_vllm',
+ precision: Precision.FP4,
+ tp: 4,
+ median_intvty: 130,
+ costhOutput: { y: 4.5, roof: true },
+ run_url: runUrl,
+ });
+ const overlayClipped = createMockInferenceData({
+ hwKey: 'h100_vllm',
+ precision: Precision.FP4,
+ tp: 8,
+ median_intvty: 145,
+ costhOutput: { y: 7.5, roof: true },
+ run_url: runUrl,
+ });
+ const runInfo = {
+ id: 707,
+ name: 'clipped-table-overlay',
+ branch: 'clipped-table-overlay',
+ sha: 'abc707',
+ createdAt: '2026-08-09T00:00:00Z',
+ url: runUrl,
+ conclusion: 'success',
+ status: 'completed',
+ isNonMainBranch: true,
+ };
+
+ mountWithProviders(, {
+ inference: {
+ graphs: [
+ {
+ model: Model.DeepSeek_R1,
+ sequence: Sequence.EightK_OneK,
+ chartDefinition,
+ data: [officialVisible],
+ clippedData: [{ point: officialClipped, reasons: ['cost'] }],
+ },
+ ],
+ selectedYAxisMetric: 'y_costhOutput',
+ selectedXAxisMode: 'interactivity',
+ activeHwTypes: new Set(['b200_sglang']),
+ hwTypesWithData: new Set(['b200_sglang']),
+ },
+ globalFilters: {
+ selectedModel: Model.DeepSeek_R1,
+ selectedSequence: Sequence.EightK_OneK,
+ effectiveSequence: Sequence.EightK_OneK,
+ },
+ unofficial: {
+ isUnofficialRun: true,
+ unofficialRunInfo: runInfo,
+ unofficialRunInfos: [runInfo],
+ runIndexByUrl: { [runUrl]: 0, '707': 0 },
+ getOverlayData: () => ({
+ data: [overlayVisible, overlayClipped],
+ hardwareConfig: hwConfig,
+ }),
+ activeOverlayHwTypes: new Set(['h100_vllm']),
+ allOverlayHwTypes: new Set(['h100_vllm']),
+ },
+ });
+
+ cy.get('[data-testid="inference-table-view-btn"]').click();
+ cy.get('[data-testid="inference-results-table"] tbody tr').should('have.length', 4);
+ cy.get('[data-testid="inference-results-table"] tbody')
+ .contains('tr', '7.0')
+ .should('contain.text', 'SGLang')
+ .find('td')
+ .eq(2)
+ .should('have.text', '8');
+ cy.get('[data-testid="inference-results-table"] tbody')
+ .contains('tr', '7.5')
+ .should('contain.text', 'vLLM')
+ .find('td')
+ .eq(2)
+ .should('have.text', '8');
+ });
+
it('keeps official table rows synchronized with legend state after a scope change', () => {
const chartDefinition = createMockChartDefinition({ chartType: 'interactivity' });
const baseInference = createMockInferenceContext();
diff --git a/packages/app/src/components/inference/ui/ChartDisplay.tsx b/packages/app/src/components/inference/ui/ChartDisplay.tsx
index 4de9bfe2..84df1055 100644
--- a/packages/app/src/components/inference/ui/ChartDisplay.tsx
+++ b/packages/app/src/components/inference/ui/ChartDisplay.tsx
@@ -415,7 +415,11 @@ export default function ChartDisplay() {
const overlayScope = useMemo(() => {
const eligibleKeys = new Set();
for (const overlay of [overlayDataByChartType.e2e, overlayDataByChartType.interactivity]) {
- for (const point of overlay?.data ?? []) {
+ const points = [
+ ...(overlay?.data ?? []),
+ ...(overlay?.clippedData ?? []).map((entry) => entry.point),
+ ];
+ for (const point of points) {
const key = String(point.hwKey);
if (
selectedPrecisions.includes(point.precision) &&
@@ -430,7 +434,8 @@ export default function ChartDisplay() {
const officialScope = useMemo(() => {
const eligibleKeys = new Set();
for (const graph of graphs) {
- for (const point of graph.data) {
+ const points = [...graph.data, ...(graph.clippedData ?? []).map((entry) => entry.point)];
+ for (const point of points) {
if (
selectedPrecisions.includes(point.precision) &&
matchesQuickFilters(point, quickFilters)
@@ -538,7 +543,9 @@ export default function ChartDisplay() {
if (graphs.length > 0) return graphs;
const hasOverlay =
(overlayDataByChartType.e2e?.data.length ?? 0) > 0 ||
- (overlayDataByChartType.interactivity?.data.length ?? 0) > 0;
+ (overlayDataByChartType.e2e?.clippedData?.length ?? 0) > 0 ||
+ (overlayDataByChartType.interactivity?.data.length ?? 0) > 0 ||
+ (overlayDataByChartType.interactivity?.clippedData?.length ?? 0) > 0;
if (!hasOverlay) return graphs;
return (chartDefinitions as ChartDefinition[]).map((chartDefinition) => ({
model: selectedModel,
@@ -835,9 +842,26 @@ export default function ChartDisplay() {
graph.chartDefinition.chartType,
overlayDataByChartType,
);
+ // Display limits keep outliers off the plotted domain but
+ // must not silently remove measured rows from the table.
+ // Restore both official and unofficial clipped points before
+ // applying the shared precision, quick-filter, and legend gates.
+ const tableOfficialData = [
+ ...graph.data,
+ ...(graph.clippedData ?? []).map((entry) => entry.point),
+ ];
+ const tableOverlay = overlay
+ ? {
+ ...overlay,
+ data: [
+ ...overlay.data,
+ ...(overlay.clippedData ?? []).map((entry) => entry.point),
+ ],
+ }
+ : overlay;
const { officialRows, overlayRows } = visibleComparisonRows(
- graph.data,
- overlay,
+ tableOfficialData,
+ tableOverlay,
);
return (
<>