Skip to content

[AMD] Qwen3.5-FP8 MI355X SGLang disagg perf tuning: image bump to v0.5.16, TP4P+TP8D baseline, add MTP / Qwen3.5-FP8 MI355X SGLang disagg 性能调优:镜像升级至v0.5.16,TP4P+TP8D基线优化,新增MTP配置 - #2557

Open
ChangLiu0709 wants to merge 5 commits into
mainfrom
chang/qwen3.5-mi355-di-baseline-and-mtp

Conversation

@ChangLiu0709

@ChangLiu0709 ChangLiu0709 commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

Changes

Baseline (qwen3.5-fp8-mi355x-sglang-disagg)

  • Docker image bump: lmsysorg/sglang:v0.5.14-rocm720-mi35xlmsysorg/sglang:v0.5.16-rocm720-mi35x (ROCm 7.2, SGLang v0.5.14 → v0.5.16, 3-5% throughput improvement across all concurrency levels).
  • TP topology optimization: TP8P+TP8D (16 GPU) → TP4P+TP8D (12 GPU). TP4 prefill delivers identical decode interactivity with 24-31% better throughput/GPU by saving 4 GPUs. Prefill TP does not affect decode TPOT.

MTP (qwen3.5-fp8-mi355x-sglang-disagg-mtp) — new config

  • EAGLE speculative decoding on the TP4P+TP8D topology: spec-decoding: mtp, DECODE_MTP_SIZE=3 (EAGLE, num-steps 3, draft-tokens 4, topk 1).
  • Concurrency sweep: [8, 16, 32, 64, 128], ISL=8K / OSL=1K.
  • models.yaml: add mtp_flags: "--speculative-algorithm EAGLE --speculative-eagle-topk 1" to Qwen3.5-397B-A17B-FP8.

Infra

  • docker_sg.sh: new wrapper that re-activates the docker supplementary group via sg docker -c for Slurm job steps where group credentials are not inherited.
  • job.slurm: update DOCKER_CMD_DETECT to try sg docker fallback before sudo docker.

Local benchmark results (v0.5.16, ISL=8K/OSL=1K)

Baseline (TP4P+TP8D, 12 GPU):

Conc Interactivity Tput/GPU TPOT (ms) TTFT (ms)
8 111.0 603 9.01 564
16 106.0 1,132 9.43 715
32 93.9 1,945 10.65 1,063
64 75.0 3,095 13.33 1,493
128 57.9 4,581 17.28 2,791

MTP (TP4P+TP8D, 12 GPU):

Conc Interactivity Tput/GPU TPOT (ms) TTFT (ms)
8 121.7 648 8.22 654
16 109.9 1,150 9.10 887
32 96.7 1,923 10.34 1,452
64 87.1 2,955 11.48 3,832
128 39.5† 5,147† 25.32† 1,715†

†conc=128 MTP uses TP4P+TP4D (8 GPU) — TP8 decode at conc=128 causes MTP collapse; TP4D resolves it with +83% tput/GPU.

Authors

@ChangLiu0709
@xiaohuguo2023
@chunfangamd

中文说明

Qwen3.5-FP8 MI355X SGLang 分离式推理优化:

  • 升级 Docker 镜像至 v0.5.16(性能提升 3-5%)
  • 基线配置从 TP8P+TP8D (16 GPU) 优化为 TP4P+TP8D (12 GPU),吞吐量/GPU 提升 24-31%
  • 新增 MTP(EAGLE 投机解码)配置,depth=3
  • 基础设施:添加 docker_sg.sh 包装脚本,解决 Slurm 作业中 docker 组权限问题

Made with Cursor

Made with Cursor

@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 关于重新运行失败任务的文档

1 similar comment
@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 关于重新运行失败任务的文档

…e, add MTP config

- Bump qwen3.5-fp8-mi355x-sglang-disagg image from v0.5.14 to v0.5.16
  (3-5% throughput improvement across all concurrency levels)
