Skip to content

perf: add GB200 Qwen3.5 FP4 SGLang MTP AgentX - #2568

Merged
cquil11 merged 6 commits into
mainfrom
agent/gb200-qwen35-sglang-mtp-agentx
Aug 12, 2026
Merged

perf: add GB200 Qwen3.5 FP4 SGLang MTP AgentX#2568
cquil11 merged 6 commits into
mainfrom
agent/gb200-qwen35-sglang-mtp-agentx

Conversation

@cquil11

@cquil11 cquil11 commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds a new GB200 Qwen3.5-397B-A17B NVFP4 SGLang MTP AgentX submission using stable SGLang v0.5.17-cu130 and NVIDIA srt-slurm v1.0.45.

The complete agentx-fast discovery matrix mirrored the useful B200/B300 single-node search space and extended beyond the expected knee. Its 30 throughput points all completed successfully after failed-only infrastructure retries.

  • TP4 without offload: c1, c4, c8, c12, c16, c20, c32, c40
  • TP2/EP2 without offload: c4, c8, c16, c20, c24
  • TP4 HiCache: c48, c56, c64, c72

These 17 measured Pareto points form the official full sweep. TP2 HiCache and the remaining sampled points were dominated and removed. HiCache uses the established bounded DRAM convention rather than an ad hoc memory override.

Broad fast run: https://github.com/SemiAnalysisAI/InferenceX/actions/runs/31563972895

Metrics correctness

  • SGLang launches with metrics and cache reporting enabled.
  • srt-slurm v1.0.45 supplies the logical aggregate worker metrics endpoint to the custom benchmark.
  • AIPERF_REQUIRED_SERVER_METRIC_PREFIX is sglang:, so missing or empty server metrics fail final validation.
  • The new SGLang synthetic-acceptance injector applies only to throughput; eval remains real MTP.

Validation

  • the three retained recipes parse and dry-run with NVIDIA srt-slurm v1.0.45
  • 15 targeted srt-slurm custom benchmark/logical endpoint tests pass
  • 231 InferenceX matrix-generator tests pass
  • generated official matrix contains exactly 17 throughput points
  • synthetic SGLang injection and EVAL_ONLY no-op behavior verified
  • shell/Python syntax and git diff checks pass

@github-actions

Copy link
Copy Markdown
Contributor

Thanks for the contribution! Please reach out to respective companies' CODEOWNER to fill in the latest PR_REVIEW_CHECKLIST.md before pinging core maintainer on Slack for review. In order for the signoff PR check bot to trigger, you must follow the PR_REVIEW_CHECKLIST.md template correctly, including the phrase As a PR reviewer and CODEOWNER, I have reviewed this and have.

For PR verification, add the full-sweep-fail-fast label (strongly recommended) to this PR — the benchmark sweep only runs on labeled PRs. Use full-sweep-enabled only if you need matrix jobs to keep running past a failure.

PR authors are responsible for ensuring that after merging, all GitHub Action jobs fully pass. A lot of the time, failures are just flakes and simply re-running the failed jobs will fix it. See GitHub's docs on re-running failed jobs


感谢你的贡献!请联系相应公司的 CODEOWNER 填写最新的 PR_REVIEW_CHECKLIST.md,然后再在 Slack 上联系核心维护者进行审阅。为了触发 signoff PR 检查机器人,你必须正确遵循 PR_REVIEW_CHECKLIST.md 模板,包括保留英文语句 As a PR reviewer and CODEOWNER, I have reviewed this and have

如需进行 PR 验证,请为此 PR 添加 full-sweep-fail-fast 标签(强烈推荐)— 基准测试 sweep 仅在带有标签的 PR 上运行。仅当需要矩阵任务在失败后继续运行时才使用 full-sweep-enabled

PR 作者有责任确保合并后所有 GitHub Action 任务完全通过。 很多时候失败只是偶发抖动(flake),重新运行失败的任务即可解决。参见 GitHub 关于重新运行失败任务的文档

@cquil11 cquil11 added the agentx-fast Run AgentX throughput with 1 warmup request per lane and a 20-minute profile; not reusable label Aug 11, 2026
@cquil11
cquil11 marked this pull request as ready for review August 11, 2026 21:58
@cquil11
cquil11 requested a review from a team August 11, 2026 21:58
@claude

