Adaptive Scale
Adaptive scale is a single-run load controller for finding and sustaining an SLA boundary. Instead of launching many independent sweep or search runs, AIPerf starts at a low control value, evaluates SLA windows, increases load while every SLA filter passes, and then sustains near the last passing boundary.
Use adaptive scale when you want one benchmark invocation to push a service until a latency or throughput constraint starts failing, then keep pressure near that edge. Use adaptive_search when you want offline Bayesian optimization across multiple runs, sweeps when you want a fixed experiment grid, fixed ramps when you already know the schedule you want to replay, and static concurrency or request rate when you only need one fixed load point.
YAML example
YAML is the preferred way to configure adaptive scale because it keeps the control variable, assessment windows, sustain period, and SLA filters together. The canonical shape uses a nested adaptive_scale.control block:
A window passes only when every SLA filter passes. Latency thresholds use milliseconds. Lower-is-better metrics usually use lt or le; higher-is-better metrics such as request throughput and goodput ratio usually use gt or ge.
The canonical adaptive shape uses adaptive_scale.control for the load-control variable and phase-level sla for the filters. Existing flat concurrency aliases such as min_concurrency and max_concurrency are still accepted for compatibility, but new configs should use control.min and control.max.
Do not combine adaptive scale with a fixed ramp on the same variable. For example, control.variable: prefill_concurrency cannot be used with prefill_ramp, and control.variable: request_rate cannot be used with rate_ramp.
Boundary Example
This example demonstrates adaptive scale discovering a latency boundary against an OpenAI-compatible chat endpoint. Make sure the endpoint is reachable at localhost:8000, then tune the model and SLA threshold for your service.
Run it with:
Sample Output (Successful Run):
The corresponding adaptive_scale_summary.json included:
Exact numbers depend on your server and hardware. If the run passes at max, lower the latency threshold or raise adaptive_scale.control.max. If it fails at min, loosen the latency threshold or lower adaptive_scale.control.min.
Control variables
For users, adaptive scale changes population pressure rather than acting as another spelling of request rate.
CLI quick start
The CLI is useful for scripts and simple one-phase runs. Prefer YAML for reusable benchmark definitions.
The compact control form is --adaptive-scale-control variable:min,max:type. Use int for concurrency, prefill_concurrency, and users; use float for request_rate. Do not mix compact control with expanded --adaptive-control-* flags.
Artifacts
Adaptive scale writes these timing-owned artifacts into the run artifact directory:
adaptive_scale_events.jsonl is an event stream for orchestration and post-processing. Each line includes schema_version, timestamps, event, control_variable, control_value_before, control_value_after, boundary_value, last_passing_value, first_failing_value, sla_values, and binding_sla fields. Pollers should key off explicit events such as sustain_started rather than sleeping for a fixed amount of time.
adaptive_scale_summary.json is the final controller summary. It records the discovered boundary, final control value, last passing value, first failing value, sustain status, throughput, sample counts, error counts, cancellation counts, and the evaluated candidate windows.
Artifact fields are intended for orchestration-facing consumers, so treat schema changes and field renames as compatibility events.
Metric semantics
Use request_latency for simple latency-boundary examples. Request throughput aliases and goodput_ratio can also be used as adaptive SLA filters. See Adaptive SLA metric support for the full metric and statistic matrix.