- Switch baseline from TP8P+TP8D (16 GPU) to TP4P+TP8D (12 GPU): TP4
  prefill delivers identical decode interactivity with 24-31% better
  throughput/GPU
- Add qwen3.5-fp8-mi355x-sglang-disagg-mtp: EAGLE speculative decoding
  (MTP depth 3) on TP4P+TP8D, conc-list [8,16,32,64,128]
- models.yaml: add mtp_flags for Qwen3.5-397B-A17B-FP8
  (--speculative-algorithm EAGLE --speculative-eagle-topk 1)
- Infra: add docker_sg.sh wrapper and update job.slurm DOCKER_CMD_DETECT
  for nodes where Slurm doesn't activate the docker supplementary group

Co-authored-by: Cursor <cursoragent@cursor.com>
@ChangLiu0709
ChangLiu0709 force-pushed the chang/qwen3.5-mi355-di-baseline-and-mtp branch from 989c2ff to d0fb017 Compare August 11, 2026 11:25
@ChangLiu0709 ChangLiu0709 changed the title [AMD] Qwen3.5-FP8 MI355X SGLang disagg: v0.5.16 image bump, TP4P+TP8D baseline optimization, add MTP config [AMD] Qwen3.5-FP8 MI355X SGLang disagg perf tuning: image bump to v0.5.16, TP4P+TP8D baseline, add MTP / Qwen3.5-FP8 MI355X SGLang disagg 性能调优:镜像升级至v0.5.16,TP4P+TP8D基线优化,新增MTP配置 Aug 11, 2026
At conc=128, TP8 decode bottlenecks MTP causing throughput collapse.
Use TP4P+TP4D (8 GPU) for conc=128 while keeping TP4P+TP8D (12 GPU)
for conc 8-64, matching the validated local benchmark results.

Co-authored-by: Cursor <cursoragent@cursor.com>
Comment thread configs/amd-master.yaml
Comment on lines +332 to 351
- spec-decoding: "mtp"
conc-list: [ 8, 16, 32, 64, 128 ]
prefill:
num-worker: 1
tp: 4
ep: 1
dp-attn: false
additional-settings:
- "PREFILL_NODES=1"
decode:
num-worker: 1
tp: 8
ep: 1
dp-attn: false
additional-settings:
- "DECODE_NODES=1"
- "DECODE_MTP_SIZE=3"

qwen3.5-fp4-mi355x-sglang:
image: lmsysorg/sglang-rocm:v0.5.16-rocm720-mi35x-20260730

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 new qwen3.5-fp8-mi355x-sglang-disagg-mtp entry (configs/amd-master.yaml:332-351) runs decode tp: 8 for the entire conc-list [8,16,32,64,128], but the PR's own results table and perf-changelog.yaml state that at conc=128 TP8 decode causes 'MTP collapse' and that the documented numbers (interactivity 39.5, tput/GPU 5147) were actually measured on TP4P+TP4D. A sweep of this config will therefore reproduce the known-collapse topology at conc=128 instead of the validated one. Consider splitting conc=128 into its own arm with decode tp: 4, matching the pattern used elsewhere in this file (e.g. dsr1-fp8-mi355x-sglang-disagg-mtp).

Extended reasoning...

The committed qwen3.5-fp8-mi355x-sglang-disagg-mtp search-space arm (configs/amd-master.yaml:332-351) is a single block covering conc-list: [8, 16, 32, 64, 128] with decode: { tp: 8, ep: 1, ... } applied uniformly to every concurrency point. There is no second arm carving out conc=128 with a different decode topology.