claude Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Claude finished @cquil11's task in 7m 58s —— View job


Review of PR #2568

  • Gather context and read the full diff
  • Review recipe YAMLs (MTP flags, EP usage, formatting)
  • Validate configs/nvidia-master.yaml changes (image accessibility, model prefixes, perf-changelog pairing)
  • Verify perf-changelog.yaml entry is appended at the end
  • Review runners/launch_gb200-nv.sh (enroot import pattern)
  • Review synthetic injector changes
  • Post inline comments and summary

Summary

One 🟡 WARNING posted inline: all four new recipes omit AIPERF_HTTP_X_DYNAMO_SESSION_ID_FROM_CORRELATION_ID/AIPERF_USE_DYNAMO_CONV_AWARE_ROUTING, so benchmark_lib.sh's dynamo-* default will append --use-dynamo-conv-aware-routing (dynamo-frontend nvext.session_control payloads) against an SGLang frontend — every existing SGLang agentic recipe, including the GB300 qwen3.5 siblings these mirror, explicitly opts out.

Everything else checks out: perf-changelog.yaml entry is correctly appended at the end of the file; lmsysorg/sglang:v0.5.17-cu130 is a public Docker Hub image; SGLang recipes correctly use explicit expert-parallel-size; the srt-slurm v1.0.45 pin is verified against a hardcoded commit SHA; the new sglang.py injector's regex matches the recipes' aggregated_environment: blocks and its interface matches the driver's contract (including the spec_tokens_from_recipe(...) or 2 fallback); the master-config search space totals exactly 35 concurrency points as claimed; and the SGLANG_SIMULATE_ACC_* env var names (including TOKEN_MODE: real-draft-token) match the already-merged GB300 recipes.

One pre-existing observation, not caused by this PR: the inter-concurrency drain gate in benchmarks/multi_node/agentic_srt.sh:78-79 only polls vllm:num_requests_running/waiting and dynamo_frontend_active_requests, so for SGLang backends it always reads 0 and passes after 3 polls (~30s fixed delay) rather than actually verifying drain. This affects all existing SGLang agentic recipes equally.

Note: I could not externally verify that srt-slurm v1.0.45 ships install-torchao.sh (appended as --setup-script for all dynamo-sglang runs in launch_gb200-nv.sh:684) — the PR's dry-run validation claim covers this.

WEKA_LOADER_OVERRIDE: semianalysis_cc_traces_weka_062126_256k
AIPERF_DATASET_MMAP_CACHE_DIR: /aiperf_mmap_cache
HF_HUB_CACHE: /hf_hub_cache
AIPERF_REQUIRED_SERVER_METRIC_PREFIX: "sglang:"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 WARNING: Missing the AIPerf dynamo conv-aware-routing opt-out that every other SGLang agentic recipe sets (applies to all 4 new recipes in this PR).

