Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
base:
schema: 2
name: musespark-fp4-gb200-sglang-agentic
resources:
gpu_type: gb200
gpus_per_node: 4
frontend:
type: sglang
enable_multiple_frontends: false
observability:
enabled: false
tachometer:
enabled: false
engine: sglang
roles:
agg:
nodes: 1
workers: 1
gpus: 4
args:
served-model-name: meta-models/Muse-Spark-Open-816B-A42B-NVFP4
trust-remote-code: true
tensor-parallel-size: 4
expert-parallel-size: 4
quantization: modelopt_fp4
moe-runner-backend: flashinfer_trtllm
kv-cache-dtype: fp8_e4m3
enable-layernorm-sp: true
enable-megamoe-for-layernorm-sp: true
# 133 GB of weights per GPU leave the KV pool what prefill graphs would take.
mem-fraction-static: 0.88
disable-prefill-cuda-graph: true
swa-full-tokens-ratio: 0.1
# DFlash2 verifies 8 tokens per step: the current token plus 7 drafts.
speculative-algorithm: DFLASH
speculative-draft-model-path: RadixArk/Muse-Spark-Open-DFlash2
speculative-draft-attention-backend: fa4
speculative-num-draft-tokens: 8
mm-feature-transport: cpu
reasoning-parser: muse
tool-call-parser: muse
watchdog-timeout: 3600
enable-metrics: true
env:
PYTHONNOUSERSITE: '1'
PYTHONUNBUFFERED: '1'
# Outlast AIPerf's pooled connections past Uvicorn's keep-alive.
SGLANG_TIMEOUT_KEEP_ALIVE: '900'
# 533 GB of weights load from Lustre before graph capture.
health_check:
max_attempts: 1440
interval_seconds: 5
benchmark:
env:
# The gated Hub repo is unreadable to the client; use the staged checkpoint.
TOKENIZER: /model
# Warmup can leave bytes unacknowledged past AIPerf's 30 s default.
AIPERF_HTTP_TCP_USER_TIMEOUT: '900000'
AIPERF_REQUIRED_SERVER_METRIC_PREFIX: 'sglang:'
AGENTIC_WARMUP_GRACE_PERIOD: '3600'


override_tp4_c1:
roles:
agg:
args:
max-running-requests: 2
cuda-graph-max-bs-decode: 2
benchmark:
env:
CONC: '1'

override_tp4_c2:
roles:
agg:
args:
max-running-requests: 4
cuda-graph-max-bs-decode: 4
benchmark:
env:
CONC: '2'

override_tp4_c4:
roles:
agg:
args:
max-running-requests: 8
cuda-graph-max-bs-decode: 8
benchmark:
env:
CONC: '4'

override_tp4_c8:
roles:
agg:
args:
max-running-requests: 16
cuda-graph-max-bs-decode: 16
benchmark:
env:
CONC: '8'

override_tp4_c12:
roles:
agg:
args:
max-running-requests: 24
cuda-graph-max-bs-decode: 24
benchmark:
env:
CONC: '12'

override_tp4_c16:
roles:
agg:
args:
max-running-requests: 32
cuda-graph-max-bs-decode: 32
benchmark:
env:
CONC: '16'

override_tp4_c24:
roles:
agg:
args:
max-running-requests: 48
cuda-graph-max-bs-decode: 48
benchmark:
env:
CONC: '24'

override_tp4_c32:
roles:
agg:
args:
max-running-requests: 64
cuda-graph-max-bs-decode: 64
benchmark:
env:
CONC: '32'
14 changes: 14 additions & 0 deletions inferencex-e2e/configs/nvidia-master.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8365,6 +8365,20 @@ dsv41flash-fp4-gb200-sglang-agentic-dspark:
- { tp: 4, ep: 4, kv-offloading: none, spec-decoding: mtp, conc-list: [1, 4, 8, 16], srt-recipe: agentic.yaml }
- { tp: 4, ep: 4, dp-attn: true, kv-offloading: none, spec-decoding: mtp, conc-list: [32, 64, 128, 192], router: { name: sglang-router, version: "0.3.2" }, srt-recipe: agentic.yaml }

