Spica Traffic
Trace, request-rate, concurrency, and KV-load workload definitions
Experimental. Spica is intended for evaluation and feedback, not production capacity planning. Its API, configuration schema, search results, and deployment output may change without a standard deprecation period. Spica provides no SLA, accuracy, or configuration optimality guarantees.
The workload: block of a SmartSearchConfig YAML is the traffic every candidate is
replayed against. Most workload fields are pinned. The exception is a ranged
kv_load_ratio under a pareto goal: Vizier searches it as a continuous load dimension.
The block maps to Workload in aisimulate/src/aisimulate/spica/config.py.
A workload is exactly one of four load shapes. The shape is inferred from which field
is set (Workload._validate_workload), and each shape is either open-loop (requests
arrive on a clock, independent of how fast the system drains them) or closed-loop (a
fixed number of requests are kept in flight; a new one starts as one finishes).
The four load shapes
is_trace_based is trace_path is not None; is_synthetic is its complement. Setting
trace_path selects shape 1; otherwise it is synthetic and exactly one of
request_rate (shape 2), concurrency (shape 3), or kv_load_ratio (shape 4) selects the
sub-shape.
The closed-loop in-flight cap is resolved by effective_in_flight_cap() (None = open-loop):
- trace ->
replay_concurrency(so a trace is open-loop unlessreplay_concurrencyis set); - synthetic KV load -> the candidate-derived
concurrency_override; - synthetic fixed
concurrency-> that value; - request-rate ->
None(open-loop).
Fields
Every Workload field:
The synthetic fields are isl, osl, request_rate, concurrency, kv_load_ratio,
num_request_ratio;
shared_prefix_ratio, num_prefix_groups, turns_per_session, inter_turn_delay_ms are
shared synthetic knobs threaded into the replay (ReplayEvaluator._synthetic_kwargs).
kv_load_ratio (candidate-relative concurrency)
kv_load_ratio requires an AI Configurator release that provides
aiconfigurator.sdk.memory. The default dynamo-planner image currently retains AI Configurator
0.9, so this workload mode fails fast before search starts in that image. Use a trace workload
or fixed concurrency with the default image.
Spica resolves a KV-load trial after the backend, parallel shape, replicas, and batching
knobs have been selected. For every active role, it asks AI Configurator for the per-rank KV token
capacity using that candidate’s max_num_batched_tokens, max_num_seqs, memory fraction,
parallel shape, and MTP setting. The scheduler-visible role capacity is:
Attention-DP ranks own independent sequence pools, so capacity is multiplied by
attention_dp; TP/EP ranks shard the same sequences and are not multipliers. For disagg,
both prefill and decode are checked for candidate-specific memory feasibility, but only
decode capacity drives load. For agg, agg capacity drives load.
The concrete closed-loop cap is:
kv_load_ratio = 0 therefore maps to the minimum concurrency 1; 1 means estimated
100% steady-state KV occupancy. It is an estimate, not a guarantee that replay sees no
temporary KV pressure or request retraction. Batching combinations that leave no KV budget
are reported to Vizier as infeasible before replay.
Every resulting candidate records kv_load_ratio, the derived concurrency,
kv_load_concurrency_capacity, kv_load_capacity_tokens, and per-role
*_kv_capacity_tokens for traceability.
num_request_ratio (synthetic length scales with the load)
resolved_request_count(concurrency_override=None) computes the synthetic request count as
where load is, in precedence order: the candidate-derived concurrency_override (KV-load
mode), else fixed concurrency (closed-loop), else request_rate (open-loop).
So the synthetic trace length scales with the swept load automatically: with
num_request_ratio = 10, concurrency 256 yields 2560 requests, concurrency 512
yields 5120. Result is floored at 1; num_request_ratio itself is treated as 0.0
when unset (max(1, …) keeps at least one request).
Validation (Workload._validate_workload)
- Trace workload (
trace_pathset): must not set any synthetic field (isl,osl,request_rate,concurrency,kv_load_ratio,num_request_ratio) — error lists the offenders.replay_concurrency, if set, must be a positive int. - Synthetic workload (no
trace_path): exactly one ofrequest_rate,concurrency, orkv_load_ratio(none / multiple -> error);isl,osl,num_request_ratioare all required;replay_concurrencyis rejected (it is trace-only — useconcurrency).concurrencymust be one positive int;request_rate,isl,osl, andnum_request_ratiomust be positive. KV-load values must be finite and non-negative. - Ranged KV load only under Pareto —
[min, max]must contain exactly two values withmin < max;SmartSearchConfig._validate_kv_load_ratio_rangerejects it for scalar goals. A scalarkv_load_ratiois valid for every goal. A synthetic Pareto config that omits all three load fields defaults tokv_load_ratio: [0.0, 1.0].
Replay routing (from evaluator.py)
Each shape × deployment case routes to a Dynamo Replay entry point; all emit the same flat
trace_report dict. ReplayEvaluator.evaluate branches on is_trace_based, then on
plan.is_static:
Notes:
- The closed-loop cap passed as
replay_concurrency=on every path iseffective_in_flight_cap()—replay_concurrencyfor a trace, fixedconcurrency, or the KV-load-derived per-trialconcurrency_overridefor synthetic. - The goodput SLA (
goal.sla) is passed assla_ttft_ms/sla_itl_ms/sla_e2e_mson every path only when an SLA is configured —_goodput_sla_kwargsreturns{}whengoal.sla is None, so nosla_*kwargs are passed and no goodput is computed. It is independent of the planner’s own scaling SLA. - Under
kv_routerthe searched router weights become a realKvRouterConfig;round_robinpassesrouter_config=None.