However, the PR description's own MTP benchmark table daggers the conc=128 row explicitly: 'conc=128 MTP uses TP4P+TP4D (8 GPU) — TP8 decode at conc=128 causes MTP collapse; TP4D resolves it with +83% tput/GPU.' The accompanying perf-changelog.yaml addition echoes this independently: 'at conc=128 the decode TP8 bottleneck causes MTP collapse (-38% tput/GPU), which is resolved by switching to TP4D.' Both artifacts agree the author already discovered and worked around this collapse during local validation, but that workaround (switching decode to TP4 at conc=128) was never encoded back into the committed YAML.

The result is a config/documentation mismatch: the recipe as written will always exercise the TP8 decode topology at conc=128, which is the exact case the author's own text says degrades throughput by ~38%. A sweep run against this config cannot reproduce the row of numbers (interactivity 39.5, tput/GPU 5147) that the PR presents as the MTP conc=128 result, because those numbers came from a TP4D run this config doesn't perform. This isn't a case of stale prose describing correct code — the YAML and the changelog/description are making mutually exclusive factual claims about which topology conc=128 runs on.

This pattern (splitting a conc range into separate arms with different decode tp/DECODE_MTP_SIZE per topology) is already established elsewhere in this same file — see dsr1-fp8-mi355x-sglang-disagg-mtp and dsr1-fp4-mi355x-sglang-disagg-8k1k-mtp, both of which use multiple per-conc arms specifically to match validated topologies. That makes the fix straightforward and consistent with existing conventions: drop conc=128 from the current TP8D arm and add a second arm with conc-list: [128], decode: { tp: 4, ... }, mirroring the existing qwen3.5-fp8-mi355x-sglang-disagg baseline entry's TP4P+TP8D pattern but with decode tp=4.

Concrete walkthrough: (1) a maintainer runs the full sweep on qwen3.5-fp8-mi355x-sglang-disagg-mtp; (2) at conc=128 the recipe launches decode with tp=8 per the single committed arm; (3) per the PR's own analysis this triggers MTP collapse, so the sweep records materially worse throughput (~38% lower tput/GPU per the changelog) than the TP4D figures published in the PR description's table; (4) anyone comparing the recorded sweep data against the PR's stated 5147 tput/GPU for conc=128 will find it doesn't match, because the committed recipe never runs the TP4D topology that produced that number.

Impact is data-quality/reproducibility rather than a hard failure: the run will complete and produce a valid (if degraded) data point rather than crashing, since the sibling spec-none baseline arm also runs conc=128 on TP8D deliberately for apples-to-apples comparison. For that reason this is best treated as a fix-before-merge nit rather than a blocking correctness bug.

Comment thread perf-changelog.yaml Outdated
- "Add qwen3.5-fp8-mi355x-sglang-disagg-mtp: EAGLE speculative decoding (MTP depth 3) on the TP4P+TP8D topology. MTP improves TPOT by 3-14% at conc≤64; at conc=128 the decode TP8 bottleneck causes MTP collapse (-38% tput/GPU), which is resolved by switching to TP4D (see Section 13 of the Qwen3.5 DI perf tuning analysis)."
- "models.yaml: add mtp_flags (--speculative-algorithm EAGLE --speculative-eagle-topk 1) to Qwen3.5-397B-A17B-FP8."
- "Infra: add docker_sg.sh wrapper and update job.slurm DOCKER_CMD_DETECT to use sg-docker fallback for nodes where Slurm doesn't activate the docker supplementary group."
pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/XXXX

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 new perf-changelog.yaml entry (line 5782) ends with pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/XXXX — an unresolved placeholder rather than the real PR number. Per docs/configuration-procedures.md, the sanctioned pre-PR placeholder is pr-link: TBD, to be replaced with the real URL right after the PR is created; since this is PR #2557, it should read pull/2557.

Extended reasoning...

The newly-added perf-changelog.yaml entry for this PR (the qwen3.5-fp8-mi355x-sglang-disagg / -mtp config-keys block) ends with:

pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/XXXX

XXXX is a literal, unresolved template placeholder — it is not a real PR number, and it is also not the documented placeholder convention.