musespark-fp4-gb200-sglang-agentic-dflash:
image: lmsysorg/sglang:dev-muse-spark-open@sha256:8cfc5a72cb296771f5f8a4a4688cb6d05685610a830cbb616fa4ab0eb7bb2b0a
model: meta-models/Muse-Spark-Open-816B-A42B-NVFP4
model-prefix: musespark
runner: cluster:gb200-nv
precision: fp4
framework: sglang
multinode: false
srt-recipe-dir: musespark/sglang/gb200-fp4-mtp
scenarios:
agentic-coding:
- search-space:
- { tp: 4, ep: 4, kv-offloading: none, spec-decoding: draft_model, conc-list: [1, 2, 4, 8, 12, 16, 24, 32], srt-recipe: agentic.yaml }

dsv41flash-fp4-b300-vllm-agentic-dspark:
image: vllm/vllm-openai:nightly-dev-x86_64-cu130-ac9126e58aa7
model: deepseek-ai/DeepSeek-V4.1-Flash
Expand Down
2 changes: 2 additions & 0 deletions inferencex-e2e/configs/runners.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,7 @@ clusters:
MiniMax-M3-NVFP4: {root: lustre-models, dir: MiniMax-M3-NVFP4}
Qwen3.5-397B-A17B-FP8: {root: lustre-models, dir: Qwen3.5-397B-A17B-FP8}
Qwen3.5-397B-A17B-NVFP4-V2: {root: lustre-models, dir: Qwen3.5-397B-A17B-NVFP4-V2}
Muse-Spark-Open-816B-A42B-NVFP4: {root: lustre-models, dir: Muse-Spark-Open-816B-A42B-NVFP4}
GLM-5.2-NVFP4: {root: sa-shared-models, dir: GLM-5.2-NVFP4}
DeepSeek-R1-0528: {root: numa1, dir: DeepSeek-R1-0528}
DeepSeek-R1-0528-NVFP4-v2: {root: numa1, dir: DeepSeek-R1-0528-NVFP4-v2}
Expand Down Expand Up @@ -613,6 +614,7 @@ clusters:
rdma-gid-index: 3
job-tag: gb200
default-time-limit: "6:00:00"
single-node-models: staged
preflight: false
segment-directive: false
container-aliases: [dynamo-trtllm, dynamo-sglang]
Expand Down
1 change: 1 addition & 0 deletions inferencex-e2e/docs/MODELS.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ Other offloading tiers, including NVMe KV cache offloading, are outside the init

