Skip to content

Commit f2b7b64

Browse files
authored
Merge pull request #27 from SemiAnalysisAI/cquil11/deterministic-agentic-warmup-count-main
feat(agentic): add deterministic warmup request budgets
2 parents 1a9d08e + 2974937 commit f2b7b64

26 files changed

Lines changed: 1093 additions & 111 deletions

docs/cli-options.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1125,7 +1125,12 @@ The maximum duration in seconds for the warmup phase. If not set, it will use th
11251125

11261126
#### `--agentic-cache-warmup-duration` `<float>`
11271127

1128-
Additional agentic replay warmup duration in seconds. After the normal snapshot warmup drains, AIPerf continues the live trajectories without recorded idle delays and with one-token outputs, then drains and resumes profiling from the resulting trajectory state using each live stream's residual next-turn delay.
1128+
Additional agentic replay warmup duration in seconds. After the normal snapshot warmup drains, AIPerf continues the live trajectories without recorded idle delays and with one-token outputs, then drains and resumes profiling from the resulting trajectory state using each live stream's residual next-turn delay. Mutually exclusive with --warmup-requests-per-lane.
1129+
<br/>_Constraints: > 0_
1130+
1131+
#### `--warmup-requests-per-lane` `<int>`
1132+
1133+
Deterministic agentic cache-pressure warmup request budget per concurrency lane. For example, 10 with concurrency 16 caps warmup at 160 wire requests, including initial snapshot priming. Mutually exclusive with --agentic-cache-warmup-duration.
11291134
<br/>_Constraints: > 0_
11301135

11311136
#### `--agentic-warmup-grace-period` `<float>`
@@ -2655,7 +2660,12 @@ The maximum duration in seconds for the warmup phase. If not set, it will use th
26552660

26562661
#### `--agentic-cache-warmup-duration` `<float>`
26572662

2658-
Additional agentic replay warmup duration in seconds. After the normal snapshot warmup drains, AIPerf continues the live trajectories without recorded idle delays and with one-token outputs, then drains and resumes profiling from the resulting trajectory state using each live stream's residual next-turn delay.
2663+
Additional agentic replay warmup duration in seconds. After the normal snapshot warmup drains, AIPerf continues the live trajectories without recorded idle delays and with one-token outputs, then drains and resumes profiling from the resulting trajectory state using each live stream's residual next-turn delay. Mutually exclusive with --warmup-requests-per-lane.
2664+
<br/>_Constraints: > 0_
2665+
2666+
#### `--warmup-requests-per-lane` `<int>`
2667+
2668+
Deterministic agentic cache-pressure warmup request budget per concurrency lane. For example, 10 with concurrency 16 caps warmup at 160 wire requests, including initial snapshot priming. Mutually exclusive with --agentic-cache-warmup-duration.
26592669
<br/>_Constraints: > 0_
26602670

26612671
#### `--agentic-warmup-grace-period` `<float>`

docs/tutorials/agentx-mvp.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,17 @@ duration expires, it stops issuing new requests, drains requests already on
417417
the wire, snapshots each live root, subagent, and unresolved join, and starts
418418
profiling from that exact state.
419419

420+
For repeatable warmup depth, use
421+
`--warmup-requests-per-lane REQUESTS` instead. Each concurrency lane is allowed
422+
exactly that many warmup wire requests, including its initial snapshot-priming
423+
requests. For example, `--concurrency 16` with
424+
`--warmup-requests-per-lane 10` produces 160 warmup requests, with a strict
425+
10-request quota on every lane.
426+
427+
`--agentic-cache-warmup-duration` and `--warmup-requests-per-lane` are mutually
428+
exclusive: choose a time-bounded warmup or a deterministic request-bounded
429+
warmup.
430+
420431
These requests remain part of warmup, so they are excluded from exported
421432
request metrics.
422433

