Skip to content

Add FleetSim workload forecast backtests#2597

Open
haowu1234 wants to merge 3 commits into
vllm-project:mainfrom
haowu1234:codex/workload-archetype-forecasting
Open

Add FleetSim workload forecast backtests#2597
haowu1234 wants to merge 3 commits into
vllm-project:mainfrom
haowu1234:codex/workload-archetype-forecasting

Conversation

@haowu1234

@haowu1234 haowu1234 commented Jul 18, 2026

Copy link
Copy Markdown
Collaborator

Stacked PR / dependency

Depends on #2596. This PR is stacked on the FleetSim workload mixture primitives from #2596 and should be reviewed/merged after that PR. The lower commit 509738a74ba074aa0efe6006d60b67892f494007 belongs to #2596; the original #2554 implementation commit is cc66912d18197c8bc13ecd11ac726d0786da953c, and the latest review-fix commit is cd81a904b1d316a2b7b960746a0a76942988e681.

After #2596 merges, I will rebase this branch onto upstream/main so the final diff only contains the forecasting work.

Closes #2554.

Summary

  • Add versioned, content-free aggregate workload forecast windows with privacy validation.
  • Add seasonal, drift, and burst forecast fixtures.
  • Add static, reactive, moving-window, seasonal-naive, and linear-trend forecast baselines.
  • Convert forecast outputs into FleetSim mixture scenarios for sizing experiments.
  • Carry aggregate token demand into mixture capacity through per-window token_scale.
  • Add FleetOptimizer backtest reporting with advise-only recommendations kept separate from actuation records.
  • Include arrival, token/request, P95 total-token, P99 TTFT, and mixture-weight calibration errors in backtest scoring/reporting.
  • Add stale-data rollback, drift/burst/oscillation diagnostics, CLI/docs, and tests.
  • Fail closed on unknown aggregate-window fields, enforce privacy.allowed_dimensions, and reject incomplete holdout horizons.

Validation

Local validation on codex/workload-archetype-forecasting at cd81a904b1d316a2b7b960746a0a76942988e681:

  • python3 -m pytest tests/test_workload_forecasts.py tests/test_workload_forecast_optimizer.py tests/test_optimizer.py::TestCLISubcommands::test_forecast_backtest -q passed: 17 tests.
  • make agent-report ENV=cpu CHANGED_FILES="..." passed and selected make vllm-sr-sim-test.
  • make agent-ci-gate CHANGED_FILES="..." passed, including lint, structure checks, Go reference config contract lint, and FleetSim tests: 339 passed, 6 warnings.
  • Explicit CLI E2E passed with actual_required_gpus=45, recommended_method=seasonal_naive, empty actuation_records, and token-scale/error fields present.
  • Reviewer repro checks passed: multiplying holdout token totals/P50/P95 by 100 changes capacity 45 -> 1901 and seasonal score 0.0005697315067356653 -> 0.4955697315067356; unknown device_fingerprint is rejected; horizon 3 with only 2 holdout windows is rejected.

Optional remote clean-clone validation on ssh root@134.199.199.149:

  • Clone path: /root/codex-validation/semantic-router/semantic-router-workload-archetype-forecasting-review-20260719045508
  • Branch: codex/workload-archetype-forecasting
  • Commit: cd81a904b1d316a2b7b960746a0a76942988e681
  • make agent-report ENV=cpu CHANGED_FILES="..." passed and selected make vllm-sr-sim-test.
  • make agent-ci-gate CHANGED_FILES="..." passed: 339 passed, 6 warnings.
  • Explicit CLI E2E passed: REMOTE_FORECAST_CLI_E2E_PASS, actual_required_gpus=45, recommended_method=seasonal_naive, actuation_records=[].
  • Reviewer repro markers passed: REMOTE_TOKEN_REPRO_PASS, REMOTE_SCORE_REPRO_PASS, REMOTE_UNKNOWN_FIELD_REJECTED, REMOTE_SHORT_HORIZON_REJECTED.

Signed-off-by: haowu1234 <13258260125@163.com>
Signed-off-by: haowu1234 <13258260125@163.com>
@haowu1234
haowu1234 requested review from Xunzhuo and rootfs as code owners July 18, 2026 15:24
@netlify

netlify Bot commented Jul 18, 2026

Copy link
Copy Markdown

