Correct F1 to a steady fixed-QPS workload
This commit is contained in:
@@ -5,9 +5,11 @@ simulator-a1/
|
||||
simulator-a2/
|
||||
simulator-a3/
|
||||
simulator-f1/
|
||||
simulator-f1-steady/
|
||||
simulator-f2/
|
||||
simulator-t1/
|
||||
fleet-state/
|
||||
fleet-artifacts/
|
||||
profiles/profile-v3-batch/
|
||||
trace-exact-v1-public/
|
||||
workloads/f1-isl512-osl1-steady10s/*.csv
|
||||
|
||||
@@ -26,6 +26,7 @@ def parse_args() -> argparse.Namespace:
|
||||
parser.add_argument("--input-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("--duration-seconds", type=float)
|
||||
parser.add_argument("--rate", type=float, action="append", required=True)
|
||||
parser.add_argument("--block-size", type=int, default=16)
|
||||
return parser.parse_args()
|
||||
@@ -47,6 +48,7 @@ def materialize(
|
||||
requests: int,
|
||||
rates: list[float],
|
||||
block_size: int,
|
||||
duration_seconds: float | None = None,
|
||||
) -> dict[str, object]:
|
||||
values = [input_tokens, output_tokens, requests, block_size]
|
||||
if any(value <= 0 for value in values):
|
||||
@@ -57,15 +59,21 @@ def materialize(
|
||||
raise ValueError("rates must be positive and finite")
|
||||
if len(set(rates)) != len(rates):
|
||||
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)
|
||||
anchors = []
|
||||
blocks = math.ceil(input_tokens / block_size)
|
||||
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"
|
||||
with path.open("w", newline="") as output:
|
||||
writer = csv.DictWriter(output, fieldnames=FIELDS, lineterminator="\n")
|
||||
writer.writeheader()
|
||||
for request_id in range(requests):
|
||||
for request_id in range(request_count):
|
||||
first_block = request_id * blocks + 1
|
||||
writer.writerow(
|
||||
{
|
||||
@@ -82,6 +90,7 @@ def materialize(
|
||||
{
|
||||
"label": rate_key(rate),
|
||||
"rate": rate,
|
||||
"requests": request_count,
|
||||
"path": path.name,
|
||||
"sha256": sha256(path),
|
||||
}
|
||||
@@ -91,7 +100,8 @@ def materialize(
|
||||
"contract": {
|
||||
"input_tokens": input_tokens,
|
||||
"output_tokens": output_tokens,
|
||||
"requests": requests,
|
||||
"minimum_requests_per_anchor": requests,
|
||||
"minimum_steady_duration_seconds": duration_seconds,
|
||||
"block_size": block_size,
|
||||
"arrival": "open_loop_uniform",
|
||||
"prefix_caching": False,
|
||||
@@ -114,6 +124,7 @@ def main() -> None:
|
||||
requests=args.requests,
|
||||
rates=args.rate,
|
||||
block_size=args.block_size,
|
||||
duration_seconds=args.duration_seconds,
|
||||
)
|
||||
print(json.dumps(manifest, sort_keys=True))
|
||||
|
||||
|
||||
@@ -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 合并。
|
||||
File diff suppressed because it is too large
Load Diff
@@ -203,6 +203,16 @@ class FidelityEnvelopeTest(unittest.TestCase):
|
||||
self.assertEqual(rows[1]["block_hash_ids"], "3|4")
|
||||
self.assertEqual(rows[1]["arrived_at"], "0.500000000000")
|
||||
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__":
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
Reference in New Issue
Block a user