Skip to content

[AMD][AgentX] Tune MI300X Qwen3.5 MORI disaggregation with srt-slurm - #2984

Open
cquil11 wants to merge 5 commits into
mainfrom
agent/mi300x-qwen35-agentx-mori-srt
Open

cquil11 wants to merge 5 commits into
mainfrom
agent/mi300x-qwen35-agentx-mori-srt

Conversation

@cquil11

@cquil11 cquil11 commented Sep 10, 2026

Copy link
Copy Markdown
Collaborator

Scope

Qwen3.5-397B-A17B FP8 AgentX disaggregation on MI300X using native MORI and srt-slurm. Based on main; no unrelated MI355X configurations or workflow changes.

Prefill Decode Session concurrency Physical GPUs
DEP8 DEP8 32, 64 16
TP8 / EP1 TP8 / EP1 1, 4 16
TEP8 (TP8 / EP8) TEP8 (TP8 / EP8) 1, 4, 8, 16 16
  • Stock image: lmsysorg/sglang-rocm:v0.5.19-rocm720-mi30x-20260910, digest pinned in each recipe.
  • srt-slurm #7, commit c6dc2f05061e504c59b8e7baa30cfeacabc93645, owns allocation, containers, router, workers, and benchmark lifecycle.
  • Native MORI KV/state transfer; DEP additionally uses MORI expert all-to-all and DP-aware, cache-aware routing.
  • AgentX 256K traces, BF16 KV/Mamba state, native MTP and golden acceptance length 3.39.
  • Any available compute nodes; whole-node GPU/CPU/RAM allocation. Throughput accounts for all physical GPUs.
  • No engine patches, provider rebuilds, host-library overrides, or bespoke test utilities.

Correctness blocker for requested mixed layout

TEP8 prefill to DEP8 decode changes attention TP8 to TP1. The pinned SGLang MORI transfer concatenates each local packed Q/K/V convolution-state shard instead of assembling each channel group separately. This silently rearranges Qwen recurrent state. The mixed layout is excluded pending a stock upstream fix.

The exact pinned transfer method was exercised on CPU with in-bounds byte-copy transport and actual model dimensions: 11,008 of 12,288 channels land incorrectly. Transfer implementation, grouped state definition.

Validation

  • 133 existing launcher/eval tests passed during integration; no new pytest files.
  • The user requested skipping evals for this iteration. All three new changelog entries use the native no-evals: true option.
  • The expanded official full-sweep-enabled matrix contains eight performance jobs, default warmup and 3600-second profiles, with no eval jobs. Fresh eight-point Run Sweep completed successfully at 7267a73c36d4a5d03f86a8bd79f32fbf0650ee16: all eight actual GPU jobs passed, along with the changelog check and final collection. Prior sweep reuse authorization was withdrawn before launch; these are fresh measurements.
  • The added homogeneous TEP8 recipe matches the serving configuration of successful exploratory Slurm job 438; native SRT validation and the eight-point changelog matrix validation pass.
  • Official Run Sweep completed successfully at 6da8c6f4695a57670b4ee8048373a94ce74933d1; all four performance jobs passed.
  • Targeted accuracy jobs were canceled at the user's request after startup; neither is claimed as accuracy validation. Both layouts initialized their intended worker/router settings without an observed fatal startup error.
  • Prior exploratory runs and artifacts are retained on agent/mi300x-qwen35-agentx-mori-frontier; the broad sweep was canceled at the user's request to narrow topology search.
  • All four added homogeneous TEP8/TEP8 points completed with zero request errors. This iteration provides performance evidence only; model accuracy and five competitive nondominated points are not established by CI success.

Fresh eight-point official performance results

All points use 16 physical GPUs. Interactivity below is P90 E2E-normalized output tokens/s/user; both displayed performance axes are higher-is-better. Values are from the official benchmark artifacts.

Topology Concurrency Output tokens/s/GPU P90 normalized interactivity Successful profiling requests
Pure TP8 / TP8 1 6.56787 56.12549 392
Pure TP8 / TP8 4 11.57377 45.19834 645
TEP8 / TEP8 1 6.20884 48.01983 377
TEP8 / TEP8 4 11.20285 44.99573 635
TEP8 / TEP8 8 19.84060 41.22020 1274
TEP8 / TEP8 16 37.02819 31.62635 2382
DEP8 / DEP8 32 15.56706 0.55875 1072
DEP8 / DEP8 64 10.39476 0.23372 696