Deploy Preview for vllm-semantic-router ready!

Name Link
🔨 Latest commit cd81a90
🔍 Latest deploy log https://app.netlify.com/projects/vllm-semantic-router/deploys/6a5c587fd8172800085a2a1c
😎 Deploy Preview https://deploy-preview-2597--vllm-semantic-router.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@github-actions

Copy link
Copy Markdown
Contributor

👥 vLLM Semantic Team Notification

The following members have been identified for the changed files in this PR and have been automatically assigned when their GitHub accounts are assignable in this repository:

📁 src/fleet-sim

Owners: @FAUST-BENCHOU, @shraderdm, @drivebyer, @ramkrishs, @WUKUNTAI-0211, @AayushSaini101, @siloteemu
Files changed:

  • src/fleet-sim/README.md
  • src/fleet-sim/data/README.md
  • src/fleet-sim/data/workload_forecast_burst.json
  • src/fleet-sim/data/workload_forecast_drift.json
  • src/fleet-sim/data/workload_forecast_seasonal.json
  • src/fleet-sim/data/workload_mixture_burst.json
  • src/fleet-sim/data/workload_mixture_drift.json
  • src/fleet-sim/data/workload_mixture_nominal.json
  • src/fleet-sim/fleet_sim/api/models.py
  • src/fleet-sim/fleet_sim/api/routes/jobs.py
  • src/fleet-sim/fleet_sim/api/routes/workloads.py
  • src/fleet-sim/fleet_sim/api/runner.py
  • src/fleet-sim/fleet_sim/core/request.py
  • src/fleet-sim/fleet_sim/data/README.md
  • src/fleet-sim/fleet_sim/data/workload_forecast_burst.json
  • src/fleet-sim/fleet_sim/data/workload_forecast_drift.json
  • src/fleet-sim/fleet_sim/data/workload_forecast_seasonal.json
  • src/fleet-sim/fleet_sim/data/workload_mixture_burst.json
  • src/fleet-sim/fleet_sim/data/workload_mixture_drift.json
  • src/fleet-sim/fleet_sim/data/workload_mixture_nominal.json
  • src/fleet-sim/fleet_sim/optimizer/__init__.py
  • src/fleet-sim/fleet_sim/optimizer/forecast.py
  • src/fleet-sim/fleet_sim/optimizer/forecast_models.py
  • src/fleet-sim/fleet_sim/optimizer/mixture.py
  • src/fleet-sim/fleet_sim/optimizer/mixture_models.py
  • src/fleet-sim/fleet_sim/workload/__init__.py
  • src/fleet-sim/fleet_sim/workload/forecast.py
  • src/fleet-sim/fleet_sim/workload/forecasting.py
  • src/fleet-sim/fleet_sim/workload/mixture.py
  • src/fleet-sim/fleet_sim/workload/mixture_sampling.py
  • src/fleet-sim/fleet_sim/workload/mixture_validation.py
  • src/fleet-sim/run_sim.py
  • src/fleet-sim/tests/test_api.py
  • src/fleet-sim/tests/test_optimizer.py
  • src/fleet-sim/tests/test_workload_forecast_optimizer.py
  • src/fleet-sim/tests/test_workload_forecasts.py
  • src/fleet-sim/tests/test_workload_mixture_optimizer.py
  • src/fleet-sim/tests/test_workload_mixtures.py

vLLM

🎉 Thanks for your contributions!

This comment was automatically generated based on the OWNER files in the repository.

@github-actions

github-actions Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

✅ Supply Chain Security Report — All Clear

Scanner Status Findings
AST Codebase Scan (Py, Go, JS/TS, Rust) 29 finding(s) — MEDIUM: 22 · LOW: 7
AST PR Diff Scan No issues detected
Regex Fallback Scan No issues detected

Scanned at 2026-07-19T04:55:18.942Z · View full workflow logs

start_s=window.start_s,
duration_s=window.duration_s,
weights=dict(window.archetype_weights),
arrival_rate_multiplier=max(window.arrival_rate / base_lam, 1e-9),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