src/aiperf/config/config.py

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -609,7 +609,8 @@ def validate_cache_bust_compatibility(self) -> Self:
609609
def validate_agentic_cache_warmup(self) -> Self:
610610
"""Restrict accelerated cache warmup to the agentic_replay timing mode.
611611
612-
``--agentic-cache-warmup-duration`` is consumed solely by
612+
The mutually exclusive duration and deterministic request-budget modes
613+
are consumed solely by
613614
``aiperf.timing.config._build_agentic_warmup_config``, which only runs
614615
when the profiling phases resolve to AGENTIC_REPLAY. On any other run
615616
the value is silently dropped, so an unguarded flag is a no-op the user
@@ -630,27 +631,42 @@ def validate_agentic_cache_warmup(self) -> Self:
630631
from aiperf.timing.config import _is_agentic_replay
631632

632633
profiling_phases = self.get_profiling_phases()
633-
if not any(
634+
has_duration = any(
634635
getattr(phase, "agentic_cache_warmup_duration", None) is not None
635636
for phase in profiling_phases
636-
):
637+
)
638+
has_request_budget = any(
639+
getattr(phase, "warmup_requests_per_lane", None) is not None
640+
for phase in profiling_phases
641+
)
642+
if not has_duration and not has_request_budget:
637643
return self
638644

645+
if any(
646+
getattr(phase, "warmup_requests_per_lane", None) is not None
647+
and getattr(phase, "agentic_cache_warmup_duration", None) is not None
648+
for phase in profiling_phases
649+
):
650+
raise ValueError(
651+
"--warmup-requests-per-lane and "
652+
"--agentic-cache-warmup-duration are mutually exclusive."
653+
)
654+
639655
if self.scenario is not None:
640656
from aiperf.common.scenario.registry import get_scenario
641657

642658
scenario_timing_mode = get_scenario(self.scenario).timing_mode
643659
if scenario_timing_mode != TimingMode.AGENTIC_REPLAY:
644660
raise ValueError(
645-
"--agentic-cache-warmup-duration requires the agentic_replay "
661+
"agentic cache warmup requires the agentic_replay "
646662
f"timing mode; scenario {self.scenario!r} locks "
647663
f"timing_mode={scenario_timing_mode}."
648664
)
649665
return self
650666

651667
if not _is_agentic_replay(profiling_phases):
652668
raise ValueError(
653-
"--agentic-cache-warmup-duration requires the agentic_replay "
669+
"agentic cache warmup requires the agentic_replay "
654670
"timing mode (set today by --scenario inferencex-agentx-mvp); "
655671
"the profiling phase(s) are not agentic_replay."
656672
)

src/aiperf/config/flags/_converter_profiling.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
"burst_phase_starts",
5555
"system_idle_gap_cap_seconds",
5656
"agentic_cache_warmup_duration",
57+
"warmup_requests_per_lane",
5758
"agentic_warmup_grace_period",
5859
)
5960

src/aiperf/config/flags/cli_config.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2280,14 +2280,31 @@ def url(self) -> str:
22802280
"After the normal snapshot warmup drains, AIPerf continues the live "
22812281
"trajectories without recorded idle delays and with one-token outputs, "
22822282
"then drains and resumes profiling from the resulting trajectory state "
2283-
"using each live stream's residual next-turn delay.",
2283+
"using each live stream's residual next-turn delay. Mutually exclusive "
2284+
"with --warmup-requests-per-lane.",
22842285
),
22852286
CLIParameter(
22862287
name=("--agentic-cache-warmup-duration",),
22872288
group=Groups.WARMUP,
22882289
),
22892290
] = None
22902291

2292+
warmup_requests_per_lane: Annotated[
2293+
int | None,
2294+
Field(
2295+
gt=0,
2296+
description="Deterministic agentic cache-pressure warmup request "
2297+
"budget per concurrency lane. For example, 10 with concurrency 16 "
2298+
"caps warmup at 160 wire requests, including initial snapshot "
2299+
"priming. Mutually exclusive with "
2300+
"--agentic-cache-warmup-duration.",
2301+
),
2302+
CLIParameter(
2303+
name=("--warmup-requests-per-lane",),
2304+
group=Groups.WARMUP,
2305+
),
2306+
] = None
2307+
22912308
agentic_warmup_grace_period: Annotated[
22922309
float | None,
22932310
Field(

src/aiperf/config/phases.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,21 @@ class BasePhaseConfig(AdaptiveScalePhaseMixin, BaseConfig):
360360
"continues the live trajectories without recorded idle delays and with "
361361
"one-token outputs for this long, then drains and resumes profiling "
362362
"from the resulting trajectory state. Read off the profiling phase by "
363-
"``timing.config._build_agentic_warmup_config``. None disables it.",
363+
"``timing.config._build_agentic_warmup_config``. Mutually exclusive "
364+
"with warmup_requests_per_lane. None disables it.",
365+
),
366+
]
367+
368+
warmup_requests_per_lane: Annotated[
369+
int | None,
370+
Field(
371+
default=None,
372+
gt=0,
373+
description="AGENTIC_REPLAY only: deterministic cache-pressure "
374+
"warmup request budget per concurrency lane. The total warmup "
375+
"wire-request cap is this value multiplied by the number of live "
376+
"trajectory lanes, including the initial snapshot-priming "
377+
"requests. Mutually exclusive with agentic_cache_warmup_duration.",
364378
),
365379
]
366380

0 commit comments

Comments
 (0)