Why it matters: With FRAMEWORK=dynamo-sglang and neither AIPERF_USE_DYNAMO_CONV_AWARE_ROUTING=0 nor AIPERF_HTTP_X_DYNAMO_SESSION_ID_FROM_CORRELATION_ID=true set, benchmarks/benchmark_lib.sh:1982-1991 defaults to appending --use-dynamo-conv-aware-routing, which makes AIPerf emit nvext.session_control bind/close actions in request bodies. That field targets the dynamo frontend's KV router — these recipes use frontend: { type: sglang }, which doesn't implement it (best case it's silently ignored payload noise; the same mechanism 400s on current dynamo builds per the comment in benchmark_lib.sh). Every existing SGLang agentic recipe (deepseek-v4, glm5.2, and the GB300 qwen3.5 siblings these recipes mirror, e.g. agg-gb300-tp2-c1-mtp-hicache-jid2530006.yaml:89-90) explicitly opts out.

Fix: Mirror the GB300 siblings in all four recipes:

Suggested change
AIPERF_REQUIRED_SERVER_METRIC_PREFIX: "sglang:"
AIPERF_REQUIRED_SERVER_METRIC_PREFIX: "sglang:"
AIPERF_HTTP_X_DYNAMO_SESSION_ID_FROM_CORRELATION_ID: "true"
AIPERF_USE_DYNAMO_CONV_AWARE_ROUTING: "0"

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good — the two findings are wording/log-convention nits (bare exception instead of sys.exit, and a stale vLLM-specific error message) in the new sglang synthetic-acceptance backend, not correctness issues.

Extended reasoning...

Overview

This PR adds a new GB200 Qwen3.5-397B-A17B NVFP4 SGLang MTP AgentX submission: four new recipe YAMLs, a new configs/nvidia-master.yaml search-space entry, a perf-changelog entry, a new branch in runners/launch_gb200-nv.sh that clones a pinned NVIDIA/srt-slurm v1.0.45 (with commit-hash verification), and a new runners/synthetic_injectors/sglang.py backend that rewrites *_environment: blocks to inject golden synthetic-acceptance env vars for throughput-only runs.

Security risks

None material. The new shell branch clones a pinned tag and verifies the resolved commit SHA before proceeding (matching the existing pattern used for other pinned srt-slurm/producer clones in this file), and the injector only operates on local recipe YAML text via regex substitution — no new user-controlled input or shell-injection surface.

Level of scrutiny

This follows the repo's well-established pattern for adding a new model+hardware AgentX recipe (mirrors prior Kimi K3 / GLM-5.2 / DSV4 additions in recent history), so moderate scrutiny is appropriate. The two reported issues are both nit-level: a bare ValueError on an unreachable double-injection guard (rather than the driver's sys.exit convention), and the shared driver's log wording still saying "speculative-config entries" for the sglang backend's environment-block injections. Neither affects correctness — the actual injection logic (regex matches on the 2-space aggregated_environment: blocks present in all four new recipes) is exercised correctly, and the explicit SYNTHETIC_ACCEPTANCE_LENGTH=3.39 setting means the AL auto-lookup / spec_tokens_from_recipe path (flagged and ruled out by the bug hunt as reading the wrong SGLang field) isn't even reached in this PR's usage.

Other factors

PR description reports recipe dry-runs, targeted srt-slurm/matrix-generator test passes, and verified synthetic-injection / EVAL_ONLY no-op behavior. The shell script changes follow the same commit-pinning and cleanup conventions already used elsewhere in launch_gb200-nv.sh.

Comment thread runners/synthetic_injectors/sglang.py
Comment on lines +17 to +30

def rewrite(content, al, log):
"""Add throughput-only golden-acceptance variables to each worker role."""
if "SGLANG_SIMULATE_ACC_LEN" in content:
raise ValueError("recipe already contains SGLANG_SIMULATE_ACC_* variables")

variables = (
f'\n SGLANG_SIMULATE_ACC_LEN: "{al:g}"'
'\n SGLANG_SIMULATE_ACC_METHOD: "match-expected"'
'\n SGLANG_SIMULATE_ACC_TOKEN_MODE: "real-draft-token"'
)
rewritten, count = _ENV_BLOCK_RE.subn(lambda match: match.group(1) + variables, content)
if count:
log(f"Added SGLANG_SIMULATE_ACC_* to {count} worker environment block(s)")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 The shared driver's diagnostics ('no speculative-config entries were found' / 'Modified {count} speculative-config entries' in runners/inject_synthetic_acceptance.py:155-163) hardcode vLLM-specific 'speculative-config' wording, but the new sglang backend (runners/synthetic_injectors/sglang.py) rewrites aggregated/prefill/decode_environment blocks — nothing to do with speculative-config JSON. This wording fires on every sglang injection, not just the count==0 error case, and could misdirect debugging. Consider generalizing to backend-neutral phrasing (e.g. 'injectable entries') in the shared driver.

Extended reasoning...

runners/inject_synthetic_acceptance.py is written as a framework-agnostic driver (per its own module docstring) that delegates the actual recipe rewrite to a backend registered in runners/synthetic_injectors/. However, its two diagnostic messages still bake in the original vLLM backend's terminology:

if count == 0:
    sys.exit(
        "ERROR: SYNTHETIC_ACCEPTANCE=true but no speculative-config "
        f"entries were found in {config_file}"
    )
...
_log(f"Modified {count} speculative-config entries")

