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
7 changes: 3 additions & 4 deletions docs/dashboard-readonly-views.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ state. GPU interactive downsampling does not alter returned raw data or statisti
Power boundary labels are GPU Level Measured, GPU Level Provisioned (TDP), All in
Provisioned, and All in Measured. The last combines measured GPU power with modeled
unmeasured components and PUE; it is not a wall-meter measurement. These labels and
collapsed power-assumption/availability notes do not change metric IDs, API selectors,
power-assumption notes do not change metric IDs, API selectors,
or calculations. Profit comparison `powerLabel` display text follows the same names.
All in Measured watts and energy accept validated 8K/1K and AgentX rows through the
shared chart/API transform, including historical and unofficial rows. AgentX reuses
Expand All @@ -78,9 +78,8 @@ Dense profit charts reserve readable space per bar and scroll within the plot on
screens; captions and controls stay fixed. This is presentation-only: API selectors,
calculations, source identities and CSV rows are unchanged. PNG export includes the full
plot regardless of its current scroll position, so no API or skills contract change is needed.
Unavailable-estimate notices distinguish unpriced SKUs from missing measured-plus-modeled
estimates using the retained provisioned result identity. This explanatory grouping preserves
the API's existing rows, skip reasons, selectors and calculations.
Profit charts omit the per-configuration unavailable-estimate list. This is presentation-only;
the API retains skipped rows and reasons, and calculations and CSV exports are unchanged.
The GPU statistics table includes startup and warmup for all chips in the selected
series, regardless of chip visibility. It is separate from serving-window power,
J/token and selected-time-window calculations. Run telemetry is DB-first with an
Expand Down
11 changes: 5 additions & 6 deletions docs/powerx-system-power.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ experimental power controls with ↑↑↓↓ if they are hidden.
4. For a capacity comparison, open `/profit-estimator-per-gigawatt`, choose the
model and a supported interactivity target, then select **Compare both** in
Benchmark Config. Match each result's workload, engine and precision to the
inference selection. Expand **Unavailable estimates** for missing results;
hover or select a bar for its power basis and read the formula notes below.
inference selection. Hover or select a bar for its power basis and read the
formula notes below.

**Expected result:** the inference table includes rows with a valid selected
metric, including supported B200/H200 multi-node deployments. Selecting All in
Expand Down Expand Up @@ -175,10 +175,9 @@ Chart/table rows and target-based profit estimates answer different questions.
| `workload`, `hardware`, `model-domain` | Use a supported workload/profile and in-domain input; do not replace the missing estimate with zero or TDP. |

In **Compare both**, a valid provisioned result remains when its measured estimate
is unavailable. Configurations that cannot be priced at all are listed separately
from missing measured estimates. Measured-only mode never substitutes provisioned
watts. See [persistence and recovery](./powerx-persistence-recovery.md) for retained
telemetry and targeted repair; new power readings cannot be attached to old
is unavailable. Measured-only mode never substitutes provisioned watts. See
[persistence and recovery](./powerx-persistence-recovery.md) for retained telemetry
and targeted repair; new power readings cannot be attached to old
throughput results.

## Provenance and reproducible exports
Expand Down
9 changes: 4 additions & 5 deletions docs/powerx-system-power.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ AgentX 估算属于容量规划预览,不代表已完成 AgentX 校准,也
AgentX 预览;独立的 **Modeled Chassis AC** 指标仍仅支持 8K/1K 单轮结果。
4. 要比较容量,打开 `/profit-estimator-per-gigawatt`,选择模型和曲线支持的
交互性目标,再在 Benchmark Config 中选择 **Compare both**。逐项核对结果的
工作负载、引擎和精度是否与推理页面所选一致。展开 **Unavailable estimates**
查看缺失原因;悬停或选中柱形查看功耗依据,并阅读图表下方的公式说明。
工作负载、引擎和精度是否与推理页面所选一致。悬停或选中柱形查看功耗依据,
并阅读图表下方的公式说明。

