From 08921193a1d8717861c36d64893c97c8d306c071 Mon Sep 17 00:00:00 2001 From: Gahow Wang Date: Thu, 23 Jul 2026 18:09:24 +0800 Subject: [PATCH] Record structured attention experiment verdict --- runs/frontier-attn-structured-v0/.gitignore | 3 + ...structured-attention-prefill-predict.patch | 249 ++ .../analyze_predictor_ablation.py | 256 ++ .../analyze_trace_verdict.py | 304 +++ .../experiment-card.md | 82 + .../figure-prototype.png | Bin 0 -> 121411 bytes .../frontier-reference.json | 525 ++++ .../plot_figure_prototype.py | 72 + .../results/predictor-ablation.csv | 10 + .../results/predictor-ablation.json | 149 ++ .../results/trace-verdict.csv | 85 + .../results/trace-verdict.json | 2219 +++++++++++++++++ .../frontier-attn-structured-v0/run_replay.py | 126 + 13 files changed, 4080 insertions(+) create mode 100644 runs/frontier-attn-structured-v0/.gitignore create mode 100644 runs/frontier-attn-structured-v0/0001-Experiment-with-structured-attention-prefill-predict.patch create mode 100644 runs/frontier-attn-structured-v0/analyze_predictor_ablation.py create mode 100644 runs/frontier-attn-structured-v0/analyze_trace_verdict.py create mode 100644 runs/frontier-attn-structured-v0/experiment-card.md create mode 100644 runs/frontier-attn-structured-v0/figure-prototype.png create mode 100644 runs/frontier-attn-structured-v0/frontier-reference.json create mode 100644 runs/frontier-attn-structured-v0/plot_figure_prototype.py create mode 100644 runs/frontier-attn-structured-v0/results/predictor-ablation.csv create mode 100644 runs/frontier-attn-structured-v0/results/predictor-ablation.json create mode 100644 runs/frontier-attn-structured-v0/results/trace-verdict.csv create mode 100644 runs/frontier-attn-structured-v0/results/trace-verdict.json create mode 100644 runs/frontier-attn-structured-v0/run_replay.py diff --git a/runs/frontier-attn-structured-v0/.gitignore b/runs/frontier-attn-structured-v0/.gitignore new file mode 100644 index 0000000..e840b79 --- /dev/null +++ b/runs/frontier-attn-structured-v0/.gitignore @@ -0,0 +1,3 @@ +__pycache__/ +cache/ +replay/ diff --git a/runs/frontier-attn-structured-v0/0001-Experiment-with-structured-attention-prefill-predict.patch b/runs/frontier-attn-structured-v0/0001-Experiment-with-structured-attention-prefill-predict.patch new file mode 100644 index 0000000..ba761a4 --- /dev/null +++ b/runs/frontier-attn-structured-v0/0001-Experiment-with-structured-attention-prefill-predict.patch @@ -0,0 +1,249 @@ +From 1f8900a4ac64e45754b03d0aa7c1dddab65785cf Mon Sep 17 00:00:00 2001 +From: Gahow Wang +Date: Thu, 23 Jul 2026 15:27:40 +0800 +Subject: [PATCH] Experiment with structured attention prefill predictor + +--- + .../shared_prediction_model_manager.py | 16 +++- + .../sklearn_execution_time_predictor.py | 16 +++- + .../structured_attention_prefill.py | 79 +++++++++++++++++++ + .../unit/test_structured_attention_prefill.py | 59 ++++++++++++++ + 4 files changed, 165 insertions(+), 5 deletions(-) + create mode 100644 frontier/execution_time_predictor/structured_attention_prefill.py + create mode 100644 tests/unit/test_structured_attention_prefill.py + +diff --git a/frontier/execution_time_predictor/shared_prediction_model_manager.py b/frontier/execution_time_predictor/shared_prediction_model_manager.py +index 8a65a49..4a21165 100644 +--- a/frontier/execution_time_predictor/shared_prediction_model_manager.py ++++ b/frontier/execution_time_predictor/shared_prediction_model_manager.py +@@ -19,6 +19,9 @@ from frontier.execution_time_predictor.attention_tp_policy import ( + from frontier.execution_time_predictor.attention_dataset_contract import ( + enforce_mixed_attention_input_contract, + ) ++from frontier.execution_time_predictor.structured_attention_prefill import ( ++ StructuredAttentionPrefillRegressor, ++) + from frontier.logger import init_logger + from frontier.moe_gating_runtime import ( + DEFAULT_MOE_GATING_RUNTIME_CONTEXT, +@@ -1254,7 +1257,10 @@ class ExecutionTimePredictionModelManager: + raise ValueError( + "Missing required column 'prefill_chunk_size' in attention profiling data." + ) +- standard_prefill_df = prefill_df[prefill_df["prefill_chunk_size"] > 0].copy() ++ standard_prefill_df = prefill_df[ ++ (prefill_df["prefill_chunk_size"] > 0) ++ & (prefill_df["batch_size"] == 1) ++ ].copy() + + prefill_model_signature = f"attn_prefill_{attention_signature}" + if prefill_model_signature not in trained_model_signatures: +@@ -1742,7 +1748,13 @@ class ExecutionTimePredictionModelManager: + # initialization to generate missing cache files. + # ============================================================ + +- estimator, grid_search_params = self._create_estimator_and_params(execution_time_predictor_config) ++ if model_name == "attn_prefill": ++ estimator = StructuredAttentionPrefillRegressor() ++ grid_search_params = {} ++ else: ++ estimator, grid_search_params = self._create_estimator_and_params( ++ execution_time_predictor_config ++ ) + + cv = min(execution_time_predictor_config.k_fold_cv_splits, len(df)) if len(df) >= 2 else 2 + +diff --git a/frontier/execution_time_predictor/sklearn_execution_time_predictor.py b/frontier/execution_time_predictor/sklearn_execution_time_predictor.py +index 27b62bf..b7f5350 100644 +--- a/frontier/execution_time_predictor/sklearn_execution_time_predictor.py ++++ b/frontier/execution_time_predictor/sklearn_execution_time_predictor.py +@@ -45,6 +45,9 @@ from frontier.execution_time_predictor.attention_tp_policy import ( + from frontier.execution_time_predictor.attention_dataset_contract import ( + enforce_mixed_attention_input_contract, + ) ++from frontier.execution_time_predictor.structured_attention_prefill import ( ++ StructuredAttentionPrefillRegressor, ++) + from frontier.logger import init_logger + from frontier.moe_gating_runtime import get_moe_gating_base_model_name + from frontier.profiling.cpu_overhead.schema import ( +@@ -2573,8 +2576,12 @@ class SklearnExecutionTimePredictor(BaseExecutionTimePredictor): + if cached_model: + return cached_model + +- model = self._get_estimator() +- grid_search_params = self._get_grid_search_params() ++ if model_name == "attn_prefill": ++ model = StructuredAttentionPrefillRegressor() ++ grid_search_params = {} ++ else: ++ model = self._get_estimator() ++ grid_search_params = self._get_grid_search_params() + + if len(df) < self._config.k_fold_cv_splits: + cv = 2 +@@ -2869,7 +2876,10 @@ class SklearnExecutionTimePredictor(BaseExecutionTimePredictor): + raise ValueError( + "Missing required column 'prefill_chunk_size' in attention profiling data." + ) +- standard_prefill_df = prefill_df[prefill_df["prefill_chunk_size"] > 0].copy() ++ standard_prefill_df = prefill_df[ ++ (prefill_df["prefill_chunk_size"] > 0) ++ & (prefill_df["batch_size"] == 1) ++ ].copy() + if len(standard_prefill_df) == 0: + raise ValueError( + "No standard prefill rows (prefill_chunk_size > 0) found in eager attention profiling data." +diff --git a/frontier/execution_time_predictor/structured_attention_prefill.py b/frontier/execution_time_predictor/structured_attention_prefill.py +new file mode 100644 +index 0000000..1829047 +--- /dev/null ++++ b/frontier/execution_time_predictor/structured_attention_prefill.py +@@ -0,0 +1,79 @@ ++"""Structured latency model for single-request chunked prefill attention.""" ++ ++from typing import Any ++ ++import numpy as np ++from sklearn.base import BaseEstimator, RegressorMixin ++from sklearn.isotonic import IsotonicRegression ++from sklearn.linear_model import LinearRegression ++ ++ ++class StructuredAttentionPrefillRegressor(RegressorMixin, BaseEstimator): ++ """Model attention as a monotone base curve plus continuous KV growth. ++ ++ Input columns retain the existing Frontier contract: ++ ``[kv_cache_size, prefill_chunk_size_squared]``. ++ """ ++ ++ def fit(self, X: Any, y: Any) -> "StructuredAttentionPrefillRegressor": ++ values = self._as_feature_array(X) ++ target = np.asarray(y, dtype=float) ++ kv_cache_size = values[:, 0] ++ prefill_chunk_size = np.sqrt(np.maximum(values[:, 1], 0.0)) ++ ++ base_mask = np.isclose(kv_cache_size, 0.0) ++ growth_mask = kv_cache_size > 0.0 ++ if not np.any(base_mask) or not np.any(growth_mask): ++ raise ValueError( ++ "structured attn_prefill training requires both KV=0 base rows " ++ "and KV>0 growth rows" ++ ) ++ ++ base_q = prefill_chunk_size[base_mask] ++ base_y = target[base_mask] ++ unique_q = np.unique(base_q) ++ grouped_y = np.asarray( ++ [np.mean(base_y[np.isclose(base_q, q)]) for q in unique_q], ++ dtype=float, ++ ) ++ self._base_model = IsotonicRegression( ++ increasing=True, ++ out_of_bounds="clip", ++ ).fit(unique_q, grouped_y) ++ ++ growth_q = prefill_chunk_size[growth_mask] ++ growth_kv = kv_cache_size[growth_mask] ++ growth_base = self._base_model.predict(growth_q) ++ growth_features = np.column_stack( ++ (growth_kv, growth_q * growth_kv) ++ ) ++ self._growth_model = LinearRegression( ++ fit_intercept=False, ++ positive=True, ++ ).fit(growth_features, target[growth_mask] - growth_base) ++ ++ self.n_features_in_ = 2 ++ self._frontier_base_q_min = float(unique_q.min()) ++ self._frontier_base_q_max = float(unique_q.max()) ++ self._frontier_growth_kv_max = float(growth_kv.max()) ++ return self ++ ++ def predict(self, X: Any) -> np.ndarray: ++ values = self._as_feature_array(X) ++ kv_cache_size = values[:, 0] ++ prefill_chunk_size = np.sqrt(np.maximum(values[:, 1], 0.0)) ++ base = self._base_model.predict(prefill_chunk_size) ++ growth_features = np.column_stack( ++ (kv_cache_size, prefill_chunk_size * kv_cache_size) ++ ) ++ return np.maximum(base + self._growth_model.predict(growth_features), 0.0) ++ ++ @staticmethod ++ def _as_feature_array(X: Any) -> np.ndarray: ++ values = np.asarray(X, dtype=float) ++ if values.ndim != 2 or values.shape[1] != 2: ++ raise ValueError( ++ "structured attn_prefill expects exactly two features: " ++ "kv_cache_size and prefill_chunk_size_squared" ++ ) ++ return values +diff --git a/tests/unit/test_structured_attention_prefill.py b/tests/unit/test_structured_attention_prefill.py +new file mode 100644 +index 0000000..12c4247 +--- /dev/null ++++ b/tests/unit/test_structured_attention_prefill.py +@@ -0,0 +1,59 @@ ++import pickle ++import unittest ++ ++import numpy as np ++ ++from frontier.execution_time_predictor.structured_attention_prefill import ( ++ StructuredAttentionPrefillRegressor, ++) ++ ++ ++class StructuredAttentionPrefillRegressorTest(unittest.TestCase): ++ def setUp(self) -> None: ++ q = np.asarray([64, 128, 256, 512, 1024, 2048, 4096, 8192], dtype=float) ++ base = 0.05 + 1e-4 * q + 4e-8 * q**2 ++ context_q = np.asarray([2048, 4096, 8192] * 3, dtype=float) ++ context_kv = np.repeat([8192, 16384, 24576], 3).astype(float) ++ context_y = ( ++ np.interp(context_q, q, base) ++ + 1.5e-5 * context_kv ++ + 3e-8 * context_q * context_kv ++ ) ++ self.X = np.column_stack( ++ ( ++ np.concatenate((np.zeros_like(q), context_kv)), ++ np.concatenate((q**2, context_q**2)), ++ ) ++ ) ++ self.y = np.concatenate((base, context_y)) ++ ++ def test_recovers_structured_curve(self) -> None: ++ model = StructuredAttentionPrefillRegressor().fit(self.X, self.y) ++ np.testing.assert_allclose(model.predict(self.X), self.y, rtol=1e-6) ++ ++ def test_prediction_is_nonnegative_and_monotone(self) -> None: ++ model = StructuredAttentionPrefillRegressor().fit(self.X, self.y) ++ q = np.arange(1, 8193, dtype=float) ++ for kv in (0, 8192, 32768, 40912): ++ X = np.column_stack((np.full_like(q, kv), q**2)) ++ prediction = model.predict(X) ++ self.assertTrue(np.all(prediction >= 0)) ++ self.assertTrue(np.all(np.diff(prediction) >= -1e-12)) ++ ++ kv = np.arange(0, 40913, 64, dtype=float) ++ for q_value in (64, 2048, 8192): ++ X = np.column_stack((kv, np.full_like(kv, q_value**2))) ++ self.assertTrue(np.all(np.diff(model.predict(X)) >= -1e-12)) ++ ++ def test_pickle_round_trip(self) -> None: ++ model = StructuredAttentionPrefillRegressor().fit(self.X, self.y) ++ restored = pickle.loads(pickle.dumps(model)) ++ np.testing.assert_allclose(restored.predict(self.X), self.y, rtol=1e-6) ++ ++ def test_requires_base_and_growth_rows(self) -> None: ++ with self.assertRaisesRegex(ValueError, "KV=0 base rows"): ++ StructuredAttentionPrefillRegressor().fit(self.X[:8], self.y[:8]) ++ ++ ++if __name__ == "__main__": ++ unittest.main() +-- +2.43.0 + diff --git a/runs/frontier-attn-structured-v0/analyze_predictor_ablation.py b/runs/frontier-attn-structured-v0/analyze_predictor_ablation.py new file mode 100644 index 0000000..4eb79ce --- /dev/null +++ b/runs/frontier-attn-structured-v0/analyze_predictor_ablation.py @@ -0,0 +1,256 @@ +#!/usr/bin/env python3 +"""Offline predictor ablation for EXP-ATTN-STRUCTURED. + +This is deliberately profile-only: it decides whether the structured model is +good enough to justify the expensive 7-cell trace replay. +""" + +from __future__ import annotations + +import argparse +import csv +import json +import sys +from pathlib import Path +from typing import Any + +import numpy as np +import pandas as pd +from sklearn.ensemble import RandomForestRegressor + +ROOT = Path(__file__).resolve().parent +REPO = ROOT.parents[1] + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser() + parser.add_argument( + "--profile", + type=Path, + default=REPO + / "runs/frontier-prefill-kvgrowth-fix-v0/profiles/" + "profile-v5-kvgrowth/attention.csv", + ) + parser.add_argument( + "--frontier-checkout", + type=Path, + default=Path("/tmp/frontier-attn-structured-v0"), + ) + parser.add_argument("--output-root", type=Path, default=ROOT / "results") + return parser.parse_args() + + +def normalize_bool(series: pd.Series) -> pd.Series: + return series.astype(str).str.strip().str.lower().isin( + {"1", "true", "t", "yes", "y"} + ) + + +def load_profile(path: Path) -> pd.DataFrame: + df = pd.read_csv(path).drop_duplicates() + for column in ("is_prefill", "is_true_mixed_batch"): + df[column] = normalize_bool(df[column]) + df = df[ + (df["n_embd"] == 2048) + & (df["n_q_head"] == 32) + & (df["n_kv_head"] == 4) + & (df["block_size"] == 16) + & df["is_prefill"] + & ~df["is_true_mixed_batch"] + & (df["prefill_chunk_size"] > 0) + ].copy() + df["prefill_chunk_size_squared"] = df["prefill_chunk_size"] ** 2 + return df + + +def mape(actual: np.ndarray, predicted: np.ndarray) -> float: + return float(np.mean(np.abs((predicted - actual) / actual)) * 100) + + +def make_rf() -> RandomForestRegressor: + # Exact best parameters selected by the current profile-v5 GridSearchCV. + return RandomForestRegressor( + random_state=0, + n_estimators=250, + max_depth=8, + min_samples_split=2, + ) + + +def features(df: pd.DataFrame) -> pd.DataFrame: + return df[["kv_cache_size", "prefill_chunk_size_squared"]] + + +def score_model( + name: str, + estimator: Any, + train: pd.DataFrame, + single: pd.DataFrame, + grid: pd.DataFrame, +) -> dict[str, Any]: + target = "time_stats.attn_prefill.median" + estimator.fit(features(train), train[target]) + grid_prediction = estimator.predict(features(grid)) + single_prediction = estimator.predict(features(single)) + + heldout_actual: list[float] = [] + heldout_prediction: list[float] = [] + for context in sorted(grid["kv_cache_size"].unique()): + test = grid[grid["kv_cache_size"] == context] + fold_train = train.drop(index=test.index, errors="ignore") + fold_model = ( + make_rf() + if name.startswith("rf") + else estimator.__class__() + ) + fold_model.fit(features(fold_train), fold_train[target]) + heldout_actual.extend(test[target].astype(float)) + heldout_prediction.extend(fold_model.predict(features(test))) + + q = np.arange(1, 8193, dtype=float) + q_deltas: list[float] = [] + prediction_min: list[float] = [] + for context in (0, 8192, 16384, 24576, 32768, 40912): + X = pd.DataFrame( + { + "kv_cache_size": np.full_like(q, context), + "prefill_chunk_size_squared": q**2, + } + ) + prediction = estimator.predict(X) + prediction_min.append(float(prediction.min())) + q_deltas.append(float(np.diff(prediction).min())) + + kv = np.arange(0, 40913, 64, dtype=float) + kv_deltas: list[float] = [] + for query in (64, 512, 2048, 4096, 8192): + X = pd.DataFrame( + { + "kv_cache_size": kv, + "prefill_chunk_size_squared": np.full_like(kv, query**2), + } + ) + kv_deltas.append(float(np.diff(estimator.predict(X)).min())) + + heldout_actual_array = np.asarray(heldout_actual) + heldout_prediction_array = np.asarray(heldout_prediction) + return { + "candidate": name, + "training_rows": len(train), + "grid_fit_mape_pct": mape( + grid[target].to_numpy(), np.asarray(grid_prediction) + ), + "single_fit_mape_pct": mape( + single[target].to_numpy(), np.asarray(single_prediction) + ), + "heldout_context_mape_pct": mape( + heldout_actual_array, heldout_prediction_array + ), + "heldout_context_max_abs_error_pct": float( + np.max( + np.abs( + (heldout_prediction_array - heldout_actual_array) + / heldout_actual_array + ) + ) + * 100 + ), + "prediction_min_ms": min(prediction_min), + "q_min_delta_ms": min(q_deltas), + "kv_min_delta_ms": min(kv_deltas), + "monotone_and_nonnegative": ( + min(prediction_min) >= 0 + and min(q_deltas) >= -1e-12 + and min(kv_deltas) >= -1e-12 + ), + } + + +def main() -> None: + args = parse_args() + sys.path.insert(0, str(args.frontier_checkout)) + from frontier.execution_time_predictor.structured_attention_prefill import ( + StructuredAttentionPrefillRegressor, + ) + + df = load_profile(args.profile) + records: list[dict[str, Any]] = [] + data_audit: dict[str, Any] = {} + for tp in (1, 2, 4): + tp_df = df[df["num_tensor_parallel_workers"] == tp].copy() + single = tp_df[tp_df["batch_size"] == 1].copy() + grid = single[ + single["prefill_chunk_size"].isin((2048, 4096, 8192)) + & (single["kv_cache_size"] > 0) + ].copy() + duplicate_groups = ( + tp_df.groupby( + ["kv_cache_size", "prefill_chunk_size_squared"] + ) + .size() + .gt(1) + .sum() + ) + data_audit[f"tp{tp}"] = { + "standard_rows": len(tp_df), + "single_request_rows": len(single), + "target_grid_rows": len(grid), + "duplicate_feature_groups": int(duplicate_groups), + } + + candidates = ( + ("rf_all", make_rf(), tp_df), + ("rf_single", make_rf(), single), + ( + "structured_single", + StructuredAttentionPrefillRegressor(), + single, + ), + ) + for name, model, train in candidates: + result = score_model(name, model, train, single, grid) + result["tp"] = tp + records.append(result) + + structured = [r for r in records if r["candidate"] == "structured_single"] + checks = { + "heldout_context_mape_le_5pct": all( + r["heldout_context_mape_pct"] <= 5 for r in structured + ), + "monotone_and_nonnegative": all( + r["monotone_and_nonnegative"] for r in structured + ), + } + checks["profile_gate"] = all(checks.values()) + payload = { + "schema": "frontier-attn-structured-ablation-v1", + "profile": str(args.profile.resolve()), + "frontier_checkout": str(args.frontier_checkout.resolve()), + "data_audit": data_audit, + "results": records, + "checks": checks, + } + + args.output_root.mkdir(parents=True, exist_ok=True) + (args.output_root / "predictor-ablation.json").write_text( + json.dumps(payload, indent=2) + ) + with (args.output_root / "predictor-ablation.csv").open( + "w", newline="" + ) as stream: + writer = csv.DictWriter(stream, fieldnames=list(records[0])) + writer.writeheader() + writer.writerows(records) + print(json.dumps(checks, indent=2)) + for row in records: + print( + f"TP{row['tp']} {row['candidate']:18s} " + f"grid={row['grid_fit_mape_pct']:.2f}% " + f"heldout={row['heldout_context_mape_pct']:.2f}% " + f"max={row['heldout_context_max_abs_error_pct']:.2f}% " + f"monotone={row['monotone_and_nonnegative']}" + ) + + +if __name__ == "__main__": + main() diff --git a/runs/frontier-attn-structured-v0/analyze_trace_verdict.py b/runs/frontier-attn-structured-v0/analyze_trace_verdict.py new file mode 100644 index 0000000..d8def59 --- /dev/null +++ b/runs/frontier-attn-structured-v0/analyze_trace_verdict.py @@ -0,0 +1,304 @@ +#!/usr/bin/env python3 +"""Trial-aware verdict for the seven structured-attention trace replays.""" + +from __future__ import annotations + +import csv +import json +import math +from pathlib import Path +from typing import Any + +ROOT = Path(__file__).resolve().parent +REPO = ROOT.parents[1] +S3_REAL = REPO / "runs/frontier-s3-real-v0" +V5 = REPO / "runs/frontier-prefill-kvgrowth-fix-v0" + +CELLS = { + "tp1_rho0p00125": { + "real": "frontier-tp1-real-r0p00125-t*", + "old": V5 / "sim-replay-tp1/v5/tp1_rho0p00125", + }, + "tp1_rho0p0025": { + "real": "frontier-tp1-real-r0p0025-t*", + "old": V5 / "sim-replay-tp1/v5/tp1_rho0p0025", + }, + "tp2_rho0p0025": { + "real": "frontier-s3-real-full-r0p0025-tp2-t*", + "old": V5 / "sim-replay/tp2_rho0p0025", + }, + "tp2_rho0p005": { + "real": "frontier-s3-real-full-r0p005-tp2-t*", + "old": V5 / "sim-replay/tp2_rho0p005", + }, + "tp4_rho0p0025": { + "real": "frontier-s3-real-full-r0p0025-tp4-t*", + "old": V5 / "sim-replay/tp4_rho0p0025", + }, + "tp4_rho0p005": { + "real": "frontier-s3-real-full-r0p005-tp4-t*", + "old": V5 / "sim-replay/tp4_rho0p005", + }, + "tp4_rho0p01": { + "real": "frontier-s3-real-full-r0p01-tp4-t*", + "old": V5 / "sim-replay/tp4_rho0p01", + }, +} +METRICS = { + "ttft": ("ttft_ms", "ttft"), + "tpot": ("tpot_ms", "tpot"), + "e2e": ("e2e_ms", "request_e2e_time"), +} +QUANTILES = {"mean": None, "p50": 0.5, "p90": 0.9, "p99": 0.99} + + +def percentile(values: list[float], quantile: float) -> float: + ordered = sorted(values) + position = (len(ordered) - 1) * quantile + lower, upper = math.floor(position), math.ceil(position) + if lower == upper: + return ordered[lower] + return ( + ordered[lower] * (upper - position) + + ordered[upper] * (position - lower) + ) + + +def summarize(values: list[float]) -> dict[str, float]: + return { + name: ( + sum(values) / len(values) + if quantile is None + else percentile(values, quantile) + ) + for name, quantile in QUANTILES.items() + } + + +def load_real_trials(pattern: str) -> list[list[dict[str, Any]]]: + trials = [] + for run_root in sorted((S3_REAL / "fleet-artifacts").glob(pattern)): + results = list( + run_root.glob( + "artifacts/outputs/full-real/*/*/trial-*/results/result.json" + ) + ) + if len(results) != 1: + raise ValueError(f"expected one result in {run_root}, got {results}") + trials.append(json.loads(results[0].read_text())["requests"]) + if len(trials) != 2: + raise ValueError(f"expected two real trials for {pattern}, got {len(trials)}") + return trials + + +def load_sim(root: Path) -> list[dict[str, str]]: + matches = list((root / "metrics").rglob("request_metrics.csv")) + if len(matches) != 1: + raise ValueError(f"expected one request_metrics.csv below {root}: {matches}") + rows = list(csv.DictReader(matches[0].open())) + rows.sort(key=lambda row: int(float(row["Request Id"]))) + return rows + + +def distribution_bias( + real_rows: list[dict[str, Any]], + sim_rows: list[dict[str, str]], +) -> dict[str, dict[str, float]]: + output: dict[str, dict[str, float]] = {} + for metric, (real_key, sim_key) in METRICS.items(): + pairs = [ + (float(real[real_key]), float(sim[sim_key])) + for real, sim in zip(real_rows, sim_rows) + if real.get("success") + ] + real_summary = summarize([pair[0] for pair in pairs]) + sim_summary = summarize([pair[1] for pair in pairs]) + output[metric] = { + name: (sim_summary[name] - real_summary[name]) / real_summary[name] + for name in QUANTILES + } + return output + + +def paired_relative_error( + real_rows: list[dict[str, Any]], + sim_rows: list[dict[str, str]], +) -> dict[str, dict[str, float]]: + output: dict[str, dict[str, float]] = {} + for metric, (real_key, sim_key) in METRICS.items(): + errors = [ + (float(sim[sim_key]) - float(real[real_key])) / float(real[real_key]) + for real, sim in zip(real_rows, sim_rows) + if real.get("success") and float(real[real_key]) != 0 + ] + output[metric] = summarize(errors) + return output + + +def aggregate_trial_bias( + trial_biases: list[dict[str, dict[str, float]]], +) -> dict[str, dict[str, dict[str, float]]]: + return { + metric: { + quantile: { + "mean": sum(values) / len(values), + "min": min(values), + "max": max(values), + } + for quantile in QUANTILES + for values in [ + [trial[metric][quantile] for trial in trial_biases] + ] + } + for metric in METRICS + } + + +def legacy_pooled_bias( + real_trials: list[list[dict[str, Any]]], + sim_rows: list[dict[str, str]], +) -> dict[str, dict[str, float]]: + output: dict[str, dict[str, float]] = {} + for metric, (real_key, sim_key) in METRICS.items(): + real_values = [ + float(row[real_key]) + for trial in real_trials + for row in trial[: len(sim_rows)] + if row.get("success") + ] + sim_values = [float(row[sim_key]) for row in sim_rows] + real_summary = summarize(real_values) + sim_summary = summarize(sim_values) + output[metric] = { + name: (sim_summary[name] - real_summary[name]) / real_summary[name] + for name in QUANTILES + } + return output + + +def waiting_p99(sim_rows: list[dict[str, str]]) -> float: + return percentile( + [float(row["request_waiting_time_total"]) for row in sim_rows], 0.99 + ) + + +def main() -> None: + results: dict[str, Any] = {} + flat_rows: list[dict[str, Any]] = [] + for label, paths in CELLS.items(): + real_trials = load_real_trials(paths["real"]) + old_sim = load_sim(paths["old"]) + new_sim = load_sim(ROOT / "replay" / label) + old_trial_bias = [ + distribution_bias(trial, old_sim) for trial in real_trials + ] + new_trial_bias = [ + distribution_bias(trial, new_sim) for trial in real_trials + ] + old_legacy = legacy_pooled_bias(real_trials, old_sim) + new_legacy = legacy_pooled_bias(real_trials, new_sim) + wait_p99 = waiting_p99(new_sim) + results[label] = { + "old": { + "trialwise_distribution_bias": old_trial_bias, + "trialwise_distribution_bias_summary": aggregate_trial_bias( + old_trial_bias + ), + "legacy_pooled_distribution_bias": old_legacy, + }, + "new": { + "trialwise_distribution_bias": new_trial_bias, + "trialwise_distribution_bias_summary": aggregate_trial_bias( + new_trial_bias + ), + "paired_relative_error": [ + paired_relative_error(trial, new_sim) + for trial in real_trials + ], + "legacy_pooled_distribution_bias": new_legacy, + "waiting_p99_ms": wait_p99, + "validity": ( + "PASS_SUBCRITICAL" + if wait_p99 < 1000 + else "GATE_FAIL_DIAGNOSTIC" + ), + }, + } + for metric in METRICS: + for quantile in QUANTILES: + flat_rows.append( + { + "cell": label, + "metric": metric, + "quantile": quantile, + "old_bias": old_legacy[metric][quantile], + "new_bias": new_legacy[metric][quantile], + "abs_bias_delta_pp": 100 + * ( + abs(new_legacy[metric][quantile]) + - abs(old_legacy[metric][quantile]) + ), + "validity": results[label]["new"]["validity"], + } + ) + + tp1_checks = [] + for cell in ("tp1_rho0p00125", "tp1_rho0p0025"): + for quantile in ("mean", "p99"): + old = results[cell]["old"]["legacy_pooled_distribution_bias"]["ttft"][ + quantile + ] + new = results[cell]["new"]["legacy_pooled_distribution_bias"]["ttft"][ + quantile + ] + tp1_checks.append(abs(old) - abs(new) >= 0.05) + + regressions = [ + row + for row in flat_rows + if row["cell"].startswith(("tp2", "tp4")) + and row["metric"] in ("ttft", "e2e") + and row["abs_bias_delta_pp"] > 5 + ] + checks = { + "tp1_ttft_mean_p99_improve_ge_5pp": all(tp1_checks), + "tp2_tp4_ttft_e2e_no_abs_regression_gt_5pp": not regressions, + "regressions": regressions, + } + checks["trace_gate"] = ( + checks["tp1_ttft_mean_p99_improve_ge_5pp"] + and checks["tp2_tp4_ttft_e2e_no_abs_regression_gt_5pp"] + ) + + payload = { + "schema": "frontier-attn-structured-trial-aware-verdict-v1", + "metric_note": ( + "Primary values are per-real-trial distribution biases with request " + "alignment by index. legacy_pooled reproduces the old milestone " + "quantile convention only for direct comparison." + ), + "cells": results, + "checks": checks, + } + output = ROOT / "results" + output.mkdir(parents=True, exist_ok=True) + (output / "trace-verdict.json").write_text(json.dumps(payload, indent=2)) + with (output / "trace-verdict.csv").open("w", newline="") as stream: + writer = csv.DictWriter(stream, fieldnames=list(flat_rows[0])) + writer.writeheader() + writer.writerows(flat_rows) + + print(json.dumps(checks, indent=2)) + for label, result in results.items(): + old = result["old"]["legacy_pooled_distribution_bias"]["ttft"] + new = result["new"]["legacy_pooled_distribution_bias"]["ttft"] + print( + f"{label}: TTFT mean {old['mean']:+.1%}->{new['mean']:+.1%}, " + f"p99 {old['p99']:+.1%}->{new['p99']:+.1%}, " + f"waiting_p99={result['new']['waiting_p99_ms']:.0f}ms " + f"{result['new']['validity']}" + ) + + +if __name__ == "__main__": + main() diff --git a/runs/frontier-attn-structured-v0/experiment-card.md b/runs/frontier-attn-structured-v0/experiment-card.md new file mode 100644 index 0000000..cb4f6a7 --- /dev/null +++ b/runs/frontier-attn-structured-v0/experiment-card.md @@ -0,0 +1,82 @@ +# 实验 EXP-ATTN-STRUCTURED:结构化 predictor 能否关闭大 KV 端的 RF 欠拟合 + +> **状态:** 已完成(profile gate PASS;global merge gate FAIL) +> +> Parent campaign:[`../frontier-simulator-gap-campaign-v0/README.md`](../frontier-simulator-gap-campaign-v0/README.md) + +## Claim 与决策 + +- **Parent claim:** profile-v5 已补齐 chunked-prefill KV-context 测量,但当前 RF 仍在 TP1/2/4 的新网格上产生约 12%--14% self-fit MAPE,并在 TP1 真实 trace 中留下 −13% 到 −22% TTFT 偏差。 +- **目的:** 检查该 residual 是否来自可工程修复的 predictor representation,而不是 profile 数据或 serving path。 +- **Competing hypotheses:** + - H1:standard prefill 模型错误混入 pure multi-request rows,且 RF 对连续 attention scaling 作阶梯平滑;使用单请求数据和结构化 `base(q)+KV×(a+bq)` 可关闭残余。 + - H2:残余主要来自未建模的 serving-path 组件;替换 predictor 不会改善 7-cell trace fidelity。 +- **事前预测:** + - H1:held-out context MAPE ≤5%,TP1 TTFT mean/p99 绝对偏差至少改善 5 pp。 + - H2:profile gate 失败,或 profile gate 通过但 trace TTFT 几乎不动。 +- **判定规则:** + - profile gate:TP1/2/4 held-out context MAPE 均 ≤5%;q/KV 单调且预测非负。 + - trace gate:两个 TP1 cell 的 TTFT mean/p99 |bias| 各改善 ≥5 pp;TP2/TP4 任一 TTFT/E2E quantile 不恶化 >5 pp。 + - profile gate 失败即停止;trace gate 失败则回退 patch,不进入 EXP-2。 + +## Setup + +- **自变量:** + - A:现有 RF,standard prefill 全部非 true-mixed rows。 + - B:现有 RF,但仅 `batch_size=1`。 + - C:仅 `batch_size=1` 的 structured predictor: + - `base(q)`:KV=0 profile 的单调分段线性插值; + - growth:非负 least-squares `KV×(a+bq)`。 +- **控制变量:** attention/linear/MoE/collective profile、trace、prefix cache、scheduler、graph mode、KV blocks、MNS、全部 argv。 +- **System context:** Qwen3-30B-A3B BF16;H20;Frontier `deadc4a3`;TP1/2/4;MNS16;chunk 8192;prefix caching。 +- **Workload 或 trace:** 现有 7-cell 60-min production chat trace matrix;real 侧每 cell 两个 trial。 +- **Baselines:** `docs/assets/frontier-fidelity/full-matrix.csv` 的 sim-v5。 +- **Metrics:** + - profile:grid fit MAPE、leave-one-context MAPE/max error、q/KV monotonicity; + - trace:request-ID paired bias;每个 real trial 单独计算后报告 mean 与 trial interval; + - queue validity:waiting p99,TP1 超过 1 s 的 cell 标为 diagnostic。 + +## 预期产物与 review + +- **预期数据:** `results/predictor-ablation.{json,csv}`、`replay//`、`results/paired-verdict.json`。 +- **Figure prototype:** `figure-prototype.png`;左图为 q8k 随 KV 增长的 actual/RF/structured,右图为 7-cell TTFT bias 的事前期望。 +- **人工 review:** 已按 campaign 顺序批准执行。 +- **Review 意见:** 只改 standard single-request predictor;不得改 mixed predictor 或任何 profile row。 + +## 复现信息 + +- **Code:** Frontier base `deadc4a321f0baaa534c6ebd17f974123733cdc2`;实验 patch 将保存为 `frontier-structured-attn.patch` 并记录 SHA256。 +- **Environment:** 本地 CPU replay;Python dependency roots 复用 `runs/frontier-collective-joint-v0/counterfactual/joint-r2/manifest.json`。 +- **产物路径:** 本目录。 +- **已知 deviation:** milestone 文档将 7-cell 口径称为“逐 request paired”,但旧脚本实际 pool 两个 real trial 后比较 quantile;本实验会修正分析口径,不改旧结果文件。 + +## 预分析事实 + +- 现有训练代码使用 `["kv_cache_size", "prefill_chunk_size_squared"]` 与 RF grid search。 +- runtime cache 注释明确 standard model 是 per-request;多请求 prefill 在模型存在时走 `attn_prefill_mixed`。 +- profile-v5 的 standard 训练集每 TP 有 29 行,其中单请求 23 行;有 4 组相同 `(KV,q²)` feature 对应多个 pure-batch 标签。 +- 初步 structured candidate 的 leave-one-context MAPE:TP1 0.84%、TP2 1.61%、TP4 3.01%;max error 分别 2.04%、3.47%、5.49%。这些是实现前的临时计算,须由版本化脚本复现后才进入结果。 + +## 结果 + +- **观察事实:** + - structured held-out-context MAPE 为 TP1/2/4=`0.84%/1.60%/3.01%`; + 当前 RF 为 `44.40%/44.20%/43.54%`。单调/非负 gate 通过。 + - TP1 两点 TTFT mean bias `−13.5/−17.7% → −6.3/−9.5%`,p99 + `−16.8/−22.1% → −8.6/−14.4%`。 + - TP2 两点 TTFT mean bias `−11.2/−14.1% → −4.5/−7.1%`,p99 + `−17.3/−19.4% → −7.7/−9.0%`。 + - TP4 三点 TTFT mean bias `+2.5/+2.9/−0.1% → +7.8/+8.4/+6.0%`; + 三点均使绝对误差恶化 `5.3--5.8 pp`,触发预设回归 gate。 + - validity 重新审计:TP1 两点 waiting p99=`1.34/1.89 s`;TP2 + ρ=.005=`1.17 s`,均标为 `GATE_FAIL_DIAGNOSTIC`。其余四点通过。 +- **异常:** TP4 ρ=.005 的 TPOT p99 从 `+31.2%` 变为 `+36.6%`, + 表明该 tail 对 prefill/mixed-decode 相位敏感,不是本 patch 能关闭的稳定 + decode predictor 偏差。 +- **含义:** H1 的 representation 机制得到支持,但“全局替换 RF 可直接提升 + 7-cell fidelity”被反驳。TP4 原先接近零的 mean TTFT 含有 predictor + 欠拟合与其它正向 residual 的误差抵消;单独修正 attention 会揭开后者。 +- **Claim update:** structured predictor 是明确的工程候选,但必须与 TP4 + residual 联合收敛后才可 merge;当前 patch 只保留为 ablation。 +- **下一步:** EXP-2 先重算 structured 分支的 TP2 chunk-level residual; + 仅 residual ≥10% 才运行 GPU serving-path 三臂 profile。 diff --git a/runs/frontier-attn-structured-v0/figure-prototype.png b/runs/frontier-attn-structured-v0/figure-prototype.png new file mode 100644 index 0000000000000000000000000000000000000000..149b544e3ed0c75a04178b1dcd07c05b34cc0209 GIT binary patch literal 121411 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 literal 0 HcmV?d00001 diff --git a/runs/frontier-attn-structured-v0/frontier-reference.json b/runs/frontier-attn-structured-v0/frontier-reference.json new file mode 100644 index 0000000..bf87302 --- /dev/null +++ b/runs/frontier-attn-structured-v0/frontier-reference.json @@ -0,0 +1,525 @@ +{ + "cc_cache": "/home/gahow/phd/aituner/runs/frontier-collective-joint-v0/counterfactual/cc-cache", + "cells": { + "tp1_mns16": { + "argv": [ + "/usr/bin/python3", + "/home/gahow/phd/aituner/runs/frontier-collective-joint-v0/run_frontier_with_curves.py", + "--simulation_mode", + "online", + "--sys_arch", + "co-location", + "--cc_backend_config_type", + "vidur", + "--cluster_config_num_replicas", + "1", + "--cluster_scheduler_config_type", + "sticky_round_robin", + "--replica_config_model_name", + "qwen3-a3b-30b-moe", + "--replica_config_device", + "h20", + "--replica_config_network_device", + "h20_dgx", + "--replica_config_attn_tensor_parallel_size", + "1", + "--replica_config_attn_data_parallel_size", + "1", + "--replica_config_moe_tensor_parallel_size", + "1", + "--replica_config_moe_expert_parallel_size", + "1", + "--replica_config_num_pipeline_stages", + "1", + "--replica_scheduler_config_type", + "vllm_v1", + "--decode_cuda_graph_mode", + "piecewise", + "--vllm_v1_scheduler_config_batch_size_cap", + "16", + "--vllm_v1_scheduler_config_max_tokens_in_batch", + "8192", + "--vllm_v1_scheduler_config_long_prefill_token_threshold", + "0", + "--vllm_v1_scheduler_config_block_size", + "16", + "--vllm_v1_scheduler_config_num_blocks_mode", + "explicit", + "--vllm_v1_scheduler_config_gpu_memory_utilization", + "0.92", + "--vllm_v1_scheduler_config_non_kv_cache_overhead_bytes", + "0", + "--request_generator_config_type", + "trace_replay", + "--trace_request_generator_config_trace_file", + "/home/gahow/phd/aituner/runs/frontier-collective-joint-v0/counterfactual/joint-r2/inputs/tp1-frontier.csv", + "--trace_request_generator_config_max_tokens", + "40960", + "--metrics_config_output_dir", + "/home/gahow/phd/aituner/runs/frontier-collective-joint-v0/counterfactual/joint-r2/sim/tp1_mns16/metrics", + "--metrics_config_run_id", + "joint_tp1_mns16", + "--metrics_config_write_metrics", + "--metrics_config_store_request_metrics", + "--metrics_config_store_batch_metrics", + "--metrics_config_store_token_completion_metrics", + "--metrics_config_store_utilization_metrics", + "--no-metrics_config_store_plots", + "--no-metrics_config_enable_chrome_trace", + "--no-metrics_config_write_json_trace", + "--metrics_config_store_frontier_stage_batch_ledger", + "--no-random_forrest_execution_time_predictor_config_enable_dummy_mode", + "--random_forrest_execution_time_predictor_config_linear_op_input_file", + "/home/gahow/phd/aituner/runs/frontier-split-rootcause-v0/frozen-inputs/q30-profiles/profile-v4-trace-final/linear_op.csv", + "--random_forrest_execution_time_predictor_config_atten_input_file", + "/home/gahow/phd/aituner/runs/frontier-split-rootcause-v0/frozen-inputs/q30-profiles/profile-v4-trace-final/attention.csv", + "--random_forrest_execution_time_predictor_config_moe_input_file", + "/home/gahow/phd/aituner/runs/frontier-split-rootcause-v0/frozen-inputs/q30-profiles/profile-v4-trace-final/moe.csv", + "--random_forrest_execution_time_predictor_config_linear_op_kernel_only_input_file", + "/home/gahow/phd/aituner/runs/frontier-split-rootcause-v0/frozen-inputs/q30-profiles/frozen-kernel-only/linear_op.csv", + "--random_forrest_execution_time_predictor_config_atten_kernel_only_input_file", + "/home/gahow/phd/aituner/runs/frontier-split-rootcause-v0/frozen-inputs/q30-profiles/frozen-kernel-only/attention.csv", + "--random_forrest_execution_time_predictor_config_moe_kernel_only_input_file", + "/home/gahow/phd/aituner/runs/frontier-split-rootcause-v0/frozen-inputs/q30-profiles/frozen-kernel-only/moe.csv", + "--random_forrest_execution_time_predictor_config_prediction_max_prefill_chunk_size", + "8192", + "--random_forrest_execution_time_predictor_config_prediction_max_batch_size", + "32", + "--random_forrest_execution_time_predictor_config_prediction_max_tokens_per_request", + "40960", + "--random_forrest_execution_time_predictor_config_no_cache", + "--random_forrest_execution_time_predictor_config_skip_cpu_overhead_modeling", + "--vllm_v1_scheduler_config_num_blocks", + "20128", + "--vllm_v1_scheduler_config_enable_chunked_prefill", + "--random_forrest_execution_time_predictor_config_num_training_job_threads", + "4", + "--cudagraph_capture_sizes", + "1", + "2", + "4", + "8", + "16", + "24", + "32", + "--vidur_cc_backend_config_all_reduce_input_file", + "/home/gahow/phd/aituner/runs/frontier-split-rootcause-v0/frozen-inputs/q30-profiles/measured-allreduce.csv", + "--vidur_cc_backend_config_cache_dir", + "/home/gahow/phd/aituner/runs/frontier-collective-joint-v0/counterfactual/cc-cache", + "--vidur_cc_backend_config_k_fold_cv_splits", + "6", + "--vidur_cc_backend_config_num_training_job_threads", + "1", + "--metrics_config_cache_dir", + "/home/gahow/phd/aituner/runs/frontier-collective-joint-v0/counterfactual/model-cache" + ], + "log": "/home/gahow/phd/aituner/runs/frontier-collective-joint-v0/counterfactual/joint-r2/logs/tp1_mns16.log", + "source_command": "/home/gahow/phd/aituner/runs/frontier-split-rootcause-v0/frozen-inputs/q30-lo-fixed-pd-cells/sim/fixed-pd/runs/tp1_mns16/tp1/command.json", + "source_command_sha256": "a9815797b1601bf6f6cdf0269e84acb376a84945609e338868dc8347aab650e6", + "usage": "/home/gahow/phd/aituner/runs/frontier-collective-joint-v0/counterfactual/joint-r2/usage/tp1_mns16.json" + }, + "tp2_mns16": { + "argv": [ + "/usr/bin/python3", + "/home/gahow/phd/aituner/runs/frontier-collective-joint-v0/run_frontier_with_curves.py", + "--simulation_mode", + "online", + "--sys_arch", + "co-location", + "--cc_backend_config_type", + "vidur", + "--cluster_config_num_replicas", + "1", + "--cluster_scheduler_config_type", + "sticky_round_robin", + "--replica_config_model_name", + "qwen3-a3b-30b-moe", + "--replica_config_device", + "h20", + "--replica_config_network_device", + "h20_dgx", + "--replica_config_attn_tensor_parallel_size", + "2", + "--replica_config_attn_data_parallel_size", + "1", + "--replica_config_moe_tensor_parallel_size", + "2", + "--replica_config_moe_expert_parallel_size", + "1", + "--replica_config_num_pipeline_stages", + "1", + "--replica_scheduler_config_type", + "vllm_v1", + "--decode_cuda_graph_mode", + "piecewise", + "--vllm_v1_scheduler_config_batch_size_cap", + "16", + "--vllm_v1_scheduler_config_max_tokens_in_batch", + "8192", + "--vllm_v1_scheduler_config_long_prefill_token_threshold", + "0", + "--vllm_v1_scheduler_config_block_size", + "16", + "--vllm_v1_scheduler_config_num_blocks_mode", + "explicit", + "--vllm_v1_scheduler_config_gpu_memory_utilization", + "0.92", + "--vllm_v1_scheduler_config_non_kv_cache_overhead_bytes", + "0", + "--request_generator_config_type", + "trace_replay", + "--trace_request_generator_config_trace_file", + "/home/gahow/phd/aituner/runs/frontier-collective-joint-v0/counterfactual/joint-r2/inputs/tp2-frontier.csv", + "--trace_request_generator_config_max_tokens", + "40960", + "--metrics_config_output_dir", + "/home/gahow/phd/aituner/runs/frontier-collective-joint-v0/counterfactual/joint-r2/sim/tp2_mns16/metrics", + "--metrics_config_run_id", + "joint_tp2_mns16", + "--metrics_config_write_metrics", + "--metrics_config_store_request_metrics", + "--metrics_config_store_batch_metrics", + "--metrics_config_store_token_completion_metrics", + "--metrics_config_store_utilization_metrics", + "--no-metrics_config_store_plots", + "--no-metrics_config_enable_chrome_trace", + "--no-metrics_config_write_json_trace", + "--metrics_config_store_frontier_stage_batch_ledger", + "--no-random_forrest_execution_time_predictor_config_enable_dummy_mode", + "--random_forrest_execution_time_predictor_config_linear_op_input_file", + "/home/gahow/phd/aituner/runs/frontier-split-rootcause-v0/frozen-inputs/q30-profiles/profile-v4-trace-final/linear_op.csv", + "--random_forrest_execution_time_predictor_config_atten_input_file", + "/home/gahow/phd/aituner/runs/frontier-split-rootcause-v0/frozen-inputs/q30-profiles/profile-v4-trace-final/attention.csv", + "--random_forrest_execution_time_predictor_config_moe_input_file", + "/home/gahow/phd/aituner/runs/frontier-split-rootcause-v0/frozen-inputs/q30-profiles/profile-v4-trace-final/moe.csv", + "--random_forrest_execution_time_predictor_config_linear_op_kernel_only_input_file", + "/home/gahow/phd/aituner/runs/frontier-split-rootcause-v0/frozen-inputs/q30-profiles/frozen-kernel-only/linear_op.csv", + "--random_forrest_execution_time_predictor_config_atten_kernel_only_input_file", + "/home/gahow/phd/aituner/runs/frontier-split-rootcause-v0/frozen-inputs/q30-profiles/frozen-kernel-only/attention.csv", + "--random_forrest_execution_time_predictor_config_moe_kernel_only_input_file", + "/home/gahow/phd/aituner/runs/frontier-split-rootcause-v0/frozen-inputs/q30-profiles/frozen-kernel-only/moe.csv", + "--random_forrest_execution_time_predictor_config_prediction_max_prefill_chunk_size", + "8192", + "--random_forrest_execution_time_predictor_config_prediction_max_batch_size", + "32", + "--random_forrest_execution_time_predictor_config_prediction_max_tokens_per_request", + "40960", + "--random_forrest_execution_time_predictor_config_no_cache", + "--random_forrest_execution_time_predictor_config_skip_cpu_overhead_modeling", + "--vllm_v1_scheduler_config_num_blocks", + "76620", + "--vllm_v1_scheduler_config_enable_chunked_prefill", + "--random_forrest_execution_time_predictor_config_num_training_job_threads", + "4", + "--cudagraph_capture_sizes", + "1", + "2", + "4", + "8", + "16", + "24", + "32", + "--vidur_cc_backend_config_all_reduce_input_file", + "/home/gahow/phd/aituner/runs/frontier-split-rootcause-v0/frozen-inputs/q30-profiles/measured-allreduce.csv", + "--vidur_cc_backend_config_cache_dir", + "/home/gahow/phd/aituner/runs/frontier-collective-joint-v0/counterfactual/cc-cache", + "--vidur_cc_backend_config_k_fold_cv_splits", + "6", + "--vidur_cc_backend_config_num_training_job_threads", + "1", + "--metrics_config_cache_dir", + "/home/gahow/phd/aituner/runs/frontier-collective-joint-v0/counterfactual/model-cache" + ], + "log": "/home/gahow/phd/aituner/runs/frontier-collective-joint-v0/counterfactual/joint-r2/logs/tp2_mns16.log", + "source_command": "/home/gahow/phd/aituner/runs/frontier-split-rootcause-v0/frozen-inputs/q30-lo-fixed-pd-cells/sim/fixed-pd/runs/tp2_mns16/tp2/command.json", + "source_command_sha256": "61788a8810be301c9dbc006624aa19b6a932bc44d341b836861087833cffc3df", + "usage": "/home/gahow/phd/aituner/runs/frontier-collective-joint-v0/counterfactual/joint-r2/usage/tp2_mns16.json" + }, + "tp4_mns16": { + "argv": [ + "/usr/bin/python3", + "/home/gahow/phd/aituner/runs/frontier-collective-joint-v0/run_frontier_with_curves.py", + "--simulation_mode", + "online", + "--sys_arch", + "co-location", + "--cc_backend_config_type", + "vidur", + "--cluster_config_num_replicas", + "1", + "--cluster_scheduler_config_type", + "sticky_round_robin", + "--replica_config_model_name", + "qwen3-a3b-30b-moe", + "--replica_config_device", + "h20", + "--replica_config_network_device", + "h20_dgx", + "--replica_config_attn_tensor_parallel_size", + "4", + "--replica_config_attn_data_parallel_size", + "1", + "--replica_config_moe_tensor_parallel_size", + "4", + "--replica_config_moe_expert_parallel_size", + "1", + "--replica_config_num_pipeline_stages", + "1", + "--replica_scheduler_config_type", + "vllm_v1", + "--decode_cuda_graph_mode", + "piecewise", + "--vllm_v1_scheduler_config_batch_size_cap", + "16", + "--vllm_v1_scheduler_config_max_tokens_in_batch", + "8192", + "--vllm_v1_scheduler_config_long_prefill_token_threshold", + "0", + "--vllm_v1_scheduler_config_block_size", + "16", + "--vllm_v1_scheduler_config_num_blocks_mode", + "explicit", + "--vllm_v1_scheduler_config_gpu_memory_utilization", + "0.92", + "--vllm_v1_scheduler_config_non_kv_cache_overhead_bytes", + "0", + "--request_generator_config_type", + "trace_replay", + "--trace_request_generator_config_trace_file", + "/home/gahow/phd/aituner/runs/frontier-collective-joint-v0/counterfactual/joint-r2/inputs/tp4-frontier.csv", + "--trace_request_generator_config_max_tokens", + "40960", + "--metrics_config_output_dir", + "/home/gahow/phd/aituner/runs/frontier-collective-joint-v0/counterfactual/joint-r2/sim/tp4_mns16/metrics", + "--metrics_config_run_id", + "joint_tp4_mns16", + "--metrics_config_write_metrics", + "--metrics_config_store_request_metrics", + "--metrics_config_store_batch_metrics", + "--metrics_config_store_token_completion_metrics", + "--metrics_config_store_utilization_metrics", + "--no-metrics_config_store_plots", + "--no-metrics_config_enable_chrome_trace", + "--no-metrics_config_write_json_trace", + "--metrics_config_store_frontier_stage_batch_ledger", + "--no-random_forrest_execution_time_predictor_config_enable_dummy_mode", + "--random_forrest_execution_time_predictor_config_linear_op_input_file", + "/home/gahow/phd/aituner/runs/frontier-split-rootcause-v0/frozen-inputs/q30-profiles/profile-v4-trace-final/linear_op.csv", + "--random_forrest_execution_time_predictor_config_atten_input_file", + "/home/gahow/phd/aituner/runs/frontier-split-rootcause-v0/frozen-inputs/q30-profiles/profile-v4-trace-final/attention.csv", + "--random_forrest_execution_time_predictor_config_moe_input_file", + "/home/gahow/phd/aituner/runs/frontier-split-rootcause-v0/frozen-inputs/q30-profiles/profile-v4-trace-final/moe.csv", + "--random_forrest_execution_time_predictor_config_linear_op_kernel_only_input_file", + "/home/gahow/phd/aituner/runs/frontier-split-rootcause-v0/frozen-inputs/q30-profiles/frozen-kernel-only/linear_op.csv", + "--random_forrest_execution_time_predictor_config_atten_kernel_only_input_file", + "/home/gahow/phd/aituner/runs/frontier-split-rootcause-v0/frozen-inputs/q30-profiles/frozen-kernel-only/attention.csv", + "--random_forrest_execution_time_predictor_config_moe_kernel_only_input_file", + "/home/gahow/phd/aituner/runs/frontier-split-rootcause-v0/frozen-inputs/q30-profiles/frozen-kernel-only/moe.csv", + "--random_forrest_execution_time_predictor_config_prediction_max_prefill_chunk_size", + "8192", + "--random_forrest_execution_time_predictor_config_prediction_max_batch_size", + "32", + "--random_forrest_execution_time_predictor_config_prediction_max_tokens_per_request", + "40960", + "--random_forrest_execution_time_predictor_config_no_cache", + "--random_forrest_execution_time_predictor_config_skip_cpu_overhead_modeling", + "--vllm_v1_scheduler_config_num_blocks", + "191882", + "--vllm_v1_scheduler_config_enable_chunked_prefill", + "--random_forrest_execution_time_predictor_config_num_training_job_threads", + "4", + "--cudagraph_capture_sizes", + "1", + "2", + "4", + "8", + "16", + "24", + "32", + "--vidur_cc_backend_config_all_reduce_input_file", + "/home/gahow/phd/aituner/runs/frontier-split-rootcause-v0/frozen-inputs/q30-profiles/measured-allreduce.csv", + "--vidur_cc_backend_config_cache_dir", + "/home/gahow/phd/aituner/runs/frontier-collective-joint-v0/counterfactual/cc-cache", + "--vidur_cc_backend_config_k_fold_cv_splits", + "6", + "--vidur_cc_backend_config_num_training_job_threads", + "1", + "--metrics_config_cache_dir", + "/home/gahow/phd/aituner/runs/frontier-collective-joint-v0/counterfactual/model-cache" + ], + "log": "/home/gahow/phd/aituner/runs/frontier-collective-joint-v0/counterfactual/joint-r2/logs/tp4_mns16.log", + "source_command": "/home/gahow/phd/aituner/runs/frontier-split-rootcause-v0/frozen-inputs/q30-lo-fixed-pd-cells/sim/fixed-pd/runs/tp4_mns16/tp4/command.json", + "source_command_sha256": "9bbcf10446336ba5885193f391dd628cd18ff64d91a51ebcd463ffd24be95532", + "usage": "/home/gahow/phd/aituner/runs/frontier-collective-joint-v0/counterfactual/joint-r2/usage/tp4_mns16.json" + }, + "tp4_mns32": { + "argv": [ + "/usr/bin/python3", + "/home/gahow/phd/aituner/runs/frontier-collective-joint-v0/run_frontier_with_curves.py", + "--simulation_mode", + "online", + "--sys_arch", + "co-location", + "--cc_backend_config_type", + "vidur", + "--cluster_config_num_replicas", + "1", + "--cluster_scheduler_config_type", + "sticky_round_robin", + "--replica_config_model_name", + "qwen3-a3b-30b-moe", + "--replica_config_device", + "h20", + "--replica_config_network_device", + "h20_dgx", + "--replica_config_attn_tensor_parallel_size", + "4", + "--replica_config_attn_data_parallel_size", + "1", + "--replica_config_moe_tensor_parallel_size", + "4", + "--replica_config_moe_expert_parallel_size", + "1", + "--replica_config_num_pipeline_stages", + "1", + "--replica_scheduler_config_type", + "vllm_v1", + "--decode_cuda_graph_mode", + "piecewise", + "--vllm_v1_scheduler_config_batch_size_cap", + "32", + "--vllm_v1_scheduler_config_max_tokens_in_batch", + "8192", + "--vllm_v1_scheduler_config_long_prefill_token_threshold", + "0", + "--vllm_v1_scheduler_config_block_size", + "16", + "--vllm_v1_scheduler_config_num_blocks_mode", + "explicit", + "--vllm_v1_scheduler_config_gpu_memory_utilization", + "0.92", + "--vllm_v1_scheduler_config_non_kv_cache_overhead_bytes", + "0", + "--request_generator_config_type", + "trace_replay", + "--trace_request_generator_config_trace_file", + "/home/gahow/phd/aituner/runs/frontier-collective-joint-v0/counterfactual/joint-r2/inputs/tp4-frontier.csv", + "--trace_request_generator_config_max_tokens", + "40960", + "--metrics_config_output_dir", + "/home/gahow/phd/aituner/runs/frontier-collective-joint-v0/counterfactual/joint-r2/sim/tp4_mns32/metrics", + "--metrics_config_run_id", + "joint_tp4_mns32", + "--metrics_config_write_metrics", + "--metrics_config_store_request_metrics", + "--metrics_config_store_batch_metrics", + "--metrics_config_store_token_completion_metrics", + "--metrics_config_store_utilization_metrics", + "--no-metrics_config_store_plots", + "--no-metrics_config_enable_chrome_trace", + "--no-metrics_config_write_json_trace", + "--metrics_config_store_frontier_stage_batch_ledger", + "--no-random_forrest_execution_time_predictor_config_enable_dummy_mode", + "--random_forrest_execution_time_predictor_config_linear_op_input_file", + "/home/gahow/phd/aituner/runs/frontier-split-rootcause-v0/frozen-inputs/q30-profiles/profile-v4-trace-final/linear_op.csv", + "--random_forrest_execution_time_predictor_config_atten_input_file", + "/home/gahow/phd/aituner/runs/frontier-split-rootcause-v0/frozen-inputs/q30-profiles/profile-v4-trace-final/attention.csv", + "--random_forrest_execution_time_predictor_config_moe_input_file", + "/home/gahow/phd/aituner/runs/frontier-split-rootcause-v0/frozen-inputs/q30-profiles/profile-v4-trace-final/moe.csv", + "--random_forrest_execution_time_predictor_config_linear_op_kernel_only_input_file", + "/home/gahow/phd/aituner/runs/frontier-split-rootcause-v0/frozen-inputs/q30-profiles/frozen-kernel-only/linear_op.csv", + "--random_forrest_execution_time_predictor_config_atten_kernel_only_input_file", + "/home/gahow/phd/aituner/runs/frontier-split-rootcause-v0/frozen-inputs/q30-profiles/frozen-kernel-only/attention.csv", + "--random_forrest_execution_time_predictor_config_moe_kernel_only_input_file", + "/home/gahow/phd/aituner/runs/frontier-split-rootcause-v0/frozen-inputs/q30-profiles/frozen-kernel-only/moe.csv", + "--random_forrest_execution_time_predictor_config_prediction_max_prefill_chunk_size", + "8192", + "--random_forrest_execution_time_predictor_config_prediction_max_batch_size", + "64", + "--random_forrest_execution_time_predictor_config_prediction_max_tokens_per_request", + "40960", + "--random_forrest_execution_time_predictor_config_no_cache", + "--random_forrest_execution_time_predictor_config_skip_cpu_overhead_modeling", + "--vllm_v1_scheduler_config_num_blocks", + "191786", + "--vllm_v1_scheduler_config_enable_chunked_prefill", + "--random_forrest_execution_time_predictor_config_num_training_job_threads", + "4", + "--cudagraph_capture_sizes", + "1", + "2", + "4", + "8", + "16", + "24", + "32", + "40", + "48", + "56", + "64", + "--vidur_cc_backend_config_all_reduce_input_file", + "/home/gahow/phd/aituner/runs/frontier-split-rootcause-v0/frozen-inputs/q30-profiles/measured-allreduce.csv", + "--vidur_cc_backend_config_cache_dir", + "/home/gahow/phd/aituner/runs/frontier-collective-joint-v0/counterfactual/cc-cache", + "--vidur_cc_backend_config_k_fold_cv_splits", + "6", + "--vidur_cc_backend_config_num_training_job_threads", + "1", + "--metrics_config_cache_dir", + "/home/gahow/phd/aituner/runs/frontier-collective-joint-v0/counterfactual/model-cache" + ], + "log": "/home/gahow/phd/aituner/runs/frontier-collective-joint-v0/counterfactual/joint-r2/logs/tp4_mns32.log", + "source_command": "/home/gahow/phd/aituner/runs/frontier-split-rootcause-v0/frozen-inputs/q30-lo-fixed-pd-cells/sim/fixed-pd/runs/tp4_mns32/tp4/command.json", + "source_command_sha256": "fbc7dee55590b415ed1cde8072de835ed155a0c20ba0eb305c3cb22aa8065a51", + "usage": "/home/gahow/phd/aituner/runs/frontier-collective-joint-v0/counterfactual/joint-r2/usage/tp4_mns32.json" + } + }, + "collective_curve": "/home/gahow/phd/aituner/runs/frontier-collective-joint-v0/results/collective-curve.json", + "collective_curve_sha256": "f9543649d4ea78f08240bf1284ab74083aa5cf5671ed47e386047f1453300b36", + "collective_curve_variant": "drop_mean", + "frontier_checkout": "/tmp/frontier-attn-structured-v0", + "frontier_commit": "1f8900a4ac64e45754b03d0aa7c1dddab65785cf", + "mode": "joint", + "model_cache": "/home/gahow/phd/aituner/runs/frontier-collective-joint-v0/counterfactual/model-cache", + "moe_curve": "/home/gahow/phd/aituner/runs/frontier-fused-moe-profile-v0/results/fused-moe-curve.json", + "moe_curve_sha256": "b94d65d9d581adefcc6c14ed4920cce6a1136f74f1014737dc3e4249bc8250d2", + "python": "/usr/bin/python3", + "python_dependency_roots": [ + "/home/gahow/phd/aituner/runs/frontier-collective-joint-v0/python-deps", + "/home/gahow/.cache/uv/archive-v0/-_kzErLcPO5nASZFX8b9k", + "/home/gahow/.cache/uv/archive-v0/FbaBs_QJ9QKEbQ9V_4aIR", + "/home/gahow/.cache/uv/archive-v0/fuHsGXD0Lv_UjFC8yI4-7", + "/home/gahow/.cache/uv/archive-v0/jFGdqQLpB1eopfm9VxT3j", + "/home/gahow/.cache/uv/archive-v0/YWW6ExSJuPVvv4-qYQTin", + "/home/gahow/.cache/uv/archive-v0/3_qxZ5Ll-EpVAGZfbksfe" + ], + "traces": { + "1": { + "first_arrival_s": 0.0, + "last_arrival_s": 595.348837209302, + "requests": 129, + "source_request_metrics": "/home/gahow/phd/aituner/runs/frontier-split-rootcause-v0/frozen-inputs/q30-lo-fixed-pd-cells/sim/fixed-pd/runs/tp1_mns16/tp1/metrics/qwen3_a3b_30b_moe/online_serving/qwen30_trace_tp1_mns16_tp1/request_metrics.csv", + "source_sha256": "0b82e09644a5884fcd10d894b68495daefdabb32b770146c2f9ece37b8469f4f", + "trace": "/home/gahow/phd/aituner/runs/frontier-collective-joint-v0/counterfactual/joint-r2/inputs/tp1-frontier.csv", + "trace_sha256": "59dd8996ff879ef94330004104dfdf515b791bce4036576eccc93290e9206dad" + }, + "2": { + "first_arrival_s": 0.0, + "last_arrival_s": 297.674418604651, + "requests": 129, + "source_request_metrics": "/home/gahow/phd/aituner/runs/frontier-split-rootcause-v0/frozen-inputs/q30-lo-fixed-pd-cells/sim/fixed-pd/runs/tp2_mns16/tp2/metrics/qwen3_a3b_30b_moe/online_serving/qwen30_trace_tp2_mns16_tp2/request_metrics.csv", + "source_sha256": "33983081bb20dd5e2053e9e3d13def8732e958150c9b47a8609ba345123f2316", + "trace": "/home/gahow/phd/aituner/runs/frontier-collective-joint-v0/counterfactual/joint-r2/inputs/tp2-frontier.csv", + "trace_sha256": "64fc077b38274a76a8279884ac4115836cd1157c95119c64fabac50d81124f69" + }, + "4": { + "first_arrival_s": 0.0, + "last_arrival_s": 148.837209302326, + "requests": 129, + "source_request_metrics": "/home/gahow/phd/aituner/runs/frontier-split-rootcause-v0/frozen-inputs/q30-lo-fixed-pd-cells/sim/fixed-pd/runs/tp4_mns16/tp4/metrics/qwen3_a3b_30b_moe/online_serving/qwen30_trace_tp4_mns16_tp4/request_metrics.csv", + "source_sha256": "b36cd383c07b546d2c1f2fac754d5dbb92efd6880316b4233a7aef9fa1115a36", + "trace": "/home/gahow/phd/aituner/runs/frontier-collective-joint-v0/counterfactual/joint-r2/inputs/tp4-frontier.csv", + "trace_sha256": "adb3d6f3932a44c86c3d9e7cf1e57739594e8c48d19a26b5aa54b37dce0e0c19" + } + } +} \ No newline at end of file diff --git a/runs/frontier-attn-structured-v0/plot_figure_prototype.py b/runs/frontier-attn-structured-v0/plot_figure_prototype.py new file mode 100644 index 0000000..a3368f9 --- /dev/null +++ b/runs/frontier-attn-structured-v0/plot_figure_prototype.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python3 +"""Schematic figure frozen before EXP-ATTN-STRUCTURED execution.""" + +from pathlib import Path + +import matplotlib + +matplotlib.use("Agg") +import matplotlib.pyplot as plt +import numpy as np + +ROOT = Path(__file__).resolve().parent +SURFACE = "#fcfcfb" +INK = "#111111" +MUTED = "#77736c" +GRID = "#dedbd2" +RF = "#d95f02" +STRUCTURED = "#1b75bc" + +fig, axes = plt.subplots(1, 2, figsize=(10.8, 4.2), dpi=160) +fig.patch.set_facecolor(SURFACE) + +for ax in axes: + ax.set_facecolor(SURFACE) + ax.grid(axis="y", color=GRID, linewidth=0.8) + ax.set_axisbelow(True) + ax.spines[["top", "right"]].set_visible(False) + ax.tick_params(colors=MUTED, labelsize=8) + +kv = np.array([8, 16, 24], dtype=float) +actual = np.array([11.97, 19.92, 27.84]) +rf = np.array([9.46, 16.40, 24.52]) +structured_expected = np.array([12.0, 19.9, 27.9]) +axes[0].plot(kv, actual, "o-", color=INK, label="profile actual") +axes[0].plot(kv, rf, "s--", color=RF, label="current RF") +axes[0].plot( + kv, + structured_expected, + "^:", + color=STRUCTURED, + label="structured (expected)", +) +axes[0].set_xlabel("KV context (ktok)") +axes[0].set_ylabel("TP1 q8k attention time (ms)") +axes[0].set_title("(a) Continuous KV growth", loc="left", fontsize=10) +axes[0].legend(frameon=False, fontsize=8) + +labels = ["TP1\n.00125", "TP1\n.0025", "TP2\n.0025", "TP2\n.005", + "TP4\n.0025", "TP4\n.005", "TP4\n.01"] +x = np.arange(len(labels)) +v5_mean = np.array([-13.5, -17.7, -11.2, -14.1, 2.5, 2.9, -0.2]) +expected = np.array([-5, -8, -9, -11, 3, 3, 0]) +axes[1].axhspan(-15, 15, color=GRID, alpha=0.5) +axes[1].axhline(0, color=MUTED, linewidth=0.8) +axes[1].plot(x, v5_mean, "o-", color=RF, label="sim-v5 measured") +axes[1].plot(x, expected, "s--", color=STRUCTURED, label="H1 expected") +axes[1].set_xticks(x, labels) +axes[1].set_ylabel("TTFT mean bias (%)") +axes[1].set_title("(b) 7-cell trace gate", loc="left", fontsize=10) +axes[1].legend(frameon=False, fontsize=8) + +fig.suptitle( + "MOCK / schematic — EXP-ATTN-STRUCTURED (not measured results)", + x=0.01, + ha="left", + color=RF, + fontsize=9, +) +fig.tight_layout(rect=(0, 0, 1, 0.95)) +fig.savefig(ROOT / "figure-prototype.png", facecolor=SURFACE) +fig.savefig(ROOT / "figure-prototype.svg", facecolor=SURFACE) +print(ROOT / "figure-prototype.png") diff --git a/runs/frontier-attn-structured-v0/results/predictor-ablation.csv b/runs/frontier-attn-structured-v0/results/predictor-ablation.csv new file mode 100644 index 0000000..3f5e290 --- /dev/null +++ b/runs/frontier-attn-structured-v0/results/predictor-ablation.csv @@ -0,0 +1,10 @@ +candidate,training_rows,grid_fit_mape_pct,single_fit_mape_pct,heldout_context_mape_pct,heldout_context_max_abs_error_pct,prediction_min_ms,q_min_delta_ms,kv_min_delta_ms,monotone_and_nonnegative,tp +rf_all,29,15.074275515235467,19.842994757611535,44.40139318281943,82.78279487156401,0.06029164119272453,0.0,-4.2841601371801374e-05,False,1 +rf_single,23,11.834992526698676,22.893412972496023,34.45356428541224,62.49334437588834,0.059327708247725125,-0.00022153525203457564,-1.4336001873005433e-05,False,1 +structured_single,23,0.8432511364168856,2.227110646811972,0.841926169535806,2.0408978739639134,0.05679146709541477,0.0,0.0016745062683911627,True,1 +rf_all,29,13.812689689573157,17.879870012606048,44.20143320278334,82.0656368501208,0.06000113548192927,-0.004361070463210395,-0.009949388915300408,False,2 +rf_single,23,10.738962684891058,20.818820413545826,34.84360402100271,66.67253880294443,0.059971319361210015,-0.003811210796127021,-0.009949388915300408,False,2 +structured_single,23,1.518412258922364,6.226292654776418,1.6047958673086566,3.464671475193195,0.05767893331746252,0.0,0.0013929374121726124,True,2 +rf_all,29,14.117015331381916,15.49366794487052,43.53650868837558,81.33508178007524,0.05866772018640992,-0.0009967416035880083,-5.5955198407176e-05,False,4 +rf_single,23,12.07517666989496,17.672692652721008,34.14562332866605,62.31478818862995,0.058213693721655094,-0.0012244979345549661,-8.259841203689389e-05,False,4 +structured_single,23,3.088740104976349,5.969109476280061,3.0103379904473164,5.490598706238697,0.05747733327249683,0.0,0.0012048051417407057,True,4 diff --git a/runs/frontier-attn-structured-v0/results/predictor-ablation.json b/runs/frontier-attn-structured-v0/results/predictor-ablation.json new file mode 100644 index 0000000..ca894c5 --- /dev/null +++ b/runs/frontier-attn-structured-v0/results/predictor-ablation.json @@ -0,0 +1,149 @@ +{ + "schema": "frontier-attn-structured-ablation-v1", + "profile": "/home/gahow/phd/aituner/runs/frontier-prefill-kvgrowth-fix-v0/profiles/profile-v5-kvgrowth/attention.csv", + "frontier_checkout": "/tmp/frontier-attn-structured-v0", + "data_audit": { + "tp1": { + "standard_rows": 29, + "single_request_rows": 23, + "target_grid_rows": 10, + "duplicate_feature_groups": 4 + }, + "tp2": { + "standard_rows": 29, + "single_request_rows": 23, + "target_grid_rows": 10, + "duplicate_feature_groups": 4 + }, + "tp4": { + "standard_rows": 29, + "single_request_rows": 23, + "target_grid_rows": 10, + "duplicate_feature_groups": 4 + } + }, + "results": [ + { + "candidate": "rf_all", + "training_rows": 29, + "grid_fit_mape_pct": 15.074275515235467, + "single_fit_mape_pct": 19.842994757611535, + "heldout_context_mape_pct": 44.40139318281943, + "heldout_context_max_abs_error_pct": 82.78279487156401, + "prediction_min_ms": 0.06029164119272453, + "q_min_delta_ms": 0.0, + "kv_min_delta_ms": -4.2841601371801374e-05, + "monotone_and_nonnegative": false, + "tp": 1 + }, + { + "candidate": "rf_single", + "training_rows": 23, + "grid_fit_mape_pct": 11.834992526698676, + "single_fit_mape_pct": 22.893412972496023, + "heldout_context_mape_pct": 34.45356428541224, + "heldout_context_max_abs_error_pct": 62.49334437588834, + "prediction_min_ms": 0.059327708247725125, + "q_min_delta_ms": -0.00022153525203457564, + "kv_min_delta_ms": -1.4336001873005433e-05, + "monotone_and_nonnegative": false, + "tp": 1 + }, + { + "candidate": "structured_single", + "training_rows": 23, + "grid_fit_mape_pct": 0.8432511364168856, + "single_fit_mape_pct": 2.227110646811972, + "heldout_context_mape_pct": 0.841926169535806, + "heldout_context_max_abs_error_pct": 2.0408978739639134, + "prediction_min_ms": 0.05679146709541477, + "q_min_delta_ms": 0.0, + "kv_min_delta_ms": 0.0016745062683911627, + "monotone_and_nonnegative": true, + "tp": 1 + }, + { + "candidate": "rf_all", + "training_rows": 29, + "grid_fit_mape_pct": 13.812689689573157, + "single_fit_mape_pct": 17.879870012606048, + "heldout_context_mape_pct": 44.20143320278334, + "heldout_context_max_abs_error_pct": 82.0656368501208, + "prediction_min_ms": 0.06000113548192927, + "q_min_delta_ms": -0.004361070463210395, + "kv_min_delta_ms": -0.009949388915300408, + "monotone_and_nonnegative": false, + "tp": 2 + }, + { + "candidate": "rf_single", + "training_rows": 23, + "grid_fit_mape_pct": 10.738962684891058, + "single_fit_mape_pct": 20.818820413545826, + "heldout_context_mape_pct": 34.84360402100271, + "heldout_context_max_abs_error_pct": 66.67253880294443, + "prediction_min_ms": 0.059971319361210015, + "q_min_delta_ms": -0.003811210796127021, + "kv_min_delta_ms": -0.009949388915300408, + "monotone_and_nonnegative": false, + "tp": 2 + }, + { + "candidate": "structured_single", + "training_rows": 23, + "grid_fit_mape_pct": 1.518412258922364, + "single_fit_mape_pct": 6.226292654776418, + "heldout_context_mape_pct": 1.6047958673086566, + "heldout_context_max_abs_error_pct": 3.464671475193195, + "prediction_min_ms": 0.05767893331746252, + "q_min_delta_ms": 0.0, + "kv_min_delta_ms": 0.0013929374121726124, + "monotone_and_nonnegative": true, + "tp": 2 + }, + { + "candidate": "rf_all", + "training_rows": 29, + "grid_fit_mape_pct": 14.117015331381916, + "single_fit_mape_pct": 15.49366794487052, + "heldout_context_mape_pct": 43.53650868837558, + "heldout_context_max_abs_error_pct": 81.33508178007524, + "prediction_min_ms": 0.05866772018640992, + "q_min_delta_ms": -0.0009967416035880083, + "kv_min_delta_ms": -5.5955198407176e-05, + "monotone_and_nonnegative": false, + "tp": 4 + }, + { + "candidate": "rf_single", + "training_rows": 23, + "grid_fit_mape_pct": 12.07517666989496, + "single_fit_mape_pct": 17.672692652721008, + "heldout_context_mape_pct": 34.14562332866605, + "heldout_context_max_abs_error_pct": 62.31478818862995, + "prediction_min_ms": 0.058213693721655094, + "q_min_delta_ms": -0.0012244979345549661, + "kv_min_delta_ms": -8.259841203689389e-05, + "monotone_and_nonnegative": false, + "tp": 4 + }, + { + "candidate": "structured_single", + "training_rows": 23, + "grid_fit_mape_pct": 3.088740104976349, + "single_fit_mape_pct": 5.969109476280061, + "heldout_context_mape_pct": 3.0103379904473164, + "heldout_context_max_abs_error_pct": 5.490598706238697, + "prediction_min_ms": 0.05747733327249683, + "q_min_delta_ms": 0.0, + "kv_min_delta_ms": 0.0012048051417407057, + "monotone_and_nonnegative": true, + "tp": 4 + } + ], + "checks": { + "heldout_context_mape_le_5pct": true, + "monotone_and_nonnegative": true, + "profile_gate": true + } +} \ No newline at end of file diff --git a/runs/frontier-attn-structured-v0/results/trace-verdict.csv b/runs/frontier-attn-structured-v0/results/trace-verdict.csv new file mode 100644 index 0000000..be7687d --- /dev/null +++ b/runs/frontier-attn-structured-v0/results/trace-verdict.csv @@ -0,0 +1,85 @@ +cell,metric,quantile,old_bias,new_bias,abs_bias_delta_pp,validity +tp1_rho0p00125,ttft,mean,-0.13461915993830945,-0.06328385143753473,-7.133530850077471,GATE_FAIL_DIAGNOSTIC +tp1_rho0p00125,ttft,p50,-0.1888032883165517,-0.1117698463137391,-7.7033442002812595,GATE_FAIL_DIAGNOSTIC +tp1_rho0p00125,ttft,p90,-0.23223319000679374,-0.0884727580604037,-14.376043194639005,GATE_FAIL_DIAGNOSTIC +tp1_rho0p00125,ttft,p99,-0.16824856840168442,-0.08585570369326061,-8.239286470842382,GATE_FAIL_DIAGNOSTIC +tp1_rho0p00125,tpot,mean,0.1305653876178269,0.14303898259628217,1.2473594978455265,GATE_FAIL_DIAGNOSTIC +tp1_rho0p00125,tpot,p50,0.16837991778063455,0.1688780144991309,0.04980967184963492,GATE_FAIL_DIAGNOSTIC +tp1_rho0p00125,tpot,p90,0.012855564422932954,0.02293841255516459,1.0082848132231637,GATE_FAIL_DIAGNOSTIC +tp1_rho0p00125,tpot,p99,-0.08151080694091946,-0.06480973978913974,-1.6701067151779714,GATE_FAIL_DIAGNOSTIC +tp1_rho0p00125,e2e,mean,0.06539157436639341,0.0838094906426525,1.8417916276259092,GATE_FAIL_DIAGNOSTIC +tp1_rho0p00125,e2e,p50,0.10867934171755954,0.11142188099086506,0.2742539273305519,GATE_FAIL_DIAGNOSTIC +tp1_rho0p00125,e2e,p90,0.10946179160934073,0.11872607178176105,0.9264280172420314,GATE_FAIL_DIAGNOSTIC +tp1_rho0p00125,e2e,p99,-0.0657146472433028,-0.04585643943465822,-1.9858207808644577,GATE_FAIL_DIAGNOSTIC +tp1_rho0p0025,ttft,mean,-0.17677087458166194,-0.09487906467830536,-8.189180990335657,GATE_FAIL_DIAGNOSTIC +tp1_rho0p0025,ttft,p50,0.008311436147272566,0.015508635458377175,0.7197199311104608,GATE_FAIL_DIAGNOSTIC +tp1_rho0p0025,ttft,p90,-0.2608553178054708,-0.129865645852306,-13.098967195316478,GATE_FAIL_DIAGNOSTIC +tp1_rho0p0025,ttft,p99,-0.22116442296103195,-0.14410151018893788,-7.706291277209407,GATE_FAIL_DIAGNOSTIC +tp1_rho0p0025,tpot,mean,0.014380733682430142,0.052302860177306544,3.7922126494876403,GATE_FAIL_DIAGNOSTIC +tp1_rho0p0025,tpot,p50,0.13351145963877706,0.14244154194999165,0.8930082311214588,GATE_FAIL_DIAGNOSTIC +tp1_rho0p0025,tpot,p90,-0.05456950130438105,0.018069551387063856,-3.649994991731719,GATE_FAIL_DIAGNOSTIC +tp1_rho0p0025,tpot,p99,-0.23635406197836167,-0.1790206784227079,-5.733338355565376,GATE_FAIL_DIAGNOSTIC +tp1_rho0p0025,e2e,mean,-0.020164189983441452,0.01563919326555167,-0.4524996717889782,GATE_FAIL_DIAGNOSTIC +tp1_rho0p0025,e2e,p50,0.07632815851795742,0.10505951594320918,2.8731357425251765,GATE_FAIL_DIAGNOSTIC +tp1_rho0p0025,e2e,p90,0.049809009042946335,0.08165607475145953,3.1847065708513194,GATE_FAIL_DIAGNOSTIC +tp1_rho0p0025,e2e,p99,-0.18303183751478602,-0.15333409130015813,-2.96977462146279,GATE_FAIL_DIAGNOSTIC +tp2_rho0p0025,ttft,mean,-0.11161154024124531,-0.045433491316312524,-6.617804892493279,PASS_SUBCRITICAL +tp2_rho0p0025,ttft,p50,-0.18420934047220774,-0.0875990583320057,-9.661028214020204,PASS_SUBCRITICAL +tp2_rho0p0025,ttft,p90,-0.21836264490202395,-0.1142200855839675,-10.414255931805645,PASS_SUBCRITICAL +tp2_rho0p0025,ttft,p99,-0.17283197594971011,-0.07674087497700505,-9.609110097270507,PASS_SUBCRITICAL +tp2_rho0p0025,tpot,mean,0.13711499081487563,0.15073709978689778,1.362210897202215,PASS_SUBCRITICAL +tp2_rho0p0025,tpot,p50,0.17555321305308488,0.18527285925405948,0.9719646200974597,PASS_SUBCRITICAL +tp2_rho0p0025,tpot,p90,0.0591579975137338,0.07863996768588354,1.9481970172149734,PASS_SUBCRITICAL +tp2_rho0p0025,tpot,p99,0.1300483675091633,0.1661995397125918,3.6151172203428503,PASS_SUBCRITICAL +tp2_rho0p0025,e2e,mean,0.10925353865257875,0.12696146154030977,1.7707922887731016,PASS_SUBCRITICAL +tp2_rho0p0025,e2e,p50,0.1339165600755408,0.14796251184179712,1.404595176625631,PASS_SUBCRITICAL +tp2_rho0p0025,e2e,p90,0.10666828724664539,0.12767235986604622,2.1004072619400835,PASS_SUBCRITICAL +tp2_rho0p0025,e2e,p99,-0.07437942975605877,-0.03965040123988098,-3.472902851617779,PASS_SUBCRITICAL +tp2_rho0p005,ttft,mean,-0.14129871969878843,-0.07082500585057615,-7.047371384821228,GATE_FAIL_DIAGNOSTIC +tp2_rho0p005,ttft,p50,-0.2042045530944649,-0.1284088888361358,-7.579566425832909,GATE_FAIL_DIAGNOSTIC +tp2_rho0p005,ttft,p90,-0.19003454588767263,-0.111136573344055,-7.889797254361763,GATE_FAIL_DIAGNOSTIC +tp2_rho0p005,ttft,p99,-0.19373351009539902,-0.09012556161973535,-10.360794847566366,GATE_FAIL_DIAGNOSTIC +tp2_rho0p005,tpot,mean,0.03117337438562004,0.05457336599027876,2.3399991604658723,GATE_FAIL_DIAGNOSTIC +tp2_rho0p005,tpot,p50,0.07668249597302182,0.0872512146277895,1.0568718654767675,GATE_FAIL_DIAGNOSTIC +tp2_rho0p005,tpot,p90,-0.03724827658429621,0.01132352325010614,-2.5924753334190074,GATE_FAIL_DIAGNOSTIC +tp2_rho0p005,tpot,p99,-0.10050436157089844,-0.05948329733667248,-4.102106423422596,GATE_FAIL_DIAGNOSTIC +tp2_rho0p005,e2e,mean,0.023867807624916495,0.050164236759908075,2.629642913499158,GATE_FAIL_DIAGNOSTIC +tp2_rho0p005,e2e,p50,0.07536668131278851,0.0912493994395978,1.588271812680929,GATE_FAIL_DIAGNOSTIC +tp2_rho0p005,e2e,p90,-0.03100470462321266,-0.0004979191794830456,-3.0506785443729614,GATE_FAIL_DIAGNOSTIC +tp2_rho0p005,e2e,p99,-0.04909581632382212,-0.0014369075488634014,-4.765890877495872,GATE_FAIL_DIAGNOSTIC +tp4_rho0p0025,ttft,mean,0.025022574738277282,0.07766646565061346,5.2643890912336175,PASS_SUBCRITICAL +tp4_rho0p0025,ttft,p50,-0.040042171846277425,0.029153379043297147,-1.0888792802980278,PASS_SUBCRITICAL +tp4_rho0p0025,ttft,p90,-0.056230097634382616,0.025222989748299444,-3.100710788608317,PASS_SUBCRITICAL +tp4_rho0p0025,ttft,p99,-0.07535478089127973,0.0205549324689376,-5.479984842234213,PASS_SUBCRITICAL +tp4_rho0p0025,tpot,mean,0.2170232618103144,0.2295170016795841,1.2493739869269715,PASS_SUBCRITICAL +tp4_rho0p0025,tpot,p50,0.22406751004936917,0.22406940610958842,0.00018960602192474862,PASS_SUBCRITICAL +tp4_rho0p0025,tpot,p90,0.1725668492041552,0.1795965483385546,0.7029699134399409,PASS_SUBCRITICAL +tp4_rho0p0025,tpot,p99,0.1603764334794579,0.254199450927048,9.382301744759008,PASS_SUBCRITICAL +tp4_rho0p0025,e2e,mean,0.18328079455378776,0.19190660476104554,0.8625810207257778,PASS_SUBCRITICAL +tp4_rho0p0025,e2e,p50,0.2057109615696404,0.21253242300694286,0.6821461437302473,PASS_SUBCRITICAL +tp4_rho0p0025,e2e,p90,0.1869703879211648,0.19279855916666536,0.5828171245500557,PASS_SUBCRITICAL +tp4_rho0p0025,e2e,p99,0.14838304065885655,0.15160588346499027,0.3222842806133719,PASS_SUBCRITICAL +tp4_rho0p005,ttft,mean,0.028648879997638963,0.08356973519379125,5.492085519615229,PASS_SUBCRITICAL +tp4_rho0p005,ttft,p50,0.028237979190582876,0.09021324737193111,6.197526818134823,PASS_SUBCRITICAL +tp4_rho0p005,ttft,p90,-0.055961238578361966,-0.0006012940489499138,-5.535994452941205,PASS_SUBCRITICAL +tp4_rho0p005,ttft,p99,-0.045491187615110146,0.05253708684194205,0.7045899226831902,PASS_SUBCRITICAL +tp4_rho0p005,tpot,mean,0.1707193936623511,0.1813506819061229,1.0631288243771824,PASS_SUBCRITICAL +tp4_rho0p005,tpot,p50,0.16851374859025317,0.1743324539248605,0.5818705334607321,PASS_SUBCRITICAL +tp4_rho0p005,tpot,p90,0.10492621353626864,0.11816822907155744,1.3242015535288796,PASS_SUBCRITICAL +tp4_rho0p005,tpot,p99,0.31231888769471766,0.3662267201704473,5.390783247572961,PASS_SUBCRITICAL +tp4_rho0p005,e2e,mean,0.151102823467785,0.1630793421767109,1.197651870892591,PASS_SUBCRITICAL +tp4_rho0p005,e2e,p50,0.1594213531394918,0.17360527090575292,1.418391776626113,PASS_SUBCRITICAL +tp4_rho0p005,e2e,p90,0.1266352410718406,0.13652104764058856,0.9885806568747962,PASS_SUBCRITICAL +tp4_rho0p005,e2e,p99,0.15576537699445703,0.17677450343779522,2.100912644333819,PASS_SUBCRITICAL +tp4_rho0p01,ttft,mean,-0.0014652143973501086,0.059650620031540064,5.8185405634189955,PASS_SUBCRITICAL +tp4_rho0p01,ttft,p50,0.22936601881498542,0.24159106387124998,1.2225045056264565,PASS_SUBCRITICAL +tp4_rho0p01,ttft,p90,-0.0646093465409875,-0.011548419893895705,-5.30609266470918,PASS_SUBCRITICAL +tp4_rho0p01,ttft,p99,-0.09621678853313553,-0.015475807392170575,-8.074098114096495,PASS_SUBCRITICAL +tp4_rho0p01,tpot,mean,0.06675609059150077,0.10596101263201793,3.9204922040517163,PASS_SUBCRITICAL +tp4_rho0p01,tpot,p50,0.08477302587551214,0.09703754188844527,1.2264516012933129,PASS_SUBCRITICAL +tp4_rho0p01,tpot,p90,0.0379183273767328,0.08369800201750718,4.577967464077439,PASS_SUBCRITICAL +tp4_rho0p01,tpot,p99,-0.010663954751357074,0.06667813160571406,5.601417685435699,PASS_SUBCRITICAL +tp4_rho0p01,e2e,mean,0.07212904317306096,0.09777288053702092,2.564383736395996,PASS_SUBCRITICAL +tp4_rho0p01,e2e,p50,0.12069215463307655,0.1388377217196832,1.8145567086606653,PASS_SUBCRITICAL +tp4_rho0p01,e2e,p90,0.03317293927357903,0.058060760567474216,2.4887821293895183,PASS_SUBCRITICAL +tp4_rho0p01,e2e,p99,0.0338378271163308,0.06380410696893425,2.996627985260345,PASS_SUBCRITICAL diff --git a/runs/frontier-attn-structured-v0/results/trace-verdict.json b/runs/frontier-attn-structured-v0/results/trace-verdict.json new file mode 100644 index 0000000..07ed0fc --- /dev/null +++ b/runs/frontier-attn-structured-v0/results/trace-verdict.json @@ -0,0 +1,2219 @@ +{ + "schema": "frontier-attn-structured-trial-aware-verdict-v1", + "metric_note": "Primary values are per-real-trial distribution biases with request alignment by index. legacy_pooled reproduces the old milestone quantile convention only for direct comparison.", + "cells": { + "tp1_rho0p00125": { + "old": { + "trialwise_distribution_bias": [ + { + "ttft": { + "mean": -0.13148990670086547, + "p50": -0.18680026171265385, + "p90": -0.2281339774144484, + "p99": -0.14956660473341468 + }, + "tpot": { + "mean": 0.1393089430926731, + "p50": 0.17688566049293195, + "p90": 0.021918816469380976, + "p99": -0.06745527151165458 + }, + "e2e": { + "mean": 0.0728867501966229, + "p50": 0.11334615386654034, + "p90": 0.11968616309773676, + "p99": -0.04061861992039894 + } + }, + { + "ttft": { + "mean": -0.13772594464937732, + "p50": -0.19220957147090617, + "p90": -0.2342597777065415, + "p99": -0.15374940938906825 + }, + "tpot": { + "mean": 0.12195501379179413, + "p50": 0.1610213245142966, + "p90": 0.005473527596398301, + "p99": -0.08127351500612069 + }, + "e2e": { + "mean": 0.05800039446459018, + "p50": 0.09970261087805131, + "p90": 0.10532164717109044, + "p99": -0.046957770855300444 + } + } + ], + "trialwise_distribution_bias_summary": { + "ttft": { + "mean": { + "mean": -0.1346079256751214, + "min": -0.13772594464937732, + "max": -0.13148990670086547 + }, + "p50": { + "mean": -0.18950491659178, + "min": -0.19220957147090617, + "max": -0.18680026171265385 + }, + "p90": { + "mean": -0.23119687756049495, + "min": -0.2342597777065415, + "max": -0.2281339774144484 + }, + "p99": { + "mean": -0.15165800706124147, + "min": -0.15374940938906825, + "max": -0.14956660473341468 + } + }, + "tpot": { + "mean": { + "mean": 0.13063197844223362, + "min": 0.12195501379179413, + "max": 0.1393089430926731 + }, + "p50": { + "mean": 0.16895349250361427, + "min": 0.1610213245142966, + "max": 0.17688566049293195 + }, + "p90": { + "mean": 0.013696172032889638, + "min": 0.005473527596398301, + "max": 0.021918816469380976 + }, + "p99": { + "mean": -0.07436439325888763, + "min": -0.08127351500612069, + "max": -0.06745527151165458 + } + }, + "e2e": { + "mean": { + "mean": 0.06544357233060655, + "min": 0.05800039446459018, + "max": 0.0728867501966229 + }, + "p50": { + "mean": 0.10652438237229583, + "min": 0.09970261087805131, + "max": 0.11334615386654034 + }, + "p90": { + "mean": 0.1125039051344136, + "min": 0.10532164717109044, + "max": 0.11968616309773676 + }, + "p99": { + "mean": -0.04378819538784969, + "min": -0.046957770855300444, + "max": -0.04061861992039894 + } + } + }, + "legacy_pooled_distribution_bias": { + "ttft": { + "mean": -0.13461915993830945, + "p50": -0.1888032883165517, + "p90": -0.23223319000679374, + "p99": -0.16824856840168442 + }, + "tpot": { + "mean": 0.1305653876178269, + "p50": 0.16837991778063455, + "p90": 0.012855564422932954, + "p99": -0.08151080694091946 + }, + "e2e": { + "mean": 0.06539157436639341, + "p50": 0.10867934171755954, + "p90": 0.10946179160934073, + "p99": -0.0657146472433028 + } + } + }, + "new": { + "trialwise_distribution_bias": [ + { + "ttft": { + "mean": -0.05989664674711635, + "p50": -0.10957660686565794, + "p90": -0.0836059887499959, + "p99": -0.0653231144095356 + }, + "tpot": { + "mean": 0.1518790062372861, + "p50": 0.17738738332864315, + "p90": 0.032091888121311134, + "p99": -0.05049862983288826 + }, + "e2e": { + "mean": 0.09143423903966252, + "p50": 0.11610023742963112, + "p90": 0.12903581929912153, + "p99": -0.020226996786041312 + } + }, + { + "ttft": { + "mean": -0.06664673546990688, + "p50": -0.11549959936391153, + "p90": -0.09087881400402557, + "p99": -0.0699202655213567 + }, + "tpot": { + "mean": 0.1343336100051224, + "p50": 0.16151628416144917, + "p90": 0.015482888492302317, + "p99": -0.0645681331290643 + }, + "e2e": { + "mean": 0.07629053599972169, + "p50": 0.10242294441887236, + "p90": 0.11455135611418107, + "p99": -0.02670088618839733 + } + } + ], + "trialwise_distribution_bias_summary": { + "ttft": { + "mean": { + "mean": -0.06327169110851161, + "min": -0.06664673546990688, + "max": -0.05989664674711635 + }, + "p50": { + "mean": -0.11253810311478474, + "min": -0.11549959936391153, + "max": -0.10957660686565794 + }, + "p90": { + "mean": -0.08724240137701074, + "min": -0.09087881400402557, + "max": -0.0836059887499959 + }, + "p99": { + "mean": -0.06762168996544615, + "min": -0.0699202655213567, + "max": -0.0653231144095356 + } + }, + "tpot": { + "mean": { + "mean": 0.14310630812120423, + "min": 0.1343336100051224, + "max": 0.1518790062372861 + }, + "p50": { + "mean": 0.16945183374504616, + "min": 0.16151628416144917, + "max": 0.17738738332864315 + }, + "p90": { + "mean": 0.023787388306806725, + "min": 0.015482888492302317, + "max": 0.032091888121311134 + }, + "p99": { + "mean": -0.05753338148097628, + "min": -0.0645681331290643, + "max": -0.05049862983288826 + } + }, + "e2e": { + "mean": { + "mean": 0.0838623875196921, + "min": 0.07629053599972169, + "max": 0.09143423903966252 + }, + "p50": { + "mean": 0.10926159092425174, + "min": 0.10242294441887236, + "max": 0.11610023742963112 + }, + "p90": { + "mean": 0.1217935877066513, + "min": 0.11455135611418107, + "max": 0.12903581929912153 + }, + "p99": { + "mean": -0.023463941487219322, + "min": -0.02670088618839733, + "max": -0.020226996786041312 + } + } + }, + "paired_relative_error": [ + { + "ttft": { + "mean": 0.3691695743143199, + "p50": -0.03099707280100344, + "p90": 1.7891828562343537, + "p99": 5.429960617790179 + }, + "tpot": { + "mean": 0.19492722441928262, + "p50": 0.15055142720578293, + "p90": 0.2670903700878269, + "p99": 0.6745762204781113 + }, + "e2e": { + "mean": 0.1844268367659844, + "p50": 0.1424666323844526, + "p90": 0.31842146555728224, + "p99": 0.8437286984487435 + } + }, + { + "ttft": { + "mean": 0.3669522667824523, + "p50": -0.03476798007471665, + "p90": 1.827734692042949, + "p99": 5.512577837970861 + }, + "tpot": { + "mean": 0.1783718677969176, + "p50": 0.13458290148059987, + "p90": 0.24952928603370794, + "p99": 0.6582817886518392 + }, + "e2e": { + "mean": 0.16858938086274747, + "p50": 0.12880754276426226, + "p90": 0.29822488192148, + "p99": 0.7895217968914289 + } + } + ], + "legacy_pooled_distribution_bias": { + "ttft": { + "mean": -0.06328385143753473, + "p50": -0.1117698463137391, + "p90": -0.0884727580604037, + "p99": -0.08585570369326061 + }, + "tpot": { + "mean": 0.14303898259628217, + "p50": 0.1688780144991309, + "p90": 0.02293841255516459, + "p99": -0.06480973978913974 + }, + "e2e": { + "mean": 0.0838094906426525, + "p50": 0.11142188099086506, + "p90": 0.11872607178176105, + "p99": -0.04585643943465822 + } + }, + "waiting_p99_ms": 1337.0359972076221, + "validity": "GATE_FAIL_DIAGNOSTIC" + } + }, + "tp1_rho0p0025": { + "old": { + "trialwise_distribution_bias": [ + { + "ttft": { + "mean": -0.178961187154444, + "p50": 0.004736647098298533, + "p90": -0.26795354312466707, + "p99": -0.22168753840926173 + }, + "tpot": { + "mean": 0.01036398277932227, + "p50": 0.13356090363025383, + "p90": -0.05541984044976886, + "p99": -0.26072314328609314 + }, + "e2e": { + "mean": -0.024645268935464575, + "p50": 0.0817280529155681, + "p90": 0.04955125280528564, + "p99": -0.1871016978849053 + } + }, + { + "ttft": { + "mean": -0.17456884440992257, + "p50": 0.011041256441842635, + "p90": -0.25172604669420906, + "p99": -0.21630340228356143 + }, + "tpot": { + "mean": 0.01842954963685723, + "p50": 0.13346201996043702, + "p90": -0.05215064358043298, + "p99": -0.15675916344669943 + }, + "e2e": { + "mean": -0.015641746084433396, + "p50": 0.07195840871873896, + "p90": 0.052264109329363505, + "p99": -0.17396512464775202 + } + } + ], + "trialwise_distribution_bias_summary": { + "ttft": { + "mean": { + "mean": -0.1767650157821833, + "min": -0.178961187154444, + "max": -0.17456884440992257 + }, + "p50": { + "mean": 0.007888951770070584, + "min": 0.004736647098298533, + "max": 0.011041256441842635 + }, + "p90": { + "mean": -0.2598397949094381, + "min": -0.26795354312466707, + "max": -0.25172604669420906 + }, + "p99": { + "mean": -0.2189954703464116, + "min": -0.22168753840926173, + "max": -0.21630340228356143 + } + }, + "tpot": { + "mean": { + "mean": 0.01439676620808975, + "min": 0.01036398277932227, + "max": 0.01842954963685723 + }, + "p50": { + "mean": 0.13351146179534543, + "min": 0.13346201996043702, + "max": 0.13356090363025383 + }, + "p90": { + "mean": -0.05378524201510092, + "min": -0.05541984044976886, + "max": -0.05215064358043298 + }, + "p99": { + "mean": -0.2087411533663963, + "min": -0.26072314328609314, + "max": -0.15675916344669943 + } + }, + "e2e": { + "mean": { + "mean": -0.020143507509948984, + "min": -0.024645268935464575, + "max": -0.015641746084433396 + }, + "p50": { + "mean": 0.07684323081715352, + "min": 0.07195840871873896, + "max": 0.0817280529155681 + }, + "p90": { + "mean": 0.05090768106732457, + "min": 0.04955125280528564, + "max": 0.052264109329363505 + }, + "p99": { + "mean": -0.18053341126632866, + "min": -0.1871016978849053, + "max": -0.17396512464775202 + } + } + }, + "legacy_pooled_distribution_bias": { + "ttft": { + "mean": -0.17677087458166194, + "p50": 0.008311436147272566, + "p90": -0.2608553178054708, + "p99": -0.22116442296103195 + }, + "tpot": { + "mean": 0.014380733682430142, + "p50": 0.13351145963877706, + "p90": -0.05456950130438105, + "p99": -0.23635406197836167 + }, + "e2e": { + "mean": -0.020164189983441452, + "p50": 0.07632815851795742, + "p90": 0.049809009042946335, + "p99": -0.18303183751478602 + } + } + }, + "new": { + "trialwise_distribution_bias": [ + { + "ttft": { + "mean": -0.09728726150141453, + "p50": 0.011908330017980539, + "p90": -0.1382218037906623, + "p99": -0.14467638598472385 + }, + "tpot": { + "mean": 0.04813594501063553, + "p50": 0.1424913754734047, + "p90": 0.01715387922135076, + "p99": -0.2052193535460428 + }, + "e2e": { + "mean": 0.010994374852847301, + "p50": 0.11060355438719509, + "p90": 0.08139049920593726, + "p99": -0.15755189584478857 + } + }, + { + "ttft": { + "mean": -0.09245798463253013, + "p50": 0.018257940864430843, + "p90": -0.11911850444197748, + "p99": -0.13875950941310633 + }, + "tpot": { + "mean": 0.05650303913152255, + "p50": 0.14239171277369528, + "p90": 0.020674254113796777, + "p99": -0.0934499151356964 + }, + "e2e": { + "mean": 0.02032688810811885, + "p50": 0.10057312063737019, + "p90": 0.0841856530995708, + "p99": -0.1439377928383722 + } + } + ], + "trialwise_distribution_bias_summary": { + "ttft": { + "mean": { + "mean": -0.09487262306697233, + "min": -0.09728726150141453, + "max": -0.09245798463253013 + }, + "p50": { + "mean": 0.015083135441205691, + "min": 0.011908330017980539, + "max": 0.018257940864430843 + }, + "p90": { + "mean": -0.12867015411631988, + "min": -0.1382218037906623, + "max": -0.11911850444197748 + }, + "p99": { + "mean": -0.1417179476989151, + "min": -0.14467638598472385, + "max": -0.13875950941310633 + } + }, + "tpot": { + "mean": { + "mean": 0.05231949207107904, + "min": 0.04813594501063553, + "max": 0.05650303913152255 + }, + "p50": { + "mean": 0.14244154412354998, + "min": 0.14239171277369528, + "max": 0.1424913754734047 + }, + "p90": { + "mean": 0.018914066667573767, + "min": 0.01715387922135076, + "max": 0.020674254113796777 + }, + "p99": { + "mean": -0.14933463434086958, + "min": -0.2052193535460428, + "max": -0.0934499151356964 + } + }, + "e2e": { + "mean": { + "mean": 0.015660631480483075, + "min": 0.010994374852847301, + "max": 0.02032688810811885 + }, + "p50": { + "mean": 0.10558833751228264, + "min": 0.10057312063737019, + "max": 0.11060355438719509 + }, + "p90": { + "mean": 0.08278807615275402, + "min": 0.08139049920593726, + "max": 0.0841856530995708 + }, + "p99": { + "mean": -0.1507448443415804, + "min": -0.15755189584478857, + "max": -0.1439377928383722 + } + } + }, + "paired_relative_error": [ + { + "ttft": { + "mean": 0.39789106943830893, + "p50": -0.037298357008305895, + "p90": 1.9730972451814688, + "p99": 6.018295451307029 + }, + "tpot": { + "mean": 0.1553028513608087, + "p50": 0.12385990892916658, + "p90": 0.2584968822537069, + "p99": 0.9658213367115374 + }, + "e2e": { + "mean": 0.1471398515879261, + "p50": 0.10601983073958936, + "p90": 0.32930377247615056, + "p99": 1.075635524765205 + } + }, + { + "ttft": { + "mean": 0.4002572158008619, + "p50": -0.031486174528958244, + "p90": 1.8666003636442456, + "p99": 5.991354563261557 + }, + "tpot": { + "mean": 0.1566771540679317, + "p50": 0.12379976526368523, + "p90": 0.25274583367589193, + "p99": 0.958693609453715 + }, + "e2e": { + "mean": 0.14911603622614725, + "p50": 0.10650308347135491, + "p90": 0.3195494670044913, + "p99": 1.1185032164459736 + } + } + ], + "legacy_pooled_distribution_bias": { + "ttft": { + "mean": -0.09487906467830536, + "p50": 0.015508635458377175, + "p90": -0.129865645852306, + "p99": -0.14410151018893788 + }, + "tpot": { + "mean": 0.052302860177306544, + "p50": 0.14244154194999165, + "p90": 0.018069551387063856, + "p99": -0.1790206784227079 + }, + "e2e": { + "mean": 0.01563919326555167, + "p50": 0.10505951594320918, + "p90": 0.08165607475145953, + "p99": -0.15333409130015813 + } + }, + "waiting_p99_ms": 1892.1769691703946, + "validity": "GATE_FAIL_DIAGNOSTIC" + } + }, + "tp2_rho0p0025": { + "old": { + "trialwise_distribution_bias": [ + { + "ttft": { + "mean": -0.11106335941203382, + "p50": -0.1855202869158692, + "p90": -0.21828233796243518, + "p99": -0.1688334681304367 + }, + "tpot": { + "mean": 0.1303208667385706, + "p50": 0.16909257797747365, + "p90": 0.05206789287995917, + "p99": 0.14191216788372232 + }, + "e2e": { + "mean": 0.1031266658038281, + "p50": 0.13020268054402595, + "p90": 0.09830535586040931, + "p99": -0.0581273596953024 + } + }, + { + "ttft": { + "mean": -0.11215904539344854, + "p50": -0.18289416715548218, + "p90": -0.21914116973979564, + "p99": -0.17209787391954623 + }, + "tpot": { + "mean": 0.14399128493700397, + "p50": 0.1866331158045056, + "p90": 0.06642456306402275, + "p99": 0.15612928840488144 + }, + "e2e": { + "mean": 0.11544885011206724, + "p50": 0.14502095370348014, + "p90": 0.10849722315778151, + "p99": -0.045303035491763635 + } + } + ], + "trialwise_distribution_bias_summary": { + "ttft": { + "mean": { + "mean": -0.11161120240274118, + "min": -0.11215904539344854, + "max": -0.11106335941203382 + }, + "p50": { + "mean": -0.18420722703567569, + "min": -0.1855202869158692, + "max": -0.18289416715548218 + }, + "p90": { + "mean": -0.2187117538511154, + "min": -0.21914116973979564, + "max": -0.21828233796243518 + }, + "p99": { + "mean": -0.17046567102499147, + "min": -0.17209787391954623, + "max": -0.1688334681304367 + } + }, + "tpot": { + "mean": { + "mean": 0.13715607583778727, + "min": 0.1303208667385706, + "max": 0.14399128493700397 + }, + "p50": { + "mean": 0.17786284689098963, + "min": 0.16909257797747365, + "max": 0.1866331158045056 + }, + "p90": { + "mean": 0.05924622797199096, + "min": 0.05206789287995917, + "max": 0.06642456306402275 + }, + "p99": { + "mean": 0.1490207281443019, + "min": 0.14191216788372232, + "max": 0.15612928840488144 + } + }, + "e2e": { + "mean": { + "mean": 0.10928775795794766, + "min": 0.1031266658038281, + "max": 0.11544885011206724 + }, + "p50": { + "mean": 0.13761181712375303, + "min": 0.13020268054402595, + "max": 0.14502095370348014 + }, + "p90": { + "mean": 0.10340128950909541, + "min": 0.09830535586040931, + "max": 0.10849722315778151 + }, + "p99": { + "mean": -0.05171519759353302, + "min": -0.0581273596953024, + "max": -0.045303035491763635 + } + } + }, + "legacy_pooled_distribution_bias": { + "ttft": { + "mean": -0.11161154024124531, + "p50": -0.18420934047220774, + "p90": -0.21836264490202395, + "p99": -0.17283197594971011 + }, + "tpot": { + "mean": 0.13711499081487563, + "p50": 0.17555321305308488, + "p90": 0.0591579975137338, + "p99": 0.1300483675091633 + }, + "e2e": { + "mean": 0.10925353865257875, + "p50": 0.1339165600755408, + "p90": 0.10666828724664539, + "p99": -0.07437942975605877 + } + } + }, + "new": { + "trialwise_distribution_bias": [ + { + "ttft": { + "mean": -0.044844475267623835, + "p50": -0.08906525404741798, + "p90": -0.11412907883561804, + "p99": -0.07227786537885415 + }, + "tpot": { + "mean": 0.14386158526258666, + "p50": 0.1787588067010671, + "p90": 0.071419448886029, + "p99": 0.17844287277146695 + }, + "e2e": { + "mean": 0.12073678040141796, + "p50": 0.14420262806746403, + "p90": 0.11915070375608593, + "p99": -0.022788557992646938 + } + }, + { + "ttft": { + "mean": -0.046021781355297144, + "p50": -0.08612813517467069, + "p90": -0.11510233828040589, + "p99": -0.07592149320892366 + }, + "tpot": { + "mean": 0.15769576871598226, + "p50": 0.196444372264794, + "p90": 0.08604019319402298, + "p99": 0.19311481061458743 + }, + "e2e": { + "mean": 0.13325567383154438, + "p50": 0.15920445684060733, + "p90": 0.12953600816854335, + "p99": -0.009483068681846096 + } + } + ], + "trialwise_distribution_bias_summary": { + "ttft": { + "mean": { + "mean": -0.045433128311460486, + "min": -0.046021781355297144, + "max": -0.044844475267623835 + }, + "p50": { + "mean": -0.08759669461104433, + "min": -0.08906525404741798, + "max": -0.08612813517467069 + }, + "p90": { + "mean": -0.11461570855801197, + "min": -0.11510233828040589, + "max": -0.11412907883561804 + }, + "p99": { + "mean": -0.07409967929388891, + "min": -0.07592149320892366, + "max": -0.07227786537885415 + } + }, + "tpot": { + "mean": { + "mean": 0.15077867698928446, + "min": 0.14386158526258666, + "max": 0.15769576871598226 + }, + "p50": { + "mean": 0.18760158948293054, + "min": 0.1787588067010671, + "max": 0.196444372264794 + }, + "p90": { + "mean": 0.07872982104002599, + "min": 0.071419448886029, + "max": 0.08604019319402298 + }, + "p99": { + "mean": 0.1857788416930272, + "min": 0.17844287277146695, + "max": 0.19311481061458743 + } + }, + "e2e": { + "mean": { + "mean": 0.12699622711648118, + "min": 0.12073678040141796, + "max": 0.13325567383154438 + }, + "p50": { + "mean": 0.15170354245403567, + "min": 0.14420262806746403, + "max": 0.15920445684060733 + }, + "p90": { + "mean": 0.12434335596231463, + "min": 0.11915070375608593, + "max": 0.12953600816854335 + }, + "p99": { + "mean": -0.016135813337246518, + "min": -0.022788557992646938, + "max": -0.009483068681846096 + } + } + }, + "paired_relative_error": [ + { + "ttft": { + "mean": 0.28317282752846445, + "p50": 0.0015652470674283874, + "p90": 0.7651897154483899, + "p99": 4.595783098224935 + }, + "tpot": { + "mean": 0.1752842205127379, + "p50": 0.17053139492828456, + "p90": 0.24211599227572878, + "p99": 0.7603540706787565 + }, + "e2e": { + "mean": 0.16397230912194014, + "p50": 0.14764836952252053, + "p90": 0.26575788904393577, + "p99": 0.6911771461107379 + } + }, + { + "ttft": { + "mean": 0.27885319671790226, + "p50": 0.0008797795879422852, + "p90": 0.7521533350007815, + "p99": 4.589795377891504 + }, + "tpot": { + "mean": 0.18903026397070546, + "p50": 0.18546796656470424, + "p90": 0.25643004508741135, + "p99": 0.7281958169280102 + }, + "e2e": { + "mean": 0.17634926693766606, + "p50": 0.15964733210774384, + "p90": 0.2801020190882037, + "p99": 0.7024304395510836 + } + } + ], + "legacy_pooled_distribution_bias": { + "ttft": { + "mean": -0.045433491316312524, + "p50": -0.0875990583320057, + "p90": -0.1142200855839675, + "p99": -0.07674087497700505 + }, + "tpot": { + "mean": 0.15073709978689778, + "p50": 0.18527285925405948, + "p90": 0.07863996768588354, + "p99": 0.1661995397125918 + }, + "e2e": { + "mean": 0.12696146154030977, + "p50": 0.14796251184179712, + "p90": 0.12767235986604622, + "p99": -0.03965040123988098 + } + }, + "waiting_p99_ms": 777.5911879793948, + "validity": "PASS_SUBCRITICAL" + } + }, + "tp2_rho0p005": { + "old": { + "trialwise_distribution_bias": [ + { + "ttft": { + "mean": -0.141581861927082, + "p50": -0.2051822104110931, + "p90": -0.1895782660551383, + "p99": -0.19346662831715172 + }, + "tpot": { + "mean": 0.025318500347963065, + "p50": 0.07182548360524435, + "p90": -0.04507556167777899, + "p99": -0.10054590154610009 + }, + "e2e": { + "mean": 0.01846906077214167, + "p50": 0.07205509683921338, + "p90": -0.037157045612690995, + "p99": -0.051216767638022506 + } + }, + { + "ttft": { + "mean": -0.1410153906245514, + "p50": -0.20356790487770302, + "p90": -0.18910363664562158, + "p99": -0.192398015096606 + }, + "tpot": { + "mean": 0.03709549859113398, + "p50": 0.08312549432043648, + "p90": -0.029759535186826266, + "p99": -0.09947054412002211 + }, + "e2e": { + "mean": 0.029324095335773688, + "p50": 0.07587484709261458, + "p90": -0.027431862141837213, + "p99": -0.04314368195514718 + } + } + ], + "trialwise_distribution_bias_summary": { + "ttft": { + "mean": { + "mean": -0.14129862627581669, + "min": -0.141581861927082, + "max": -0.1410153906245514 + }, + "p50": { + "mean": -0.20437505764439806, + "min": -0.2051822104110931, + "max": -0.20356790487770302 + }, + "p90": { + "mean": -0.18934095135037993, + "min": -0.1895782660551383, + "max": -0.18910363664562158 + }, + "p99": { + "mean": -0.19293232170687885, + "min": -0.19346662831715172, + "max": -0.192398015096606 + } + }, + "tpot": { + "mean": { + "mean": 0.031206999469548524, + "min": 0.025318500347963065, + "max": 0.03709549859113398 + }, + "p50": { + "mean": 0.07747548896284041, + "min": 0.07182548360524435, + "max": 0.08312549432043648 + }, + "p90": { + "mean": -0.03741754843230263, + "min": -0.04507556167777899, + "max": -0.029759535186826266 + }, + "p99": { + "mean": -0.1000082228330611, + "min": -0.10054590154610009, + "max": -0.09947054412002211 + } + }, + "e2e": { + "mean": { + "mean": 0.02389657805395768, + "min": 0.01846906077214167, + "max": 0.029324095335773688 + }, + "p50": { + "mean": 0.07396497196591398, + "min": 0.07205509683921338, + "max": 0.07587484709261458 + }, + "p90": { + "mean": -0.0322944538772641, + "min": -0.037157045612690995, + "max": -0.027431862141837213 + }, + "p99": { + "mean": -0.047180224796584846, + "min": -0.051216767638022506, + "max": -0.04314368195514718 + } + } + }, + "legacy_pooled_distribution_bias": { + "ttft": { + "mean": -0.14129871969878843, + "p50": -0.2042045530944649, + "p90": -0.19003454588767263, + "p99": -0.19373351009539902 + }, + "tpot": { + "mean": 0.03117337438562004, + "p50": 0.07668249597302182, + "p90": -0.03724827658429621, + "p99": -0.10050436157089844 + }, + "e2e": { + "mean": 0.023867807624916495, + "p50": 0.07536668131278851, + "p90": -0.03100470462321266, + "p99": -0.04909581632382212 + } + } + }, + "new": { + "trialwise_distribution_bias": [ + { + "ttft": { + "mean": -0.07113138559444453, + "p50": -0.1294796632798084, + "p90": -0.11063584772248519, + "p99": -0.08982438463776078 + }, + "tpot": { + "mean": 0.048585629713612626, + "p50": 0.08234652581183928, + "p90": 0.003101343693636994, + "p99": -0.05952673172238401 + }, + "e2e": { + "mean": 0.04462683161260099, + "p50": 0.0878889042422101, + "p90": -0.006843953727060337, + "p99": -0.0036641600308731643 + } + }, + { + "ttft": { + "mean": -0.07051842392629604, + "p50": -0.12771160295843229, + "p90": -0.11011498510890981, + "p99": -0.08861845103384182 + }, + "tpot": { + "mean": 0.060629878515092876, + "p50": 0.09375745746657616, + "p90": 0.019190079238111446, + "p99": -0.05840233314016777 + }, + "e2e": { + "mean": 0.05576066061144686, + "p50": 0.09176507061640418, + "p90": 0.003187406757202862, + "p99": 0.004813545234813467 + } + } + ], + "trialwise_distribution_bias_summary": { + "ttft": { + "mean": { + "mean": -0.07082490476037029, + "min": -0.07113138559444453, + "max": -0.07051842392629604 + }, + "p50": { + "mean": -0.12859563311912034, + "min": -0.1294796632798084, + "max": -0.12771160295843229 + }, + "p90": { + "mean": -0.11037541641569751, + "min": -0.11063584772248519, + "max": -0.11011498510890981 + }, + "p99": { + "mean": -0.0892214178358013, + "min": -0.08982438463776078, + "max": -0.08861845103384182 + } + }, + "tpot": { + "mean": { + "mean": 0.05460775411435275, + "min": 0.048585629713612626, + "max": 0.060629878515092876 + }, + "p50": { + "mean": 0.08805199163920771, + "min": 0.08234652581183928, + "max": 0.09375745746657616 + }, + "p90": { + "mean": 0.01114571146587422, + "min": 0.003101343693636994, + "max": 0.019190079238111446 + }, + "p99": { + "mean": -0.05896453243127589, + "min": -0.05952673172238401, + "max": -0.05840233314016777 + } + }, + "e2e": { + "mean": { + "mean": 0.05019374611202393, + "min": 0.04462683161260099, + "max": 0.05576066061144686 + }, + "p50": { + "mean": 0.08982698742930714, + "min": 0.0878889042422101, + "max": 0.09176507061640418 + }, + "p90": { + "mean": -0.0018282734849287376, + "min": -0.006843953727060337, + "max": 0.003187406757202862 + }, + "p99": { + "mean": 0.0005746926019701514, + "min": -0.0036641600308731643, + "max": 0.004813545234813467 + } + } + }, + "paired_relative_error": [ + { + "ttft": { + "mean": 0.3165020807873401, + "p50": 0.008761867404954687, + "p90": 1.027515859973651, + "p99": 4.618320663100516 + }, + "tpot": { + "mean": 0.09697936002481403, + "p50": 0.08127529560627057, + "p90": 0.21395969552811614, + "p99": 0.6138944058729238 + }, + "e2e": { + "mean": 0.09434768590630697, + "p50": 0.07464475818134242, + "p90": 0.22980866153598797, + "p99": 0.6060590884554267 + } + }, + { + "ttft": { + "mean": 0.3247210835745076, + "p50": 0.00808317178222498, + "p90": 1.0875948711956118, + "p99": 4.791245921444296 + }, + "tpot": { + "mean": 0.10993925696112139, + "p50": 0.09402822239992542, + "p90": 0.22283625990015465, + "p99": 0.6083519770881531 + }, + "e2e": { + "mean": 0.10658386724241943, + "p50": 0.08490549835786211, + "p90": 0.2445084767702898, + "p99": 0.6267174054324888 + } + } + ], + "legacy_pooled_distribution_bias": { + "ttft": { + "mean": -0.07082500585057615, + "p50": -0.1284088888361358, + "p90": -0.111136573344055, + "p99": -0.09012556161973535 + }, + "tpot": { + "mean": 0.05457336599027876, + "p50": 0.0872512146277895, + "p90": 0.01132352325010614, + "p99": -0.05948329733667248 + }, + "e2e": { + "mean": 0.050164236759908075, + "p50": 0.0912493994395978, + "p90": -0.0004979191794830456, + "p99": -0.0014369075488634014 + } + }, + "waiting_p99_ms": 1166.1196883368564, + "validity": "GATE_FAIL_DIAGNOSTIC" + } + }, + "tp4_rho0p0025": { + "old": { + "trialwise_distribution_bias": [ + { + "ttft": { + "mean": 0.025153752214840692, + "p50": -0.04039475356731359, + "p90": -0.05617389473222491, + "p99": -0.07293111999637672 + }, + "tpot": { + "mean": 0.21469140550335514, + "p50": 0.22290333666146916, + "p90": 0.1721777151300294, + "p99": 0.1622573651896084 + }, + "e2e": { + "mean": 0.18156895570089593, + "p50": 0.20381782987468136, + "p90": 0.18582117345248075, + "p99": 0.15166386730143064 + } + }, + { + "ttft": { + "mean": 0.024891430828052088, + "p50": -0.03968933093624011, + "p90": -0.05623634198811063, + "p99": -0.0733553458724018 + }, + "tpot": { + "mean": 0.21936408831731027, + "p50": 0.2282296491940284, + "p90": 0.17345944256977727, + "p99": 0.16387998107689886 + }, + "e2e": { + "mean": 0.18499760077470503, + "p50": 0.2077274237083677, + "p90": 0.18741568436689596, + "p99": 0.15614012298902055 + } + } + ], + "trialwise_distribution_bias_summary": { + "ttft": { + "mean": { + "mean": 0.02502259152144639, + "min": 0.024891430828052088, + "max": 0.025153752214840692 + }, + "p50": { + "mean": -0.04004204225177685, + "min": -0.04039475356731359, + "max": -0.03968933093624011 + }, + "p90": { + "mean": -0.05620511836016777, + "min": -0.05623634198811063, + "max": -0.05617389473222491 + }, + "p99": { + "mean": -0.07314323293438926, + "min": -0.0733553458724018, + "max": -0.07293111999637672 + } + }, + "tpot": { + "mean": { + "mean": 0.21702774691033272, + "min": 0.21469140550335514, + "max": 0.21936408831731027 + }, + "p50": { + "mean": 0.22556649292774877, + "min": 0.22290333666146916, + "max": 0.2282296491940284 + }, + "p90": { + "mean": 0.17281857884990334, + "min": 0.1721777151300294, + "max": 0.17345944256977727 + }, + "p99": { + "mean": 0.16306867313325363, + "min": 0.1622573651896084, + "max": 0.16387998107689886 + } + }, + "e2e": { + "mean": { + "mean": 0.1832832782378005, + "min": 0.18156895570089593, + "max": 0.18499760077470503 + }, + "p50": { + "mean": 0.20577262679152453, + "min": 0.20381782987468136, + "max": 0.2077274237083677 + }, + "p90": { + "mean": 0.18661842890968836, + "min": 0.18582117345248075, + "max": 0.18741568436689596 + }, + "p99": { + "mean": 0.1539019951452256, + "min": 0.15166386730143064, + "max": 0.15614012298902055 + } + } + }, + "legacy_pooled_distribution_bias": { + "ttft": { + "mean": 0.025022574738277282, + "p50": -0.040042171846277425, + "p90": -0.056230097634382616, + "p99": -0.07535478089127973 + }, + "tpot": { + "mean": 0.2170232618103144, + "p50": 0.22406751004936917, + "p90": 0.1725668492041552, + "p99": 0.1603764334794579 + }, + "e2e": { + "mean": 0.18328079455378776, + "p50": 0.2057109615696404, + "p90": 0.1869703879211648, + "p99": 0.14838304065885655 + } + } + }, + "new": { + "trialwise_distribution_bias": [ + { + "ttft": { + "mean": 0.07780438024003325, + "p50": 0.028775382574128122, + "p90": 0.025284043303025253, + "p99": 0.02322998991779303 + }, + "tpot": { + "mean": 0.2271612069590991, + "p50": 0.22290523091840317, + "p90": 0.17920508135226615, + "p99": 0.25623246663646587 + }, + "e2e": { + "mean": 0.19018228704673856, + "p50": 0.21062858068127338, + "p90": 0.1916437019129637, + "p99": 0.15489591747842305 + } + }, + { + "ttft": { + "mean": 0.07752858635145746, + "p50": 0.029531653384293997, + "p90": 0.025216206468834785, + "p99": 0.022761760805360378 + }, + "tpot": { + "mean": 0.2318818586865509, + "p50": 0.22823155170133197, + "p90": 0.1804944929238653, + "p99": 0.2579862802233231 + }, + "e2e": { + "mean": 0.19363592605420304, + "p50": 0.21456029353388054, + "p90": 0.1932460420729579, + "p99": 0.15938473541043005 + } + } + ], + "trialwise_distribution_bias_summary": { + "ttft": { + "mean": { + "mean": 0.07766648329574535, + "min": 0.07752858635145746, + "max": 0.07780438024003325 + }, + "p50": { + "mean": 0.02915351797921106, + "min": 0.028775382574128122, + "max": 0.029531653384293997 + }, + "p90": { + "mean": 0.02525012488593002, + "min": 0.025216206468834785, + "max": 0.025284043303025253 + }, + "p99": { + "mean": 0.022995875361576705, + "min": 0.022761760805360378, + "max": 0.02322998991779303 + } + }, + "tpot": { + "mean": { + "mean": 0.229521532822825, + "min": 0.2271612069590991, + "max": 0.2318818586865509 + }, + "p50": { + "mean": 0.22556839130986756, + "min": 0.22290523091840317, + "max": 0.22823155170133197 + }, + "p90": { + "mean": 0.1798497871380657, + "min": 0.17920508135226615, + "max": 0.1804944929238653 + }, + "p99": { + "mean": 0.2571093734298945, + "min": 0.25623246663646587, + "max": 0.2579862802233231 + } + }, + "e2e": { + "mean": { + "mean": 0.1919091065504708, + "min": 0.19018228704673856, + "max": 0.19363592605420304 + }, + "p50": { + "mean": 0.21259443710757697, + "min": 0.21062858068127338, + "max": 0.21456029353388054 + }, + "p90": { + "mean": 0.1924448719929608, + "min": 0.1916437019129637, + "max": 0.1932460420729579 + }, + "p99": { + "mean": 0.15714032644442655, + "min": 0.15489591747842305, + "max": 0.15938473541043005 + } + } + }, + "paired_relative_error": [ + { + "ttft": { + "mean": 0.28957904842187726, + "p50": 0.11967766737369243, + "p90": 0.5365251338257485, + "p99": 3.680446479340459 + }, + "tpot": { + "mean": 0.2360056579049085, + "p50": 0.21333501659187393, + "p90": 0.27188619704554073, + "p99": 0.8481115630045084 + }, + "e2e": { + "mean": 0.22033571422861917, + "p50": 0.20586761334949796, + "p90": 0.282293891126381, + "p99": 0.6891849392053429 + } + }, + { + "ttft": { + "mean": 0.28322292774037994, + "p50": 0.12089296869324834, + "p90": 0.5087862765467016, + "p99": 3.551749946511281 + }, + "tpot": { + "mean": 0.24183792864428846, + "p50": 0.21903748389459432, + "p90": 0.2783964492106047, + "p99": 0.973107877920707 + }, + "e2e": { + "mean": 0.2239979384097061, + "p50": 0.21064946414808636, + "p90": 0.28840198884356866, + "p99": 0.6983274345617249 + } + } + ], + "legacy_pooled_distribution_bias": { + "ttft": { + "mean": 0.07766646565061346, + "p50": 0.029153379043297147, + "p90": 0.025222989748299444, + "p99": 0.0205549324689376 + }, + "tpot": { + "mean": 0.2295170016795841, + "p50": 0.22406940610958842, + "p90": 0.1795965483385546, + "p99": 0.254199450927048 + }, + "e2e": { + "mean": 0.19190660476104554, + "p50": 0.21253242300694286, + "p90": 0.19279855916666536, + "p99": 0.15160588346499027 + } + }, + "waiting_p99_ms": 302.3540478261558, + "validity": "PASS_SUBCRITICAL" + } + }, + "tp4_rho0p005": { + "old": { + "trialwise_distribution_bias": [ + { + "ttft": { + "mean": 0.02817612266853226, + "p50": 0.029949406527602123, + "p90": -0.05512408243570239, + "p99": -0.04532941341343785 + }, + "tpot": { + "mean": 0.17688090609346543, + "p50": 0.1740795026677315, + "p90": 0.11018831255907795, + "p99": 0.3192029274754835 + }, + "e2e": { + "mean": 0.1569382150647865, + "p50": 0.1678105991098637, + "p90": 0.12797847572660626, + "p99": 0.16781804606311032 + } + }, + { + "ttft": { + "mean": 0.02912207227616738, + "p50": 0.027190990310942655, + "p90": -0.056337427761921965, + "p99": -0.04121672646120952 + }, + "tpot": { + "mean": 0.16462206191460754, + "p50": 0.16195538436894344, + "p90": 0.09988703619210754, + "p99": 0.31352142471539024 + }, + "e2e": { + "mean": 0.1453260018192159, + "p50": 0.15247501518771847, + "p90": 0.12213267160696055, + "p99": 0.15897391264426655 + } + } + ], + "trialwise_distribution_bias_summary": { + "ttft": { + "mean": { + "mean": 0.028649097472349817, + "min": 0.02817612266853226, + "max": 0.02912207227616738 + }, + "p50": { + "mean": 0.02857019841927239, + "min": 0.027190990310942655, + "max": 0.029949406527602123 + }, + "p90": { + "mean": -0.055730755098812174, + "min": -0.056337427761921965, + "max": -0.05512408243570239 + }, + "p99": { + "mean": -0.04327306993732369, + "min": -0.04532941341343785, + "max": -0.04121672646120952 + } + }, + "tpot": { + "mean": { + "mean": 0.1707514840040365, + "min": 0.16462206191460754, + "max": 0.17688090609346543 + }, + "p50": { + "mean": 0.16801744351833747, + "min": 0.16195538436894344, + "max": 0.1740795026677315 + }, + "p90": { + "mean": 0.10503767437559275, + "min": 0.09988703619210754, + "max": 0.11018831255907795 + }, + "p99": { + "mean": 0.3163621760954369, + "min": 0.31352142471539024, + "max": 0.3192029274754835 + } + }, + "e2e": { + "mean": { + "mean": 0.1511321084420012, + "min": 0.1453260018192159, + "max": 0.1569382150647865 + }, + "p50": { + "mean": 0.1601428071487911, + "min": 0.15247501518771847, + "max": 0.1678105991098637 + }, + "p90": { + "mean": 0.1250555736667834, + "min": 0.12213267160696055, + "max": 0.12797847572660626 + }, + "p99": { + "mean": 0.16339597935368844, + "min": 0.15897391264426655, + "max": 0.16781804606311032 + } + } + }, + "legacy_pooled_distribution_bias": { + "ttft": { + "mean": 0.028648879997638963, + "p50": 0.028237979190582876, + "p90": -0.055961238578361966, + "p99": -0.045491187615110146 + }, + "tpot": { + "mean": 0.1707193936623511, + "p50": 0.16851374859025317, + "p90": 0.10492621353626864, + "p99": 0.31231888769471766 + }, + "e2e": { + "mean": 0.151102823467785, + "p50": 0.1594213531394918, + "p90": 0.1266352410718406, + "p99": 0.15576537699445703 + } + } + }, + "new": { + "trialwise_distribution_bias": [ + { + "ttft": { + "mean": 0.0830717367573255, + "p50": 0.09202782803564245, + "p90": 0.00028495427033840576, + "p99": 0.052715475291315185 + }, + "tpot": { + "mean": 0.1875681469549417, + "p50": 0.17992592310879849, + "p90": 0.12349339185025797, + "p99": 0.37339354462095886 + }, + "e2e": { + "mean": 0.16897544744343032, + "p50": 0.18209714770541094, + "p90": 0.13787606868147936, + "p99": 0.18904626199769245 + } + }, + { + "ttft": { + "mean": 0.08406819180217444, + "p50": 0.08910315304597226, + "p90": -0.0009995435685739617, + "p99": 0.05725053613897321 + }, + "tpot": { + "mean": 0.1751979803646619, + "p50": 0.1677414318174738, + "p90": 0.11306865958187659, + "p99": 0.3674786553708338 + }, + "e2e": { + "mean": 0.1572424162428063, + "p50": 0.1665739541099918, + "p90": 0.1319789697978685, + "p99": 0.18004136280321917 + } + } + ], + "trialwise_distribution_bias_summary": { + "ttft": { + "mean": { + "mean": 0.08356996427974997, + "min": 0.0830717367573255, + "max": 0.08406819180217444 + }, + "p50": { + "mean": 0.09056549054080736, + "min": 0.08910315304597226, + "max": 0.09202782803564245 + }, + "p90": { + "mean": -0.00035729464911777795, + "min": -0.0009995435685739617, + "max": 0.00028495427033840576 + }, + "p99": { + "mean": 0.054983005715144195, + "min": 0.052715475291315185, + "max": 0.05725053613897321 + } + }, + "tpot": { + "mean": { + "mean": 0.18138306365980178, + "min": 0.1751979803646619, + "max": 0.1875681469549417 + }, + "p50": { + "mean": 0.17383367746313616, + "min": 0.1677414318174738, + "max": 0.17992592310879849 + }, + "p90": { + "mean": 0.11828102571606727, + "min": 0.11306865958187659, + "max": 0.12349339185025797 + }, + "p99": { + "mean": 0.37043609999589633, + "min": 0.3674786553708338, + "max": 0.37339354462095886 + } + }, + "e2e": { + "mean": { + "mean": 0.1631089318431183, + "min": 0.1572424162428063, + "max": 0.16897544744343032 + }, + "p50": { + "mean": 0.17433555090770136, + "min": 0.1665739541099918, + "max": 0.18209714770541094 + }, + "p90": { + "mean": 0.13492751923967394, + "min": 0.1319789697978685, + "max": 0.13787606868147936 + }, + "p99": { + "mean": 0.1845438124004558, + "min": 0.18004136280321917, + "max": 0.18904626199769245 + } + } + }, + "paired_relative_error": [ + { + "ttft": { + "mean": 0.3546551986110786, + "p50": 0.13992436338556363, + "p90": 0.6114206167819235, + "p99": 3.950640311967927 + }, + "tpot": { + "mean": 0.20750924221545067, + "p50": 0.19665829732786516, + "p90": 0.3036816181470401, + "p99": 0.6918780517787506 + }, + "e2e": { + "mean": 0.1987877190488419, + "p50": 0.1867264266897267, + "p90": 0.3097631367891218, + "p99": 0.6627422276019761 + } + }, + { + "ttft": { + "mean": 0.35485558010616797, + "p50": 0.1421694148145008, + "p90": 0.6220489522097341, + "p99": 3.6653171696017184 + }, + "tpot": { + "mean": 0.19287611849010033, + "p50": 0.17961331208149112, + "p90": 0.2699038364626021, + "p99": 0.6456553921719683 + }, + "e2e": { + "mean": 0.18689663758628208, + "p50": 0.17071369418138402, + "p90": 0.2832272665867874, + "p99": 0.6154236743406891 + } + } + ], + "legacy_pooled_distribution_bias": { + "ttft": { + "mean": 0.08356973519379125, + "p50": 0.09021324737193111, + "p90": -0.0006012940489499138, + "p99": 0.05253708684194205 + }, + "tpot": { + "mean": 0.1813506819061229, + "p50": 0.1743324539248605, + "p90": 0.11816822907155744, + "p99": 0.3662267201704473 + }, + "e2e": { + "mean": 0.1630793421767109, + "p50": 0.17360527090575292, + "p90": 0.13652104764058856, + "p99": 0.17677450343779522 + } + }, + "waiting_p99_ms": 499.9578367015957, + "validity": "PASS_SUBCRITICAL" + } + }, + "tp4_rho0p01": { + "old": { + "trialwise_distribution_bias": [ + { + "ttft": { + "mean": 0.001069282130605019, + "p50": 0.23624600468603504, + "p90": -0.06243912870195954, + "p99": -0.09510776821394695 + }, + "tpot": { + "mean": 0.06803177229402764, + "p50": 0.08606085683396018, + "p90": 0.04169520062620168, + "p99": -0.007371970069137671 + }, + "e2e": { + "mean": 0.07347872011642306, + "p50": 0.12052386744228415, + "p90": 0.03440294047660334, + "p99": 0.038874086941855734 + } + }, + { + "ttft": { + "mean": -0.003986909712741579, + "p50": 0.22473642702400629, + "p90": -0.06765340173498505, + "p99": -0.09602231432410636 + }, + "tpot": { + "mean": 0.06548345266052943, + "p50": 0.08325866738979519, + "p90": 0.03667309817451709, + "p99": -0.012893094435078642 + }, + "e2e": { + "mean": 0.07078275584585807, + "p50": 0.1217320014916679, + "p90": 0.03247676382487049, + "p99": 0.03246095420030834 + } + } + ], + "trialwise_distribution_bias_summary": { + "ttft": { + "mean": { + "mean": -0.0014588137910682799, + "min": -0.003986909712741579, + "max": 0.001069282130605019 + }, + "p50": { + "mean": 0.23049121585502066, + "min": 0.22473642702400629, + "max": 0.23624600468603504 + }, + "p90": { + "mean": -0.06504626521847229, + "min": -0.06765340173498505, + "max": -0.06243912870195954 + }, + "p99": { + "mean": -0.09556504126902665, + "min": -0.09602231432410636, + "max": -0.09510776821394695 + } + }, + "tpot": { + "mean": { + "mean": 0.06675761247727854, + "min": 0.06548345266052943, + "max": 0.06803177229402764 + }, + "p50": { + "mean": 0.08465976211187769, + "min": 0.08325866738979519, + "max": 0.08606085683396018 + }, + "p90": { + "mean": 0.039184149400359386, + "min": 0.03667309817451709, + "max": 0.04169520062620168 + }, + "p99": { + "mean": -0.010132532252108157, + "min": -0.012893094435078642, + "max": -0.007371970069137671 + } + }, + "e2e": { + "mean": { + "mean": 0.07213073798114056, + "min": 0.07078275584585807, + "max": 0.07347872011642306 + }, + "p50": { + "mean": 0.12112793446697602, + "min": 0.12052386744228415, + "max": 0.1217320014916679 + }, + "p90": { + "mean": 0.033439852150736915, + "min": 0.03247676382487049, + "max": 0.03440294047660334 + }, + "p99": { + "mean": 0.03566752057108204, + "min": 0.03246095420030834, + "max": 0.038874086941855734 + } + } + }, + "legacy_pooled_distribution_bias": { + "ttft": { + "mean": -0.0014652143973501086, + "p50": 0.22936601881498542, + "p90": -0.0646093465409875, + "p99": -0.09621678853313553 + }, + "tpot": { + "mean": 0.06675609059150077, + "p50": 0.08477302587551214, + "p90": 0.0379183273767328, + "p99": -0.010663954751357074 + }, + "e2e": { + "mean": 0.07212904317306096, + "p50": 0.12069215463307655, + "p90": 0.03317293927357903, + "p99": 0.0338378271163308 + } + } + }, + "new": { + "trialwise_distribution_bias": [ + { + "ttft": { + "mean": 0.06234024172127873, + "p50": 0.24853946560541346, + "p90": -0.009255094378797821, + "p99": -0.014267710892388628 + }, + "tpot": { + "mean": 0.10728357759318019, + "p50": 0.09833993314940369, + "p90": 0.08764146258310636, + "p99": 0.07022746965618598 + }, + "e2e": { + "mean": 0.09915483987796365, + "p50": 0.13866670972485098, + "p90": 0.05932039093418303, + "p99": 0.068986345174611 + } + }, + { + "ttft": { + "mean": 0.056974583059155086, + "p50": 0.23691543455574957, + "p90": -0.014765152021066699, + "p99": -0.01526395950520138 + }, + "tpot": { + "mean": 0.10464160330568303, + "p50": 0.09550606196492119, + "p90": 0.08239784923775459, + "p99": 0.06427472725757602 + }, + "e2e": { + "mean": 0.09639439188714723, + "p50": 0.13989440514740228, + "p90": 0.05734781513815735, + "p99": 0.06238732473827772 + } + } + ], + "trialwise_distribution_bias_summary": { + "ttft": { + "mean": { + "mean": 0.05965741239021691, + "min": 0.056974583059155086, + "max": 0.06234024172127873 + }, + "p50": { + "mean": 0.2427274500805815, + "min": 0.23691543455574957, + "max": 0.24853946560541346 + }, + "p90": { + "mean": -0.01201012319993226, + "min": -0.014765152021066699, + "max": -0.009255094378797821 + }, + "p99": { + "mean": -0.014765835198795003, + "min": -0.01526395950520138, + "max": -0.014267710892388628 + } + }, + "tpot": { + "mean": { + "mean": 0.10596259044943161, + "min": 0.10464160330568303, + "max": 0.10728357759318019 + }, + "p50": { + "mean": 0.09692299755716244, + "min": 0.09550606196492119, + "max": 0.09833993314940369 + }, + "p90": { + "mean": 0.08501965591043048, + "min": 0.08239784923775459, + "max": 0.08764146258310636 + }, + "p99": { + "mean": 0.067251098456881, + "min": 0.06427472725757602, + "max": 0.07022746965618598 + } + }, + "e2e": { + "mean": { + "mean": 0.09777461588255544, + "min": 0.09639439188714723, + "max": 0.09915483987796365 + }, + "p50": { + "mean": 0.13928055743612663, + "min": 0.13866670972485098, + "max": 0.13989440514740228 + }, + "p90": { + "mean": 0.05833410303617019, + "min": 0.05734781513815735, + "max": 0.05932039093418303 + }, + "p99": { + "mean": 0.06568683495644435, + "min": 0.06238732473827772, + "max": 0.068986345174611 + } + } + }, + "paired_relative_error": [ + { + "ttft": { + "mean": 0.31553688775988453, + "p50": 0.11838592821378686, + "p90": 0.6506248643406535, + "p99": 3.727741795520502 + }, + "tpot": { + "mean": 0.1255843946058368, + "p50": 0.09013696629948227, + "p90": 0.2591848042876693, + "p99": 0.6394926577997524 + }, + "e2e": { + "mean": 0.12720160501967023, + "p50": 0.09589002059334667, + "p90": 0.26593105160104036, + "p99": 0.6329767056751748 + } + }, + { + "ttft": { + "mean": 0.3055207717400012, + "p50": 0.11067975650739464, + "p90": 0.6346487333489169, + "p99": 3.723279708208583 + }, + "tpot": { + "mean": 0.12290433684113768, + "p50": 0.08881300531692908, + "p90": 0.2544711123916822, + "p99": 0.635068592349857 + }, + "e2e": { + "mean": 0.1238739253923782, + "p50": 0.0938720089907427, + "p90": 0.2617045417392297, + "p99": 0.6208489208233263 + } + } + ], + "legacy_pooled_distribution_bias": { + "ttft": { + "mean": 0.059650620031540064, + "p50": 0.24159106387124998, + "p90": -0.011548419893895705, + "p99": -0.015475807392170575 + }, + "tpot": { + "mean": 0.10596101263201793, + "p50": 0.09703754188844527, + "p90": 0.08369800201750718, + "p99": 0.06667813160571406 + }, + "e2e": { + "mean": 0.09777288053702092, + "p50": 0.1388377217196832, + "p90": 0.058060760567474216, + "p99": 0.06380410696893425 + } + }, + "waiting_p99_ms": 743.1356935161051, + "validity": "PASS_SUBCRITICAL" + } + } + }, + "checks": { + "tp1_ttft_mean_p99_improve_ge_5pp": true, + "tp2_tp4_ttft_e2e_no_abs_regression_gt_5pp": false, + "regressions": [ + { + "cell": "tp4_rho0p0025", + "metric": "ttft", + "quantile": "mean", + "old_bias": 0.025022574738277282, + "new_bias": 0.07766646565061346, + "abs_bias_delta_pp": 5.2643890912336175, + "validity": "PASS_SUBCRITICAL" + }, + { + "cell": "tp4_rho0p005", + "metric": "ttft", + "quantile": "mean", + "old_bias": 0.028648879997638963, + "new_bias": 0.08356973519379125, + "abs_bias_delta_pp": 5.492085519615229, + "validity": "PASS_SUBCRITICAL" + }, + { + "cell": "tp4_rho0p005", + "metric": "ttft", + "quantile": "p50", + "old_bias": 0.028237979190582876, + "new_bias": 0.09021324737193111, + "abs_bias_delta_pp": 6.197526818134823, + "validity": "PASS_SUBCRITICAL" + }, + { + "cell": "tp4_rho0p01", + "metric": "ttft", + "quantile": "mean", + "old_bias": -0.0014652143973501086, + "new_bias": 0.059650620031540064, + "abs_bias_delta_pp": 5.8185405634189955, + "validity": "PASS_SUBCRITICAL" + } + ], + "trace_gate": false + } +} \ No newline at end of file diff --git a/runs/frontier-attn-structured-v0/run_replay.py b/runs/frontier-attn-structured-v0/run_replay.py new file mode 100644 index 0000000..054452e --- /dev/null +++ b/runs/frontier-attn-structured-v0/run_replay.py @@ -0,0 +1,126 @@ +#!/usr/bin/env python3 +"""Replay one real-trace cell with the structured-attention experiment commit.""" + +from __future__ import annotations + +import argparse +import importlib.util +import json +import subprocess +import sys +from pathlib import Path + +ROOT = Path(__file__).resolve().parent +REPO = ROOT.parents[1] +S3_REAL = REPO / "runs/frontier-s3-real-v0" +BASE_REFERENCE = ( + REPO + / "runs/frontier-collective-joint-v0/counterfactual/joint-r2/manifest.json" +) +BASE_COMMIT = "deadc4a321f0baaa534c6ebd17f974123733cdc2" +EXPERIMENT_COMMIT = "1f8900a4ac64e45754b03d0aa7c1dddab65785cf" +PATCH = ROOT / "0001-Experiment-with-structured-attention-prefill-predict.patch" + + +def load_s3_module(): + spec = importlib.util.spec_from_file_location( + "s3_prefix_replay", S3_REAL / "run_frontier_prefix_replay.py" + ) + module = importlib.util.module_from_spec(spec) + sys.path.insert(0, str(S3_REAL)) + spec.loader.exec_module(module) + return module + + +def git(checkout: Path, *args: str) -> str: + return subprocess.check_output( + ["git", "-C", str(checkout), *args], text=True + ).strip() + + +def main() -> None: + parser = argparse.ArgumentParser() + parser.add_argument("--trace", type=Path, required=True) + parser.add_argument("--output-root", type=Path, required=True) + parser.add_argument( + "--config", + choices=("tp4_mns16", "tp2_mns16", "tp1_mns16"), + required=True, + ) + parser.add_argument("--label", required=True) + parser.add_argument("--max-tokens", type=int, required=True) + parser.add_argument("--duration-s", type=float) + parser.add_argument("--cache-root", type=Path, required=True) + parser.add_argument( + "--frontier-checkout", + type=Path, + default=Path("/tmp/frontier-attn-structured-v0"), + ) + parser.add_argument( + "--attention-profile", + type=Path, + default=REPO + / "runs/frontier-prefill-kvgrowth-fix-v0/profiles/" + "profile-v5-kvgrowth/attention.csv", + ) + args = parser.parse_args() + + frontier = args.frontier_checkout.resolve() + profile = args.attention_profile.resolve() + if git(frontier, "rev-parse", "HEAD") != EXPERIMENT_COMMIT: + raise SystemExit(f"unexpected experiment checkout HEAD: {frontier}") + if git(frontier, "rev-parse", "HEAD^") != BASE_COMMIT: + raise SystemExit("experiment commit is not directly based on frozen Frontier") + if git(frontier, "status", "--porcelain"): + raise SystemExit("experiment Frontier checkout must be clean") + if not profile.is_file(): + raise SystemExit(f"attention profile missing: {profile}") + + reference = json.loads(BASE_REFERENCE.read_text()) + reference["frontier_checkout"] = str(frontier) + reference["frontier_commit"] = EXPERIMENT_COMMIT + generated_reference = ROOT / "frontier-reference.json" + generated_reference.write_text(json.dumps(reference, indent=2)) + + module = load_s3_module() + module.REFERENCE = generated_reference + module.EXPECTED_FRONTIER_COMMIT = EXPERIMENT_COMMIT + original_replace = module.replace_flag + + def replace_and_override(argv: list[str], flag: str, value: str) -> None: + original_replace(argv, flag, value) + if flag.endswith("trace_file"): + atten_flag = ( + "--random_forrest_execution_time_predictor_config_atten_input_file" + ) + original_replace(argv, atten_flag, str(profile)) + no_cache = ( + "--random_forrest_execution_time_predictor_config_no_cache" + ) + if no_cache in argv: + argv.remove(no_cache) + + module.replace_flag = replace_and_override + module.parse_args = lambda: args + module.main() + + manifest_path = args.output_root / "manifest.json" + manifest = json.loads(manifest_path.read_text()) + manifest.update( + { + "schema": "frontier-attn-structured-replay-v1", + "frontier_base_commit": BASE_COMMIT, + "frontier_experiment_commit": EXPERIMENT_COMMIT, + "frontier_patch": str(PATCH.resolve()), + "frontier_patch_sha256": module.sha256(PATCH), + "attention_profile_override": str(profile), + "attention_profile_sha256": module.sha256(profile), + "model_cache_enabled": True, + } + ) + manifest_path.write_text(json.dumps(manifest, indent=2)) + print(f"structured replay done: {args.output_root}") + + +if __name__ == "__main__": + main()