Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,11 @@ describe('Chart overflow continuations', () => {
cy.wrap($continuation)
.find('[data-testid="overflow-continuation-label"]')
.should(($label) => {
expect(Number($label.attr('y'))).to.be.greaterThan(arrowY);
const offset = Number($label.attr('y')) - arrowY;
expect(
Math.abs(offset - 18) < 0.01 || Math.abs(offset + 12) < 0.01,
'label is below the arrow or uses the above-arrow bottom-edge fallback',
).to.equal(true);
});
});
cy.wrap($continuation)
Expand Down
53 changes: 24 additions & 29 deletions packages/app/cypress/e2e/overview.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ const AGENTX_LABEL_ZH = '长上下文多轮真实智能体场景(AgentX)';

const PAGE_TITLE = 'Inference Cost per Million Tokens';
const PAGE_TITLE_ZH = '推理每百万 token 成本';
const SOURCE_NOTE = 'Source: InferenceX & SemiAnalysis Market August 2025 AI Cloud TCO Model';
const SOURCE_LINK_TEXT = 'SemiAnalysis Market August 2025 AI Cloud TCO Model';
const SOURCE_NOTE_ZH = '来源:InferenceX 与 SemiAnalysis Market August 2025 AI Cloud TCO Model';
const SOURCE_NOTE = 'Source: InferenceX & SemiAnalysis Market July 2026 AI Cloud TCO Model';
const SOURCE_LINK_TEXT = 'SemiAnalysis Market July 2026 AI Cloud TCO Model';
const SOURCE_NOTE_ZH = '来源:InferenceX 与 SemiAnalysis Market July 2026 AI Cloud TCO Model';
const SOURCE_HREF = 'https://semianalysis.com/ai-cloud-tco-model/';
const SCOPE_METRIC = 'Hyperscaler cost';
const SCOPE_DIRECTION = '↓ Lower is better';
Expand Down Expand Up @@ -213,7 +213,7 @@ describe('Overview page', () => {
// its hover/focus/screen-reader label, never as visible text.
cy.get(
'[data-testid="overview-pair-value"][data-hardware="b200"] [data-testid="overview-cost-evidence-link"]',
).should('have.text', '$0.067');
).should('have.text', '$0.059');
cy.get(
'[data-testid="overview-pair-value"][data-hardware="b200"] [data-testid="overview-cost-evidence-link"]',
)
Expand All @@ -225,7 +225,7 @@ describe('Overview page', () => {
.and(
'have.attr',
'aria-label',
'Approximately $0.067. Estimated from validated benchmark runs. Open raw source dashboard for Jul 18: DeepSeek V4 Pro 1.6T · B200 · SGLang · FP4 · MTP',
'Approximately $0.059. Estimated from validated benchmark runs. Open raw source dashboard for Jul 18: DeepSeek V4 Pro 1.6T · B200 · SGLang · FP4 · MTP',
);
cy.get('[data-testid="overview-pair-missing"]').should('not.exist');
});
Expand Down Expand Up @@ -261,7 +261,7 @@ describe('Overview page', () => {
platform('b200').find('[data-testid="overview-cost-delta"]').should('not.exist');
platform('mi355x')
.find('[data-testid="overview-cost-delta"]')
.should('contain.text', '25%')
.should('contain.text', '-15%')
.and('have.attr', 'data-cost-polarity', 'cheaper')
.then(($badge) => {
// The shade lives on the cell now, never on the badge itself.
Expand All @@ -274,9 +274,9 @@ describe('Overview page', () => {
desktopModel('DeepSeek-V4-Pro', SINGLE_TURN).within(() => {
platform('gb200')
.find('[data-testid="overview-cost-delta"]')
.should('contain.text', '+80%')
.should('contain.text', '+71%')
.and('have.attr', 'data-cost-polarity', 'pricier');
// +80% saturates the alpha ramp; read the computed value so the
// +71% saturates the alpha ramp; read the computed value so the
// assertion survives the browser normalizing `0.40` to `0.4`.
expectCellTint('gb200', 'rgba(239, 68, 68, 0.4)');
// No read at the tier means nothing to grade — the cell stays untinted.
Expand Down Expand Up @@ -316,18 +316,13 @@ describe('Overview page', () => {
});
});

// Within the ±5% parity band the cell reads as even, not polarity.
// Outside the ±5% parity band the cell carries the matching polarity.
desktopModel('Kimi-K2.5').within(() => {
platform('b300')
.find('[data-testid="overview-cost-delta"]')
.should('contain.text', '+2%')
.and('have.attr', 'data-cost-polarity', 'even');
platform('b300').then(([cell]) => {
const [r, g, b] = getComputedStyle(cell.closest('td')!)
.backgroundColor.match(/\d+/g)!
.map(Number);
expect(Math.max(r, g, b) - Math.min(r, g, b)).to.be.lessThan(60);
});
.should('contain.text', '+11%')
.and('have.attr', 'data-cost-polarity', 'pricier');
expectCellTint('b300', 'rgba(239, 68, 68,');
});
});

Expand Down Expand Up @@ -440,7 +435,7 @@ describe('Overview page', () => {
// Priced from the AgentX rows alone — the single-turn sweep never leaks in.
cy.get(
'[data-testid="overview-pair-value"][data-hardware="b200"] [data-testid="overview-cost-evidence-link"]',
).should('have.text', '$0.072');
).should('have.text', '$0.064');
cy.get(
'[data-testid="overview-pair-value"][data-hardware="mi355x"] [data-testid="overview-cost-evidence-link"]',
).should('have.text', '$0.069');
Expand Down Expand Up @@ -508,7 +503,7 @@ describe('Overview page', () => {
cy.get(
'[data-testid="overview-pair-value"][data-hardware="mi355x"] [data-testid="overview-cost-evidence-link"]',
)
.should('have.text', '$0.061')
.should('have.text', '$0.062')
.and(
'have.attr',
'title',
Expand All @@ -517,7 +512,7 @@ describe('Overview page', () => {
.and(
'have.attr',
'aria-label',
'$0.061. Open raw source dashboard for Jul 18: Qwen3.5 397B · MI355X · SGLang · FP8 · MTP',
'$0.062. Open raw source dashboard for Jul 18: Qwen3.5 397B · MI355X · SGLang · FP8 · MTP',
)
.should('have.attr', 'href')
.and('include', '/inference?')
Expand All @@ -530,7 +525,7 @@ describe('Overview page', () => {
cy.get(
'[data-testid="overview-pair-value"][data-hardware="b200"] [data-testid="overview-cost-evidence-link"]',
)
.should('contain.text', '$0.082')
.should('contain.text', '$0.073')
.should('have.attr', 'href')
.and('include', 'i_prec=fp4')
.and('include', 'i_gpus=b200_sglang_mtp');
Expand Down Expand Up @@ -576,7 +571,7 @@ describe('Overview page', () => {
platform('gb300').within(() => {
cy.get('[data-testid="overview-pair-value"][data-hardware="gb300"]').should(
'contain.text',
'$0.113',
'$0.099',
);
cy.get('[data-testid="overview-cost-delta"][data-hardware="gb300"]').should(
'have.attr',
Expand Down Expand Up @@ -628,7 +623,7 @@ describe('Overview page', () => {
});

desktopModel('Qwen-3.5-397B-A17B', SINGLE_TURN).within(() => {
platform('b200').should('contain.text', '$0.139').and('contain.text', 'FP8');
platform('b200').should('contain.text', '$0.124').and('contain.text', 'FP8');
platform('mi355x').within(() => {
cy.get('[data-testid="overview-pair-value"][data-hardware="mi355x"]').should(
'contain.text',
Expand Down Expand Up @@ -659,7 +654,7 @@ describe('Overview page', () => {
platform('b300').within(() => {
cy.get('[data-testid="overview-pair-value"][data-hardware="b300"]').should(
'contain.text',
'$0.050',
'$0.049',
);
cy.get('[data-testid="overview-cost-delta"][data-hardware="b300"]')
.should('contain.text', '∞')
Expand Down Expand Up @@ -700,13 +695,13 @@ describe('Overview page', () => {
platform('mi355x').within(() => {
cy.get(
'[data-testid="overview-pair-value"][data-hardware="mi355x"] [data-testid="overview-cost-evidence-link"]',
).should('have.text', '$0.061');
).should('have.text', '$0.062');
});
});
mobileModel('DeepSeek-V4-Pro', SINGLE_TURN).within(() => {
cy.get(
'[data-testid="overview-pair-value"][data-hardware="b200"] [data-testid="overview-cost-evidence-link"]',
).should('have.text', '$0.067');
).should('have.text', '$0.059');
cy.get('[data-testid="overview-pair-missing"][data-hardware="gb300"]').should(
'have.attr',
'title',
Expand Down Expand Up @@ -915,8 +910,8 @@ describe('Overview page', () => {
.and('include', '原始数据仪表板:DeepSeek V4 Pro 1.6T · B200 · SGLang · FP4 · MTP');
cy.get('@estimatedB200')
.invoke('attr', 'aria-label')
.should('include', '约 $0.067。根据已验证的基准运行结果估算。');
cy.get('@estimatedB200').should('have.text', '$0.067');
.should('include', '约 $0.059。根据已验证的基准运行结果估算。');
cy.get('@estimatedB200').should('have.text', '$0.059');
cy.get('@estimatedB200')
.should('have.attr', 'href')
.and('include', '/zh/inference?')
Expand Down Expand Up @@ -958,7 +953,7 @@ describe('Overview page', () => {
cy.get('[data-testid="overview-model-scenario"]').should('have.text', AGENTX_LABEL_ZH);
cy.get(
'[data-testid="overview-pair-value"][data-hardware="b200"] [data-testid="overview-cost-evidence-link"]',
).should('have.text', '$0.072');
).should('have.text', '$0.064');
});
cy.contains('若某款芯片不支持 FP4 推测解码,则采用次优的可用配置。').should('exist');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ export default function ComparePerDollarPageClient({
className="underline hover:text-primary"
onClick={() => track('compare_per_dollar_tco_source_clicked', { slug })}
>
SemiAnalysis Market August 2025 Pricing Surveys &amp; AI Cloud TCO Model
SemiAnalysis Market July 2026 Pricing Surveys &amp; AI Cloud TCO Model
</a>
.
</p>
Expand Down
2 changes: 1 addition & 1 deletion packages/app/src/components/calculator/FleetPlanner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ export default function FleetPlanner({
className="underline hover:text-foreground"
href="https://semianalysis.com/ai-cloud-tco-model/"
>
SemiAnalysis Market August 2025 Pricing Surveys & AI Cloud TCO Model
SemiAnalysis Market July 2026 Pricing Surveys & AI Cloud TCO Model
<ExternalLinkIcon />
</Link>
</small>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1140,7 +1140,7 @@ function ThroughputCalculatorInner({ initialPercentile }: { initialPercentile: P
className="underline hover:text-foreground"
href="https://semianalysis.com/ai-cloud-tco-model/"
>
SemiAnalysis Market August 2025 Pricing Surveys & AI Cloud TCO Model
SemiAnalysis Market July 2026 Pricing Surveys & AI Cloud TCO Model
<ExternalLinkIcon />
</Link>
</small>
Expand Down
4 changes: 2 additions & 2 deletions packages/app/src/components/overview/overview-scorecard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export const OVERVIEW_STRINGS = {
// The unit is dropped from the visible line but kept for screen readers.
scopeAria: 'Hyperscaler cost per one million total tokens. Lower is better.',
sourcePrefix: 'Source: InferenceX & ',
sourceLinkText: 'SemiAnalysis Market August 2025 AI Cloud TCO Model',
sourceLinkText: 'SemiAnalysis Market July 2026 AI Cloud TCO Model',
tierNavLabel: 'SLO',
tierUnit: 'tok/s/user',
engineScopeNavLabel: 'Engine scope',
Expand Down Expand Up @@ -73,7 +73,7 @@ export const OVERVIEW_STRINGS = {
scopeDirection: '↓ 越低越好',
scopeAria: '超大规模云(hyperscaler)每百万总 token 成本,越低越好。',
sourcePrefix: '来源:InferenceX 与 ',
sourceLinkText: 'SemiAnalysis Market August 2025 AI Cloud TCO Model',
sourceLinkText: 'SemiAnalysis Market July 2026 AI Cloud TCO Model',
tierNavLabel: 'SLO',
tierUnit: 'tok/s/用户',
engineScopeNavLabel: '引擎范围',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ describe('MetricAssumptionNotes', () => {

expect(getVisibleText()).toContain('TCO $/GPU/hr:');
expect(getVisibleText()).toContain(
'SemiAnalysis Market August 2025 Pricing Surveys & AI Cloud TCO Model',
'SemiAnalysis Market July 2026 Pricing Surveys & AI Cloud TCO Model',
);
expect(getVisibleCaveatText()).toContain('calculate cost per decode GPU or per prefill GPU');
});
Expand Down
2 changes: 1 addition & 1 deletion packages/app/src/components/ui/chart-display-helpers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ export function MetricAssumptionNotes({
<>
<MetricBadges label={costLabel} values={costValues} />
<SourceLink href="https://semianalysis.com/ai-cloud-tco-model/" sourceLabel={sourceLabel}>
SemiAnalysis Market August 2025 Pricing Surveys & AI Cloud TCO Model
SemiAnalysis Market July 2026 Pricing Surveys & AI Cloud TCO Model
</SourceLink>
</>
)}
Expand Down
26 changes: 22 additions & 4 deletions packages/app/src/lib/constants.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,24 @@ describe('getHardwareConfig', () => {
expect(entry.costr).toBeGreaterThanOrEqual(0);
}
});

it('uses the July 2026 TCO rates for modeled datacenter GPUs', () => {
const expectedRates = {
h100: [1.168, 1.5501205804741525, 1.78],
h200: [1.2174257813639555, 1.5918579041035947, 2.05],
b200: [1.7349236084834354, 2.0693175588620671, 2.6],
b300: [2.2550110908541448, 2.5151486614356386, 3],
gb200: [1.8648110244453284, 2.263552701012252, 2.6],
gb300: [2.313899859674561, 2.7890137161029926, 3.3],
mi300x: [0.9535220083742874, 1.1567197344221469, 1.3],
mi325x: [1.0998080408523334, 1.3234578915100057, 1.6],
mi355x: [1.4960710469526235, 2.089023971578409, 2.1],
} as const;

for (const [gpu, [costh, costn, costr]] of Object.entries(expectedRates)) {
expect(HW_REGISTRY[gpu]).toMatchObject({ costh, costn, costr });
}
});
});

// ===========================================================================
Expand All @@ -197,9 +215,9 @@ describe('getGpuSpecs', () => {
it('returns specs for a base GPU key', () => {
const specs = getGpuSpecs('h100');
expect(specs.power).toBe(1.37);
expect(specs.costh).toBe(1.3);
expect(specs.costn).toBe(1.69);
expect(specs.costr).toBe(1.3);
expect(specs.costh).toBe(1.168);
expect(specs.costn).toBe(1.5501205804741525);
expect(specs.costr).toBe(1.78);
});

it('extracts base from compound key (e.g. h100_vllm)', () => {
Expand All @@ -210,7 +228,7 @@ describe('getGpuSpecs', () => {
it('extracts base from dash-separated key (e.g. h200-dynamo-trt)', () => {
const specs = getGpuSpecs('h200-dynamo-trt');
expect(specs.power).toBe(1.37);
expect(specs.costh).toBe(1.41);
expect(specs.costh).toBe(1.2174257813639555);
});

it('returns zero specs for unknown GPU', () => {
Expand Down
Loading