The DEP points are not performant: P90 time to first token is 284.58 seconds at c32 and 802.78 seconds at c64. They incurred 39 and 87 end-of-window cancellations respectively. The c64 artifact also records one ClientPayloadError before mass cancellation, with an approximately 1800-second request lifetime and a matching upstream stream termination. This repeats the prior c64 timeout pattern; it is not a cutoff cancellation or a demonstrated RDMA fault. The other seven points record zero client errors. TEP8 c8/c16 had two/one end-of-window cancellations respectively; both pure-TP points and TEP8 c1/c4 had none.

TEP8 c16 is the highest-throughput measured point. Pure TP8 at c1/c4 exceeds the matching TEP8 low-concurrency points on both displayed metrics. CI success does not establish model accuracy or a competitive frontier against matched full-length single-node controls.

@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 force-pushed the agent/mi300x-qwen35-agentx-mori-srt branch from a5b1a48 to 76d77d4 Compare September 10, 2026 20:47
@cquil11
cquil11 changed the base branch from agent/port-dsv4-mi355x-agentx-srt-slurm to agent/srt-slurm-amd-integration September 10, 2026 20:47
@cquil11
cquil11 force-pushed the agent/mi300x-qwen35-agentx-mori-srt branch from ee7b0e6 to 2369fb1 Compare September 11, 2026 01:40
@cquil11
cquil11 changed the base branch from agent/srt-slurm-amd-integration to main September 11, 2026 01:40
@cquil11 cquil11 changed the title [AMD][AgentX] Bring up MI300X Qwen3.5 MTP disagg with MORI and srt-slurm [AMD][AgentX] Tune MI300X Qwen3.5 MORI disaggregation with srt-slurm Sep 11, 2026
@github-actions

Copy link
Copy Markdown
Contributor

@cquil11
cquil11 force-pushed the agent/mi300x-qwen35-agentx-mori-srt branch from 0513c80 to 252968b Compare September 11, 2026 04:57
@github-actions

Copy link
Copy Markdown
Contributor

@cquil11

cquil11 commented Sep 11, 2026

Copy link
Copy Markdown
Collaborator Author

Previous sweep reuse authorization withdrawn: the user requested adding TEP8/TEP8 points and running a new full official sweep. Run 34565384525 remains historical evidence for the earlier four-point matrix.

@cquil11
cquil11 marked this pull request as ready for review September 11, 2026 15:14
@cquil11
cquil11 requested a review from a team September 11, 2026 15:14

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit eae1874. Configure here.

if backend not in {"sglang", "dynamo"}:
raise SystemExit(f"Unsupported AIPERF_DRAIN_BACKEND: {backend}")
if not all(worker_urls):
raise SystemExit("Agentic drain requires non-empty worker metrics URLs")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Drain requires worker URLs unconditionally

Medium Severity

wait_for_agentic_servers_idle now treats an empty AIPERF_SERVER_METRICS_URLS as a fatal SystemExit for every backend. Existing Dynamo AgentX recipes that rely on this script never set that variable and previously drained from the frontend gauge alone. Because SystemExit bypasses the retry handler, any multi-concurrency job exits as soon as drain runs.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit eae1874. Configure here.

@cquil11

cquil11 commented Sep 11, 2026

Copy link
Copy Markdown
Collaborator Author

/stage-results 34565384525

@github-actions

github-actions Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

@cquil11 staged run 34565384525: https://inferencemax-app-git-staging-semianalysisai.vercel.app/inference?i_dates=2026-09-11~r34565384525

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

@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.

Nothing blocking. The comments below are optional suggestions. There is no need to push a fix for them before merging.

Beyond the inline findings, I also checked utils/srt_slurm.py's image-cache handling: prepare_recipe only reads a pre-existing cached image path under SRT_SLURM_SHARED_BASE/containers and falls back to the raw image tag when no cached artifact exists — it never writes to or grows that directory itself, so this PR isn't introducing new unbounded cache growth outside GITHUB_WORKSPACE.

Extended reasoning...