It looks like this conversion only carries arrival rate and archetype weights into the mixture scenario. total_tokens, token percentiles, and latency aggregates are dropped, so changing the observed token demand does not affect the capacity result or forecast score. I reproduced this by multiplying the holdout token totals and P95 values by 100: the required GPUs, method scores, and recommendation remained identical. Could the backtest incorporate these demand signals, or clearly narrow the schema and claims if they are intentionally unsupported?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Addressed in cd81a904b1d316a2b7b960746a0a76942988e681. Forecast windows now compute a per-window token_scale from aggregate tokens/request plus optional P50/P95 total-token aggregates against the source mixture CDF, and mixture capacity evaluation scales the token CDF before sizing. The backtest report/score also includes token/request, P95-token, and P99-TTFT calibration errors.

I reran the repro: multiplying holdout token totals/P50/P95 by 100 now changes required GPUs 45 -> 1901 and seasonal score 0.0005697315067356653 -> 0.4955697315067356.

forbidden = {_normalise_key(item) for item in privacy.forbidden_dimensions}
errors = []
for path, key in _walk_keys(raw_data):
if _normalise_key(key) in forbidden:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The privacy validation checks only names listed in forbidden_dimensions; allowed_dimensions is never enforced, and unknown fields are silently discarded by from_dict(). For example, adding a unique device_fingerprint to an aggregate window still passes validation, despite the content-free, low-cardinality contract. Could we validate window dimensions against an explicit allowlist so new high-cardinality identifiers fail closed?

@haowu1234 haowu1234 Jul 19, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Addressed in cd81a904b1d316a2b7b960746a0a76942988e681. AggregateWindow.from_dict() now preserves unknown window fields in extra_fields, and validation rejects fields outside the explicit aggregate-window schema instead of silently dropping them. privacy.allowed_dimensions is also enforced for model_class, slo_class, region, and archetype_weights.

The repro with device_fingerprint now fails closed with ForecastValidationError: aggregate_windows[0]: fields are not allowed by forecast window schema: ['device_fingerprint'].

if not scenario.holdout_windows:
raise ForecastBacktestError("holdout_windows are required for backtesting")
gammas = gammas or [round(1.0 + 0.1 * k, 1) for k in range(11)]
actual_windows = scenario.holdout_windows[: scenario.forecast_horizon_windows]

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Could we reject scenarios where forecast_horizon_windows exceeds the available holdout windows? The current slice and later zip() silently shorten the backtest—for example, a five-window horizon with only two holdouts validates and reports results for just two windows. That makes an incomplete evaluation look like a successful full-horizon backtest.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Addressed in cd81a904b1d316a2b7b960746a0a76942988e681. validate_forecast_scenario() now rejects forecast_horizon_windows when it exceeds the available holdout windows, and the backtest path keeps an explicit guard before slicing.

The repro with horizon 3 and only 2 holdout windows now raises ForecastValidationError: forecast_horizon_windows exceeds available holdout_windows: horizon=3 holdout_windows=2.

Signed-off-by: haowu1234 <13258260125@163.com>
@haowu1234

Copy link
Copy Markdown
Collaborator Author

Review follow-up pushed in cd81a904b1d316a2b7b960746a0a76942988e681.

What changed:

  • Carry aggregate token demand into forecast-to-mixture capacity via per-window token_scale from tokens/request plus optional P50/P95 total-token aggregates.
  • Include token/request, P95 total-token, and P99 TTFT calibration errors in backtest windows, method summaries, scoring, and JSON output.
  • Fail closed on unknown aggregate-window fields and enforce privacy.allowed_dimensions for allowed low-cardinality dimensions.
  • Reject scenarios where forecast_horizon_windows exceeds available holdout_windows.

Validation:

  • Local targeted pytest: 17 passed.
  • Local make agent-ci-gate CHANGED_FILES="...": 339 passed, 6 warnings.
  • Local CLI E2E: actual_required_gpus=45, recommended_method=seasonal_naive, empty actuation_records, token-scale/error fields present.
  • Remote clean-clone validation on ssh root@134.199.199.149 at /root/codex-validation/semantic-router/semantic-router-workload-archetype-forecasting-review-20260719045508: make agent-report, make agent-ci-gate (339 passed, 6 warnings), CLI E2E, and reviewer repro checks all passed.
  • Reviewer token-demand repro now changes capacity 45 -> 1901 and score 0.0005697315067356653 -> 0.4955697315067356; unknown device_fingerprint and short holdout horizon are rejected.

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.

research: forecast workload archetypes for proactive per-pool scaling

7 participants