Close Menu
NCIJ Network NCIJ Network
    What's Hot

    Saipem-Subsea7 merger under the microscope as EU flags competition concerns

    July 24, 2026

    Shahed-Type Drones Filmed During Mali Village Attacks

    July 24, 2026

    How a U.S. Ground Operation in Iran Could Unfold

    July 24, 2026
    Facebook X (Twitter) Instagram
    Trending
    • Saipem-Subsea7 merger under the microscope as EU flags competition concerns
    • Shahed-Type Drones Filmed During Mali Village Attacks
    • How a U.S. Ground Operation in Iran Could Unfold
    • Angela Rayner is not the new health secretary – Full Fact
    • Life without refrigerators: Gaza residents fight heat and food spoilage | Energy News
    • Dvorkovich faces endgame after EU agrees new Russia war sanctions
    • Reform councillors told to call donations inquiry ‘establishment stitch-up’ | Reform UK
    • Chris Mason: What his first week in power tells us about Andy Burnham
    • About
      • Our Team
      • Editorial Policy
      • Editorial Independence
      • International Support
    • Trust & Standards
      • AI Usage Policy
      • Conflict of Interest Policy
      • Corrections Policy
      • Ethics Policy
      • Fact-Checking Policy
      • Source Protection
    • Get Involved
      • Guide for Sources
      • Support Independent Journalism
    • Legal
      • Cookie Policy
      • Privacy Policy
      • Terms of Use
    Facebook X (Twitter) Instagram
    NCIJ Network NCIJ Network
    Friday, July 24
    • Home
    • World
    • Ai
    • Business
    • Politics
    • Health
    • Crypto
    • Science
    • Technology
    • Cybersecurity
    • Defense & Security
    • Economy
    • Energy
    • Europe
    • More
      • Fact Check
      • Investigations
      • Opinion & Analysis
      • Environment
    NCIJ Network NCIJ Network
    Home»Artificial Intelligence

    Validating Distributed LLM Serving Benchmarks with NVIDIA srt-slurm, SLURM Recipes, Parameter Sweeps, and Pareto Analysis

    NCIJ NETWNCIJ NETWORKBy NCIJ NETWNCIJ NETWORKJuly 23, 2026 Artificial Intelligence No Comments7 Mins Read
    Share
    Facebook Twitter LinkedIn Pinterest Email

    In this tutorial, we explore NVIDIA’s srt-slurm framework and learn how we use srtctl to convert declarative YAML configurations into reproducible SLURM benchmark workflows for distributed LLM serving. We set up the project in Google Colab, inspect its internal architecture, define a cluster configuration, dry-run built-in and custom recipes, and model a disaggregated prefill-and-decode deployment for DeepSeek-R1. We also generate parameter sweeps, interact with the typed Python API, validate expanded configurations, and analyze simulated benchmark results through a throughput-versus-latency Pareto frontier. Although Colab does not provide a real SLURM environment, we use it as a practical development workspace to understand, validate, and prepare production-grade benchmark recipes before we submit them to an actual GPU cluster.

    import os, sys, subprocess, textwrap, json, shutil, importlib
    from pathlib import Path
    def run(cmd, check=True, quiet=False):
       """Run a shell command, stream output."""
       print(f"n$ {cmd}")
       r = subprocess.run(cmd, shell=True, text=True, capture_output=True)
       out = (r.stdout or "") + (r.stderr or "")
       if not quiet:
           print(out[-6000:])
       if check and r.returncode != 0:
           raise RuntimeError(f"Command failed ({r.returncode}): {cmd}")
       return out
    def section(title):
       print("n" + "═"*78 + f"n {title}n" + "═"*78)
    section("1. Install srt-slurm")
    REPO = Path("/content/srt-slurm") if Path("/content").exists() else Path.cwd()/"srt-slurm"
    if not REPO.exists():
       run(f"git clone --depth 1 https://github.com/NVIDIA/srt-slurm.git {REPO}", quiet=True)
    run(f"{sys.executable} -m pip install -q -e {REPO}", quiet=True)
    sys.path.insert(0, str(REPO / "src"))
    importlib.invalidate_caches()
    os.chdir(REPO)
    run("srtctl --help")
    

    We prepare the Colab environment by importing the required modules and defining reusable helper functions for command execution and section formatting. We clone the NVIDIA srt-slurm repository, install it in editable mode, and expose its source directory to the active Python runtime. We then switch to the repository directory and verify that the srtctl command-line interface is installed correctly.

    section("2. Repository architecture")
    print(textwrap.dedent("""
       src/srtctl/
         cli/        submit.py (apply/dry-run/preflight/monitor), do_sweep, interactive
         core/       schema.py (typed config), sweep.py, slurm.py (sbatch gen),
                     validation.py, health.py, topology.py, fingerprint.py
         backends/   sglang.py, trtllm.py, vllm.py, mocker.py  ← engine adapters
         frontends/  Dynamo / router frontends
         templates/  Jinja2 → sbatch + orchestrator scripts
       recipes/      ready-made benchmarks per platform (gb200-fp4, h100, b200-fp8,
                     qwen3-32b, dsv4-pro, mocker smoke tests, ...)
       analysis/     srtlog (log parsers) + Streamlit dashboard (Pareto, latency...)
       docs/         sweeps.md, profiling.md, analyzing.md, config-reference.md
    """))
    for d in ["recipes", "docs"]:
       print(f"{d}/ →", ", ".join(sorted(p.name for p in (REPO/d).iterdir()))[:300])
    section("3. Cluster configuration (srtslurm.yaml)")
    (REPO/"srtslurm.yaml").write_text(textwrap.dedent("""
       cluster: "colab-demo"
       default_account: "demo-account"
       default_partition: "gpu"
       default_time_limit: "01:00:00"
       gpus_per_node: 4
       use_gpus_per_node_directive: true
       use_segment_sbatch_directive: true
       containers:
         dynamo-sglang: "/containers/dynamo-sglang.sqsh"
         lmsysorg+sglang+v0.5.5.post2.sqsh: "/containers/sglang-v0.5.5.sqsh"
       model_paths:
         deepseek-r1: "/models/DeepSeek-R1"
    """))
    print((REPO/"srtslurm.yaml").read_text())
    

    We inspect the repository structure to understand how srtctl organizes its command-line tools, schemas, backends, templates, recipes, and analysis components. We then create a local srtslurm.yaml file containing simulated cluster defaults, container aliases, GPU settings, and model paths. We use this configuration to resolve recipe references in Colab without requiring access to an actual SLURM cluster.

    section("4. Dry-run: mocker smoke test → generated sbatch script")
    run("srtctl dry-run -f recipes/mocker/agg.yaml", check=False)
    section("5. Custom disaggregated recipe (prefill/decode split)")
    (REPO/"my-disagg.yaml").write_text(textwrap.dedent("""
       name: "colab-disagg-demo"
       model:
         path: "deepseek-r1"
         container: "lmsysorg+sglang+v0.5.5.post2.sqsh"
         precision: "fp8"
       resources:
         gpu_type: "gb200"
         gpus_per_node: 4
         prefill_nodes: 1
         decode_nodes: 2
         prefill_workers: 1
         decode_workers: 2
       backend:
         prefill_environment: { PYTHONUNBUFFERED: "1" }
         decode_environment:  { PYTHONUNBUFFERED: "1" }
         sglang_config:
           prefill:
             served-model-name: "deepseek-ai/DeepSeek-R1"
             model-path: "/model/"
             trust-remote-code: true
             kv-cache-dtype: "fp8_e4m3"
             tensor-parallel-size: 4
             disaggregation-mode: "prefill"
           decode:
             served-model-name: "deepseek-ai/DeepSeek-R1"
             model-path: "/model/"
             trust-remote-code: true
             kv-cache-dtype: "fp8_e4m3"
             tensor-parallel-size: 4
             disaggregation-mode: "decode"
       benchmark:
         type: "sa-bench"
         isl: 1024
         osl: 1024
         concurrencies: [64, 128, 256]
         req_rate: "inf"
    """))
    run("srtctl dry-run -f my-disagg.yaml", check=False)
    

    We dry-run the built-in mocker recipe to examine how srtctl validates configurations and generates SLURM submission artifacts without executing a real benchmark. We then define an advanced DeepSeek-R1 recipe that separates prefill and decode workloads across independent node and worker pools. We validate this disaggregated SGLang configuration through another dry run and inspect how the serving parameters are translated into job scripts.

    section("6. Parameter sweep (grid search) — dry-run + expansion on disk")
    run("srtctl dry-run -f examples/example-sweep.yaml", check=False)
    sweep_dirs = sorted((REPO/"dry-runs").glob("example-sweep_sweep_*"))
    if sweep_dirs:
       latest = sweep_dirs[-1]
       print("Per-job configs generated by the sweep expander:")
       for p in sorted(latest.rglob("config.yaml")):
           print("  ", p.relative_to(REPO))
    section("7. Programmatic use of srtctl's Python API")
    import yaml
    from srtctl.core.config import load_config
    from srtctl.core.sweep import generate_sweep_configs, expand_template
    from srtctl.core.schema import BenchmarkType, Precision, GpuType
    cfg = load_config("my-disagg.yaml")
    print(f"Loaded  : {cfg.name}")
    print(f"Model   : {cfg.model.path} ({cfg.model.precision}) on {cfg.resources.gpu_type}")
    print(f"Layout  : {cfg.resources.prefill_nodes}P + {cfg.resources.decode_nodes}D nodes, "
         f"{cfg.resources.gpus_per_node} GPUs/node")
    print(f"Bench   : {cfg.benchmark.type} isl={cfg.benchmark.isl} osl={cfg.benchmark.osl} "
         f"concurrencies={cfg.benchmark.concurrencies}")
    print(f"Enums   : benchmarks={[b.value for b in BenchmarkType]}")
    print(f"          precisions={[p.value for p in Precision]}, gpus={[g.value for g in GpuType]}")
    raw_sweep = yaml.safe_load(Path("examples/example-sweep.yaml").read_text())
    jobs = generate_sweep_configs(raw_sweep)
    print(f"nSweep expands to {len(jobs)} jobs:")
    for job_cfg, params in jobs:
       pf = job_cfg["backend"]["sglang_config"]["prefill"]
       print(f"  {params}  → chunked-prefill-size={pf['chunked-prefill-size']}, "
             f"max-total-tokens={pf['max-total-tokens']}")
    print("nTemplate substitution:",
         expand_template({"flag": "{x}", "n": "{y}"}, {"x": 4096, "y": 2}))
    

    We execute the example parameter sweep and inspect the individual job configurations created from its Cartesian search space. We load our custom recipe through the typed Python API and examine its model, precision, GPU topology, benchmark settings, and supported enumeration values. We also programmatically expand sweep templates and verify how each parameter combination affects the generated backend configuration.

    section("8. Analysis: Pareto frontier from (simulated) benchmark results")
    import numpy as np, matplotlib.pyplot as plt
    rng = np.random.default_rng(0)
    def simulate(variant, base_tps, base_itl):
       rows = []
           tps_gpu = base_tps * c / (c + 90) * rng.uniform(.97, 1.03)
           itl     = base_itl * (1 + c/220) * rng.uniform(.97, 1.03)
           rows.append({"variant": variant, "concurrency": c,
                        "tok_s_gpu": tps_gpu, "itl_ms": itl})
       return rows
    results = simulate("chunked=4096", 260, 9.5) + simulate("chunked=8192", 300, 11.5)
    print(json.dumps(results[:3], indent=2), "...")
    plt.figure(figsize=(8, 5))
    for variant in ("chunked=4096", "chunked=8192"):
       pts = [(r["itl_ms"], r["tok_s_gpu"], r["concurrency"])
              for r in results if r["variant"] == variant]
       xs, ys, cs = zip(*pts)
       plt.plot(xs, ys, "o-", label=variant)
       for x, y, c in pts:
           plt.annotate(str(c), (x, y), fontsize=7, xytext=(3, 3),
                        textcoords="offset points")
    plt.xlabel("Inter-token latency (ms/token)  →  worse")
    plt.ylabel("Throughput (tokens/s/GPU)  →  better")
    plt.title("Pareto frontier: sweep variants (points labeled by concurrency)")
    plt.legend(); plt.grid(alpha=.3); plt.tight_layout(); plt.show()
    

    We simulate benchmark observations for two chunked-prefill variants across increasing concurrency levels. We calculate representative throughput per GPU and inter-token latency values to model the saturation and latency growth commonly observed in distributed serving systems. We then visualize these results in a Pareto-style plot to compare throughput and responsiveness across configurations.

    section("9. Next steps on a real cluster")
    print(textwrap.dedent("""
       make setup ARCH=aarch64|x86_64
       srtctl preflight -f my-disagg.yaml
       srtctl apply -f my-disagg.yaml
       srtctl apply -f sweep.yaml
       srtctl monitor
       uv run streamlit run analysis/dashboard/app.py
       srtctl diff runA runB
       Logs land in outputs/{JOB_ID}/logs/;  analysis/srtlog parses them
       (NodeAnalyzer, RunLoader) for programmatic post-processing.
       Reproducibility tip (srtctl also prints this in dry-run): add an
       identity: block to your recipe — HF model repo + revision, container
       image URI, and framework versions — so srtctl can verify the runtime
       matches your declaration at job start.
    """))
    print("✅ Tutorial complete.")
    

    We outline the production workflow that we follow when transferring validated recipes from Colab to a real SLURM-based GPU cluster. We review the commands used for environment setup, preflight validation, job submission, sweep execution, monitoring, dashboard analysis, and experiment comparison. We also emphasize reproducibility by declaring model revisions, container identities, and framework versions inside each benchmark recipe.

    In conclusion, we built a complete understanding of how srtctl structures, validates, expands, and prepares distributed LLM-serving benchmarks for execution on SLURM infrastructure. We moved from basic installation and repository inspection to advanced disaggregated serving configurations, Cartesian parameter sweeps, programmatic schema access, and benchmark-result analysis. We also saw how dry runs expose generated job artifacts and help us detect configuration problems before expensive cluster resources are allocated. With this workflow in place, we can confidently transfer our validated recipes to a real NVIDIA GPU cluster, run preflight checks, submit benchmark jobs, monitor execution, compare experiment fingerprints, and analyze performance trade-offs in a reproducible manner.


    Check out the Full Code here. Also, feel free to follow us on Twitter and don’t forget to join our 150k+ML SubReddit and Subscribe to our Newsletter. Wait! are you on telegram? now you can join us on telegram as well.

    Need to partner with us for promoting your GitHub Repo OR Hugging Face Page OR Product Release OR Webinar etc.? Connect with us


    Sana Hassan, a consulting intern at Marktechpost and dual-degree student at IIT Madras, is passionate about applying technology and AI to address real-world challenges. With a keen interest in solving practical problems, he brings a fresh perspective to the intersection of AI and real-life solutions.

    Analysis Benchmarks Distributed LLM Nvidia Parameter Pareto Recipes Serving SLURM srtslurm Sweeps Validating
    NCIJ NETWNCIJ NETWORK
    • Website

    Keep Reading

    Meta, Microsoft, Nvidia, IBM, and others back open-weight AI

    OpenAI pushes ChatGPT into patient health records

    OpenAI Presence: enterprise AI agents, engineers included

    How to Build an End-to-End OCR Pipeline with Baidu’s Unlimited-OCR for High-Resolution Images and Multi-Page PDF Parsing

    AMD takes on Nvidia with its Helios AI rack-scale system

    You Didn’t Get the AI Model You Paid For

    Add A Comment
    Leave A Reply Cancel Reply

    Editors Picks

    Saipem-Subsea7 merger under the microscope as EU flags competition concerns

    July 24, 2026

    Shahed-Type Drones Filmed During Mali Village Attacks

    July 24, 2026

    How a U.S. Ground Operation in Iran Could Unfold

    July 24, 2026

    Angela Rayner is not the new health secretary – Full Fact

    July 24, 2026
    Latest Posts

    Trump slaps 50% tariffs on Canada and Carney vows to ‘intensify’ trade talks

    July 21, 2026

    How Two Brothers Dug for Dead Relatives: With a Shovel and a Kitchen Knife

    July 21, 2026

    Chile floods: Towns evacuated following heavy rain in Coquimbo

    July 21, 2026

    Subscribe to News

    Get the latest sports news from NewsSite about world, sports and politics.

    NCIJ Network is an independent digital news platform delivering trusted investigative journalism, European and global news, in-depth analysis, and fact-based reporting with accuracy, transparency, and integrity.

    Facebook X (Twitter) Instagram Pinterest YouTube

    Saipem-Subsea7 merger under the microscope as EU flags competition concerns

    July 24, 2026

    Shahed-Type Drones Filmed During Mali Village Attacks

    July 24, 2026

    How a U.S. Ground Operation in Iran Could Unfold

    July 24, 2026

    Subscribe to Updates

    Get the latest creative news from FooBar about art, design and business.

    Type above and press Enter to search. Press Esc to cancel.