This run reported findings (including a confirmed WORK_DIR-not-cleaned-up bug in runners/launch_srt_slurm.sh) that will be posted as inline comments, so approval is not appropriate. Beyond those, I independently checked utils/srt_slurm.py's prepare_recipe to see whether its image-cache lookup (image_cache / (image.replace(...) + '.sqsh'), backing --image-cache SRT_SLURM_SHARED_BASE/containers in runners/launch_srt_slurm.sh) itself creates or grows a persistent cache directory outside the CI workspace's clean lifecycle. It does not: the function only performs a read-only is_file() check and falls back to the plain image tag if no cached artifact is present, so this PR's own code path does not add to any cache-growth concern for that directory.

SRT_SLURM_REPOSITORY="${SRT_SLURM_REPOSITORY:-https://github.com/SemiAnalysisAI/srt-slurm.git}"
SRT_SLURM_COMMIT="${SRT_SLURM_COMMIT:-81d46274f508e18ab14d1f123b75132005818dcf}"
RUN_KEY="${GITHUB_RUN_ID:-manual}-${GITHUB_RUN_ATTEMPT:-0}-${RUNNER_NAME:-runner}"
WORK_DIR=$(mktemp -d "${GITHUB_WORKSPACE}/.srt-slurm-${RUN_KEY}.XXXXXX")

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.

🟡 (optional) WORK_DIR is created with mktemp under $GITHUB_WORKSPACE per invocation (unique per RUN_KEY) but is never removed on any exit path, including the success path and the cleanup() trap, unlike every other srt-slurm launcher in this repo (e.g. launch_b200-nscale-slurm.sh) which reuses a fixed dir and rm -rf's it before/after cloning specifically because GITHUB_WORKSPACE persists across jobs on these self-hosted runners. Each run leaves behind a full srt-slurm git clone plus its uv venv and outputs, so repeated CI runs (this is a full-sweep-enabled, repeatedly-scheduled workflow) accumulate GBs of clones/venvs on the shared runner disk indefinitely. Fix: rm -rf "$WORK_DIR" in cleanup() (or trap it separately) after collect_results has copied out what it needs, regardless of exit code.

Extended reasoning...

launch_mi300x-amd.sh execs launch_srt_slurm.sh whenever CONFIG_FILE is set (i.e. for every srt-slurm recipe run on this fleet). WORK_DIR=$(mktemp -d "$GITHUB_WORKSPACE/.srt-slurm-${RUN_KEY}.XXXXXX") creates a fresh directory named with GITHUB_RUN_ID-GITHUB_RUN_ATTEMPT-RUNNER_NAME, so it never collides with a prior run's directory (unlike the fixed 'srt-slurm' dir other launchers rm -rf before cloning into). git clone + make setup-compute + uv venv + uv pip install -e . populate SRT_REPO_DIR=$WORK_DIR/srt-slurm, and profile output_dir/results also live under $WORK_DIR. cleanup() (the EXIT trap) only calls the python adapter's collect (which copies files OUT of $WORK_DIR/results_root into $GITHUB_WORKSPACE) and then exit "$rc"; nothing in the file ever deletes $WORK_DIR itself. Because GITHUB_WORKSPACE is a persistent path on this self-hosted fleet (confirmed by sibling launchers explicitly rm -rf "$SRT_REPO_DIR" before every clone to avoid exactly this buildup), every successful or failed run of this new script leaves its full clone+venv on disk. Over the many scheduled…

Verification: nit. Factual claim is correct: launch_srt_slurm.sh:17 creates WORK_DIR=$(mktemp -d "${GITHUB_WORKSPACE}/.srt-slurm-${RUN_KEY}.XXXXXX") with a per-run-unique name (RUN_KEY=GITHUB_RUN_ID-RUN_ATTEMPT-RUNNER_NAME plus mktemp's .XXXXXX), and nothing in the script ever removes it. The cleanup() trap (lines 46-60) only scancels the job and runs the collect adapter; it explicitly does `trap - EXIT INT…

@github-actions

Copy link
Copy Markdown
Contributor

@cquil11

cquil11 commented Sep 13, 2026

Copy link
Copy Markdown
Collaborator Author

/reuse-sweep-run 34619026982

@cquil11

cquil11 commented Sep 13, 2026

Copy link
Copy Markdown
Collaborator Author

/stage-results 34619026982

@github-actions

github-actions Bot commented Sep 13, 2026

Copy link
Copy Markdown
Contributor

@cquil11 staged run 34619026982: https://inferencemax-app-git-staging-semianalysisai.vercel.app/inference?i_dates=2026-09-11~r34619026982

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

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