| Model architecture class | Prefix | Date added | Active scenarios | Deprecated scenarios |
|---|---|---|---|---|
| Muse Spark Open 816B-A42B | `musespark` | 2026-10-15 | Agentic coding (SGLang with DFlash2 draft `RadixArk/Muse-Spark-Open-DFlash2`; golden AL curve `musespark_dflash.yaml`) | |
| DeepSeek-V4.1-Flash | `dsv41flash` | 2026-09-10 | Agentic coding (vLLM: DSpark, Engram UVA offload; SGLang: DSpark arms added per SKU from 2026-09-17; ATOM: MI355X TP2/TP4 DSpark added 2026-09-23, removed in #3463, restored on srt-slurm 2026-09-30; GPU validation pending) | |
| GLM-5.3 | `glm5.3` | 2026-09-22 ([#3366](https://github.com/SemiAnalysisAI/InferenceX/pull/3366)) | Agentic coding (MTP only, per the deprecation policy) | Single-turn 1k1k (deprecated for all models before this model was added; never run) |
| Qwen3.8-Flash-Next | `qwen3.8next` | 2026-08-26 ([#2742](https://github.com/SemiAnalysisAI/InferenceX/pull/2742)) | Agentic coding | |
Expand Down
4 changes: 2 additions & 2 deletions inferencex-e2e/infx/srt_slurm/single_node.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,9 @@ def validate_recipe(recipe: dict[str, Any], environment: Mapping[str, str]) -> N
if environment["FRAMEWORK"] not in {"sglang", "trt", "atom", "vllm"}:
raise ValueError(f"Unsupported single-node framework: {environment['FRAMEWORK']!r}")
spec = spec_parameters(role, engine)
if spec and spec["method"] not in {"eagle", "eagle3", "nextn", "mtp", "dspark"}:
if spec and spec["method"] not in {"eagle", "eagle3", "nextn", "mtp", "dspark", "dflash"}:
raise ValueError(
"Single-node SRT supports only native MTP, EAGLE3, DSpark or no speculation"
"Single-node SRT supports only native MTP, EAGLE3, DSpark, DFlash or no speculation"
)
speculation = "mtp" if spec else workload.get("SPEC_DECODING", "none")
agentic = environment["IS_AGENTIC"] == "1"
Expand Down
10 changes: 10 additions & 0 deletions inferencex-e2e/infx/srt_slurm/synthetic_acceptance.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,16 @@ def spec_parameters(role: Mapping[str, Any], engine: str) -> dict[str, Any]:
algorithm = next(iter(algorithms), "")
if not algorithm:
return {}
if algorithm == "dflash":
# DFlash verifies a block of the current token plus its drafts.
width = args.get("speculative-num-draft-tokens")
return {
"method": "dflash",
"num_speculative_tokens": width - 1
if isinstance(width, int) and not isinstance(width, bool)
else None,
"model": args.get("speculative-draft-model-path", ""),
}
return {
"method": "dspark" if algorithm == "dspark" else algorithm,
"num_speculative_tokens": args.get(
Expand Down
15 changes: 15 additions & 0 deletions inferencex-e2e/infx/tests/srt_slurm/test_synthetic_acceptance.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ def golden_dir(tmp_path: Path) -> Path:
("minimaxm3_eagle3.yaml", "minimax-m3", 2.5),
("minimaxm3_eagle3_gqa.yaml", "minimax-m3", 2.6),
("glm5.3_mtp.yaml", "glm-5.3", 3.2),
("musespark_dflash.yaml", "muse-spark-open", 3.4),
]:
(directory / filename).write_text(
yaml.safe_dump(
Expand Down Expand Up @@ -177,6 +178,20 @@ def test_kimi_curve_requires_an_explicit_supported_sampler(
"SGLANG_SIMULATE_ACC_TOKEN_MODE": "real-draft-token",
},
),
(
"sglang",
{
"speculative-algorithm": "DFLASH",
"speculative-draft-model-path": "RadixArk/Muse-Spark-Open-DFlash2",
"speculative-num-draft-tokens": 4,
},
{"MODEL_PREFIX": "musespark"},
{
"SGLANG_SIMULATE_ACC_LEN": "3.4",
"SGLANG_SIMULATE_ACC_METHOD": "match-expected",
"SGLANG_SIMULATE_ACC_TOKEN_MODE": "real-draft-token",
},
),
(
"dynamo-sglang",
{"speculative-algorithm": "EAGLE", "speculative-num-steps": 3},
Expand Down
15 changes: 13 additions & 2 deletions inferencex-e2e/perf-changelog.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5595,7 +5595,7 @@
- "Image ghcr.io/tile-ai/tilert:0.1.5 (tilert 0.1.5.post2 installed at container start); commands aligned to TileRT README Topology A -- NIXL KV transfer, --kv-cache-dtype fp8_ds_mla (prefill) <-> fp8 (decode), max-seq-len 202752; MTP speculative-config wired via spec-decoding=mtp"
- "Topology: 1 prefill node (TP8) + 1 decode node (TP8), each 8xB200 exclusive; TileRT decode is bs=1 only so conc-list is a single point [1], ISL 1k/8k OSL 1k"
- "Runner: launch_b200-dgxc.sh tilert early-return branch (zero impact on the dynamo path); tilert_utils/submit.sh issues two srun --ntasks=1, one per role, because prefill and decode need different container images; roles are dispatched by the TILERT_ROLE it exports, and torn down across nodes via a sentinel file on the shared /workspace"
pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/XXX
pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/4140

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: This entry's XXX placeholder now points to #4140. The entry is the TileRT glm5.1-fp8-b200-tilert entry from #2533 (commit 077d483), not Muse Spark. It looks like a blanket XXX→4140 replace in commit a107f97 caught it.
Why it matters: The changelog is the historical record, and ingest/recovery tooling uses pr-link to attribute results. These TileRT results would be credited to this PR.
Fix: Revert this line, or correct it to the real PR:

Suggested change
pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/4140
pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/2533


- config-keys:
- qwen3.5-fp8-b200-sglang-agentic-mtp
Expand Down Expand Up @@ -9724,7 +9724,7 @@
- "Replace the TP4/EP1 and TP2/EP1 C1-C128 sweeps with TP4/EP4 points at concurrency 1, 4, 8 and 16, plus aggregated TP4/EP4 points with DP attention (DP4) at concurrency 32, 64, 128 and 192 behind sglang-router 0.3.2."
- "Apply the point-specific prefill-decode interval, prefill chunking, admission, memory and SWA prefix-tail settings from the single-node recipe; all points use the default fcfs schedule policy."
- "No data-type or precision change to the DSpark draft: the bundled draft of deepseek-ai/DeepSeek-V4.1-Flash runs as shipped with block size 5."
pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/XXX
pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/4140

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: Same problem as the TileRT entry. This is the dsv41flash-fp4-gb200-sglang-agentic-dspark refresh from #3927 (commit 2b97216), not this PR.
Why it matters: The DSV4.1-Flash GB200 SGLang results would be attributed to #4140.
Fix:

Suggested change
pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/4140
pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/3927

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.

🔴 Changelog validation in CI will fail for this PR, and two older entries would point at #4140 although it did not make those changes. Lines 5598 and 9727 change historical pr-link: .../pull/XXX lines in the same diff that appends the new block. compare_entries rejects that mix with "do not mix historical pr-link corrections with new changelog entries". Fix: restore both historical pr-link lines byte-for-byte so the only change is the appended musespark block. Any XXX placeholder fixes belong in their own correction-only change that uses each entry's real PR number.

Why this was flagged

The diff appends a new entry at the end of inferencex-e2e/perf-changelog.yaml. It also changes two existing entries' pr-link from pull/XXX to pull/4140: the TileRT entry at line 5598 and the dsv41flash-fp4-gb200-sglang-agentic-dspark entry at line 9727. In infx/workflows/validate_perf_changelog.py:compare_entries (lines 184-190), each changed pr-link counts as a correction. When there are both corrections and additions, it raises ChangelogValidationError("do not mix historical pr-link corrections with new changelog entries"). validate_raw_change (lines 205-210) would reject the file too, because head_raw no longer starts with base_raw. That breaks AGENTS.md:140 ("append-only and byte-sensitive ... Preserve all existing bytes"). Even if this got past CI, the TileRT and DSpark entries would now link to PR #4140, which did not make them. #4140 would then show up in three blocks, against the one-block-per-PR rule at AGENTS.md:141. On the base branch those entries keep their XXX placeholders and the validator passes.

Verification: At inferencex-e2e/perf-changelog.yaml lines 5598 and 9727 the diff changes pr-link: .../pull/XXX to .../pull/4140 in existing entries and also appends a new musespark block. In inferencex-e2e/infx/workflows/validate_perf_changelog.py lines 186-190, compare_entries raises "do not mix historical pr-link corrections with new changelog entries" when both are present.


- config-keys:
- kimik3-fp4-mi355x-vllm-disagg-agentic
Expand Down Expand Up @@ -9892,3 +9892,14 @@
- "The new image brings Kimi-K3 ROCm changes vllm-project/vllm#59591 (latent MoE up-proj stores only the local rank's shards), #59069 (AttnRes output fused with per-token FP8 input quantization), #60717 (vLLM's FP8 max in that fused quantization), #60446 (KDA autotune keys), #59523 (cuMem CUDA-graph pool offload on ROCm) and #59880 (speculative block reservations across KV cache groups with a KV connector)."
- "No change to the Inferact/Kimi-K3-DSpark draft's precision: K3DSparkModel and get_draft_quant_config() are unchanged between the two images, so the draft keeps BF16 weights and an fp8 KV cache."
pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/3951

- config-keys:
- musespark-fp4-gb200-sglang-agentic-dflash
scenario-type:
- agentic-coding
description:
- "Add Muse Spark Open (meta-models/Muse-Spark-Open-816B-A42B-NVFP4) agentic coding on one GB200 node via SGLang (lmsysorg/sglang:dev-muse-spark-open, multiarch digest sha256:8cfc5a72cb296771f5f8a4a4688cb6d05685610a830cbb616fa4ab0eb7bb2b0a) at TP4/EP4, concurrency 1, 2, 4, 8, 12, 16, 24 and 32, GPU-resident KV."
- "Serve flags follow the SGLang cookbook's NVFP4 cell: modelopt_fp4, flashinfer_trtllm MoE, fp8_e4m3 KV, layernorm SP with MegaMoE prefill, DFlash2 draft RadixArk/Muse-Spark-Open-DFlash2 with fa4 draft attention and 8 verify tokens (7 drafts), muse reasoning and tool-call parsers. Prefill CUDA graphs are off and mem-fraction-static is 0.88 to leave room for the KV pool; admission and the decode graph batch are 2x concurrency."
- "Synthetic acceptance follows the committed musespark_dflash golden curve: AL 4.05 at 7 draft tokens, thinking_on."
- "The checkpoint is served from the staged Lustre copy; the AgentX client reads its tokenizer from it."
pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/4140
Loading