dynamo-graph-deployment-request.mdx
September 10, 2026 · View on GitHub
A DynamoGraphDeploymentRequest (DGDR) is Dynamo's deploy-by-intent generator for DynamoGraphDeployment (DGD) resources. You describe what you want to run and your performance targets; the profiler determines a configuration and produces the DGD that serves traffic.
For the task-oriented walkthrough — authoring a request step by step — see Auto Deploy with DGDR. For ready-to-copy manifests, see DGDR Templates.
This page documents the nvidia.com/v1beta1 API — the served, storage version.
Spec reference
Only model is required; every other field has a default or is auto-detected.
Allowed values:
Allowed values:
Profiler image version compatibility
When spec.image is omitted, the operator defaults it on creation to
nvcr.io/nvidia/ai-dynamo/dynamo-planner:<operatorVersion>. The operator
requires operatorVersion to be valid semantic versioning, so the default
image has a parseable version tag.
The DGDR-level spec.runtimeVersionOverride supplies a default for generated
DGD components. After the profiler materializes the DGD and applies
spec.overrides.dgd, the operator copies the DGDR value only to components that
do not already have an explicit override. This behavior applies across profiler
versions. Profilers through Dynamo 1.3.0 may discard the field while parsing the
DGDR, but the operator reapplies the default from the stored DGDR.
Set spec.runtimeVersionOverride when an effective generated component image
uses a non-semantic-version tag or digest, or when its tag does not identify the
intended Dynamo runtime version. The DGDR value also covers images replaced
through spec.overrides.dgd when that component does not set its own
runtimeVersionOverride. An explicit component-level value takes precedence.
While a DGDR has autoApply: false, you may set or change
runtimeVersionOverride during Profiling or Ready. After it reaches
Ready, you may enable autoApply, either separately or while changing the
override. The operator applies the current value while creating the new DGD.
These updates do not modify status.profilingResults.selectedConfig or the
nvidia.com/generated-dgd-spec annotation. Other spec updates remain
forbidden after profiling starts.
When the DGDR-level field is unset, each effective generated DGD component
follows the DGD component rules independently. An overridden image without a
parseable semantic-version tag requires runtimeVersionOverride on that
component.
Profilers through Dynamo 1.3.0 discard the embedded DGD override's apiVersion
and kind, then directly merge the remaining dictionary into a generated
v1alpha1 DGD. Raw storage preserves the override fields but does not convert
between DGD schemas. Use a v1alpha1-shaped override under spec.services; a
v1beta1 spec.components override is not translated into the generated
service.
<span className="enum-values"><span className="enum-label">Allowed values:</span> <Badge intent="note" minimal>latency</Badge> <Badge intent="note" minimal>throughput</Badge></span>
<a href="https://pkg.go.dev/k8s.io/apimachinery/pkg/runtime#RawExtension" target="_blank">runtime.RawExtension</a>
Overrides
<a href="https://pkg.go.dev/k8s.io/api/batch/v1#JobSpec" target="_blank">batch/v1.JobSpec</a>
<a href="https://pkg.go.dev/k8s.io/apimachinery/pkg/runtime#RawExtension" target="_blank">runtime.RawExtension</a>
Planner
spec.features.planner is a PlannerConfig object, passed through to the Planner service without field-level validation; the Planner validates it at startup. Setting it (non-null) enables the planner in the generated DGD. The same object is documented standalone at Planner Configuration; its fields are reproduced here. Nested list-and-object types are expanded under Additional Types. All fields are optional.
Core settings
Allowed values:
Allowed values:
Allowed values:
Optimization target
Allowed values:
Performance model and pre-deployment sweeping
Allowed values:
GPU budget
Throughput-based scaling
Allowed values:
Load-based scaling
Load prediction
Allowed values:
Prometheus metrics
These fields default from environment variables and are excluded from serialized output.
Advisory and diagnostics
Scheduling and plugin pipeline
<span className="enum-values"><span className="enum-label">Allowed values:</span> <Badge intent="note" minimal>static_secret</Badge> <Badge intent="note" minimal>allow_unauthenticated</Badge></span>
</ParamField>
<ParamField path="static_secrets" type="object" default="{}">
Map of `secret_value` to `subject_label`. Populate from a mounted Kubernetes Secret rather than hard-coding in the ConfigMap.
</ParamField>
Generated DGD overrides
spec.overrides.dgd is a partial, versioned DGD. It does not define or extend
the profiler's candidate topology. Thorough profiling merges the override into
each generated benchmark candidate before measurement and into the
interpolation deployment. Every search strategy merges it into the final
generated DGD. Use apiVersion: nvidia.com/v1beta1 and
kind: DynamoGraphDeployment for new overrides. Components, pod-template
containers, and container environment variables merge by name; atomic lists
such as graph-level spec.env and container args replace their generated
values.
To permit custom model repository code without depending on the selected topology, set
spec.overrides.trustRemoteCode: true. The profiler applies --trust-remote-code to every generated
vLLM or SGLang worker after the component topology is known. Enable this setting only for model
repositories you trust.
Generated component names
An entry in spec.overrides.dgd.spec.components must use the exact, case-sensitive
component name from the generated DGD. These are DGD component names, not Kubernetes
Service resource names. The current profiler templates generate these components:
| Backend | Aggregated | Disaggregated |
|---|---|---|
| vLLM | Frontend, worker | Frontend, decode, prefill |
| SGLang | Frontend, decode | Frontend, decode, prefill |
| TensorRT-LLM | Frontend, TRTLLMWorker | Frontend, decode, prefill |
Setting spec.features.mocker.enabled: true replaces the inference workers with decode and
prefill mocker components. Setting spec.features.planner adds a Planner component.
Add overrides before profiling starts. The DGDR spec becomes immutable during profiling, so you
cannot inspect selectedConfig and then add overrides to the same resource. To inspect the names
generated by a specific Dynamo release, follow the
discovery workflow,
then recreate the DGDR with the required overrides.
For example, set an environment variable on one generated component:
apiVersion: nvidia.com/v1beta1
kind: DynamoGraphDeploymentRequest
metadata:
name: qwen3-sglang
spec:
model: Qwen/Qwen3-30B-A3B
backend: sglang
overrides:
dgd:
apiVersion: nvidia.com/v1beta1
kind: DynamoGraphDeployment
spec:
components:
- name: decode
podTemplate:
spec:
containers:
- name: main
env:
- name: TRITON_PTXAS_PATH
value: /usr/local/cuda/bin/ptxas
Overrides can modify only components present in the generated DGD. An unresolved spec.components or
spec.services name causes DGD materialization to fail. A recognized deprecated name may be
translated to the corresponding component in the selected topology with a warning. An override
cannot add deployment topology. Labels and annotations merge, metadata.name selects the final DGD
name, and other identity metadata is ignored. status, null values for typed fields, and field
deletion are not supported.
To add flags to a container already present in the generated DGD, set $patch.args to append on
that named container:
spec:
overrides:
dgd:
apiVersion: nvidia.com/v1beta1
kind: DynamoGraphDeployment
spec:
components:
- name: Frontend
podTemplate:
spec:
containers:
- name: main
$patch:
args: append
args:
- --router-mode
- kv
The only supported modifier is args: append, and its args list must contain at least one
non-empty string. The target container and its args list must already be present in the generated
blueprint. The profiler blueprints define the complete default CLI for Frontend/main, so the
example preserves python3 -m dynamo.frontend and appends the KV router flags. The override helper
combines the argument lists and removes $patch before returning the final DGD. Without $patch,
specifying args retains the standard replacement behavior and requires the complete desired list.
For worked examples, see DGDR Templates. For router configuration and EPP topologies, see the Router Guide and Gateway API Inference Extension.
SKU format
hardware.gpuSku uses lowercase underscore format (h100_sxm, not H100-SXM5-80GB).
Allowed values:
Status
The operator maintains observed state under status. See Lifecycle for how phase and profilingPhase progress, and for the full condition-type list.
Allowed values:
Allowed values:
<a href="https://pkg.go.dev/k8s.io/apimachinery/pkg/runtime#RawExtension" target="_blank">runtime.RawExtension</a>
Additional Types
Nested struct types referenced by the fields above, broken out here to keep the field lists shallow. Types prefixed batch/v1., metav1., or runtime. are standard Kubernetes types and link to their Go package documentation instead of being expanded.
ParetoConfig
Deprecated compatibility type for status.profilingResults.pareto. Current
profiling runs do not populate this type.
PickedParallelConfig
A parallelism pick emitted by AIConfigurator. Referenced by features.planner.aic_perf_model.prefill_pick / decode_pick and by AICInterpolationSpec.
AICInterpolationSpec
Everything the Planner needs to reproduce a rapid-mode AIC sweep. Written by the profiler onto the Planner ConfigMap; not normally hand-authored. Referenced by features.planner.aic_interpolation.
ExternalPluginEntry
One static external-plugin registration under features.planner.scheduling.external_plugins. Rejects unknown fields.
Allowed values: grpc://host:port; inproc:// is rejected here.
0.0 runs every tick; a positive value throttles to every N seconds. Must be 0 or greater.
HOLD_LAST reuses the cached result; ACCEPT_WHEN_IDLE treats the plugin as no-opinion when not due. Accepts the name (case-insensitive) or its integer value.
Allowed values: predictions, observations.traffic) that must be set for the plugin to fire on a tick. Empty means no gating.
needs. 0.0 uses scale_interval freshness; a positive value aggregates over the last N seconds and must be an integer multiple of scale_interval_seconds.
InProcessPluginSpec
One in-process plugin under features.planner.plugin_registration.in_process_plugins. Rejects unknown fields.
Allowed values: needs. Must be 0.0 or a positive integer multiple of scale_interval_seconds.
Lifecycle
When you create a DGDR, it progresses through these phases (status.phase):
| Phase | What is happening |
|---|---|
Pending | Spec validated; operator is discovering GPU hardware and preparing the profiling job |
Profiling | Profiling job running — sub-phases in status.profilingPhase: Initializing, SweepingPrefill, SweepingDecode, SelectingConfig, BuildingCurves, GeneratingDGD, Done |
Ready | Profiling complete; optimal config stored in status.profilingResults.selectedConfig. Waits for manual application or for autoApply to be enabled. |
Deploying | Creating the DGD (only when autoApply: true) |
Deployed | DGD is running and healthy |
Failed | Unrecoverable error — profiling failures are not retried (backoffLimit: 0); check events and conditions for details |
Conditions
The operator maintains these conditions on status.conditions:
| Condition | Meaning |
|---|---|
Validation | Spec validation passed or failed |
Profiling | Profiling job is running, succeeded, or failed |
SpecGenerated | Generated DGD spec is available |
DeploymentReady | DGD is deployed and healthy |
Succeeded | Aggregate condition — true when the DGDR has reached its target state |
Monitoring
# Watch phase transitions
kubectl get dgdr my-model -n $NAMESPACE -w
# Detailed status, conditions, and events
kubectl describe dgdr my-model -n $NAMESPACE
# Profiling sub-phase
kubectl get dgdr my-model -n $NAMESPACE -o jsonpath='{.status.profilingPhase}'
# Profiling job logs
PROFILING_JOB=$(kubectl get dgdr my-model -n "$NAMESPACE" -o jsonpath='{.status.profilingJobName}')
kubectl logs -f "job/${PROFILING_JOB}" -c profiler -n "$NAMESPACE"
# View generated DGD spec (when autoApply: false)
kubectl get dgdr my-model -n $NAMESPACE \
-o jsonpath='{.status.profilingResults.selectedConfig}' | python3 -m json.tool
Resource ownership
- The DGDR does not set an owner reference on the DGD it creates. Deleting a DGDR does not delete the DGD — it persists independently so it can continue serving traffic.
- The relationship is tracked via labels:
dgdr.nvidia.com/nameanddgdr.nvidia.com/namespace. - Additional resources (planner ConfigMaps) are created in the same namespace and labeled with
dgdr.nvidia.com/name.
Known issues
- PCIe profiler data not yet available. See the PCIe callout under SKU format.