From 95f4af3d996b75b715a73eb864d80361d72652df Mon Sep 17 00:00:00 2001 From: Gahow Wang Date: Fri, 17 Jul 2026 09:44:49 +0800 Subject: [PATCH] Add Frontier fidelity envelope campaign --- runs/frontier-fidelity-envelope-v1/.gitignore | 8 ++ .../experiment-card.md | 76 ++++++++++++ runs/frontier-fidelity-envelope-v1/fleet.toml | 24 ++++ .../jobs_attention_composition.toml | 43 +++++++ .../materialize_frontier_allreduce.py | 115 ++++++++++++++++++ .../mock-fidelity-envelope.png | Bin 0 -> 133230 bytes ...vidur-large-payload-model-prediction.patch | 84 +++++++++++++ .../plot_mock_envelope.py | 75 ++++++++++++ .../profiles/measured-allreduce.csv | 25 ++++ .../profiles/measured-allreduce.manifest.json | 15 +++ .../remote-sync-marker/README.md | 2 + .../run_flashattn_composition.sh | 65 ++++++++++ .../smoke-report.md | 15 +++ .../test_fidelity_envelope.py | 69 +++++++++++ .../run_frontier_qwen30_prefill_surface.py | 54 ++++++++ .../test_phase_factorial.py | 17 +++ .../freeze_frontier_profiles.py | 2 +- 17 files changed, 688 insertions(+), 1 deletion(-) create mode 100644 runs/frontier-fidelity-envelope-v1/.gitignore create mode 100644 runs/frontier-fidelity-envelope-v1/experiment-card.md create mode 100644 runs/frontier-fidelity-envelope-v1/fleet.toml create mode 100644 runs/frontier-fidelity-envelope-v1/jobs_attention_composition.toml create mode 100644 runs/frontier-fidelity-envelope-v1/materialize_frontier_allreduce.py create mode 100644 runs/frontier-fidelity-envelope-v1/mock-fidelity-envelope.png create mode 100644 runs/frontier-fidelity-envelope-v1/patches/0001-vidur-large-payload-model-prediction.patch create mode 100644 runs/frontier-fidelity-envelope-v1/plot_mock_envelope.py create mode 100644 runs/frontier-fidelity-envelope-v1/profiles/measured-allreduce.csv create mode 100644 runs/frontier-fidelity-envelope-v1/profiles/measured-allreduce.manifest.json create mode 100644 runs/frontier-fidelity-envelope-v1/remote-sync-marker/README.md create mode 100644 runs/frontier-fidelity-envelope-v1/run_flashattn_composition.sh create mode 100644 runs/frontier-fidelity-envelope-v1/smoke-report.md create mode 100644 runs/frontier-fidelity-envelope-v1/test_fidelity_envelope.py diff --git a/runs/frontier-fidelity-envelope-v1/.gitignore b/runs/frontier-fidelity-envelope-v1/.gitignore new file mode 100644 index 0000000..008f888 --- /dev/null +++ b/runs/frontier-fidelity-envelope-v1/.gitignore @@ -0,0 +1,8 @@ +__pycache__/ +a1-native-smoke/ +a2-measured-fix-smoke/ +simulator-a1/ +simulator-a2/ +simulator-a3/ +fleet-state/ +fleet-artifacts/ diff --git a/runs/frontier-fidelity-envelope-v1/experiment-card.md b/runs/frontier-fidelity-envelope-v1/experiment-card.md new file mode 100644 index 0000000..c1563db --- /dev/null +++ b/runs/frontier-fidelity-envelope-v1/experiment-card.md @@ -0,0 +1,76 @@ +# EXP-SIMFID-ENVELOPE-V1:Frontier best-effort fidelity envelope + +> **状态:** 已批准,准备执行(2026-07-17)。用户要求先把 simulator 现有能力跑到最好,并同时覆盖 fixed input/output 与真实 trace replay。 + +## Claim 与可证伪假设 + +- **研究问题:** 在不使用被评测 config/workload 的 serving E2E calibration 时,Frontier 的 measured operator/collective profiles 与 scheduler state abstraction,是否足以找到真机上的低-regret config? +- **H-CC:** Qwen30 prefill-only 的 TP 排序错误主要来自默认 analytical all-reduce;注入同机、同 TP 的 measured collective 后,已知 `2048/1` surface 的 regret 降至不超过 5%,Kendall tau-b 升至至少 0.8。 +- **H-BATCH:** 若 H-CC 不足,错误主要来自 pure-prefill attention 只有 batch=1 profile,而 Frontier 在多请求 batch 上使用没有 coverage 的 `attn_prefill_mixed` 外推;增加 MBT 可达的真实 batch composition 后可恢复排序。 +- **H-STATE:** 若 measured collective 与 batch-composition profile 都不能恢复排序,则缺失量位于 isolated operators 之外的 scheduler-state-conditioned step composition;继续增加静态 kernel rows不是有效修复。 +- **成功门槛:** worst selected-config regret `<=5%`、tie-aware Kendall tau-b `>=0.8`、真机 capacity bracket 不足以反转 top decision,并且没有使用同一 surface 的 E2E scalar calibration。 + +## Simulator ablation(先用已有 ground truth,零新增 GPU 成本) + +| variant | compute profile | collective | 目的 | +|---|---|---|---| +| A0 | vLLM 0.20 frozen profile-v2 | Frontier analytical | 已冻结 baseline | +| A1 | 同 A0 | Frontier 原生 Vidur + measured TP2/TP4 CSV | 检查原生 profile consumption;大 payload fallback 保留并计数 | +| A2 | 同 A0 | measured Vidur,cache miss 直接调用已训练 estimator | 最小 correctness fix;消除 `>100k elements` 静默 analytical fallback | +| A3 | 增加 pure-prefill batch-composition rows | 同 A2 | 检验 batch-composition coverage 是否是剩余误差来源 | + +A1/A2/A3 都重新运行完整 `TP∈{1,2,4} × MNS∈{8,16,32,64}` surface;TP1 无 all-reduce。所有 simulator variants 在查看新增真机 case 前冻结。A2 是单独标注、带单测的 compatibility patch,不与 Frontier upstream 原生能力混写。 + +## Workload matrix + +| ID | workload | arrival / prefix | phase role | +|---|---|---|---| +| F0 | fixed `ISL=2048, OSL=1` | uniform QPS;distinct prefixes | 已有 real ground truth,选择 A0--A3 | +| F1 | fixed `ISL=512, OSL=1` | uniform QPS;distinct prefixes | short-prefill、多请求 batch composition | +| F2 | fixed `ISL=2048, OSL=128` | uniform QPS;distinct prefixes | true prefill+decode mixed serving | +| T1 | `thinking_w20260327_1000` eligible trace | 原 timestamp/order;exact prompt/output/session/hash;prefix on | production joint distribution 与 cache/scheduler feedback | + +T1 只排除已经审计的 72 个超 40,960 context rows 和 6 个 zero-output rows,eligible universe 为 `15,401/15,479`。负载轴只使用 trace 已有、同 session 共享的 `sampling_u`;入选 request 的 arrival、input/output、prompt、hash 和相对次序不变。真实 runtime 设置 `min_tokens=max_tokens=output_length` 且 `ignore_eos=true`,逐请求核对 usage。 + +## 固定系统与 config surface + +| 项目 | 冻结设置 | +|---|---| +| machine | 仅 `dash0`,8×NVIDIA H20 | +| model/runtime | `/home/admin/cpfs/wjh/models/Qwen/Qwen3-30B-A3B`;community vLLM 0.20.0+cu129;BF16 weight/activation/KV | +| simulator | Frontier `d9cfeb6d8791fbf2f295dd9744c56a666171776e` + manifest 中列出的现有 compatibility patches;A2 patch 独立 hash | +| configs | `TP∈{1,2,4} × MNS∈{8,16,32,64}`;DP=PP=EP=1;MBT=8192;block=16 | +| runtime | chunked prefill on;fixed cases prefix off;T1 prefix on;fresh server per `(config, load, round)` | +| score | `capacity(c)=max tested offered req/s with joint SLO pass rate >=0.95`;primary `capacity/actual TP GPUs` | +| SLO | TTFT `<=1000ms + 1000×ISL/8000`;mixed case同时要求 TPOT `<=150ms`;另报告 50/100/180ms sensitivity,不用 sensitivity 改写 primary | + +F0 沿用已经冻结的 rate lattice与两个 fresh-server rounds。F1/F2 先由冻结 simulator 给出 boundary,再加入共同 per-GPU guard anchors,避免只测 simulator 预测附近而漏掉真实最优。每个 boundary anchor 两个 fresh-server rounds,二者都 pass 才算 feasible。 + +T1 保持原 600 秒 arrival window。先在 simulator 上冻结 `sampling_u` bracket;真机只运行 topological guard set `{TP1,TP2,TP4} × {MNS8,MNS32,MNS64}`,若 top set 或 bracket 仍可能被未测 MNS 反转再补 MNS16。每个入选 source-row vector在 real/sim 两侧必须有相同 digest;至少两个 session-hash folds,若本轮只完成一个 window则明确标为 single-window evidence。 + +## 诊断与停止规则 + +1. A1 必须报告每次 collective prediction 的 measured-model hit 与 analytical fallback 次数;不能只看最终 rank。 +2. A2 对超过 100k elements 的 payload 必须由单测证明走 estimator;A2 若不改变任何 TP2/TP4 step,立即停止并检查 CLI/config 注入,不进入 GPU。 +3. A3 profile 只覆盖 MBT=8192 可达的 pure-prefill composition:F0 为 `1/2/4 × q2048`,F1 为 `1/2/4/8/16 × q512`,TP1/2/4 分别实测;不做无边界的 profile sweep。 +4. 若 A3 在 F0 仍不能达到 fidelity gate,先采集 `TP1@8, TP2@16, TP4@32` 的 per-step batch/queue/component residual;禁止用 per-TP E2E scale把答案拟合正确。 +5. 只有 best-effort simulator 在 F0 通过或形成可解释、可定位的失败后,才运行 F1/F2/T1 真机;任一 case 的结论不外推到其它 workload。 + +## 预期成本与产物 + +- simulator A1--A3:CPU only,约 1--3 小时总 CPU wall,0 GPU-hour。 +- attention composition profile:3 张 H20 并行,预计 5--10 分钟,`<0.5 H20-GPU-hour`。 +- F1/F2 real boundary:预计合计 12--24 H20-GPU-hours,smoke 后再锁定。 +- T1 real boundary:600 秒原 arrival window使单 anchor较贵;预计 30--60 H20-GPU-hours,必须在 simulator bracket 和一配置 smoke 后重新 echo 精确预算。 +- 产物:variant/profile manifests、full surfaces、anchor-level request metrics、rank/regret/confusion tables、profile-consumption counters,以及 fixed-vs-trace fidelity summary figure。 + +## Benchmark design audit + +| 风险 | 处理 | +|---|---| +| selective benchmarking | 预先冻结 F0/F1/F2/T1,不因结果删除失败 case | +| calibration=evaluation | 禁止使用同一 surface 的 serving E2E scalar;microprofile GPU 成本单独报告 | +| trace filtering | 只做 context/zero-output correctness exclusion和 session-coherent thinning,不按长度筛选 | +| simulator-guided real sampling | 使用共同 guard anchors;未闭合 bracket 不能宣布 top match | +| absolute-vs-rank metric | 同时报绝对 capacity/latency、rank、regret、tau-b、pair direction和 SLO confusion | +| hidden fallback | A1/A2 强制计数 measured-model hit/fallback,并写入 frozen manifest | diff --git a/runs/frontier-fidelity-envelope-v1/fleet.toml b/runs/frontier-fidelity-envelope-v1/fleet.toml new file mode 100644 index 0000000..612e4f7 --- /dev/null +++ b/runs/frontier-fidelity-envelope-v1/fleet.toml @@ -0,0 +1,24 @@ +version = 1 + +[paths] +state_dir = "runs/frontier-fidelity-envelope-v1/fleet-state" +artifacts_dir = "runs/frontier-fidelity-envelope-v1/fleet-artifacts" + +[ssh] +connect_timeout_sec = 10 + +[scheduler] +gpu_free_memory_mb = 1024 +gpu_free_utilization_pct = 10 +prefer_pack = true + +[sync] +mode = "scp" +local_path = "runs/frontier-fidelity-envelope-v1/remote-sync-marker" + +[[hosts]] +name = "dash0" +ssh_alias = "dash0" +enabled = true +sync_remote_path = "/home/admin/cpfs/wjh/aituner/fidelity-envelope-sync-marker" +fleet_root = "/home/admin/cpfs/wjh/aituner/gpu-fleet-fidelity-envelope-v1" diff --git a/runs/frontier-fidelity-envelope-v1/jobs_attention_composition.toml b/runs/frontier-fidelity-envelope-v1/jobs_attention_composition.toml new file mode 100644 index 0000000..7e2aa3b --- /dev/null +++ b/runs/frontier-fidelity-envelope-v1/jobs_attention_composition.toml @@ -0,0 +1,43 @@ +version = 1 + +[[jobs]] +name = "qwen30-attention-composition-tp1-20260717-v1" +gpus = 1 +gpu_model = "H20" +hosts = ["dash0"] +command = "cd /home/admin/cpfs/wjh/aituner/aituner-qwen30-vllm020-profile-v1/runs/frontier-fidelity-envelope-v1 && timeout --signal=TERM --kill-after=30s 900 bash run_flashattn_composition.sh" +artifacts = ["artifacts/attention-composition-tp1-v1"] + +[jobs.env] +HOME = "/tmp/wjh" +XDG_CACHE_HOME = "/tmp/wjh/.cache" +TP = "1" +OUTPUT_ROOT = "/home/admin/cpfs/wjh/aituner/gpu-fleet-fidelity-envelope-v1/artifacts/attention-composition-tp1-v1" + +[[jobs]] +name = "qwen30-attention-composition-tp2-20260717-v1" +gpus = 1 +gpu_model = "H20" +hosts = ["dash0"] +command = "cd /home/admin/cpfs/wjh/aituner/aituner-qwen30-vllm020-profile-v1/runs/frontier-fidelity-envelope-v1 && timeout --signal=TERM --kill-after=30s 900 bash run_flashattn_composition.sh" +artifacts = ["artifacts/attention-composition-tp2-v1"] + +[jobs.env] +HOME = "/tmp/wjh" +XDG_CACHE_HOME = "/tmp/wjh/.cache" +TP = "2" +OUTPUT_ROOT = "/home/admin/cpfs/wjh/aituner/gpu-fleet-fidelity-envelope-v1/artifacts/attention-composition-tp2-v1" + +[[jobs]] +name = "qwen30-attention-composition-tp4-20260717-v1" +gpus = 1 +gpu_model = "H20" +hosts = ["dash0"] +command = "cd /home/admin/cpfs/wjh/aituner/aituner-qwen30-vllm020-profile-v1/runs/frontier-fidelity-envelope-v1 && timeout --signal=TERM --kill-after=30s 900 bash run_flashattn_composition.sh" +artifacts = ["artifacts/attention-composition-tp4-v1"] + +[jobs.env] +HOME = "/tmp/wjh" +XDG_CACHE_HOME = "/tmp/wjh/.cache" +TP = "4" +OUTPUT_ROOT = "/home/admin/cpfs/wjh/aituner/gpu-fleet-fidelity-envelope-v1/artifacts/attention-composition-tp4-v1" diff --git a/runs/frontier-fidelity-envelope-v1/materialize_frontier_allreduce.py b/runs/frontier-fidelity-envelope-v1/materialize_frontier_allreduce.py new file mode 100644 index 0000000..bb57bc0 --- /dev/null +++ b/runs/frontier-fidelity-envelope-v1/materialize_frontier_allreduce.py @@ -0,0 +1,115 @@ +#!/usr/bin/env python3 +"""Convert frozen vLLM collective measurements to Frontier Vidur CC CSV.""" + +from __future__ import annotations + +import argparse +import csv +import hashlib +import json +from pathlib import Path + + +FIELDS = ( + "time_stats.all_reduce.min", + "time_stats.all_reduce.max", + "time_stats.all_reduce.mean", + "time_stats.all_reduce.median", + "time_stats.all_reduce.std", + "rank", + "num_workers", + "size", + "collective", + "devices_per_node", + "max_devices_per_node", +) + + +def sha256(path: Path) -> str: + digest = hashlib.sha256() + with path.open("rb") as source: + for chunk in iter(lambda: source.read(1 << 20), b""): + digest.update(chunk) + return digest.hexdigest() + + +def convert(input_path: Path, output_path: Path) -> dict[str, object]: + payload = json.loads(input_path.read_text()) + if payload.get("schema_version") != "qwen30_vllm020_allreduce_frozen.v1": + raise ValueError(f"unexpected input schema: {payload.get('schema_version')!r}") + + rows = [] + seen = set() + for source in payload["rows"]: + tp = int(source["tensor_parallel_size"]) + tokens = int(source["num_tokens"]) + key = (tp, tokens) + if key in seen: + raise ValueError(f"duplicate collective row: {key}") + seen.add(key) + if tp not in (2, 4): + raise ValueError(f"unsupported TP: {tp}") + expected_bytes = tokens * int(source["hidden_dim"]) * 2 + if int(source["payload_bytes"]) != expected_bytes: + raise ValueError(f"payload mismatch for {key}") + + # Frontier Vidur consumes only the median target. The raw profiler kept + # per-rank distributions but not aligned per-repeat critical-path + # samples, so do not invent critical-path min/mean/max/std. Repeating + # the observed critical-path median in the unused fields keeps the CSV + # schema explicit without changing the trained target. + median = float(source["critical_path_median_ms"]) + rows.append( + { + "time_stats.all_reduce.min": median, + "time_stats.all_reduce.max": median, + "time_stats.all_reduce.mean": median, + "time_stats.all_reduce.median": median, + "time_stats.all_reduce.std": 0.0, + "rank": 0, + "num_workers": tp, + "size": expected_bytes, + "collective": "all_reduce", + "devices_per_node": tp, + "max_devices_per_node": 8, + } + ) + + expected = {(tp, tokens) for tp in (2, 4) for tokens in (1, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192)} + if seen != expected: + raise ValueError(f"collective coverage mismatch: missing={expected - seen}, extra={seen - expected}") + + output_path.parent.mkdir(parents=True, exist_ok=True) + with output_path.open("w", newline="") as output: + writer = csv.DictWriter(output, fieldnames=FIELDS, lineterminator="\n") + writer.writeheader() + writer.writerows(sorted(rows, key=lambda row: (row["num_workers"], row["size"]))) + + return { + "schema": "frontier-vidur-allreduce-materialization-v1", + "source": str(input_path.resolve()), + "source_sha256": sha256(input_path), + "output": str(output_path.resolve()), + "output_sha256": sha256(output_path), + "rows": len(rows), + "tp_coverage": [2, 4], + "target": "time_stats.all_reduce.median", + "unused_stat_policy": "repeat critical_path_median; std=0", + "payload_contract": "size=num_tokens*hidden_dim*2_bytes", + } + + +def main() -> None: + parser = argparse.ArgumentParser() + parser.add_argument("--input", type=Path, required=True) + parser.add_argument("--output", type=Path, required=True) + parser.add_argument("--manifest", type=Path, required=True) + args = parser.parse_args() + manifest = convert(args.input, args.output) + args.manifest.parent.mkdir(parents=True, exist_ok=True) + args.manifest.write_text(json.dumps(manifest, indent=2, sort_keys=True) + "\n") + print(json.dumps(manifest, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/runs/frontier-fidelity-envelope-v1/mock-fidelity-envelope.png b/runs/frontier-fidelity-envelope-v1/mock-fidelity-envelope.png new file mode 100644 index 0000000000000000000000000000000000000000..0e63a4e1036265f16fd579d28755cbbfd2fe7bb4 GIT binary patch literal 133230 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 literal 0 HcmV?d00001 diff --git a/runs/frontier-fidelity-envelope-v1/patches/0001-vidur-large-payload-model-prediction.patch b/runs/frontier-fidelity-envelope-v1/patches/0001-vidur-large-payload-model-prediction.patch new file mode 100644 index 0000000..56eac1f --- /dev/null +++ b/runs/frontier-fidelity-envelope-v1/patches/0001-vidur-large-payload-model-prediction.patch @@ -0,0 +1,84 @@ +diff --git a/frontier/cc_backend/backends/vidur_cc_backend.py b/frontier/cc_backend/backends/vidur_cc_backend.py +index ca1983a..0c57f05 100644 +--- a/frontier/cc_backend/backends/vidur_cc_backend.py ++++ b/frontier/cc_backend/backends/vidur_cc_backend.py +@@ -882,2 +882,21 @@ class VidurCCBackend(BaseCCBackend): +- # Fallback to analytical if not in cache +- logger.debug(f"num_tokens={num_tokens} not in cache, using analytical fallback") ++ # The precomputed lookup is capped at 100k elements, while realistic ++ # TP payloads are commonly much larger. A cache miss does not mean the ++ # measured-data model is unavailable: predict on demand and memoize the ++ # exact payload instead of silently switching model families. ++ with self._cache_lock: ++ model = self._models.get("all_reduce") ++ if model is not None: ++ features = pd.DataFrame({"num_tokens": [num_tokens]}) ++ result = float(model.predict(features)[0]) ++ with self._cache_lock: ++ self._predictions["all_reduce"][(num_tokens,)] = result ++ logger.debug( ++ f"predict_allreduce: data_size={data_size_bytes}, num_tokens={num_tokens}, " ++ f"result={result:.6f} ms (ML model, on-demand cache miss)" ++ ) ++ return max(0.0, result) ++ ++ logger.debug( ++ f"num_tokens={num_tokens} not in cache and model unavailable, " ++ "using analytical fallback" ++ ) +diff --git a/tests/unit/test_vidur_cc_large_payload.py b/tests/unit/test_vidur_cc_large_payload.py +new file mode 100644 +index 0000000..7e87aa7 +--- /dev/null ++++ b/tests/unit/test_vidur_cc_large_payload.py +@@ -0,0 +1,50 @@ ++from __future__ import annotations ++ ++import threading ++import unittest ++ ++import numpy as np ++ ++from frontier.cc_backend.backends.vidur_cc_backend import VidurCCBackend ++ ++ ++class RecordingModel: ++ def __init__(self, value: float) -> None: ++ self.value = value ++ self.features = [] ++ ++ def predict(self, features): ++ self.features.append(features.copy()) ++ return np.array([self.value]) ++ ++ ++class VidurCCLargePayloadTest(unittest.TestCase): ++ def test_cache_miss_uses_measured_model_and_memoizes(self) -> None: ++ backend = object.__new__(VidurCCBackend) ++ backend._cache_lock = threading.RLock() ++ backend._num_devices = 2 ++ backend._predictions = {"all_reduce": {(100000,): 0.1}} ++ model = RecordingModel(0.321) ++ backend._models = {"all_reduce": model} ++ backend._analytical_fallback_allreduce = lambda *_: self.fail( ++ "analytical fallback must not run when the measured model exists" ++ ) ++ ++ data_size_bytes = 2048 * 2048 * 2 ++ expected_elements = data_size_bytes // 2 ++ first = backend.predict_allreduce(data_size_bytes, num_devices=2) ++ second = backend.predict_allreduce(data_size_bytes, num_devices=2) ++ ++ self.assertEqual(first, 0.321) ++ self.assertEqual(second, 0.321) ++ self.assertEqual(len(model.features), 1) ++ self.assertEqual( ++ int(model.features[0].iloc[0]["num_tokens"]), expected_elements ++ ) ++ self.assertEqual( ++ backend._predictions["all_reduce"][(expected_elements,)], 0.321 ++ ) ++ ++ ++if __name__ == "__main__": ++ unittest.main() diff --git a/runs/frontier-fidelity-envelope-v1/plot_mock_envelope.py b/runs/frontier-fidelity-envelope-v1/plot_mock_envelope.py new file mode 100644 index 0000000..8d21765 --- /dev/null +++ b/runs/frontier-fidelity-envelope-v1/plot_mock_envelope.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python3 +"""Render the preregistered fidelity-envelope figure prototype.""" + +from pathlib import Path + +import matplotlib.pyplot as plt +import numpy as np + + +OUT = Path(__file__).with_name("mock-fidelity-envelope.png") + + +def main() -> None: + workloads = ["F0\n2048/1", "F1\n512/1", "F2\n2048/128", "T1\nexact trace"] + variants = ["A0 analytical", "A1 native measured", "A2 measured+fix", "A3 +batch profile"] + # Prototype values are deliberately marked as MOCK and encode possible, + # distinguishable outcomes only. They are never read by result analysis. + regret = np.array( + [ + [12.5, 14.0, 18.0, 25.0], + [11.0, 13.0, 16.0, 22.0], + [7.5, 10.0, 12.0, 18.0], + [2.0, 4.0, 7.0, 12.0], + ] + ) + + fig, (ax0, ax1) = plt.subplots( + 1, 2, figsize=(11.5, 4.5), gridspec_kw={"width_ratios": [1.35, 1.0]} + ) + x = np.arange(len(workloads)) + width = 0.19 + colors = ["#7f7f7f", "#4c78a8", "#f58518", "#54a24b"] + for index, (variant, color) in enumerate(zip(variants, colors)): + ax0.bar( + x + (index - 1.5) * width, + regret[index], + width, + label=variant, + color=color, + ) + ax0.axhline(5.0, color="#d62728", linestyle="--", linewidth=1.5, label="5% gate") + ax0.set_xticks(x, workloads) + ax0.set_ylabel("Worst selected-config regret (%)") + ax0.set_title("A. Rank fidelity across workload complexity") + ax0.legend(fontsize=8, ncol=2, frameon=False) + ax0.grid(axis="y", alpha=0.25) + + consumption = np.array( + [ + [0, 0, 0], + [35, 65, 0], + [100, 0, 0], + [100, 0, 100], + ] + ) + bottom = np.zeros(len(variants)) + labels = ["measured collective hit", "analytical fallback", "batch-profile coverage"] + stack_colors = ["#4c78a8", "#e45756", "#54a24b"] + for values, label, color in zip(consumption.T, labels, stack_colors): + ax1.barh(variants, values, left=bottom, label=label, color=color) + bottom += values + ax1.set_xlim(0, 200) + ax1.set_xlabel("Coverage counters (normalized; separate axes by mechanism)") + ax1.set_title("B. Profile consumption, not just final rank") + ax1.grid(axis="x", alpha=0.25) + ax1.legend(fontsize=8, frameon=False, loc="lower right") + + fig.suptitle("MOCK / preregistered layout — values are not experimental results", fontsize=12) + fig.tight_layout() + fig.savefig(OUT, dpi=180, bbox_inches="tight") + print(OUT) + + +if __name__ == "__main__": + main() diff --git a/runs/frontier-fidelity-envelope-v1/profiles/measured-allreduce.csv b/runs/frontier-fidelity-envelope-v1/profiles/measured-allreduce.csv new file mode 100644 index 0000000..85fedab --- /dev/null +++ b/runs/frontier-fidelity-envelope-v1/profiles/measured-allreduce.csv @@ -0,0 +1,25 @@ +time_stats.all_reduce.min,time_stats.all_reduce.max,time_stats.all_reduce.mean,time_stats.all_reduce.median,time_stats.all_reduce.std,rank,num_workers,size,collective,devices_per_node,max_devices_per_node +0.08288000151515007,0.08288000151515007,0.08288000151515007,0.08288000151515007,0.0,0,2,4096,all_reduce,2,8 +0.0793600007891655,0.0793600007891655,0.0793600007891655,0.0793600007891655,0.0,0,2,32768,all_reduce,2,8 +0.0713919997215271,0.0713919997215271,0.0713919997215271,0.0713919997215271,0.0,0,2,65536,all_reduce,2,8 +0.08056000247597694,0.08056000247597694,0.08056000247597694,0.08056000247597694,0.0,0,2,131072,all_reduce,2,8 +0.0865279994904995,0.0865279994904995,0.0865279994904995,0.0865279994904995,0.0,0,2,262144,all_reduce,2,8 +0.07135999947786331,0.07135999947786331,0.07135999947786331,0.07135999947786331,0.0,0,2,524288,all_reduce,2,8 +0.07321599870920181,0.07321599870920181,0.07321599870920181,0.07321599870920181,0.0,0,2,1048576,all_reduce,2,8 +0.09025600180029869,0.09025600180029869,0.09025600180029869,0.09025600180029869,0.0,0,2,2097152,all_reduce,2,8 +0.08083200082182884,0.08083200082182884,0.08083200082182884,0.08083200082182884,0.0,0,2,4194304,all_reduce,2,8 +0.10891199856996536,0.10891199856996536,0.10891199856996536,0.10891199856996536,0.0,0,2,8388608,all_reduce,2,8 +0.1703840047121048,0.1703840047121048,0.1703840047121048,0.1703840047121048,0.0,0,2,16777216,all_reduce,2,8 +0.25539200007915497,0.25539200007915497,0.25539200007915497,0.25539200007915497,0.0,0,2,33554432,all_reduce,2,8 +0.1021759994328022,0.1021759994328022,0.1021759994328022,0.1021759994328022,0.0,0,4,4096,all_reduce,4,8 +0.12694399803876877,0.12694399803876877,0.12694399803876877,0.12694399803876877,0.0,0,4,32768,all_reduce,4,8 +0.09161599725484848,0.09161599725484848,0.09161599725484848,0.09161599725484848,0.0,0,4,65536,all_reduce,4,8 +0.08580800145864487,0.08580800145864487,0.08580800145864487,0.08580800145864487,0.0,0,4,131072,all_reduce,4,8 +0.09867199882864952,0.09867199882864952,0.09867199882864952,0.09867199882864952,0.0,0,4,262144,all_reduce,4,8 +0.09646400064229965,0.09646400064229965,0.09646400064229965,0.09646400064229965,0.0,0,4,524288,all_reduce,4,8 +0.08377600088715553,0.08377600088715553,0.08377600088715553,0.08377600088715553,0.0,0,4,1048576,all_reduce,4,8 +0.1128000020980835,0.1128000020980835,0.1128000020980835,0.1128000020980835,0.0,0,4,2097152,all_reduce,4,8 +0.08755199983716011,0.08755199983716011,0.08755199983716011,0.08755199983716011,0.0,0,4,4194304,all_reduce,4,8 +0.12361599877476692,0.12361599877476692,0.12361599877476692,0.12361599877476692,0.0,0,4,8388608,all_reduce,4,8 +0.20030399411916733,0.20030399411916733,0.20030399411916733,0.20030399411916733,0.0,0,4,16777216,all_reduce,4,8 +0.2924960106611252,0.2924960106611252,0.2924960106611252,0.2924960106611252,0.0,0,4,33554432,all_reduce,4,8 diff --git a/runs/frontier-fidelity-envelope-v1/profiles/measured-allreduce.manifest.json b/runs/frontier-fidelity-envelope-v1/profiles/measured-allreduce.manifest.json new file mode 100644 index 0000000..6ea2791 --- /dev/null +++ b/runs/frontier-fidelity-envelope-v1/profiles/measured-allreduce.manifest.json @@ -0,0 +1,15 @@ +{ + "output": "/home/gahow/phd/aituner/runs/frontier-fidelity-envelope-v1/profiles/measured-allreduce.csv", + "output_sha256": "9d693fd406616b599e57bcde66c980c7fc2831b3acf37d3eb633cec80ea0070d", + "payload_contract": "size=num_tokens*hidden_dim*2_bytes", + "rows": 24, + "schema": "frontier-vidur-allreduce-materialization-v1", + "source": "/home/gahow/phd/aituner/runs/frontier-qwen30-vllm020-profile-v1/frozen/profile-v2/allreduce.json", + "source_sha256": "b38d14f990578d668523d25b107aceed433da5020d8ada3b6e44d3562261a3b3", + "target": "time_stats.all_reduce.median", + "tp_coverage": [ + 2, + 4 + ], + "unused_stat_policy": "repeat critical_path_median; std=0" +} diff --git a/runs/frontier-fidelity-envelope-v1/remote-sync-marker/README.md b/runs/frontier-fidelity-envelope-v1/remote-sync-marker/README.md new file mode 100644 index 0000000..bf2fe4b --- /dev/null +++ b/runs/frontier-fidelity-envelope-v1/remote-sync-marker/README.md @@ -0,0 +1,2 @@ +This directory is the gpu-fleet synchronization marker. Experiment code is +synchronized to dash0 through the project Git branch before dispatch. diff --git a/runs/frontier-fidelity-envelope-v1/run_flashattn_composition.sh b/runs/frontier-fidelity-envelope-v1/run_flashattn_composition.sh new file mode 100644 index 0000000..03afe43 --- /dev/null +++ b/runs/frontier-fidelity-envelope-v1/run_flashattn_composition.sh @@ -0,0 +1,65 @@ +#!/usr/bin/env bash + +set -euo pipefail + +TP="${TP:?TP must be set to 1, 2, or 4}" +case "${TP}" in + 1|2|4) ;; + *) echo "ERROR: invalid TP=${TP}" >&2; exit 1 ;; +esac + +OUTPUT_ROOT="${OUTPUT_ROOT:?OUTPUT_ROOT must be set}" +VENV_ROOT="${VENV_ROOT:-/tmp/wjh/venvs/vllm-0.20.0-cu129-profiler-v1}" +VLLM_SOURCE="${VLLM_SOURCE:-/home/admin/cpfs/wjh/agentic-kv/third_party/vllm_v20_build}" +MODEL="${MODEL:-/home/admin/cpfs/wjh/models/Qwen/Qwen3-30B-A3B}" +CAMPAIGN_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROFILE_SCRIPT="${CAMPAIGN_ROOT}/../frontier-qwen30-vllm020-profile-v1/profile_vllm020_flashattn.py" +LOG_DIR="${OUTPUT_ROOT}/logs" +PROVENANCE_DIR="${OUTPUT_ROOT}/provenance" +BATCH_SPECS=(2q512 4q512 8q512 16q512 2q2k 4q2k) + +mkdir -p "${LOG_DIR}" "${PROVENANCE_DIR}" "${OUTPUT_ROOT}/raw" +exec > >(tee -a "${LOG_DIR}/composition.log") 2>&1 + +if [[ -z "${CUDA_VISIBLE_DEVICES:-}" ]]; then + echo "ERROR: CUDA_VISIBLE_DEVICES must contain the fleet-allocated GPU" >&2 + exit 1 +fi +IFS=',' read -r -a GPU_IDS <<< "${CUDA_VISIBLE_DEVICES}" +if [[ "${#GPU_IDS[@]}" -ne 1 ]]; then + echo "ERROR: expected exactly one GPU, got ${CUDA_VISIBLE_DEVICES}" >&2 + exit 1 +fi + +echo "PROFILE_LAUNCH_ECHO host=$(hostname) gpu=${CUDA_VISIBLE_DEVICES} model=${MODEL} runtime=vLLM-0.20.0+cu129 operator=FlashAttention3 tp=${TP} batch_specs=${BATCH_SPECS[*]} profile_script=${PROFILE_SCRIPT} output=${OUTPUT_ROOT} expected_wall=3-8m hard_wall=900s hard_gpu_cap=0.25_H20h" +date -u +"START_UTC=%Y-%m-%dT%H:%M:%SZ" +nvidia-smi --query-gpu=index,name,driver_version,memory.used,utilization.gpu --format=csv,noheader + +test -x "${VENV_ROOT}/bin/python" +test -f "${VLLM_SOURCE}/benchmarks/attention_benchmarks/runner.py" +test -f "${MODEL}/config.json" +test -f "${PROFILE_SCRIPT}" + +git -C "${CAMPAIGN_ROOT}/../.." rev-parse HEAD > "${PROVENANCE_DIR}/aituner.commit" +git -C "${VLLM_SOURCE}" rev-parse HEAD > "${PROVENANCE_DIR}/vllm-source.commit" +sha256sum "${PROFILE_SCRIPT}" "${BASH_SOURCE[0]}" > "${PROVENANCE_DIR}/source.sha256" +uv pip freeze --python "${VENV_ROOT}/bin/python" > "${PROVENANCE_DIR}/pip-freeze.txt" +nvidia-smi --query-gpu=index,uuid,name,driver_version,memory.total --format=csv,noheader > "${PROVENANCE_DIR}/gpus.csv" +printf '%s\n' "${BATCH_SPECS[@]}" > "${PROVENANCE_DIR}/batch-specs.txt" + +timeout --signal=TERM --kill-after=30s 780 \ + "${VENV_ROOT}/bin/python" "${PROFILE_SCRIPT}" \ + --vllm-source "${VLLM_SOURCE}" \ + --model "${MODEL}" \ + --output "${OUTPUT_ROOT}/raw/flashattn-composition-tp${TP}.json" \ + --tp "${TP}" \ + --batch-specs "${BATCH_SPECS[@]}" \ + --warmup-iters 5 \ + --repeats 10 \ + --profile-kv-update + +test -s "${OUTPUT_ROOT}/raw/flashattn-composition-tp${TP}.json" +sha256sum "${OUTPUT_ROOT}/raw/flashattn-composition-tp${TP}.json" "${PROVENANCE_DIR}"/* > "${OUTPUT_ROOT}/artifacts.sha256" +nvidia-smi --query-gpu=index,name,memory.used,utilization.gpu --format=csv,noheader +date -u +"END_UTC=%Y-%m-%dT%H:%M:%SZ" +echo "FLASHATTN_COMPOSITION_COMPLETE tp=${TP} cases=${#BATCH_SPECS[@]}" diff --git a/runs/frontier-fidelity-envelope-v1/smoke-report.md b/runs/frontier-fidelity-envelope-v1/smoke-report.md new file mode 100644 index 0000000..f55c31b --- /dev/null +++ b/runs/frontier-fidelity-envelope-v1/smoke-report.md @@ -0,0 +1,15 @@ +# Frontier measured-collective smoke + +日期:2026-07-17。设备:local CPU(Frontier simulation only)。Frontier commit:`d9cfeb6d8791fbf2f295dd9744c56a666171776e`,沿用既有 dirty compatibility patch set;A2 额外 patch SHA256 为 `35cc6be846589faf8cb5fa3ce5fdfe0aee8f086ba7dbb5dbcdc677148f19a3c8`。 + +固定 cell:Qwen3-30B-A3B BF16 profile-v2,`TP2/MNS8/MBT8192`,`ISL=2048/OSL=1`,64 requests,8 req/s,prefix off,TTFT SLO 1256 ms。 + +| variant | CC path for 2048-token payload | TTFT p50/p95/max (ms) | pass rate | +|---|---|---:|---:| +| A0 analytical | analytical | 122.2406276 | 1.0 | +| A1 native Vidur | `4,194,304 > 100,000` elements,lookup miss 后 analytical fallback | 122.2406276 | 1.0 | +| A2 measured + direct miss | measured random-forest estimator;exact payload memoized | 120.8898909 | 1.0 | + +A1 与 A0 的所有 TTFT 数值完全一致,验证 measured CSV 虽成功加载和训练,但没有参与该 payload 的 prediction。A2 model 对该 payload 的预测为 `0.09877793 ms`;同一个 TP2/2048 row 的 measured critical-path median 是 `0.10891200 ms`。A2 相对 A1 的 E2E delta 为 `-1.3507367 ms`(`-1.105%`),与每层多次 collective 的累计量级一致,因此通过“execution path 必须变化”的 smoke gate。 + +这个 smoke 只证明 profile consumption;不证明 ranking 已恢复。下一步必须运行完整 A2 TP×MNS surface,并与已冻结 real capacity比较。 diff --git a/runs/frontier-fidelity-envelope-v1/test_fidelity_envelope.py b/runs/frontier-fidelity-envelope-v1/test_fidelity_envelope.py new file mode 100644 index 0000000..3f5a79c --- /dev/null +++ b/runs/frontier-fidelity-envelope-v1/test_fidelity_envelope.py @@ -0,0 +1,69 @@ +#!/usr/bin/env python3 + +from __future__ import annotations + +import csv +import importlib.util +import json +import sys +import tempfile +import unittest +from pathlib import Path + + +ROOT = Path(__file__).parent + + +def load(name: str): + path = ROOT / name + spec = importlib.util.spec_from_file_location(path.stem, path) + assert spec and spec.loader + module = importlib.util.module_from_spec(spec) + sys.modules[spec.name] = module + spec.loader.exec_module(module) + return module + + +class FidelityEnvelopeTest(unittest.TestCase): + def test_materialize_allreduce(self) -> None: + module = load("materialize_frontier_allreduce.py") + rows = [] + for tp in (2, 4): + for tokens in (1, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192): + rows.append( + { + "tensor_parallel_size": tp, + "num_tokens": tokens, + "hidden_dim": 2048, + "payload_bytes": tokens * 2048 * 2, + "critical_path_median_ms": tp + tokens / 1000, + } + ) + with tempfile.TemporaryDirectory() as temporary: + root = Path(temporary) + source = root / "allreduce.json" + source.write_text( + json.dumps( + { + "schema_version": "qwen30_vllm020_allreduce_frozen.v1", + "rows": rows, + } + ) + ) + output = root / "all_reduce.csv" + manifest = module.convert(source, output) + self.assertEqual(manifest["rows"], 24) + with output.open(newline="") as handle: + converted = list(csv.DictReader(handle)) + self.assertEqual(converted[0]["num_workers"], "2") + self.assertEqual(converted[0]["size"], "4096") + self.assertEqual(converted[-1]["num_workers"], "4") + self.assertEqual(converted[-1]["size"], str(8192 * 2048 * 2)) + self.assertEqual( + converted[-1]["time_stats.all_reduce.median"], + str(4 + 8192 / 1000), + ) + + +if __name__ == "__main__": + unittest.main() diff --git a/runs/frontier-phase-factorial-v0/run_frontier_qwen30_prefill_surface.py b/runs/frontier-phase-factorial-v0/run_frontier_qwen30_prefill_surface.py index 10249d7..ecd0e74 100644 --- a/runs/frontier-phase-factorial-v0/run_frontier_qwen30_prefill_surface.py +++ b/runs/frontier-phase-factorial-v0/run_frontier_qwen30_prefill_surface.py @@ -48,6 +48,10 @@ def parse_args() -> argparse.Namespace: parser.add_argument("--requests", type=int, default=64) parser.add_argument("--rate", type=float, action="append") parser.add_argument("--config", action="append") + parser.add_argument( + "--cc-backend", choices=("analytical", "vidur"), default="analytical" + ) + parser.add_argument("--allreduce-csv", type=Path) parser.add_argument("--timeout-seconds", type=float, default=900.0) parser.add_argument("--resume", action="store_true") return parser.parse_args() @@ -182,6 +186,37 @@ def knobs(config: Config, paths: dict[str, Path], cache: Path) -> dict[str, Any] } +def configure_cc_command( + command: list[str], *, backend: str, allreduce_csv: Path | None, cache: Path +) -> list[str]: + configured = list(command) + option = "--cc_backend_config_type" + try: + index = configured.index(option) + except ValueError as error: + raise ValueError(f"Frontier command is missing {option}") from error + configured[index + 1] = backend + if backend == "analytical": + if allreduce_csv is not None: + raise ValueError("--allreduce-csv requires --cc-backend vidur") + return configured + if allreduce_csv is None: + raise ValueError("--cc-backend vidur requires --allreduce-csv") + configured.extend( + [ + "--vidur_cc_backend_config_all_reduce_input_file", + str(allreduce_csv), + "--vidur_cc_backend_config_cache_dir", + str(cache), + "--vidur_cc_backend_config_k_fold_cv_splits", + "6", + "--vidur_cc_backend_config_num_training_job_threads", + "1", + ] + ) + return configured + + def find_metrics(run_dir: Path) -> tuple[Path, Path]: systems = list((run_dir / "metrics").rglob("system_metrics.json")) requests = list((run_dir / "metrics").rglob("request_metrics.csv")) @@ -231,6 +266,10 @@ def main() -> None: args.profile_root = args.profile_root.resolve() args.python_deps = args.python_deps.resolve() args.output_root = args.output_root.resolve() + if args.allreduce_csv is not None: + args.allreduce_csv = args.allreduce_csv.resolve() + if not args.allreduce_csv.is_file(): + raise FileNotFoundError(args.allreduce_csv) rates = tuple(args.rate or RATES) selected = list(GRID) if args.config: @@ -274,6 +313,12 @@ def main() -> None: run_id=f"qwen30_prefill_{config.name}_r{rate:g}", knobs=config_knobs, ) + command = configure_cc_command( + command, + backend=args.cc_backend, + allreduce_csv=args.allreduce_csv, + cache=args.output_root / "cc-cache", + ) write_json(run_dir / "command.json", command) environment = os.environ.copy() pythonpath = [str(args.python_deps), str(args.frontier_source)] @@ -389,6 +434,15 @@ def main() -> None: "coverage": coverage, "sha256": {name: sha256(path) for name, path in paths.items()}, }, + "collective": { + "backend": args.cc_backend, + "allreduce_csv": ( + str(args.allreduce_csv) if args.allreduce_csv is not None else None + ), + "allreduce_csv_sha256": ( + sha256(args.allreduce_csv) if args.allreduce_csv is not None else None + ), + }, "config_results": config_results, "capacity": capacities, } diff --git a/runs/frontier-phase-factorial-v0/test_phase_factorial.py b/runs/frontier-phase-factorial-v0/test_phase_factorial.py index 4172926..0ceb170 100644 --- a/runs/frontier-phase-factorial-v0/test_phase_factorial.py +++ b/runs/frontier-phase-factorial-v0/test_phase_factorial.py @@ -43,3 +43,20 @@ def test_kendall_tau_b() -> None: analysis = load("analyze_qwen30_prefill_fidelity.py") assert analysis.kendall_tau_b([1, 2, 3], [1, 2, 3])["kendall_tau_b"] == 1 assert analysis.kendall_tau_b([1, 2, 3], [3, 2, 1])["kendall_tau_b"] == -1 + + +def test_configure_cc_command(tmp_path: Path) -> None: + surface = load("run_frontier_qwen30_prefill_surface.py") + base = ["python", "--cc_backend_config_type", "analytical", "--other", "x"] + analytical = surface.configure_cc_command( + base, backend="analytical", allreduce_csv=None, cache=tmp_path + ) + assert analytical == base + profile = tmp_path / "all_reduce.csv" + profile.write_text("header\n") + vidur = surface.configure_cc_command( + base, backend="vidur", allreduce_csv=profile, cache=tmp_path / "cache" + ) + assert vidur[2] == "vidur" + assert "--vidur_cc_backend_config_all_reduce_input_file" in vidur + assert str(profile) in vidur diff --git a/runs/frontier-qwen30-vllm020-profile-v1/freeze_frontier_profiles.py b/runs/frontier-qwen30-vllm020-profile-v1/freeze_frontier_profiles.py index 0d420e0..16f1b68 100644 --- a/runs/frontier-qwen30-vllm020-profile-v1/freeze_frontier_profiles.py +++ b/runs/frontier-qwen30-vllm020-profile-v1/freeze_frontier_profiles.py @@ -114,7 +114,7 @@ MOE_METADATA = ( def parse_args() -> argparse.Namespace: parser = argparse.ArgumentParser() parser.add_argument("--linear", type=Path, required=True) - parser.add_argument("--attention", type=Path, nargs=3, required=True) + parser.add_argument("--attention", type=Path, nargs="+", required=True) parser.add_argument("--moe", type=Path, required=True) parser.add_argument("--router", type=Path, required=True) parser.add_argument("--allreduce", type=Path, nargs=2, required=True)