**预期结果:**推理表格列出所选指标有效的记录,包括满足要求的 B200/H200 多节点
部署。All in Measured 不会包含所有 GPU 功耗有效的记录,还需满足下述输入要求。
Expand Down Expand Up @@ -151,9 +151,8 @@ NVL72 记录。利润规划始终要求 schema 2。
| 缺少成本、token 组成或预配功率 | 检查财务输入;即使功耗有效,也可能无法计算两种利润结果。 |
| `workload`、`hardware`、`model-domain` | 使用受支持的工作负载/profile 和定义域内的输入,不以零值或 TDP 替代缺失估算。 |

**Compare both** 在实测估算不可用时仍保留有效预配结果。完全无法定价的配置,与
仅缺少实测估算的配置分开列出;仅实测模式不会用预配功率代替。保留遥测和定向修复
方式见[持久化与恢复](./powerx-persistence-recovery.md);新采集的功率不能附到旧吞吐量上。
**Compare both** 在实测估算不可用时仍保留有效预配结果。仅实测模式不会用预配
功率代替。保留遥测和定向修复方式见[持久化与恢复](./powerx-persistence-recovery.md);新采集的功率不能附到旧吞吐量上。

## 来源与可复现导出

Expand Down
6 changes: 3 additions & 3 deletions docs/tco-calculator.md
Original file line number Diff line number Diff line change
Expand Up @@ -1135,7 +1135,7 @@ and the two can be collapsed into one once both are on master.
input / $0.06 cached / $1.20 output per M tok, the permanent 50%-off rate on its
pay-as-you-go page); the OpenRouter aggregate also sits below it. At 83
tok/s/user the B200, B300, GB200, and MI355X agentic curves are priced, and the
H100, H200, MI300X, and MI325X curves top out below it and list as not priced.
H100, H200, MI300X, and MI325X curves top out below it and are omitted at that target.
GLM 5.2/5.3 opens on a 10% model license fee and MiniMax M3 on 20%; Kimi K3
opens on the 30% `DEFAULT_LAB_CUT_PCT`. DeepSeek V4 Pro opens on 24 tok/s/user,
the speed DeepSeek's own API serves at, DeepSeek's peak-hour list price for
Expand All @@ -1144,14 +1144,14 @@ and the two can be collapsed into one once both are on master.
and a 0% model license fee, since the weights ship under the MIT license. At 24
tok/s/user the B200, B300, and MI355X agentic curves are priced; the
GB200, GB300, and H200 curves bottom out above it (their lowest measured
points sit at roughly 40, 30, and 27 tok/s/user) and list as not priced until
points sit at roughly 40, 30, and 27 tok/s/user) and are omitted until
a lower-interactivity run lands. DeepSeek V4.1 Flash opens on 125 tok/s/user,
the speed DeepSeek's own API serves the Flash tier at, DeepSeek's peak-hour
list price for `deepseek-flash` ($0.30 input / $0.006 cached / $1.20 output
per M tok; off-peak is half that), and a 0% model license fee, since the
weights ship under the MIT license. It entered the fleet on AgentX only (InferenceX#2961), so the page is
wired ahead of the first published rows; SKUs whose agentic curves stop short
of 125 tok/s/user list as not priced rather than extrapolated. A
of 125 tok/s/user are omitted rather than extrapolated. A
model with a list price gets a third Token Price option, `<vendor> list
price`, next to OpenRouter and Custom; the caption names the source in force and
links the lab's pricing page when the list price is used. Switching to Custom
Expand Down
83 changes: 12 additions & 71 deletions packages/app/cypress/e2e/profit-estimator.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,22 +95,10 @@ const chart = () => cy.get('[data-testid="profit-estimator-chart"]');
const chartSvg = () => chart().find('svg').filter(':has(.chart-root)').first();
const bars = () => chart().find('rect.bar');

function assertDisclosureOpen(testId: string, open: boolean) {
cy.get<HTMLDetailsElement>(`[data-testid="${testId}"]`).should(($details) => {
expect($details[0].open, `${testId} native disclosure state`).to.equal(open);
const content = $details[0].querySelector('p');
expect(content, `${testId} content`).not.to.equal(null);
// Cypress visibility omits native closed-details rendering in some browsers.
if (content && typeof content.checkVisibility === 'function') {
expect(content.checkVisibility(), `${testId} browser visibility`).to.equal(open);
}
});
}

// Clear the preceding chart before each case changes the viewport.
describe('Profit estimator power option', { testIsolation: true }, () => {
for (const locale of ['en', 'zh'] as const) {
it(`distinguishes unpriced SKUs from missing measured-power estimates (${locale})`, () => {
it(`keeps available estimates without a per-configuration warning list (${locale})`, () => {
stubOpenRouter();
const width = locale === 'en' ? 1280 : 390;
cy.viewport(width, 900);
Expand All @@ -135,34 +123,12 @@ describe('Profit estimator power option', { testIsolation: true }, () => {
.should('not.contain', 'H200')
.and('contain', 'B300')
.and('contain', 'GB300');
const unpriced = locale === 'en' ? 'Not priced:' : '未定价:';
const measured =
locale === 'en' ? 'Measured + modeled unavailable:' : '实测加建模估算不可用:';
cy.get('[data-testid="profit-power-unavailable"] > summary').click();
cy.get('[data-testid="profit-power-unavailable"] > p')
.should('be.visible')
.should(($notice) => {
const [baseline, measurement] = $notice.text().split(measured);
expect(baseline).to.contain(unpriced).and.to.contain('H200');
expect(baseline).not.to.contain('B300');
expect(measurement).to.contain('B300').and.to.contain('GB300');
expect(measurement).not.to.contain('H200');
expect(measurement).to.contain(
locale === 'en' ? 'no usable measured power' : '同一组基准测试数据点缺少有效功耗',
);
expect(measurement).to.contain(
locale === 'en'
? 'missing complete Grace or module power'
: '缺少完整的 Grace 或 module 功耗',
);
const bounds = $notice[0].getBoundingClientRect();
expect(bounds.left).to.be.at.least(0);
expect(bounds.right).to.be.at.most(width);
});
cy.get('[data-testid="profit-power-unavailable"]').scrollIntoView({
offset: { top: -70, left: 0 },
cy.get('[data-testid="profit-power-unavailable"]').should('not.exist');
chart().scrollIntoView();
cy.screenshot(`profit-no-unavailable-list-${locale}`, {
capture: 'viewport',
overwrite: true,
});
cy.screenshot(`profit-unavailable-basis-${locale}`, { capture: 'viewport', overwrite: true });
});

it(`prices DeepSeek Flash partial chassis with a one-line power note and CSV labels (${locale})`, () => {
Expand Down Expand Up @@ -202,30 +168,18 @@ describe('Profit estimator power option', { testIsolation: true }, () => {
},
);
const label = locale === 'en' ? 'Full-chassis extrapolation' : '整机外推';
const cpuReason =
locale === 'en'
? 'missing complete Grace or module power'
: '缺少完整的 Grace 或 module 功耗';
cy.get('#profit-target').should('have.value', '125');
chart().find('text.revenue-label').should('have.length', 3);
chart()
.should('contain', 'B200')
.and('contain', 'B300')
.and('contain', 'MI355X')
.and('contain', label);
cy.get('[data-testid="profit-power-unavailable"]')
.should('contain', 'GB300')
.and('contain', cpuReason);
assertDisclosureOpen('profit-power-unavailable', false);
cy.get('[data-testid="profit-power-unavailable"] > summary').click();
assertDisclosureOpen('profit-power-unavailable', true);
cy.get('[data-testid="profit-power-unavailable"] > p').should('be.visible');
cy.get('[data-testid="profit-power-unavailable"]').should('not.exist');
cy.get('[data-testid="profit-power-note"]')
.should('contain', locale === 'en' ? 'All in Measured' : '整体实测功耗')
.and('not.contain', locale === 'en' ? 'unmeasured components' : '未实测的组件');
cy.get('[data-testid="profit-power-assumptions"]').should('not.exist');
cy.get('[data-testid="profit-power-unavailable"] > summary').click();
assertDisclosureOpen('profit-power-unavailable', false);
cy.get('[data-testid="profit-power-note"]').then(($note) => {
const box = $note[0].getBoundingClientRect();
expect(box.left).to.be.at.least(0);
Expand Down Expand Up @@ -293,7 +247,7 @@ describe('Profit estimator power option', { testIsolation: true }, () => {
});

for (const currentValid of [true, false]) {
it(`dates historical power skips without current hardware metadata (${currentValid ? 'with current bars' : 'provisioned bars only'})`, () => {
it(`keeps historical provisioned bars when measured power is unavailable (${currentValid ? 'with current bars' : 'provisioned bars only'})`, () => {
stubOpenRouter();
cy.intercept('GET', '/api/v1/benchmarks*', (req) => {
const historical = req.query['date'] === PROFIT_HISTORY_DATE;
Expand All @@ -318,14 +272,6 @@ describe('Profit estimator power option', { testIsolation: true }, () => {
`/profit-estimator-per-gigawatt?c_power=compare&i_gpus=b200_sglang,b300_vllm&i_dstart=${PROFIT_HISTORY_DATE}&i_dend=${PROFIT_HISTORY_DATE}`,
{ onBeforeLoad: unlockPowerGate },
);
cy.get('[data-testid="profit-power-unavailable"]').should(
'contain',
`B300 (vLLM) (FP4) • ${PROFIT_HISTORY_DATE}`,
);
cy.get('[data-testid="profit-power-unavailable"]').should(
'contain',
`B200 (SGLang) (FP4) • ${PROFIT_HISTORY_DATE}`,
);
chart()
.find('text.revenue-label')
.should('have.length', currentValid ? 4 : 3);
Expand Down Expand Up @@ -361,7 +307,7 @@ describe('Profit estimator power option', { testIsolation: true }, () => {
chart().find('text.revenue-label').should('have.length', 7);
chart().should('contain', 'B200').and('contain', 'B300').and('contain', 'MI355X');
chart().should('contain', 'All in Measured').and('contain', 'All in Provisioned');
cy.get('[data-testid="profit-power-unavailable"]').should('contain', 'GB300');
cy.get('[data-testid="profit-power-unavailable"]').should('not.exist');
});

it('prices a GB200 NVL72 tray on its measured compute module and names the basis', () => {
Expand Down Expand Up @@ -421,10 +367,7 @@ describe('Profit estimator power option', { testIsolation: true }, () => {
.and('contain', 'DLC PUE 1.1');
cy.get('body').type('{esc}');
cy.get('[data-testid="option-help-content-profit-power"]').should('not.exist');
// Only GB300's measured estimate is unavailable; its provisioned estimate remains visible.
cy.get('[data-testid="profit-power-unavailable"]')
.should('contain', 'GB300')
.and('not.contain', 'GB200');
cy.get('[data-testid="profit-power-unavailable"]').should('not.exist');
chart().scrollIntoView();
cy.screenshot('profit-nvl72-compare-desktop', { capture: 'viewport', overwrite: true });
cy.viewport(393, 900);
Expand Down Expand Up @@ -611,10 +554,8 @@ describe('Profit estimator power option', { testIsolation: true }, () => {
cy.get('#profit-power').click();
cy.get('[role="option"]').contains('All in Measured').click();
// These existing fixtures intentionally have throughput but no validated power.
cy.get('[data-testid="profit-power-unavailable"]').should(
'contain',
'no usable measured power',
);
cy.get('[data-testid="profit-power-unavailable"]').should('not.exist');
cy.contains('No SKU can be priced for the current selection.').should('be.visible');
cy.get('#profit-target').should('have.value', '45');
cy.get('[data-testid="profit-model-selector"]').should('contain', 'Kimi K3');
cy.get('[data-testid="profit-price-source-selector"]').should('contain', 'Moonshot');
Expand Down
Loading
Loading