Skip to content

Commit a141bfc

Browse files
ichbinblaucquil11cursoragentAMD-yanfeiwangDuyi-Wang
authored
[AMD][AgentX] DeepSeek-V4 MI355X agentic disaggregated benchmarking (#2170)
* [AMD][AgentX] Add DeepSeek V4 MI355X agentic disagg * run-sweep: fix broken conc-list interpolation for multi-node agentic matrix.config.conc for multi-node agentic is already a JSON array (e.g. [16,32,64] from generate_sweep_configs.py). Wrapping it in a string literal as '[${{ matrix.config.conc }}]' can't correctly interpolate an array into a string, producing a malformed conc-list so fromJson(inputs.conc-list) in the reusable template ended up with an empty/wrong CONC_LIST. Use toJson(matrix.config.conc) instead, matching the pattern already used for the other two conc-list inputs in this file. Co-authored-by: Cursor <cursoragent@cursor.com> * bump image to rocm/sgl-dev:sglang-0.5.14-rocm720-mi35x-mori-0706 Signed-off-by: Theresa Shan <theresa.shan@amd.com> * run-sweep: fix sequence-typed conc input for multi-node agentic matrix.config.conc for multi-node agentic entries is a JSON array (chunked concurrencies per allocation), but sweep-multi-node-agentic passed it directly into benchmark-multinode-tmpl.yml's `conc` input, which is declared `type: string` ("First concurrency for agentic-coding scenarios; CONC_LIST carries the full batch"). GitHub Actions' reusable-workflow input validator rejects a sequence value for a string-typed input at evaluation time, so the whole job failed to even load: evaluate reusable workflow inputs: .github/workflows/run-sweep.yml (Line: 554, Col: 19): A sequence was not expected Since the job never materializes when this happens, sweep-multi-node- agentic silently disappeared from run summaries entirely instead of showing as failed. Slice to the first element (matching the intended "first concurrency" semantics and the same fix already applied elsewhere, e.g. PR #2122) to restore a scalar value. Co-authored-by: Cursor <cursoragent@cursor.com> * agentic: run one task per concurrency for multi-node sweeps Multi-node agentic sweeps batched up to 4 concurrencies per SLURM allocation, running them sequentially against one shared server session. A slow/hung conc could block the rest of the batch from ever producing results, which is why run #6719 only reported c16 despite a 16/32/48/64 conc-list. Drop the batch size to 1 so each concurrency gets its own task/allocation, matching the granularity already used for single-node agentic sweeps. Cherry-picked from backup/agentx-v1.0-rebase-pre-upstream-rewrite-20260710 (082a59d), adapted for the current test suite. Co-authored-by: Cursor <cursoragent@cursor.com> * Bump image to latest upstream image with 4 PR fixes included. * update con-list Signed-off-by: Theresa Shan <theresa.shan@amd.com> * setup_deps: remove disabled decode_tp_queue_agree patch patch_decode_tp_queue_agree()'s invocation was already commented out (dead code with no runtime effect), and the reference-only patches/decode_tp_queue_agree.patch it mirrored had no other callers. Drop both plus the README bullet pointing at it. Co-authored-by: Cursor <cursoragent@cursor.com> * setup_deps: broaden GLM transformers gate; disable prefill bootstrap-desync patch install_transformers_glm5() was gated on an exact MODEL_NAME == "GLM-5-FP8" match; broaden to any model name containing "GLM" so other GLM variants pick up the same glm_moe_dsa transformers fix. Also disable patch_disagg_prefill_bootstrap_desync's invocation (commented out, matching the already-disabled decode_tp_queue_agree pattern removed earlier). Co-authored-by: Cursor <cursoragent@cursor.com> * agentic: node-0 sibling benchmark-client container for DSv4 sweeps (#2147) * agentic: add node-0 sibling benchmark-client container for DSv4 sweeps Port the "same-node sibling container" client mode from ROCm/InferenceY: when CLIENT_IMAGE is set (and no CLIENT_NODES), node 0 launches the aiperf trace replay in its own pre-baked container via the host docker socket, instead of rebuilding the aiperf venv inside the server container and running it co-located. This keeps the client's CPU-heavy tokenize/aggregate work off the sglang scheduler + router, which inflates TTFT/E2E and lowers throughput under agentic concurrency. - server_sglang.sh: add IS_AGENTIC_RUN and a CLIENT_IMAGE sibling-container branch that writes client.env and docker-runs the client against the local router (--network host). - job.slurm: define CLIENT_CONT_NAME; when CLIENT_IMAGE is set, mount the host docker socket + CLI into the server container, forward HOST_REPO_DIR/HOST_MODEL_DIR/HOST_BENCH_LOGS/CLIENT_CONT_NAME, pre-pull the client image, and clean up the client container on teardown. - amd-master.yaml: enable the sibling client on dsv4-fp4-mi355x-sglang-disagg-agentic-hicache via CLIENT_IMAGE. The separate-client-NODE mode is intentionally not ported. * agentic: use server image for sibling client so upstream CI can pull it The pre-baked rocm/pytorch-private aiperf client image is not pullable by upstream CI runners. Reuse the (public) server image as CLIENT_IMAGE and build aiperf on the fly from /workspace/utils/aiperf, matching the co-located path. Gate the pre-baked-venv env (AIPERF_USE_PREBUILT / AIPERF_VENV) behind an optional CLIENT_AIPERF_VENV so a real pre-baked client image can still opt in. * enable log info and extend timeout Signed-off-by: Theresa Shan <theresa.shan@amd.com> * fix: address PR 2170 review comments Update the DSv4 MI355X agentic perf-changelog entry to point at PR 2170 with an accurate description, and move hf_dir into the DeepSeek-V4-Pro YAML block so the SGLang model path extractor can read it. 中文:修复 PR 2170 的 review 反馈:将 DSv4 MI355X agentic 的 perf-changelog 条目改为指向 PR 2170 并更新为准确描述,同时把 hf_dir 移入 DeepSeek-V4-Pro YAML 配置块,确保 SGLang 模型路径提取逻辑可以读取。 * setup_deps: remove prefill bootstrap-desync patch entirely The disaggregation-prefill bootstrap-desync patch was already disabled (commented out); drop the function, its comment block, and the stale invocation now that the fix is carried upstream in the pinned image. Co-authored-by: Cursor <cursoragent@cursor.com> * fix perf changelog * consolidate sglang agentic envs Signed-off-by: Theresa Shan <theresa.shan@amd.com> * select models.yaml recipe by IS_AGENTIC (AgentX/DI variants) Resolve the models.yaml entry per run type: agentic runs (IS_AGENTIC) use the '<model>-AgentX' recipe, non-agentic disaggregated runs use '<model>-DI', falling back to the bare model name when no variant key exists. Apply the same logic in both server_sglang.sh (lookup) and job.slurm (validation guard) so a bare MODEL_NAME (e.g. DeepSeek-V4-Pro) correctly maps to the suffixed key. Add DeepSeek-V4-Pro-DI and rename the agentic recipe to DeepSeek-V4-Pro-AgentX. Co-authored-by: Cursor <cursoragent@cursor.com> * DPTP enabling. Signed-off-by: Theresa Shan <theresa.shan@amd.com> * tune hicache ratio, router barrier timeout, and agentic conc sweep - server_sglang.sh: lower default HICACHE_RATIO 24->5 (cut host-pool pin/registration startup cost) and raise router health barrier timeout 1800->3000 so a slow server bring-up no longer trips the cross-node router wait first. - amd-master.yaml: restore conc 32 on the non-DP-attn (TP8) point and comment out the DP-attn c64/128 sweep block. - models.yaml: drop explicit max_total_tokens override for the AgentX dp variant (let it derive from context_length). Co-authored-by: Cursor <cursoragent@cursor.com> * raise hicache ratio to 16 Signed-off-by: Theresa Shan <theresa.shan@amd.com> * fix: restore qwen3.5 changelog entry removed during rebase perf-changelog.yaml must only gain entries; re-adding the upstream qwen3.5-fp8-gb300-dynamo-sglang block fixes process_changelog.py. Co-authored-by: Cursor <cursoragent@cursor.com> * fix: validate agentic hicache master config for changelog gate Use kv-offload-backend object form and add kv-p2p-transfer: mori for the disaggregated dsv4-fp4-mi355x-sglang-disagg-agentic-hicache entry. Co-authored-by: Cursor <cursoragent@cursor.com> * feat: wire KV_P2P_TRANSFER env into SGLang launch flags Override models.yaml --disaggregation-transfer-backend when kv-p2p-transfer from amd-master.yaml is set via CI, and forward KV_P2P_TRANSFER to the agentic client env for result metadata. Co-authored-by: Cursor <cursoragent@cursor.com> * chore: drop max_total_tokens from DSv4 AgentX prefill no_dp recipe Let SGLang auto-size the prefill KV pool instead of pinning 1M tokens. Co-authored-by: Cursor <cursoragent@cursor.com> * tune: raise router barrier timeout to 3000s for worker nodes Give prefill/decode workers more time to wait for the node-0 proxy during long agentic server startup. Co-authored-by: Cursor <cursoragent@cursor.com> * test: fix sweep config fixtures for kv-p2p-transfer validation Add kv-p2p-transfer to disagg multinode test configs and use KVOffloadBackendMetadata dict form for kv-offload-backend fields. Co-authored-by: Cursor <cursoragent@cursor.com> * refactor: centralize sync barrier timeouts for DSV4 startup Extract SYNC_BARRIER_TIMEOUT (3000s for DeepSeek-V4, 1800s otherwise) and apply it to server-up, router readiness, and prefill/decode proxy barriers. Also lower the default HICACHE_RATIO from 16 to 5. Co-authored-by: Cursor <cursoragent@cursor.com> * fix: forward KV offload backend metadata to agentic client Pass KV_OFFLOAD_BACKEND_METADATA into server containers via job.slurm and forward it to sibling client containers in server_sglang client.env so process_agentic_result can write aggregate JSON. Derive KV_OFFLOAD_BACKEND from metadata in the DSv4 agentic recipe when unset. Co-authored-by: Cursor <cursoragent@cursor.com> * revert: drop metadata-derived KV_OFFLOAD_BACKEND from DSv4 recipe CI already sets KV_OFFLOAD_BACKEND from the workflow; keep the job.slurm and server_sglang metadata forwarding fixes without the redundant recipe logic. Co-authored-by: Cursor <cursoragent@cursor.com> * fix: quote KV_OFFLOAD_BACKEND_METADATA in docker run env forwarding toJson() pretty-prints with embedded newlines, so the unquoted expansion in job.slurm's DOCKER_ENV_COMMON was word-split across the docker run command, corrupting its argument list ("docker: invalid reference format", exit 125). Quote the value so the whole JSON stays one token. Co-authored-by: Cursor <cursoragent@cursor.com> * Fix client.env generation to flatten multi-line env values docker run --env-file requires strict single-line KEY=VALUE entries. KV_OFFLOAD_BACKEND_METADATA carries pretty-printed multi-line JSON, which split into invalid env-file lines (e.g. '"name": "hicache",') and aborted the sibling client container launch with "docker: invalid env file ... contains whitespaces". Strip embedded newlines before writing each value so the JSON stays valid but single-line. Co-authored-by: Cursor <cursoragent@cursor.com> * Re-serialize KV_OFFLOAD_BACKEND_METADATA as compact JSON instead of stripping newlines Naive newline-stripping could silently corrupt a value if a JSON string ever contained a literal embedded newline (merging tokens across the line break). Round-tripping through json.loads/json.dumps guarantees a correct compact single-line representation for client.env, and fails loudly with a clear error if the value isn't valid JSON. Co-authored-by: Cursor <cursoragent@cursor.com> * Fix regression: skip JSON round-trip for empty KV_OFFLOAD_BACKEND_METADATA job.slurm always forwards KV_OFFLOAD_BACKEND_METADATA into the server container, even as "" when KV offloading is disabled (the common default case). The prior commit unconditionally ran it through json.loads/json.dumps, which raised JSONDecodeError on that empty string and hard-failed every agentic client-container launch without KV offloading. Only attempt the JSON round-trip when the value is non-empty and not "null", matching how optional_kv_offload_backend_metadata() already treats those as "no metadata" rather than invalid JSON. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(changelog): append PR entry after main * fix(changelog): omit null optional metadata * fix(agentx): set DeepSeek reasoning effort high * Remove stale patches/README.md documenting an already-retired mori_conn.py overlay mori_conn.py and the job.slurm auto-apply block it documented were already deleted upstream (retire MoRI conn.py PD-disagg overlay, aca9cee) once the real sglang fix landed in published images. A later unrelated commit (183a987) accidentally recreated this README from scratch while only intending to drop a bullet about a different, already-removed patch (decode_tp_queue_agree.patch), leaving stale docs pointing at a file and job.slurm block that no longer exist. Co-authored-by: Cursor <cursoragent@cursor.com> * feat(agentx): enforce agentic DRAM offload budget for multinode disagg Multinode agentic entries hardcoded total-cpu-dram-gb=0, so the DRAM KV-offload pool was never bounded at runtime (HiCache fell back to a relative --hicache-ratio). Compute a real per-node budget from the prefill worker (the only KV offloader today) and wire it through to a --hicache-size cap. - generate_sweep_configs: fold multinode into agentic_dram_offload_gb; budget the prefill worker's per-node GPU footprint via worker_gpus_per_node, which rejects node-misaligned topologies instead of silently truncating. - validation: add total-cpu-dram-gb to MultiNodeAgenticMatrixEntry. - run-sweep: forward total-cpu-dram-gb to the multi-node agentic dispatch. - server_sglang.sh: size prefill HiCache via absolute --hicache-size (budget / ranks-per-node / host-pools), falling back to --hicache-ratio when no budget is provided; drop the dead HICACHE_TOTAL_CPU_DRAM_GB default. * Fix indentation of dsv4-fp4-b200-vllm-agentic entry in perf-changelog.yaml The config-keys entry was missing its leading indentation, breaking YAML list alignment with sibling entries. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(agentx): skip --hicache-size for DeepSeek V4 in multinode HiCache DeepSeek V4's hybrid HiCache pool assembler rejects --hicache-size and requires --hicache-ratio, so the absolute per-node DRAM budget cannot be applied to it. Restrict the --hicache-size enforcement to non-V4 models; V4 falls back to --hicache-ratio. Budget stays recorded in the config. 中文:多节点 HiCache 对 DeepSeek V4 跳过 --hicache-size。DeepSeek V4 的 混合 HiCache 池不支持 --hicache-size、必须用 --hicache-ratio,因此绝对 的每节点 DRAM 预算无法作用于它。将 --hicache-size 限制为非 V4 模型; V4 回退到 --hicache-ratio。预算仍记录在 config 中。 --------- Signed-off-by: Theresa Shan <theresa.shan@amd.com> Co-authored-by: Cam Quilici <cjquilici@gmail.com> Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: AMD-yanfeiwang <yanfei.wang@amd.com> Co-authored-by: Duyi-Wang <duyi.wang@amd.com> Co-authored-by: billishyahao <bill.he@amd.com>
1 parent 673a601 commit a141bfc

16 files changed

Lines changed: 1326 additions & 272 deletions

File tree

.github/workflows/run-sweep.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,7 @@ jobs:
581581
kv-offloading: ${{ matrix.config.kv-offloading }}
582582
kv-offload-backend: ${{ matrix.config['kv-offload-backend'].name }}
583583
kv-offload-backend-metadata: ${{ matrix.config['kv-offload-backend'] && toJson(matrix.config['kv-offload-backend']) || '' }}
584+
total-cpu-dram-gb: ${{ matrix.config['total-cpu-dram-gb'] }}
584585
duration: ${{ matrix.config.duration }}
585586
run-eval: false
586587
scenario-type: agentic-coding
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
#!/usr/bin/env bash
2+
3+
# Agentic trace-replay recipe for a disaggregated SGLang server on MI355X
4+
# (DeepSeek-V4-Pro FP4, 1P1D TP8).
5+
#
6+
# CI-style sibling of dsr1_fp4_mi355x_sglang-disagg.sh: driven entirely by
7+
# environment variables and submits a SLURM job via submit.sh. The agentic /
8+
# HiCache-offload configuration mirrors the DSR1 recipe but uses DSV4-Pro
9+
# specific flags (dsv4 attention backend, page-size 256, SWA settings).
10+
11+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
12+
source "$SCRIPT_DIR/../../benchmark_lib.sh"
13+
14+
check_env_vars \
15+
CONC_LIST \
16+
ISL \
17+
OSL \
18+
IMAGE \
19+
SPEC_DECODING \
20+
MODEL_PATH \
21+
PREFILL_NUM_WORKERS \
22+
PREFILL_TP \
23+
PREFILL_EP \
24+
PREFILL_DP_ATTN \
25+
DECODE_NUM_WORKERS \
26+
DECODE_TP \
27+
DECODE_EP \
28+
DECODE_DP_ATTN \
29+
PREFILL_NODES \
30+
DECODE_NODES \
31+
RANDOM_RANGE_RATIO \
32+
DURATION \
33+
KV_OFFLOADING \
34+
IS_AGENTIC \
35+
FRAMEWORK
36+
37+
if [[ -n "$SLURM_JOB_ID" ]]; then
38+
echo "JOB $SLURM_JOB_ID running on $SLURMD_NODENAME"
39+
fi
40+
41+
set -x
42+
43+
# Use upstreamed multi_node scripts (no external clone needed)
44+
cd "$GITHUB_WORKSPACE/benchmarks/multi_node/amd_utils" || exit 1
45+
46+
# Set up SGL launch script-specific environment variables
47+
export TIME_LIMIT="${TIME_LIMIT:-08:00:00}"
48+
export MODEL_PATH=$MODEL_PATH
49+
export MODEL_NAME=$MODEL_NAME
50+
export CONTAINER_IMAGE=$IMAGE
51+
52+
# ── Identity / result naming ──
53+
export MODEL_PREFIX="${MODEL_PREFIX:-dsv4}"
54+
export PRECISION="${PRECISION:-fp4}"
55+
export RESULT_FILENAME="${RESULT_FILENAME:-${RUNNER_NAME:-dsv4-fp4-agentic}}"
56+
57+
# ── Agentic benchmark params ──
58+
export DURATION="${DURATION:-1800}"
59+
# DSV4-Pro max model len for agentic traces (matches single-node recipe).
60+
export MAX_MODEL_LEN="${MAX_MODEL_LEN:-1000000}"
61+
62+
# ── In-tree sglang patches ──
63+
# mori_conn.py targets hybrid-state bugs (GLM-5, Qwen3.5). DSV4-Pro uses a
64+
# pure MoE/DSA architecture without hybrid state; skip to avoid interference.
65+
export MORI_CONN_PATCH="${MORI_CONN_PATCH:-skip}"
66+
67+
# ── Aiter fault mitigation ──
68+
# --disable-custom-all-reduce avoids a known aiter fault on MI355X.
69+
export DISABLE_CUSTOM_ALL_REDUCE="${DISABLE_CUSTOM_ALL_REDUCE:-0}"
70+
71+
# ── KV cache offloading (HiCache) ──
72+
# KV_OFFLOADING=none | dram (passed from YAML; default none for disagg).
73+
# KV_OFFLOAD_BACKEND selects the backend when offloading is on; this recipe
74+
# only implements HiCache, so "hicache" is the only supported value.
75+
# HICACHE_TIER: L2 -> GPU + CPU-DRAM host pool. L3 -> + Mooncake store.
76+
export KV_OFFLOADING="${KV_OFFLOADING:-none}"
77+
if [[ "$KV_OFFLOADING" != "none" ]]; then
78+
export KV_OFFLOAD_BACKEND="${KV_OFFLOAD_BACKEND:-hicache}"
79+
fi
80+
# HiCache/Mooncake tunables only matter when KV offloading is enabled.
81+
if [[ "$KV_OFFLOADING" != "none" && "${KV_OFFLOAD_BACKEND:-}" == "hicache" ]]; then
82+
export HICACHE_TIER="${HICACHE_TIER:-L2}"
83+
export HICACHE_HOST_POOL_COUNT="${HICACHE_HOST_POOL_COUNT:-1}"
84+
# DSV4 uses page-size 256 (set in models.yaml); HiCache must match.
85+
export HICACHE_PAGE_SIZE="${HICACHE_PAGE_SIZE:-256}"
86+
# HiCache ratio (host pool = ratio * GPU KV pool). Default derived in server_sglang.sh.
87+
export HICACHE_RATIO="${HICACHE_RATIO:-}"
88+
89+
# ── HiCache layout/backend by tier ──
90+
# L3 (Mooncake): page_first + direct + write_through + storage=mooncake
91+
# L2 (CPU DRAM): layer_first + direct + write_through_selective + storage=none
92+
# NOTE: write_through_selective evicts only under GPU memory pressure, avoiding
93+
# the mori RDMA race that causes GPU memory access faults with write_through.
94+
if [[ "${HICACHE_TIER^^}" == "L3" ]]; then
95+
export HICACHE_MEM_LAYOUT="${HICACHE_MEM_LAYOUT:-page_first}"
96+
export HICACHE_IO_BACKEND="${HICACHE_IO_BACKEND:-direct}"
97+
export HICACHE_WRITE_POLICY="${HICACHE_WRITE_POLICY:-write_through}"
98+
export HICACHE_STORAGE_BACKEND="${HICACHE_STORAGE_BACKEND:-mooncake}"
99+
else
100+
export HICACHE_MEM_LAYOUT="${HICACHE_MEM_LAYOUT:-page_first}"
101+
export HICACHE_IO_BACKEND="${HICACHE_IO_BACKEND:-direct}"
102+
export HICACHE_WRITE_POLICY="${HICACHE_WRITE_POLICY:-write_through}"
103+
export HICACHE_STORAGE_BACKEND="${HICACHE_STORAGE_BACKEND:-}"
104+
fi
105+
export HICACHE_PREFETCH_POLICY="${HICACHE_PREFETCH_POLICY:-best_effort}"
106+
# Shared nodes: use non-default Mooncake ports to avoid collisions.
107+
export MC_MASTER_PORT="${MC_MASTER_PORT:-58137}"
108+
export MC_METADATA_PORT="${MC_METADATA_PORT:-8080}"
109+
export MC_METRICS_PORT="${MC_METRICS_PORT:-19003}"
110+
export MC_MASTER_THREADS="${MC_MASTER_THREADS:-64}"
111+
export MC_EVICTION_HIGH_WATERMARK="${MC_EVICTION_HIGH_WATERMARK:-0.95}"
112+
export MC_PATCH_HOSTPOOL="${MC_PATCH_HOSTPOOL:-1}"
113+
export MC_PROTOCOL="${MC_PROTOCOL:-tcp}"
114+
export MC_GLOBAL_SEG="${MC_GLOBAL_SEG:-64gb}"
115+
export MC_DEVICE="${MC_DEVICE:-}"
116+
export MC_MASTER_ADDR="${MC_MASTER_ADDR:-}"
117+
export MC_METADATA_SERVER="${MC_METADATA_SERVER:-}"
118+
fi
119+
120+
# ── MoRIIO RDMA Send Queue tuning ──
121+
export MORI_IO_SQ_BACKOFF_TIMEOUT_US="${MORI_IO_SQ_BACKOFF_TIMEOUT_US:-500000}"
122+
export MORI_IO_QP_MAX_SEND_WR="${MORI_IO_QP_MAX_SEND_WR:-32768}"
123+
124+
# ── SGLang PD router policy + server metrics ──
125+
export PREFILL_ROUTER_POLICY="${PREFILL_ROUTER_POLICY:-cache_aware}"
126+
export ENABLE_METRICS="${ENABLE_METRICS:-1}"
127+
128+
# ── MTP ──
129+
export DECODE_MTP_SIZE="${DECODE_MTP_SIZE:-0}"
130+
131+
# Derive EP/DP enable flags from the topology inputs.
132+
if [[ "${PREFILL_EP:-1}" -eq 1 ]]; then
133+
export PREFILL_ENABLE_EP=false
134+
else
135+
export PREFILL_ENABLE_EP=true
136+
fi
137+
138+
if [[ "$PREFILL_DP_ATTN" == "true" ]]; then
139+
export PREFILL_ENABLE_DP=true
140+
else
141+
export PREFILL_ENABLE_DP=false
142+
fi
143+
144+
if [[ "${DECODE_EP:-1}" -eq 1 ]]; then
145+
export DECODE_ENABLE_EP=false
146+
else
147+
export DECODE_ENABLE_EP=true
148+
fi
149+
150+
if [[ "$DECODE_DP_ATTN" == "true" ]]; then
151+
export DECODE_ENABLE_DP=true
152+
else
153+
export DECODE_ENABLE_DP=false
154+
fi
155+
156+
# Launch the job. CONC_LIST is space-delimited in YAML; submit.sh wants 'x'.
157+
JOB_ID=$(bash ./submit.sh $PREFILL_NODES \
158+
$PREFILL_NUM_WORKERS \
159+
$DECODE_NODES \
160+
$DECODE_NUM_WORKERS \
161+
$ISL $OSL "${CONC_LIST// /x}" inf \
162+
${PREFILL_ENABLE_EP} ${PREFILL_ENABLE_DP} \
163+
${DECODE_ENABLE_EP} ${DECODE_ENABLE_DP} \
164+
${PREFILL_TP} ${DECODE_TP} \
165+
${RANDOM_RANGE_RATIO})
166+
167+
if [[ $? -ne 0 ]]; then
168+
echo "Failed to submit job" >&2
169+
exit 1
170+
fi
171+
172+
echo "$JOB_ID"

benchmarks/multi_node/amd_utils/env.sh

Lines changed: 76 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,23 @@ set -x
1212
ENGINE="${ENGINE:-sglang-disagg}"
1313
export PYTHONDONTWRITEBYTECODE=1
1414

15+
# =============================================================================
16+
# HiCache / Mooncake settings from job.slurm
17+
# =============================================================================
18+
# job.slurm writes the recipe-provided HiCache/Mooncake tunables to
19+
# hicache_mc_<JID>.env and mounts it read-only at /config/hicache_mc.env. Source
20+
# it here (auto-export) so values like HICACHE_PAGE_SIZE=256 reach the container
21+
# before server_sglang.sh applies its "${VAR:-default}" fallbacks. Without this
22+
# the vars arrive unset and server_sglang.sh defaults HICACHE_PAGE_SIZE to 1,
23+
# overriding the recipe's --page-size. Empty values in the file are harmless:
24+
# the "${VAR:-default}" fallbacks still treat "" as unset.
25+
if [[ -f /config/hicache_mc.env ]]; then
26+
set -a
27+
source /config/hicache_mc.env
28+
set +a
29+
echo "[env.sh] sourced HiCache config from /config/hicache_mc.env (HICACHE_PAGE_SIZE=${HICACHE_PAGE_SIZE:-unset})"
30+
fi
31+
1532
# =============================================================================
1633
# Shared: IBDEVICES detection
1734
# =============================================================================
@@ -50,11 +67,11 @@ export NCCL_IB_HCA=${NCCL_IB_HCA:-$IBDEVICES}
5067
# =============================================================================
5168
# Shared by the vLLM MoRIIOConnector and the SGLang/MoRI KV-transfer path.
5269

53-
export MORI_IO_SQ_BACKOFF_TIMEOUT_US=50000
54-
export MORI_IO_QP_MAX_SEND_WR=16384
55-
export MORI_IO_QP_MAX_CQE=32768
56-
export MORI_IO_QP_MAX_SGE=2
57-
export MORI_IO_TC_DISABLE=0
70+
export MORI_IO_SQ_BACKOFF_TIMEOUT_US="${MORI_IO_SQ_BACKOFF_TIMEOUT_US:-50000}"
71+
export MORI_IO_QP_MAX_SEND_WR="${MORI_IO_QP_MAX_SEND_WR:-16384}"
72+
export MORI_IO_QP_MAX_CQE="${MORI_IO_QP_MAX_CQE:-32768}"
73+
export MORI_IO_QP_MAX_SGE="${MORI_IO_QP_MAX_SGE:-2}"
74+
export MORI_IO_TC_DISABLE="${MORI_IO_TC_DISABLE:-0}"
5875

5976
# QoS/DSCP configuration
6077
# Priority order: 1) Set by runner, 2) Detect via nicctl, 3) Detect from hostname
@@ -197,14 +214,27 @@ else
197214
export AITER_LOG_LEVEL=ERROR
198215

199216
export SGLANG_MORI_DISPATCH_DTYPE=auto
200-
export MORI_COMBINE_DTYPE_PREFILL=fp8_direct_cast
201-
export MORI_COMBINE_DTYPE_DECODE=fp8
217+
# export MORI_COMBINE_DTYPE_PREFILL=fp8_direct_cast
218+
# export MORI_COMBINE_DTYPE_DECODE=fp8
219+
export MORI_COMBINE_DTYPE_PREFILL=""
220+
export MORI_COMBINE_DTYPE_DECODE=""
202221
export SGLANG_MORI_QP_PER_TRANSFER=4
203222
export SGLANG_MORI_NUM_WORKERS=4
223+
# Keep these as overridable defaults (not hard assignments), otherwise
224+
# later tuning blocks cannot raise them for high-concurrency runs.
225+
# export MORI_IO_SQ_BACKOFF_TIMEOUT_US="${MORI_IO_SQ_BACKOFF_TIMEOUT_US:-500000}"
226+
227+
# export MORI_IO_QP_MAX_SEND_WR="${MORI_IO_QP_MAX_SEND_WR:-16384}"
228+
# export MORI_IO_QP_MAX_CQE=32768
229+
# export MORI_IO_QP_MAX_SGE=1
230+
231+
# export MORI_IO_TC_DISABLE=0
204232

205233
export SGLANG_DISAGGREGATION_BOOTSTRAP_TIMEOUT=3600
206234
export SGLANG_DISAGGREGATION_WAITING_TIMEOUT=3600
207235

236+
export SGLANG_HEALTH_CHECK_TIMEOUT=600
237+
208238
# GLM-5: uses NSA (not MLA), needs fused-decode-MLA disabled + fast loading
209239
if [[ "$MODEL_NAME" == "GLM-5-FP8" ]]; then
210240
export SGLANG_ROCM_FUSED_DECODE_MLA=0
@@ -242,15 +272,34 @@ else
242272
# 1 mirrors router logs to stdout via tee (useful for live debugging).
243273
export SGLANG_ROUTER_STDOUT_LOGS="${SGLANG_ROUTER_STDOUT_LOGS:-0}"
244274

275+
# FIXME: WA for latest upstream 0305 image
276+
export PYTHONPATH=/sgl-workspace/aiter:${PYTHONPATH}
277+
245278
# =========================================================================
246279
# DeepSeek-V4-Pro PD recipe overrides
247280
# Placed at the end of the SGLang env block so it wins over the global
248281
# MoRI/SGLang defaults set above. Mirrors the validated DSv4 manual PD
249-
# commands (see dsv4_mi355x_sglang_disagg_plan.md §2). Only the SGLang/MoRI
250-
# env knobs are pinned here; CLI flags live in models.yaml and the cluster
251-
# NIC/socket vars (NCCL_IB_HCA, *_SOCKET_IFNAME, IBDEVICES) stay runner-derived.
282+
# commands (ported from InferenceX amd/dsv4_sgl_di). These SGLANG_OPT_* /
283+
# AITER_* kernel-routing knobs steer DSv4 away from the default aiter CK
284+
# fused-MoE path, which raises "Unsupported kernel config for moe heuristic
285+
# dispatch" at decode time on this fp4 model (job 19034 crash). Only the
286+
# SGLang/MoRI env knobs are pinned here; CLI flags live in models.yaml and
287+
# the cluster NIC/socket vars stay runner-derived.
252288
# =========================================================================
253289
if [[ "$MODEL_NAME" == "DeepSeek-V4-Pro" ]]; then
290+
# MoRI RDMA send-queue depth for DSv4 (overrides the global default above).
291+
export MORI_IO_QP_MAX_SEND_WR=32767
292+
# Unified radix tree: cache impl with per-component (full-attn / SWA)
293+
# management for hybrid-attention models. Set unconditionally (not gated on
294+
# hicache) so all SGLang runs use it.
295+
export SGLANG_ENABLE_UNIFIED_RADIX_TREE=1
296+
# Proactively free out-of-window SWA KV slots during chunked prefill.
297+
# Without it, in-flight requests pin SWA KV for their whole context, keeping
298+
# the SWA pool under constant eviction pressure; under LRU the trailing
299+
# window of cached sessions gets flushed, making prefix-cache hits bimodal
300+
# and collapsing the effective hit rate on multi-turn agentic workloads.
301+
export SGLANG_OPT_UNIFIED_CACHE_FREE_OUT_OF_WINDOW_SLOTS=1
302+
254303
# MoRI dispatch/combine dtypes: auto for both roles (not the fp8 split default)
255304
export SGLANG_MORI_DISPATCH_DTYPE=auto
256305
export MORI_COMBINE_DTYPE_PREFILL=auto
@@ -262,42 +311,44 @@ else
262311
unset MORI_MOE_MAX_INPUT_TOKENS_PREFILL
263312
unset MORI_MOE_MAX_INPUT_TOKENS_DECODE
264313

265-
# PER_RANK dispatch tokens are pinned independently of the sizing above
266-
# (16384 prefill / 128 decode in the reference recipe). server_sglang.sh
267-
# prefers these over the MORI_MAX_DISPATCH_TOKENS_* coupling when set.
314+
# PER_RANK dispatch tokens pinned independently (16384 prefill / 128
315+
# decode); server_sglang.sh prefers these over the MORI_MAX_DISPATCH_*
316+
# coupling when set.
268317
export MORI_NUM_MAX_DISPATCH_TOKENS_PER_RANK_PREFILL=16384
269318
export MORI_NUM_MAX_DISPATCH_TOKENS_PER_RANK_DECODE=128
270319

271-
# Fixed inter-kernel switch threshold (not derived). NOTE: the DP+EP path in
272-
# server_sglang.sh recomputes this dynamically for the DEP topology.
320+
# Fixed inter-kernel switch threshold (not derived).
273321
export SGLANG_MORI_DISPATCH_INTER_KERNEL_SWITCH_THRESHOLD=4096
274322

275323
# Overlap plan stream on for DSv4 (global default is 0)
276-
export SGLANG_ENABLE_OVERLAP_PLAN_STREAM=0
324+
# export SGLANG_ENABLE_OVERLAP_PLAN_STREAM=0
277325

278326
# DSv4 model kernel routing (mirrors the single-node / manual PD recipe)
279327
export SGLANG_DEFAULT_THINKING=1
280-
export SGLANG_DSV4_REASONING_EFFORT=max
281-
export SGLANG_USE_ROCM700A=0
282-
export SGLANG_HACK_FLASHMLA_BACKEND=unified_kv_triton
328+
export SGLANG_DSV4_REASONING_EFFORT=high
283329
export SGLANG_OPT_DEEPGEMM_HC_PRENORM=false
330+
export SGLANG_USE_AITER=1
331+
export SGLANG_USE_ROCM700A=0
284332
export SGLANG_OPT_USE_FUSED_COMPRESS=true
285-
export SGLANG_OPT_USE_FUSED_COMPRESS_TRITON=true
333+
export SGLANG_HACK_FLASHMLA_BACKEND=unified_kv_triton
286334
export SGLANG_OPT_FP8_WO_A_GEMM=false
287335
export SGLANG_OPT_USE_JIT_INDEXER_METADATA=false
288336
export SGLANG_OPT_USE_TOPK_V2=false
289-
export SGLANG_OPT_USE_AITER_INDEXER=true
337+
export SGLANG_OPT_USE_AITER_INDEXER=${SGLANG_OPT_USE_AITER_INDEXER:-true}
290338
export SGLANG_OPT_USE_TILELANG_INDEXER=false
291339
export SGLANG_OPT_USE_TILELANG_MHC_PRE=false
292340
export SGLANG_OPT_USE_TILELANG_MHC_POST=false
293341
export SGLANG_FP8_PAGED_MQA_LOGITS_TORCH=1
342+
export SGLANG_OPT_USE_FUSED_COMPRESS_TRITON=true
294343
export SGLANG_OPT_USE_MULTI_STREAM_OVERLAP=false
295344
export SGLANG_ROCM_USE_MULTI_STREAM=false
296345
export AITER_BF16_FP8_MOE_BOUND=0
297346
export SGLANG_EAGER_INPUT_NO_COPY=true
347+
export SGLANG_SHARED_EXPERT_TP1=1
348+
export SGLANG_DP_SHARED_EXPERT_LOCAL=1
349+
export SGLANG_DP_USE_GATHERV=1
350+
export SGLANG_DP_USE_REDUCE_SCATTER=1
351+
export GPU_MAX_HW_QUEUES=5
298352
fi
299353

300-
# FIXME: WA for latest upstream 0305 image
301-
export PYTHONPATH=/sgl-workspace/aiter:${PYTHONPATH}
302-
303-
fi
354+
fi

0 commit comments

Comments
 (0)