Correct F1 to a steady fixed-QPS workload

This commit is contained in:
2026-07-17 10:36:28 +08:00
parent 10afe4e2e8
commit ec775cdafd
6 changed files with 4004 additions and 2 deletions

View File

@@ -5,9 +5,11 @@ simulator-a1/
simulator-a2/ simulator-a2/
simulator-a3/ simulator-a3/
simulator-f1/ simulator-f1/
simulator-f1-steady/
simulator-f2/ simulator-f2/
simulator-t1/ simulator-t1/
fleet-state/ fleet-state/
fleet-artifacts/ fleet-artifacts/
profiles/profile-v3-batch/ profiles/profile-v3-batch/
trace-exact-v1-public/ trace-exact-v1-public/
workloads/f1-isl512-osl1-steady10s/*.csv

View File

@@ -26,6 +26,7 @@ def parse_args() -> argparse.Namespace:
parser.add_argument("--input-tokens", type=int, required=True) parser.add_argument("--input-tokens", type=int, required=True)
parser.add_argument("--output-tokens", type=int, required=True) parser.add_argument("--output-tokens", type=int, required=True)
parser.add_argument("--requests", type=int, default=64) parser.add_argument("--requests", type=int, default=64)
parser.add_argument("--duration-seconds", type=float)
parser.add_argument("--rate", type=float, action="append", required=True) parser.add_argument("--rate", type=float, action="append", required=True)
parser.add_argument("--block-size", type=int, default=16) parser.add_argument("--block-size", type=int, default=16)
return parser.parse_args() return parser.parse_args()
@@ -47,6 +48,7 @@ def materialize(
requests: int, requests: int,
rates: list[float], rates: list[float],
block_size: int, block_size: int,
duration_seconds: float | None = None,
) -> dict[str, object]: ) -> dict[str, object]:
values = [input_tokens, output_tokens, requests, block_size] values = [input_tokens, output_tokens, requests, block_size]
if any(value <= 0 for value in values): if any(value <= 0 for value in values):
@@ -57,15 +59,21 @@ def materialize(
raise ValueError("rates must be positive and finite") raise ValueError("rates must be positive and finite")
if len(set(rates)) != len(rates): if len(set(rates)) != len(rates):
raise ValueError("rates must be unique") raise ValueError("rates must be unique")
if duration_seconds is not None and duration_seconds <= 0:
raise ValueError("duration must be positive")
root.mkdir(parents=True, exist_ok=True) root.mkdir(parents=True, exist_ok=True)
anchors = [] anchors = []
blocks = math.ceil(input_tokens / block_size) blocks = math.ceil(input_tokens / block_size)
for rate in rates: for rate in rates:
request_count = max(
requests,
math.ceil(rate * duration_seconds) if duration_seconds is not None else 0,
)
path = root / f"{rate_key(rate)}.csv" path = root / f"{rate_key(rate)}.csv"
with path.open("w", newline="") as output: with path.open("w", newline="") as output:
writer = csv.DictWriter(output, fieldnames=FIELDS, lineterminator="\n") writer = csv.DictWriter(output, fieldnames=FIELDS, lineterminator="\n")
writer.writeheader() writer.writeheader()
for request_id in range(requests): for request_id in range(request_count):
first_block = request_id * blocks + 1 first_block = request_id * blocks + 1
writer.writerow( writer.writerow(
{ {
@@ -82,6 +90,7 @@ def materialize(
{ {
"label": rate_key(rate), "label": rate_key(rate),
"rate": rate, "rate": rate,
"requests": request_count,
"path": path.name, "path": path.name,
"sha256": sha256(path), "sha256": sha256(path),
} }
@@ -91,7 +100,8 @@ def materialize(
"contract": { "contract": {
"input_tokens": input_tokens, "input_tokens": input_tokens,
"output_tokens": output_tokens, "output_tokens": output_tokens,
"requests": requests, "minimum_requests_per_anchor": requests,
"minimum_steady_duration_seconds": duration_seconds,
"block_size": block_size, "block_size": block_size,
"arrival": "open_loop_uniform", "arrival": "open_loop_uniform",
"prefix_caching": False, "prefix_caching": False,
@@ -114,6 +124,7 @@ def main() -> None:
requests=args.requests, requests=args.requests,
rates=args.rate, rates=args.rate,
block_size=args.block_size, block_size=args.block_size,
duration_seconds=args.duration_seconds,
) )
print(json.dumps(manifest, sort_keys=True)) print(json.dumps(manifest, sort_keys=True))

View File

@@ -0,0 +1,10 @@
# F1 64-request pilot非 decision-bearing
该 surface 使用固定 `ISL=512/OSL=1`、uniform QPS、prefix off 和每个 anchor
64 requests。它完成了 runner correctness smoke但不能用于 capacity/ranking claim
512 req/s 时64 个请求只覆盖 0.123 秒TP4 的 64/64 SLO pass 只说明这个有限 burst
能在 TTFT SLO 内排空,并不说明系统能持续承载 512 req/s。
Decision-bearing F1 改为每个 anchor 至少 64 requests 且至少 10 秒 steady arrivals
物化 contract 位于 `../../workloads/f1-isl512-osl1-steady10s/manifest.json`。原始 pilot
manifest 保留用于审计,不与 steady surface 合并。

View File

@@ -203,6 +203,16 @@ class FidelityEnvelopeTest(unittest.TestCase):
self.assertEqual(rows[1]["block_hash_ids"], "3|4") self.assertEqual(rows[1]["block_hash_ids"], "3|4")
self.assertEqual(rows[1]["arrived_at"], "0.500000000000") self.assertEqual(rows[1]["arrived_at"], "0.500000000000")
self.assertEqual(manifest["contract"]["prefix_caching"], False) self.assertEqual(manifest["contract"]["prefix_caching"], False)
steady = module.materialize(
root / "steady",
input_tokens=32,
output_tokens=4,
requests=2,
rates=[2.0],
block_size=16,
duration_seconds=10.0,
)
self.assertEqual(steady["anchors"][0]["requests"], 20)
if __name__ == "__main__": if __name__ == "__main__":

View File

@@ -0,0 +1,57 @@
{
"anchors": [
{
"label": "r16",
"path": "r16.csv",
"rate": 16.0,
"requests": 160,
"sha256": "931604bdf085b1e0c2c70ffed9d10cbaeb6bfb3523976ce25c9bb3faf5fb20a9"
},
{
"label": "r32",
"path": "r32.csv",
"rate": 32.0,
"requests": 320,
"sha256": "3f839823181c75149184df43326df4139c1f00cbc607dd305323d34e92467140"
},
{
"label": "r64",
"path": "r64.csv",
"rate": 64.0,
"requests": 640,
"sha256": "b5bea5cf977f6a875a863a135eca70e643653b07ab92233f933f8b5e44e4a8c7"
},
{
"label": "r128",
"path": "r128.csv",
"rate": 128.0,
"requests": 1280,
"sha256": "ea94212548621233172e430649e523f494064d035a7609d0b9ec3b1930222a3b"
},
{
"label": "r256",
"path": "r256.csv",
"rate": 256.0,
"requests": 2560,
"sha256": "1e580f6ca30317f1f1ff81a86f318347341607cf1afcfef7ba53123335f02295"
},
{
"label": "r512",
"path": "r512.csv",
"rate": 512.0,
"requests": 5120,
"sha256": "992ad52e6e6c08bcb0843d59ff7d529d637ad8ed812aca96d1318cb1ecfeb71b"
}
],
"contract": {
"arrival": "open_loop_uniform",
"block_size": 16,
"input_tokens": 512,
"minimum_requests_per_anchor": 64,
"minimum_steady_duration_seconds": 10.0,
"output_tokens": 1,
"prefix_caching": false,
"prefix_relation": "all request block identities are disjoint"
},
"schema": "qwen30-fixed-frontier-traces-v1"
}