This PR wires in the new sglang backend via runners/synthetic_injectors/__init__.py (from . import sglang, vllm), and sglang.py's rewrite() derives count from _ENV_BLOCK_RE.subn(...), where _ENV_BLOCK_RE = re.compile(r"(?m)^( (?:aggregated|prefill|decode)_environment:\s*)$"). That regex matches YAML environment-variable blocks, not speculative-config JSON entries (that term belongs solely to the vLLM backend's _SPEC_CONFIG_RE). So the driver's wording no longer describes what the sglang path actually modified.

Step-by-step proof:

  1. A GB200 Qwen3.5 SGLang recipe (e.g. agg-gb200-tp4-mtp.yaml added in this PR) sets SYNTHETIC_ACCEPTANCE=true and FRAMEWORK=dynamo-sglang via additional-settings in configs/nvidia-master.yaml.
  2. launch_gb200-nv.sh invokes inject_synthetic_acceptance.py "$CONFIG_PATH" "$FRAMEWORK".
  3. The driver resolves the sglang backend via get_injector("dynamo-sglang") and calls sglang.rewrite(content, al, log).
  4. rewrite() matches the recipe's aggregated_environment: block with _ENV_BLOCK_RE, injects SGLANG_SIMULATE_ACC_* env vars, and returns count=1.
  5. Back in the driver, since count != 0, it logs "Modified 1 speculative-config entries" — inaccurate on every successful run, since what was actually modified was an environment-variable block, not a speculative-config entry.
  6. If a future sglang recipe's env-block key or indentation ever drifted from the exact 2-space _ENV_BLOCK_RE pattern (e.g. a differently indented YAML style), count would be 0 and the driver would exit with "no speculative-config entries were found in {config_file}" — pointing whoever is debugging toward the wrong recipe section (speculative-config JSON, which doesn't exist for sglang) instead of the actual environment-block regex mismatch.

This is purely a diagnostic-text accuracy issue — I confirmed both messages are reachable (the success message on literally every current sglang injection since all four new recipes have a 2-space aggregated_environment: block that matches count≥1, and the error message only on the more speculative future-drift scenario). Nothing about the injection logic itself is wrong, and the error message does include {config_file}, so a developer isn't completely lost — but the phrase "speculative-config entries" actively points at the wrong artifact type for sglang, since sglang recipes have no speculative-config JSON section at all.

The fix is simple: since inject_synthetic_acceptance.py is explicitly designed to be framework-agnostic (per its own docstring), generalize the wording in both messages to something backend-neutral, e.g. "no injectable entries were found" and "Modified {count} injectable entries", so the message stays accurate regardless of which backend (vLLM speculative-config, sglang env blocks, or a future trtllm backend) produced the count.

One verifier argued the term is defensible because both backends inject "speculative-acceptance configuration," just in different locations, and that the count==0 trigger requires a hypothetical future indentation drift. That's a fair point for the error path, but it doesn't address the success-path message, which is inaccurate on every single sglang run today, not just a hypothetical drift scenario — so this is a real (if low-severity) wording bug in the current code, not purely speculative.

@github-actions

Copy link
Copy Markdown
Contributor

@github-actions

Copy link
Copy Markdown
Contributor

2 similar comments
@github-actions

Copy link
Copy Markdown
Contributor

@github-actions

Copy link
Copy Markdown
Contributor

@cquil11 cquil11 removed full-sweep-enabled agentx-fast Run AgentX throughput with 1 warmup request per lane and a 20-minute profile; not reusable labels Aug 12, 2026
@github-actions

Copy link
Copy Markdown
Contributor

1 similar comment
@github-actions

Copy link
Copy Markdown
Contributor

@cquil11

cquil11 commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator Author

/stage-results 31582035733

@github-actions

github-actions Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

@cquil11 staged run 31582035733: https://inferencemax-app-git-staging-semianalysisai.vercel.app/inference?i_dates=2026-08-12~r31582035733

This run remains available across future /stage-results requests. Staging the same run ID again updates its staged data. Staging workflow

@cquil11

cquil11 commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator Author

/reuse-sweep-run 31582035733

@cquil11
cquil11 merged commit 6a9c623 into main Aug 12, 2026
29 checks passed
@cquil11
cquil11 deleted the agent/gb200-qwen35-sglang-mtp-agentx branch August 12, 2026 15:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Development

Successfully merging this pull request may close these issues.

1 participant