Planner Live Retune
Experimental, development clusters only. Live retune builds on DGDR v1beta2, which the
operator serves only with the experimental dgdrV1Beta2.enabled Helm value, and it writes
router parameters through the frontend admin API, which has no authentication. Do not enable it
on a cluster that serves production traffic.
Live retune is the Kubernetes form of Periodic Retune.
Every retune.interval_seconds, the Planner cuts the window of request traces that just ended,
creates DynamoGraphDeploymentRequests (DGDR) v1beta2 that replay the window for a grid of KV
router parameters, scores the candidates the Runs report on retune.objective, and keeps the
current parameters unless a candidate beats them by more than retune.min_improvement_percentage.
Outside advisory mode it then sets the winner on every frontend router with
PATCH /router_policy.
Live retune searches the three router knobs a DGDR Request can express:
overlap_score_credit, prefill_load_scale and temperature. Replicas stay fixed: the Planner
runs in retune-only mode and never scales.
How it works
- Record. Each frontend writes a
request_endrecord per request to its own directory on a shared ReadWriteMany claim (<segments_dir>/<dgd>/<pod>/). - Cut a window. At
L_k = window end + grace_seconds, the Planner merges the records of the window into one canonical trace file,<windows_dir>/<dgd>/<window_end_ms>-<selection>.jsonl.gz, in a subprocess bounded bycut_budget_seconds.<selection>is a digest of the window’s start, end and cutoff (window end + grace_seconds), so a Planner restarted with anotherinterval_secondsorgrace_secondscuts its own file and creates its own Requests instead of reusing those of a window with the same end. - Search. The Planner splits the router grid into at most
run.max_shardsCartesian shards of at most 100 points and creates one DGDR v1beta2 Request per shard. Each Request replays the window file on the pinnedretune.dgdr.enginewith the replica counts of the DGD spec. One more single-point Request replays a grid point again as a common-random-numbers probe: its score must match the grid’s within a relative error of 1e-9. - Decide. The Planner reads each Run’s Candidates, scores them on
retune.objective, and decides with the same rules as replay retune. A decision is persisted in a Lease before it reaches any router. - Apply. The Planner sets all eight router policy parameters of every frontend router to the decided values, and keeps them there: a manual change to them is reverted.
Windows are aligned to retune.dgdr.phase_seconds + k × interval_seconds in epoch time, so a
restarted Planner continues the same windows. Leadership and state live in two Leases owned by
the DGD, <dgd>-planner-retune and <dgd>-planner-retune-state. The first window after retune is
first enabled is skipped, since its trace is incomplete.
Every DGDR trace Run replays with common random numbers: ordinal request ids and a fixed router seed. A Run’s score therefore does not depend on the other candidates or the Run’s parallelism. This applies to all DGDR trace Runs, not only those the Planner creates.
Prerequisites
- Operator with DGDR v1beta2 traces. Install the platform chart with
dynamo-operator.dgdrV1Beta2.enabled=trueand an operator that acceptsspec.workload.trace. Also setdynamo-operator.dgdrV1Beta2.plannerLiveRetune=trueto grant the Planner ServiceAccount the access it needs (see RBAC). In a cluster-wide install, the operator must also hold the DGDR v1beta2 Run and Candidate permissions of ai-dynamo/dynamo#17308; see RBAC. - Run Job scheduling. The namespace needs a LimitRange for the Run Jobs, and the operator must discover GPUs, through DCGM or GPU discovery with labeled nodes. See Auto Deploy with DGDR.
- A public model. The Run Job has no Hugging Face credentials and no model mount, so
retune.dgdr.modelmust be a public Hugging Face repository id that AISimulate can resolve. - A ReadWriteMany claim in the DGD namespace, dedicated to traces. Create
segments/andwindows/at its root, writable by the user the frontend and Planner containers run as. The Planner writes each window file with mode0644, so the Run Job, which reads it as UID 1000 with supplemental group 65532, can read it whatever user the Planner runs as. - A KV-router frontend with default routing fields, and workers that do not set their own router mode or pass a value the Planner cannot read where an option could stand. See Deployment rules.
- One Planner replica.
Configure the frontend
Add the trace environment and the claim to the frontend container of the DGD. The planner checks
these values against retune.dgdr at startup and whenever the DGD changes.
DYN_REQUEST_TRACE_FILE_PATHis a file prefix directly under<mount_path>/<segments_dir>/$(DYN_PARENT_DGD_K8S_NAME)/$(DYN_POD_NAME)/, such asreq: the part after$(DYN_POD_NAME)/must not contain/.<mount_path>is where the frontend mountsretune.dgdr.claim_name. The operator injectsDYN_PARENT_DGD_K8S_NAME.- Records are dropped without a count for
prompt_embeds, multimodal,n > 1andbest_of > 1requests, and when the writer lags or a batch write fails. - The trace holds unkeyed xxh3 hash chains of the prompts. Anyone who can create pods in the namespace can mount the claim and read them.
See Agent Tracing for the request_end record.
Configure the Planner
Mount the same claim in the Planner container at retune.dgdr.mount_path, and pass a
configuration like the one below with --config:
retune.dgdr fields:
For the other retune fields and the limits that executor: dgdr adds to them, see the
Retune field reference.
Live retune takes its scoring SLA when it starts: retune.sla_ttft_ms and retune.sla_itl_ms,
or the Planner’s ttft_ms and itl_ms where they are unset. An update of ttft_ms or itl_ms
through the
runtime reconfiguration API
that would change that SLA fails with HTTP 422. To change the SLA, restart the Planner with the
new values; to keep ttft_ms and itl_ms changeable at runtime, set both retune SLA fields.
Engine section
retune.dgdr.engine becomes spec.aisim.inputOverrides.engine of every Request, so every
value in it must be a scalar. A {choices: ...} or {range: ...} domain, or an omitted knob that
AISimulate searches by default, would make the Run search engine settings as well.
modeisaggregatedformode: agganddisaggregatedformode: disagg.- Each worker role of the mode (
aggregated, orprefillanddecode) setsparallelism.presetto a list of exactly one entry withtensor,pipeline,attention_data,moe_tensorandmoe_expert, and setsscheduler.max_batched_tokensandscheduler.max_sequences. - The preset entry may also set
prefill_context, but only to1, and must not setdecode_context: the pinned AISimulate recommendation does not run context parallelism. - Do not set
replicasanywhere: the Planner fills them in from the DGD spec at each launch and setsspec.hardware.gpu.budgetto their GPU total. - Write roles the mode does not use as
null, or leave them out. - Set the model and GPU with
retune.dgdr.modelandretune.dgdr.sku, not in the engine. - Leave
backend_versionout to let the pinned AISimulate pick its version forretune.dgdr.sku. If you set it, it must be a version AISimulate accepts for that GPU; otherwise every Run fails withUnlistedQueryVersionError.
Time budget
Each shard must finish before the window’s deadline, L_k + timeout_seconds. A shard of n
points needs
AISimulate evaluates the first candidate alone, hence the 1 +. The Planner rejects a
configuration whose largest grid shard needs more than timeout_seconds, because the baseline
can fall in any shard and a window without a baseline score fails. With the defaults, the 108-point
grid splits into 3 shards of 36 points and needs 900 + 300 + 6 × 1800 = 12000 seconds. Measure
replay time and memory on your trace before relying on these defaults.
Deployment rules
The Planner checks three kinds of rules. None of them stops a running Planner except a configuration error at startup.
Configuration, checked when the Planner starts:
Deployment, checked at startup, when the DGD changes and before every router round. While one fails, the Planner launches no windows, resets the routers to their startup parameters, and retries:
Health, checked every round. While one fails, windows do not launch; nothing is reset:
The Planner only warns when AISimulate does not list the model among its default models (P6).
Roll out
-
Prepare the claim and its directories, then add the frontend trace configuration and the Planner mount.
-
Start with
advisory: true. In advisory mode the Planner records the decision it would make and changes no router value it has not set itself. Watchdynamo_planner_retune_readyand the decision history: -
Set
advisory: false. Withretune.dgdr.promote_last_advisory: true, the Planner applies the last advisory recommendation right away if it is at most one interval old and the configuration has not changed since.
Disable
-
Set
advisory: trueand wait untildynamo_planner_retune_router_convergedis 1 anddynamo_planner_retune_rollback_pendingis 0. The routers are then back at their startup parameters. The mode stored in the state alone does not show that. -
Remove
retunefrom the Planner configuration. -
Remove the trace environment from the frontend.
-
Delete the Planner’s Requests and both Leases. Select the Requests by the DGD’s
metadata.uid: thenvidia.com/planner-retune-dgdlabel holds a hash instead of the name when the name is longer than 63 characters.While the chart still grants the live retune RBAC, a Planner without
retunedoes this on its own: it looks for the Leases in the background after it starts (once more after a transient API error), resets any router the removed retune changed, then deletes the Requests and both Leases. -
Delete
<segments_dir>/<dgd>and<windows_dir>/<dgd>from the claim.
Before upgrading the operator or its CRDs, switch to advisory or disable retune, then delete the retune Requests.
Security
- Frontend admin API.
/router_policyis served on the frontend HTTP port, next to the OpenAI API, without authentication, and is on by default. An Ingress that forwards/exposes it. Deny the admin paths at L7 and allow in-cluster access only from the ingress controller and the Planner. Do not setDYN_DISABLE_FRONTEND_ADMIN_APIon the frontend: the Planner reports a frontend whose/router_policyanswers 404 as not ready. - Ownership. Outside advisory mode the Planner owns the eight router policy parameters and reverts manual changes.
- Trace data. See the privacy note in Configure the frontend.
RBAC
With dynamo-operator.dgdrV1Beta2.enabled=true and
dynamo-operator.dgdrV1Beta2.plannerLiveRetune=true, the platform chart adds these rules to the
Planner Role (namespace-restricted installs) and ClusterRole (cluster-wide installs). Both values
default to false; dgdrV1Beta2.enabled alone grants the Planner nothing new.
The chart has one Planner role for the whole install, so Planners without retune get these
rules too. The Planner also lists pods with its existing permission. These rules are namespace-wide: a
Role or a RoleBinding of the ClusterRole has no resourceNames, because the Planner creates its
Leases and Requests under per-DGD names. As a result, any workload that runs as the Planner
ServiceAccount can:
- create DGDR Requests, which start Run Jobs, in its namespace;
- read, update or delete any Lease in its namespace, not only the two retune Leases. In a namespace-restricted install, the Planner Role lives in the release namespace, which by default also holds the operator’s leader-election Lease, so such a workload can disrupt operator leader election.
In a cluster-wide install, the operator binds the Planner ClusterRole into each DGD namespace with
a RoleBinding, and Kubernetes lets it bind only permissions it holds itself. Set
dynamo-operator.dgdrV1Beta2.plannerLiveRetune=true there only with an operator whose own role
grants get on dynamographdeploymentruns and list on dynamographdeploymentcandidates,
which the DGDR v1beta2 operator change in
ai-dynamo/dynamo#17308 adds.
Without it, the API server rejects the Planner RoleBinding in every namespace that does not have
one yet, and the DGDs there fail to reconcile their Planner RBAC, with or without live retune.
Metrics
The Planner exports these on metric_reporting_prometheus_port: