# Interactive mode - browse recipes, preview, and submit
srtctl
# Submit a job directly
srtctl apply -f recipes/gb200-fp8/sglang-1p4d.yaml
# Preview without submitting
srtctl dry-run -f config.yamlsrtctl
# or explicitly:
srtctl -i? Select a recipe:
── gb200-fp8 ──
sglang-1p4d.yaml
sglang-2p8d.yaml
dynamo-router.yaml
── h100-fp8 ──
baseline.yaml
high-throughput.yaml
──────────────
📁 Browse for file...📋 Configuration
┌─────────────────────────────────────────────────────────────┐
│ deepseek-r1-1p4d │
└─────────────────────────────────────────────────────────────┘
deepseek-r1-1p4d
├── 📦 Model
│ ├── path: deepseek-r1
│ ├── container: latest
│ └── precision: fp8
├── 🖥️ Resources
│ ├── gpu_type: gb200
│ ├── prefill: 1 workers
│ ├── decode: 4 workers
│ └── gpus_per_node: 4
├── 📊 Benchmark
│ ├── type: sa-bench
│ ├── isl: 1024, osl: 1024
│ └── concurrencies: [128, 256, 512]
└── 🔄 Sweep Parameters (if present)
├── chunked_prefill_size: [4096, 8192]
└── max_total_tokens: [8192, 16384]? What would you like to do?
🚀 Submit job(s) - Submit to SLURM cluster
👁️ Preview sbatch script - View generated SLURM script with syntax highlighting
✏️ Modify parameters - Interactively change values before submission
🔍 Dry-run - Full dry-run preview without submission
📁 Select different config - Choose a different recipe
❌ Exit - Exit interactive mode┌─ Generated sbatch Script ────────────────────────────────────────────────────┐
│ 1 │ #!/bin/bash │
│ 2 │ #SBATCH --job-name=deepseek-r1-1p4d │
│ 3 │ #SBATCH --nodes=5 │
│ 4 │ #SBATCH --gpus-per-node=4 │
│ 5 │ #SBATCH --time=04:00:00 │
│ 6 │ #SBATCH --partition=batch │
│ 7 │ ... │
└──────────────────────────────────────────────────────────────────────────────┘Modify Configuration
Press Enter to keep current value, or type new value
? Job name [deepseek-r1-1p4d]: my-experiment
? Prefill workers [1]:
? Decode workers [4]: 8
? Input sequence length [1024]: 2048
? Output sequence length [1024]: 2048┌─ Sweep Jobs ────────────────────────────────────────────────────────────────┐
│ # │ Job Name │ Parameters │
├────┼────────────────────────────────────┼───────────────────────────────────┤
│ 1 │ deepseek-r1-1p4d_cps4096_mtt8192 │ chunked_prefill_size=4096, │
│ │ │ max_total_tokens=8192 │
│ 2 │ deepseek-r1-1p4d_cps4096_mtt16384 │ chunked_prefill_size=4096, │
│ │ │ max_total_tokens=16384 │
│ 3 │ deepseek-r1-1p4d_cps8192_mtt8192 │ chunked_prefill_size=8192, │
│ │ │ max_total_tokens=8192 │
│ 4 │ deepseek-r1-1p4d_cps8192_mtt16384 │ chunked_prefill_size=8192, │
│ │ │ max_total_tokens=16384 │
└─────────────────────────────────────────────────────────────────────────────┘
Total jobs: 4? Submit to SLURM? (y/N)$ srtctl
> Select: gb200-fp8/sglang-1p4d.yaml
> Action: 👁️ Preview sbatch script (review generated script)
> Action: 🔍 Dry-run (full dry-run)
> Action: 📁 Select different config (try another)$ srtctl
> Select: gb200-fp8/sglang-1p4d.yaml
> Action: ✏️ Modify parameters
> Change decode_workers: 8
> Change isl: 2048
> Action: 🚀 Submit job(s)
> Confirm: y$ srtctl
> Select: configs/my-sweep.yaml
> View: Sweep table showing 16 jobs
> Action: 🔍 Dry-run (saves all expanded configs to dry-runs/)
> Review generated configs
> Action: 🚀 Submit job(s)srtctl apply -f <config.yaml> [options]# Submit single job
srtctl apply -f recipes/gb200-fp8/sglang-1p4d.yaml
# Submit sweep (auto-detected from sweep: section)
srtctl apply -f configs/my-sweep.yaml
# Submit all override variants (base + overrides)
srtctl apply -f config.yaml
# Submit only a specific override variant
srtctl apply -f config.yaml:override_tp64
# Submit only the base config (ignore overrides)
srtctl apply -f config.yaml:base
# With tags
srtctl apply -f config.yaml --tags "experiment-1,baseline"srtctl dry-run -f <config.yaml> [options]# Preview single job - shows sbatch script
srtctl dry-run -f config.yaml
# Preview sweep - shows job table and saves configs
srtctl dry-run -f sweep-config.yaml
# Preview all override variants
srtctl dry-run -f override-config.yaml
# Preview a specific override variant
srtctl dry-run -f override-config.yaml:override_tp64srtctl resolve-override -f <config.yaml> [options]# Write all variants next to the source file
srtctl resolve-override -f config.yaml
# Write a single override variant
srtctl resolve-override -f config.yaml:override_lowmem
# Print to stdout
srtctl resolve-override -f config.yaml:override_lowmem --stdout
# Inspect a single zip variant
srtctl resolve-override -f config.yaml:zip_override_tp_sweep[0] --stdoutoutputs/<job_id>/
├── config.yaml # Copy of submitted config
├── sbatch_script.sh # Generated SLURM script
└── <job_id>.json # Job metadatasweep:
chunked_prefill_size: [4096, 8192]
max_total_tokens: [8192, 16384]# Submit all variants (base + all overrides)
srtctl apply -f override-config.yaml
# Submit only the tp64 override variant
srtctl apply -f override-config.yaml:override_tp64
# Submit only the base (ignoring overrides)
srtctl apply -f override-config.yaml:basesrtctl resolve-override -f override-config.yaml --stdout# Find the full srun commands for a running job
grep "srun command" outputs/<job_id>/logs/sweep_<job_id>.log
# Per-worker env vars and inner commands are also logged
grep -E "Env:|Command:" outputs/<job_id>/logs/sweep_<job_id>.log