docs/configuration-procedures.md (around lines 251-254) specifies the changelog convention explicitly: the pr-link field should resolve to https://github.com/SemiAnalysisAI/InferenceX/pull/<number>, and before the PR exists, the sanctioned interim value is pr-link: TBD, which must be "replace[d] with the real URL immediately after creating the PR." The doc further calls out (around line 272) that a changelog still carrying an unresolved placeholder is a stop-condition / not-ready-for-sweep signal when the PR is otherwise ready to run — and this PR already carries the full-sweep-fail-fast label, i.e. it is being treated as ready.

Every other entry in perf-changelog.yaml follows the convention with a resolved numeric PR link (e.g. pull/2206, pull/2238, pull/2309 for the immediately preceding entries), confirming XXXX here is simply a forgotten fill-in rather than an intentional convention. Since this change is PR #2557 (per the PR metadata), the line should read:

pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/2557

Why this slips through: the documented automated check (line 272 of configuration-procedures.md) appears to look for the literal string TBD as the "not yet filled in" marker. Because the author used XXXX instead of TBD, it likely doesn't match that check's leftover-placeholder detection, making it more likely for this entry to merge unresolved than if the author had used the sanctioned TBD value.

Step-by-step proof:

  1. Open perf-changelog.yaml and note every other entry's pr-link resolves to a real PR number (e.g. .../pull/2309 for the DSv4 AgentX entry immediately above this one).
  2. Open docs/configuration-procedures.md and find the changelog template section — it documents pr-link: TBD as the only sanctioned pre-merge placeholder, to be swapped for the real URL right after PR creation.
  3. Look at the new entry at the end of perf-changelog.yaml (line 5782): pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/XXXX. This is neither a real number nor TBD.
  4. Cross-reference the PR metadata: this change is submitted as PR [AMD] Qwen3.5-FP8 MI355X SGLang disagg perf tuning: image bump to v0.5.16, TP4P+TP8D baseline, add MTP / Qwen3.5-FP8 MI355X SGLang disagg 性能调优:镜像升级至v0.5.16,TP4P+TP8D基线优化,新增MTP配置 #2557.
  5. Conclusion: the line should read pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/2557.

Impact is limited to changelog metadata/traceability — it does not affect the benchmark configs, scripts, or results in this PR — so this doesn't block correctness of the actual benchmark work, but it is a concrete, easily-fixed convention violation a maintainer would want corrected before merge.

When a GPU hang leaves a container in an unkillable state ("did not
receive an exit event"), docker rm -f is insufficient. Add a fallback
that retrieves the container's init PID and kills it directly so the
daemon can release GPU VRAM and the cgroup.

Applied to pre-run cleanup, trap handler, and post-run cleanup.

Co-authored-by: Cursor <cursoragent@cursor.com>
@github-actions

Copy link
Copy Markdown
Contributor

The container creation barrier (300s timeout) races against Docker
image downloads when one node has the image cached and another doesn't.
A multi-GB SGLang image pull can easily exceed 300s, causing the
barrier to timeout and the job to fail with "No logs directory found".

Add a best-effort srun pre-pull step before the main benchmark srun
so all nodes have the image cached before the barrier starts.

Co-authored-by: Cursor <cursoragent@cursor.com>
@github-actions

Copy link
Copy Markdown
Contributor

Keep both the PR #2557 Qwen3.5-FP8 disagg entry and the entries
added to main (PRs #2536, #2476, #2364, #2475).

Co-authored-by: Cursor <cursoragent@cursor.com>
@SemiAnalysisAI SemiAnalysisAI deleted a comment from github-actions Bot Aug 12, 2026
@SemiAnalysisAI SemiAnalysisAI deleted a comment from github-actions Bot Aug 12, 2026
@SemiAnalysisAI SemiAnalysisAI deleted a comment from github-actions Bot Aug 12, 2026
@SemiAnalysisAI SemiAnalysisAI deleted a comment from github-actions Bot Aug 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

1 participant