From dc74d0a484b0d0f8e3538415173f8d8706308cf5 Mon Sep 17 00:00:00 2001 From: Duyi-Wang Date: Wed, 24 Jun 2026 05:07:33 +0000 Subject: [PATCH 01/10] [AMD] Add MiniMax-M3-MXFP4 MI355X vLLM disagg recipe Disaggregated (prefill/decode) vLLM recipe for amd/MiniMax-M3-MXFP4 on MI355X over the MoRI-IO KV connector. Recipe: - benchmarks/multi_node/minimaxm3_fp4_mi355x_vllm-disagg.sh: launcher. - models_vllm.yaml: MiniMax-M3-MXFP4 entry. block-size 128 (MSA), TRITON_ATTN, --language-model-only, AITER MoE, minimax_m3 parsers. No --kv-cache-dtype fp8 (the checkpoint ships no calibrated FP8 KV scales). - amd-master.yaml: minimaxm3-fp4-mi355x-vllm-disagg config, 8k1k, two layouts (1P1D TP4 and 2P1D TP4), conc 1..512. Supporting fixes to the shared vllm-disagg path: - server_vllm.sh: count prefill/decode GPUs from the per-worker TP size (PREFILL_TP_SIZE*xP / DECODE_TP_SIZE*yD) instead of GPUS_PER_NODE*xP. With TP < node GPU count (e.g. TP4 on an 8-GPU node) the old expression over-counted, corrupting PREFILL_GPUS/DECODE_GPUS and halving tput_per_gpu. - env.sh / job.slurm: set the MoRI-IO RDMA QP knobs (MORI_IO_QP_MAX_SEND_WR etc.) for the vllm-disagg path. They were only set in the SGLang branch, so vllm-disagg ran at the default send-queue depth and stalled at high concurrency ("SQ full"). --- .github/configs/amd-master.yaml | 50 +++++++ benchmarks/multi_node/amd_utils/env.sh | 122 +++++++++--------- .../multi_node/amd_utils/models_vllm.yaml | 6 + .../multi_node/amd_utils/server_vllm.sh | 2 +- .../minimaxm3_fp4_mi355x_vllm-disagg.sh | 78 +++++++++++ 5 files changed, 198 insertions(+), 60 deletions(-) create mode 100755 benchmarks/multi_node/minimaxm3_fp4_mi355x_vllm-disagg.sh diff --git a/.github/configs/amd-master.yaml b/.github/configs/amd-master.yaml index a3f352adaf..4fafc96206 100644 --- a/.github/configs/amd-master.yaml +++ b/.github/configs/amd-master.yaml @@ -2587,6 +2587,56 @@ minimaxm3-fp8-mi355x-vllm-mtp: - { tp: 4, conc-start: 1, conc-end: 64, spec-decoding: mtp } - { tp: 8, ep: 8, dp-attn: true, conc-start: 128, conc-end: 256, spec-decoding: mtp } +# MiniMax-M3 MXFP4 MI355X vLLM disaggregated (prefill/decode) config. +minimaxm3-fp4-mi355x-vllm-disagg: + image: rocm/sgl-dev:vllm-0.23.1-rocm723-mi35x-mori-0623-m3 + model: amd/MiniMax-M3-MXFP4 + model-prefix: minimaxm3 + runner: mi355x-disagg + precision: fp4 + framework: vllm-disagg + multinode: true + disagg: true + scenarios: + fixed-seq-len: + - isl: 8192 + osl: 1024 + search-space: + # 1P TP4 + 1D TP4 (2 nodes total), conc sweep 1..512 (single job, looped) + - spec-decoding: "none" + conc-list: [ 1, 2, 4, 8, 16, 32, 64, 128, 256, 512 ] + prefill: + num-worker: 1 + tp: 4 + ep: 1 + dp-attn: false + additional-settings: + - "PREFILL_NODES=1" + decode: + num-worker: 1 + tp: 4 + ep: 1 + dp-attn: false + additional-settings: + - "DECODE_NODES=1" + # 2P TP4 + 1D TP4 (3 nodes total), conc sweep 1..512 (single job, looped) + - spec-decoding: "none" + conc-list: [ 1, 2, 4, 8, 16, 32, 64, 128, 256, 512 ] + prefill: + num-worker: 2 + tp: 4 + ep: 1 + dp-attn: false + additional-settings: + - "PREFILL_NODES=2" + decode: + num-worker: 1 + tp: 4 + ep: 1 + dp-attn: false + additional-settings: + - "DECODE_NODES=1" + # MiniMax-M3 MXFP4 MI355X atom recipe: # https://github.com/ROCm/ATOM/blob/5d42d49f9e4292e5b61475917e92e7ec1b1dacb7/recipes/MiniMax-M3.md # block size 128 is mandatory for MSA. TP4 on a single gfx950 node, per the recipe. diff --git a/benchmarks/multi_node/amd_utils/env.sh b/benchmarks/multi_node/amd_utils/env.sh index a24347114b..a05182bf16 100755 --- a/benchmarks/multi_node/amd_utils/env.sh +++ b/benchmarks/multi_node/amd_utils/env.sh @@ -45,6 +45,68 @@ set +x export NCCL_IB_HCA=${NCCL_IB_HCA:-$IBDEVICES} +# ============================================================================= +# MoRI-specific environment +# ============================================================================= +# Shared by the vLLM MoRIIOConnector and the SGLang/MoRI KV-transfer path. + +export MORI_IO_SQ_BACKOFF_TIMEOUT_US=50000 +export MORI_IO_QP_MAX_SEND_WR=16384 +export MORI_IO_QP_MAX_CQE=32768 +export MORI_IO_QP_MAX_SGE=2 +export MORI_IO_TC_DISABLE=0 + +# QoS/DSCP configuration +# Priority order: 1) Set by runner, 2) Detect via nicctl, 3) Detect from hostname +if [[ -n "$MORI_RDMA_TC" ]]; then + echo "[INFO] Using MORI_RDMA_TC=$MORI_RDMA_TC (set by runner or environment)" +elif command -v nicctl &> /dev/null; then + ND_PRIO=$(nicctl show qos 2>/dev/null | awk '/PFC no-drop priorities/ {print $NF; exit}') + ND_DSCP=$(nicctl show qos 2>/dev/null| awk -v p="$ND_PRIO" ' +$1 == "DSCP" && $2 == ":" && $NF == p { + print $3; exit +}') + + if [[ -n "$ND_DSCP" ]] && [[ -n "$ND_PRIO" ]]; then + TC=$(( 4 * ND_DSCP )) + export MORI_RDMA_SL=$ND_PRIO + export MORI_IO_SL=$ND_PRIO + export MORI_RDMA_TC=$TC + export MORI_IO_TC=$TC + echo "[INFO] Detected QoS config from nicctl: MORI_RDMA_TC=$MORI_RDMA_TC, MORI_RDMA_SL=$MORI_RDMA_SL, MORI_IO_TC=$MORI_IO_TC, MORI_IO_SL=$MORI_IO_SL" + else + echo "[WARN] nicctl available but QoS data unavailable; trying hostname detection." + # Fall back to hostname-based detection + NODENAME=$(hostname -s) + if [[ $NODENAME == GPU* ]] || [[ $NODENAME == smci355-ccs-aus* ]]; then + export MORI_RDMA_TC=96 + export MORI_IO_TC=96 + echo "[INFO] Auto-detected MORI_RDMA_TC=$MORI_RDMA_TC from hostname $NODENAME" + elif [[ $NODENAME == mia1* ]]; then + export MORI_RDMA_TC=104 + export MORI_IO_TC=104 + echo "[INFO] Auto-detected MORI_RDMA_TC=$MORI_RDMA_TC from hostname $NODENAME" + else + echo "[INFO] Unable to detect MORI_RDMA_TC from hostname. Skipping RDMA QoS configuration." + fi + fi +else + # nicctl not available, try hostname-based detection + NODENAME=$(hostname -s) + if [[ $NODENAME == GPU* ]] || [[ $NODENAME == smci355-ccs-aus* ]]; then + export MORI_RDMA_TC=96 + export MORI_IO_TC=96 + echo "[INFO] Auto-detected MORI_RDMA_TC=$MORI_RDMA_TC from hostname $NODENAME" + elif [[ $NODENAME == mia1* ]]; then + export MORI_RDMA_TC=104 + export MORI_IO_TC=104 + echo "[INFO] Auto-detected MORI_RDMA_TC=$MORI_RDMA_TC from hostname $NODENAME" + else + echo "[INFO] nicctl not found and unable to detect from hostname. Skipping RDMA QoS configuration." + echo " This is normal for clusters without QoS or outside Docker containers." + fi +fi + # ============================================================================= # Engine-specific environment # ============================================================================= @@ -120,7 +182,7 @@ $1 == "DSCP" && $2 == ":" && $NF == p { else # ========================================================================= - # SGLang/MoRI-specific environment + # SGLang-specific environment # ========================================================================= export SGLANG_USE_AITER=1 @@ -131,13 +193,6 @@ else export MORI_COMBINE_DTYPE_DECODE=fp8 export SGLANG_MORI_QP_PER_TRANSFER=4 export SGLANG_MORI_NUM_WORKERS=4 - export MORI_IO_SQ_BACKOFF_TIMEOUT_US=50000 - - export MORI_IO_QP_MAX_SEND_WR=16384 - export MORI_IO_QP_MAX_CQE=32768 - export MORI_IO_QP_MAX_SGE=4 - - export MORI_IO_TC_DISABLE=0 export SGLANG_DISAGGREGATION_BOOTSTRAP_TIMEOUT=3600 export SGLANG_DISAGGREGATION_WAITING_TIMEOUT=3600 @@ -179,57 +234,6 @@ else # 1 mirrors router logs to stdout via tee (useful for live debugging). export SGLANG_ROUTER_STDOUT_LOGS="${SGLANG_ROUTER_STDOUT_LOGS:-0}" - # QoS/DSCP configuration - # Priority order: 1) Set by runner, 2) Detect via nicctl, 3) Detect from hostname - if [[ -n "$MORI_RDMA_TC" ]]; then - echo "[INFO] Using MORI_RDMA_TC=$MORI_RDMA_TC (set by runner or environment)" - elif command -v nicctl &> /dev/null; then - ND_PRIO=$(nicctl show qos 2>/dev/null | awk '/PFC no-drop priorities/ {print $NF; exit}') - ND_DSCP=$(nicctl show qos 2>/dev/null| awk -v p="$ND_PRIO" ' -$1 == "DSCP" && $2 == ":" && $NF == p { - print $3; exit -}') - - if [[ -n "$ND_DSCP" ]] && [[ -n "$ND_PRIO" ]]; then - TC=$(( 4 * ND_DSCP )) - export MORI_RDMA_SL=$ND_PRIO - export MORI_IO_SL=$ND_PRIO - export MORI_RDMA_TC=$TC - export MORI_IO_TC=$TC - echo "[INFO] Detected QoS config from nicctl: MORI_RDMA_TC=$MORI_RDMA_TC, MORI_RDMA_SL=$MORI_RDMA_SL, MORI_IO_TC=$MORI_IO_TC, MORI_IO_SL=$MORI_IO_SL" - else - echo "[WARN] nicctl available but QoS data unavailable; trying hostname detection." - # Fall back to hostname-based detection - NODENAME=$(hostname -s) - if [[ $NODENAME == GPU* ]] || [[ $NODENAME == smci355-ccs-aus* ]]; then - export MORI_RDMA_TC=96 - export MORI_IO_TC=96 - echo "[INFO] Auto-detected MORI_RDMA_TC=$MORI_RDMA_TC from hostname $NODENAME" - elif [[ $NODENAME == mia1* ]]; then - export MORI_RDMA_TC=104 - export MORI_IO_TC=104 - echo "[INFO] Auto-detected MORI_RDMA_TC=$MORI_RDMA_TC from hostname $NODENAME" - else - echo "[INFO] Unable to detect MORI_RDMA_TC from hostname. Skipping RDMA QoS configuration." - fi - fi - else - # nicctl not available, try hostname-based detection - NODENAME=$(hostname -s) - if [[ $NODENAME == GPU* ]] || [[ $NODENAME == smci355-ccs-aus* ]]; then - export MORI_RDMA_TC=96 - export MORI_IO_TC=96 - echo "[INFO] Auto-detected MORI_RDMA_TC=$MORI_RDMA_TC from hostname $NODENAME" - elif [[ $NODENAME == mia1* ]]; then - export MORI_RDMA_TC=104 - export MORI_IO_TC=104 - echo "[INFO] Auto-detected MORI_RDMA_TC=$MORI_RDMA_TC from hostname $NODENAME" - else - echo "[INFO] nicctl not found and unable to detect from hostname. Skipping RDMA QoS configuration." - echo " This is normal for clusters without QoS or outside Docker containers." - fi - fi - # FIXME: WA for latest upstream 0305 image export PYTHONPATH=/sgl-workspace/aiter:${PYTHONPATH} diff --git a/benchmarks/multi_node/amd_utils/models_vllm.yaml b/benchmarks/multi_node/amd_utils/models_vllm.yaml index a566fe449b..ddfa5356eb 100644 --- a/benchmarks/multi_node/amd_utils/models_vllm.yaml +++ b/benchmarks/multi_node/amd_utils/models_vllm.yaml @@ -38,6 +38,12 @@ MiniMax-M2.5: env: "VLLM_USE_V1=1 VLLM_ROCM_USE_AITER=1 VLLM_ROCM_QUICK_REDUCE_QUANTIZATION=INT4 VLLM_ENGINE_READY_TIMEOUT_S=3600 VLLM_ROCM_SHUFFLE_KV_CACHE_LAYOUT=1" hf_dir: "models--MiniMaxAI--MiniMax-M2.5" +MiniMax-M3-MXFP4: + prefill_flags: "--tensor-parallel-size 8 --max-num-batched-tokens 16384 --max-num-seqs 512 --block-size 128 --language-model-only --attention-backend TRITON_ATTN --moe-backend aiter --no-enable-prefix-caching --gpu-memory-utilization 0.90 --tool-call-parser minimax_m3 --reasoning-parser minimax_m3 --enable-auto-tool-choice" + decode_flags: "--tensor-parallel-size 8 --max-num-batched-tokens 16384 --max-num-seqs 512 --block-size 128 --language-model-only --attention-backend TRITON_ATTN --moe-backend aiter --no-enable-prefix-caching --gpu-memory-utilization 0.90 --tool-call-parser minimax_m3 --reasoning-parser minimax_m3 --enable-auto-tool-choice" + env: "VLLM_USE_V1=1 VLLM_ROCM_USE_AITER=1 VLLM_ROCM_USE_AITER_MOE=1 VLLM_USE_BREAKABLE_CUDAGRAPH=0 VLLM_ENGINE_READY_TIMEOUT_S=3600" + hf_dir: "models--amd--MiniMax-M3-MXFP4" + gpt-oss-120b: prefill_flags: "--tensor-parallel-size 8" decode_flags: "--tensor-parallel-size 8" diff --git a/benchmarks/multi_node/amd_utils/server_vllm.sh b/benchmarks/multi_node/amd_utils/server_vllm.sh index f02b1cd563..c3a6dbf14a 100755 --- a/benchmarks/multi_node/amd_utils/server_vllm.sh +++ b/benchmarks/multi_node/amd_utils/server_vllm.sh @@ -302,7 +302,7 @@ if [ "$NODE_RANK" -eq 0 ]; then cd $WS_PATH export ROUTER_PORT=$ROUTER_PORT - BENCH_CMD="bash $WS_PATH/bench.sh ${xP} ${yD} $((GPUS_PER_NODE*xP)) $((GPUS_PER_NODE*yD)) \ + BENCH_CMD="bash $WS_PATH/bench.sh ${xP} ${yD} $((PREFILL_TP_SIZE*xP)) $((DECODE_TP_SIZE*yD)) \ $MODEL_DIR $MODEL_NAME /run_logs/slurm_job-${SLURM_JOB_ID} ${BENCH_INPUT_LEN} \ ${BENCH_OUTPUT_LEN} \"${BENCH_MAX_CONCURRENCY}\" ${BENCH_REQUEST_RATE} \ ${BENCH_RANDOM_RANGE_RATIO} ${BENCH_NUM_PROMPTS_MULTIPLIER}" diff --git a/benchmarks/multi_node/minimaxm3_fp4_mi355x_vllm-disagg.sh b/benchmarks/multi_node/minimaxm3_fp4_mi355x_vllm-disagg.sh new file mode 100755 index 0000000000..2658b8615c --- /dev/null +++ b/benchmarks/multi_node/minimaxm3_fp4_mi355x_vllm-disagg.sh @@ -0,0 +1,78 @@ +#!/usr/bin/env bash + +source "$(dirname "$0")/../benchmark_lib.sh" + +check_env_vars \ + CONC_LIST \ + ISL \ + OSL \ + IMAGE \ + SPEC_DECODING \ + MODEL_PATH \ + PREFILL_NUM_WORKERS \ + PREFILL_TP \ + PREFILL_EP \ + PREFILL_DP_ATTN \ + DECODE_NUM_WORKERS \ + DECODE_TP \ + DECODE_EP \ + DECODE_DP_ATTN \ + PREFILL_NODES \ + DECODE_NODES \ + RANDOM_RANGE_RATIO \ + FRAMEWORK + +if [[ -n "$SLURM_JOB_ID" ]]; then + echo "JOB $SLURM_JOB_ID running on $SLURMD_NODENAME" +fi + +set -x + +cd "$GITHUB_WORKSPACE/benchmarks/multi_node/amd_utils" || exit 1 + +export TIME_LIMIT="08:00:00" +export MODEL_PATH=$MODEL_PATH +export MODEL_NAME=$MODEL_NAME +export CONTAINER_IMAGE=$IMAGE + +if [[ "${PREFILL_EP:-1}" -eq 1 ]]; then + export PREFILL_ENABLE_EP=false +else + export PREFILL_ENABLE_EP=true +fi + +if [[ "$PREFILL_DP_ATTN" == "true" ]]; then + export PREFILL_ENABLE_DP=true +else + export PREFILL_ENABLE_DP=false +fi + +if [[ "${DECODE_EP:-1}" -eq 1 ]]; then + export DECODE_ENABLE_EP=false +else + export DECODE_ENABLE_EP=true +fi + +if [[ "$DECODE_DP_ATTN" == "true" ]]; then + export DECODE_ENABLE_DP=true +else + export DECODE_ENABLE_DP=false +fi + +JOB_ID=$(bash ./submit.sh $PREFILL_NODES \ + $PREFILL_NUM_WORKERS \ + $DECODE_NODES \ + $DECODE_NUM_WORKERS \ + $ISL $OSL "${CONC_LIST// /x}" inf \ + ${PREFILL_ENABLE_EP} ${PREFILL_ENABLE_DP} \ + ${DECODE_ENABLE_EP} ${DECODE_ENABLE_DP} \ + ${PREFILL_TP} ${DECODE_TP} \ + ${RANDOM_RANGE_RATIO} \ + "${NODE_LIST:-}") + +if [[ $? -ne 0 ]]; then + echo "Failed to submit job" >&2 + exit 1 +fi + +echo "$JOB_ID" From 7b3ed239d73c6aa835fae4f9b7e4ec2b2f0cbdfd Mon Sep 17 00:00:00 2001 From: Duyi-Wang Date: Wed, 24 Jun 2026 06:30:59 +0000 Subject: [PATCH 02/10] [AMD] perf-changelog: add MiniMax-M3-MXFP4 MI355X vLLM disagg entry --- perf-changelog.yaml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/perf-changelog.yaml b/perf-changelog.yaml index 9c45a352ad..887abf5e53 100644 --- a/perf-changelog.yaml +++ b/perf-changelog.yaml @@ -4146,7 +4146,7 @@ - "Image: lmsysorg/sglang:nightly-dev-cu13-20260528-0abe6a85" - "8 topologies: low-latency 1p1d-tp8-tp8 + 1p6d-dep8-tp8; mid-curve 1p1d through 6p1d-dep8-dep16." pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/1676 - + - config-keys: - minimaxm3-fp8-b300-dynamo-vllm description: @@ -4162,7 +4162,7 @@ - "server_atom.sh: fix _MAX_CONC assignment before cudagraph size check; gate ATOM_MOE_GU_ITLV/AITER_BF16_FP8_MOE_BOUND on DeepSeek-V4-Pro only" - "Search space: ISL=8192 and ISL=1024, 1P1D TP4, conc 1-512" pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/1865 - + - config-keys: - minimaxm3-fp8-mi355x-vllm-disagg description: @@ -4183,10 +4183,16 @@ - "server_atom.sh: fix _MAX_CONC assignment before cudagraph size check; gate ATOM_MOE_GU_ITLV/AITER_BF16_FP8_MOE_BOUND on DeepSeek-V4-Pro only" - "Search space: ISL=8192 and ISL=1024, 1P1D TP4, conc 1-512" pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/1927 - + - config-keys: - dsv4-fp4-b200-dynamo-vllm description: - "Update the DeepSeek-V4-Pro B200 disaggregated Dynamo-vLLM benchmark to the vllm/vllm-openai:v0.23.0 image" - "Lower max-num-batched-tokens to 16384 and gpu-memory-utilization to 0.9 on the high-throughput and max-throughput recipes to avoid OOM" pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/1899 + +- config-keys: + - minimaxm3-fp4-mi355x-vllm-disagg + description: + - "Initial submission: MiniMax-M3 MXFP4 disagg (prefill/decode) on MI355X with vLLM over the MoRI-IO KV connector (8k/1k)." + pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/1914 From 6592e7f3b4ebd6cead2e684b82ab853c192e1ff0 Mon Sep 17 00:00:00 2001 From: Duyi-Wang Date: Wed, 24 Jun 2026 07:03:51 +0000 Subject: [PATCH 03/10] [AMD] server_vllm.sh: default PREFILL/DECODE_TP_SIZE to a full node Mirror server_sglang.sh / server_atom.sh so the bench.sh GPU count never resolves to 0 if submit.sh did not export the per-worker TP size. --- benchmarks/multi_node/amd_utils/server_vllm.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/benchmarks/multi_node/amd_utils/server_vllm.sh b/benchmarks/multi_node/amd_utils/server_vllm.sh index c3a6dbf14a..f19ce8560b 100755 --- a/benchmarks/multi_node/amd_utils/server_vllm.sh +++ b/benchmarks/multi_node/amd_utils/server_vllm.sh @@ -39,6 +39,9 @@ BENCH_MAX_CONCURRENCY="${BENCH_MAX_CONCURRENCY:-512}" DRY_RUN="${DRY_RUN:-0}" GPUS_PER_NODE="${GPUS_PER_NODE:-8}" +PREFILL_TP_SIZE="${PREFILL_TP_SIZE:-$GPUS_PER_NODE}" +DECODE_TP_SIZE="${DECODE_TP_SIZE:-$GPUS_PER_NODE}" + ROUTER_PORT="${ROUTER_PORT:-30000}" SERVER_PORT="${SERVER_PORT:-2584}" ENGINE_ID="${ENGINE_ID:-${MODEL_NAME}-pd-run}" From a29be9b833babebe005f46ab5a9663487cc57c77 Mon Sep 17 00:00:00 2001 From: Duyi-Wang Date: Wed, 24 Jun 2026 09:28:41 +0000 Subject: [PATCH 04/10] [AMD] job.slurm: inject MoRI-IO QP knobs via docker -e for vllm-disagg env.sh exports the MORI_IO_* QP knobs but they do not propagate to the vLLM worker processes, so inject them into the container base env via docker -e. MORI_IO_TC_DISABLE is intentionally omitted: the TC value is detected per-node in env.sh and cannot reach the workers, so enabling TC steering without a TC value would just fall back to TC=0; leave MoRI-IO at its library default instead. --- benchmarks/multi_node/amd_utils/job.slurm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/benchmarks/multi_node/amd_utils/job.slurm b/benchmarks/multi_node/amd_utils/job.slurm index 895f1ac2fb..3c851ad5ab 100755 --- a/benchmarks/multi_node/amd_utils/job.slurm +++ b/benchmarks/multi_node/amd_utils/job.slurm @@ -404,6 +404,10 @@ if [[ "$ENGINE" == "vllm-disagg" ]]; then -e HSA_ENABLE_SDMA=1 -e PROXY_STREAM_IDLE_TIMEOUT=\${PROXY_STREAM_IDLE_TIMEOUT:-300} -e PYTHONPYCACHEPREFIX=/tmp/pycache + -e MORI_IO_SQ_BACKOFF_TIMEOUT_US=\${MORI_IO_SQ_BACKOFF_TIMEOUT_US:-50000} + -e MORI_IO_QP_MAX_SEND_WR=\${MORI_IO_QP_MAX_SEND_WR:-16384} + -e MORI_IO_QP_MAX_CQE=\${MORI_IO_QP_MAX_CQE:-32768} + -e MORI_IO_QP_MAX_SGE=\${MORI_IO_QP_MAX_SGE:-2} ) elif [[ "$ENGINE" == "atom-disagg" ]]; then DOCKER_ENV_ENGINE=( From 68c3d63945892f371e5b7f894cdbd91cee2b808a Mon Sep 17 00:00:00 2001 From: Duyi-Wang Date: Wed, 24 Jun 2026 12:18:41 +0000 Subject: [PATCH 05/10] [AMD] minimaxm3-fp4 disagg: switch to mori-0624-2 image, read_mode, 1P1D only - amd-master.yaml: bump image to rocm/sgl-dev:vllm-0.23.1-rocm723-mi35x-mori-0624-2; drop the 2P1D layout and cap the 1P1D conc sweep at 256. - server_vllm.sh: set read_mode:true on the MoRIIOConnector kv-transfer-config. - job.slurm: drop the MORI_IO_* docker -e injection (handled by the image / env.sh). --- .github/configs/amd-master.yaml | 23 +++-------------------- benchmarks/multi_node/amd_utils/job.slurm | 4 ---- 2 files changed, 3 insertions(+), 24 deletions(-) diff --git a/.github/configs/amd-master.yaml b/.github/configs/amd-master.yaml index 4fafc96206..cdd91d83e7 100644 --- a/.github/configs/amd-master.yaml +++ b/.github/configs/amd-master.yaml @@ -2589,7 +2589,7 @@ minimaxm3-fp8-mi355x-vllm-mtp: # MiniMax-M3 MXFP4 MI355X vLLM disaggregated (prefill/decode) config. minimaxm3-fp4-mi355x-vllm-disagg: - image: rocm/sgl-dev:vllm-0.23.1-rocm723-mi35x-mori-0623-m3 + image: rocm/sgl-dev:vllm-0.23.1-rocm723-mi35x-mori-0624-2 model: amd/MiniMax-M3-MXFP4 model-prefix: minimaxm3 runner: mi355x-disagg @@ -2602,9 +2602,9 @@ minimaxm3-fp4-mi355x-vllm-disagg: - isl: 8192 osl: 1024 search-space: - # 1P TP4 + 1D TP4 (2 nodes total), conc sweep 1..512 (single job, looped) + # 1P TP4 + 1D TP4 (2 nodes total), conc sweep 1..256 (single job, looped) - spec-decoding: "none" - conc-list: [ 1, 2, 4, 8, 16, 32, 64, 128, 256, 512 ] + conc-list: [ 1, 2, 4, 8, 16, 32, 64, 128, 256 ] prefill: num-worker: 1 tp: 4 @@ -2619,23 +2619,6 @@ minimaxm3-fp4-mi355x-vllm-disagg: dp-attn: false additional-settings: - "DECODE_NODES=1" - # 2P TP4 + 1D TP4 (3 nodes total), conc sweep 1..512 (single job, looped) - - spec-decoding: "none" - conc-list: [ 1, 2, 4, 8, 16, 32, 64, 128, 256, 512 ] - prefill: - num-worker: 2 - tp: 4 - ep: 1 - dp-attn: false - additional-settings: - - "PREFILL_NODES=2" - decode: - num-worker: 1 - tp: 4 - ep: 1 - dp-attn: false - additional-settings: - - "DECODE_NODES=1" # MiniMax-M3 MXFP4 MI355X atom recipe: # https://github.com/ROCm/ATOM/blob/5d42d49f9e4292e5b61475917e92e7ec1b1dacb7/recipes/MiniMax-M3.md diff --git a/benchmarks/multi_node/amd_utils/job.slurm b/benchmarks/multi_node/amd_utils/job.slurm index 3c851ad5ab..895f1ac2fb 100755 --- a/benchmarks/multi_node/amd_utils/job.slurm +++ b/benchmarks/multi_node/amd_utils/job.slurm @@ -404,10 +404,6 @@ if [[ "$ENGINE" == "vllm-disagg" ]]; then -e HSA_ENABLE_SDMA=1 -e PROXY_STREAM_IDLE_TIMEOUT=\${PROXY_STREAM_IDLE_TIMEOUT:-300} -e PYTHONPYCACHEPREFIX=/tmp/pycache - -e MORI_IO_SQ_BACKOFF_TIMEOUT_US=\${MORI_IO_SQ_BACKOFF_TIMEOUT_US:-50000} - -e MORI_IO_QP_MAX_SEND_WR=\${MORI_IO_QP_MAX_SEND_WR:-16384} - -e MORI_IO_QP_MAX_CQE=\${MORI_IO_QP_MAX_CQE:-32768} - -e MORI_IO_QP_MAX_SGE=\${MORI_IO_QP_MAX_SGE:-2} ) elif [[ "$ENGINE" == "atom-disagg" ]]; then DOCKER_ENV_ENGINE=( From 3d5a50797524b59bfd5f7e999e5275dbf6339762 Mon Sep 17 00:00:00 2001 From: Duyi-Wang Date: Wed, 24 Jun 2026 14:00:43 +0000 Subject: [PATCH 06/10] [AMD] minimaxm3-fp4: prefill-only INT4 quick-reduce, max-num-batched-tokens 32768 - models_vllm.yaml: add prefill_env (VLLM_ROCM_QUICK_REDUCE_QUANTIZATION=INT4, VLLM_ROCM_QUICK_REDUCE_MAX_SIZE_BYTES_MB=2048); bump prefill+decode --max-num-batched-tokens 16384 -> 32768. - server_vllm.sh: add a prefill_env / PREFILL_MODEL_ENVS channel (mirrors the existing decode_env path) so prefill-only env reaches every prefill rank. --- benchmarks/multi_node/amd_utils/models_vllm.yaml | 5 +++-- benchmarks/multi_node/amd_utils/server_vllm.sh | 12 ++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/benchmarks/multi_node/amd_utils/models_vllm.yaml b/benchmarks/multi_node/amd_utils/models_vllm.yaml index ddfa5356eb..646cdba2ac 100644 --- a/benchmarks/multi_node/amd_utils/models_vllm.yaml +++ b/benchmarks/multi_node/amd_utils/models_vllm.yaml @@ -39,9 +39,10 @@ MiniMax-M2.5: hf_dir: "models--MiniMaxAI--MiniMax-M2.5" MiniMax-M3-MXFP4: - prefill_flags: "--tensor-parallel-size 8 --max-num-batched-tokens 16384 --max-num-seqs 512 --block-size 128 --language-model-only --attention-backend TRITON_ATTN --moe-backend aiter --no-enable-prefix-caching --gpu-memory-utilization 0.90 --tool-call-parser minimax_m3 --reasoning-parser minimax_m3 --enable-auto-tool-choice" - decode_flags: "--tensor-parallel-size 8 --max-num-batched-tokens 16384 --max-num-seqs 512 --block-size 128 --language-model-only --attention-backend TRITON_ATTN --moe-backend aiter --no-enable-prefix-caching --gpu-memory-utilization 0.90 --tool-call-parser minimax_m3 --reasoning-parser minimax_m3 --enable-auto-tool-choice" + prefill_flags: "--tensor-parallel-size 8 --max-num-batched-tokens 32768 --max-num-seqs 512 --block-size 128 --language-model-only --attention-backend TRITON_ATTN --moe-backend aiter --no-enable-prefix-caching --gpu-memory-utilization 0.90 --tool-call-parser minimax_m3 --reasoning-parser minimax_m3 --enable-auto-tool-choice" + decode_flags: "--tensor-parallel-size 8 --max-num-batched-tokens 32768 --max-num-seqs 512 --block-size 128 --language-model-only --attention-backend TRITON_ATTN --moe-backend aiter --no-enable-prefix-caching --gpu-memory-utilization 0.90 --tool-call-parser minimax_m3 --reasoning-parser minimax_m3 --enable-auto-tool-choice" env: "VLLM_USE_V1=1 VLLM_ROCM_USE_AITER=1 VLLM_ROCM_USE_AITER_MOE=1 VLLM_USE_BREAKABLE_CUDAGRAPH=0 VLLM_ENGINE_READY_TIMEOUT_S=3600" + prefill_env: "VLLM_ROCM_QUICK_REDUCE_QUANTIZATION=INT4 VLLM_ROCM_QUICK_REDUCE_MAX_SIZE_BYTES_MB=2048" hf_dir: "models--amd--MiniMax-M3-MXFP4" gpt-oss-120b: diff --git a/benchmarks/multi_node/amd_utils/server_vllm.sh b/benchmarks/multi_node/amd_utils/server_vllm.sh index f19ce8560b..55154cd015 100755 --- a/benchmarks/multi_node/amd_utils/server_vllm.sh +++ b/benchmarks/multi_node/amd_utils/server_vllm.sh @@ -145,10 +145,12 @@ pf = bash_escape(m.get('prefill_flags', '--tensor-parallel-size 8')) df = bash_escape(m.get('decode_flags', '--tensor-parallel-size 8')) ev = bash_escape(m.get('env', '')) dev = bash_escape(m.get('decode_env', '')) +pev = bash_escape(m.get('prefill_env', '')) print(f'PREFILL_SERVER_CONFIG=\"{pf}\"') print(f'DECODE_SERVER_CONFIG=\"{df}\"') print(f'MODEL_ENVS=\"{ev}\"') print(f'DECODE_MODEL_ENVS=\"{dev}\"') +print(f'PREFILL_MODEL_ENVS=\"{pev}\"') ")" echo "Loaded model configuration for: $MODEL_NAME" @@ -251,6 +253,11 @@ if [ "$NODE_RANK" -eq 0 ]; then setup_vllm_env + for env_pair in ${PREFILL_MODEL_ENVS}; do + export "$env_pair" + echo "[PREFILL_ENV] $env_pair" + done + # Router is started as an external container by job.slurm (VLLM_ROUTER_IMAGE) echo "Using external vllm-router container (started by job.slurm on this node)" @@ -420,6 +427,11 @@ elif [ "$NODE_RANK" -gt 0 ] && [ "$NODE_RANK" -lt "$xP" ]; then setup_vllm_env + for env_pair in ${PREFILL_MODEL_ENVS}; do + export "$env_pair" + echo "[PREFILL_ENV] $env_pair" + done + SERVED_MODEL="${MODEL_NAME}" PREFILL_CMD="vllm serve ${MODEL_PATH} \ --served-model-name ${SERVED_MODEL} \ From 2eb5331e1593953b1ed892813fab4faa0444d7b0 Mon Sep 17 00:00:00 2001 From: Duyi-Wang Date: Wed, 24 Jun 2026 14:05:37 +0000 Subject: [PATCH 07/10] [AMD] minimaxm3-fp4 disagg: cap 1P1D conc sweep at 128 --- .github/configs/amd-master.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/configs/amd-master.yaml b/.github/configs/amd-master.yaml index cdd91d83e7..698f2d02d3 100644 --- a/.github/configs/amd-master.yaml +++ b/.github/configs/amd-master.yaml @@ -2602,9 +2602,9 @@ minimaxm3-fp4-mi355x-vllm-disagg: - isl: 8192 osl: 1024 search-space: - # 1P TP4 + 1D TP4 (2 nodes total), conc sweep 1..256 (single job, looped) + # 1P TP4 + 1D TP4 (2 nodes total), conc sweep 1..128 (single job, looped) - spec-decoding: "none" - conc-list: [ 1, 2, 4, 8, 16, 32, 64, 128, 256 ] + conc-list: [ 1, 2, 4, 8, 16, 32, 64, 128 ] prefill: num-worker: 1 tp: 4 From 5dc09e4ed63d9e9263dee012a4bd5ac96630126b Mon Sep 17 00:00:00 2001 From: Duyi-Wang Date: Thu, 25 Jun 2026 05:45:29 +0000 Subject: [PATCH 08/10] [AMD] minimaxm3-fp4: drop prefill_env (INT4 quick-reduce) and its plumbing Remove the prefill-only VLLM_ROCM_QUICK_REDUCE_* env from the MiniMax-M3-MXFP4 model entry, and the now-unused prefill_env / PREFILL_MODEL_ENVS channel in server_vllm.sh. --- benchmarks/multi_node/amd_utils/models_vllm.yaml | 1 - benchmarks/multi_node/amd_utils/server_vllm.sh | 12 ------------ 2 files changed, 13 deletions(-) diff --git a/benchmarks/multi_node/amd_utils/models_vllm.yaml b/benchmarks/multi_node/amd_utils/models_vllm.yaml index 646cdba2ac..13456c2dcb 100644 --- a/benchmarks/multi_node/amd_utils/models_vllm.yaml +++ b/benchmarks/multi_node/amd_utils/models_vllm.yaml @@ -42,7 +42,6 @@ MiniMax-M3-MXFP4: prefill_flags: "--tensor-parallel-size 8 --max-num-batched-tokens 32768 --max-num-seqs 512 --block-size 128 --language-model-only --attention-backend TRITON_ATTN --moe-backend aiter --no-enable-prefix-caching --gpu-memory-utilization 0.90 --tool-call-parser minimax_m3 --reasoning-parser minimax_m3 --enable-auto-tool-choice" decode_flags: "--tensor-parallel-size 8 --max-num-batched-tokens 32768 --max-num-seqs 512 --block-size 128 --language-model-only --attention-backend TRITON_ATTN --moe-backend aiter --no-enable-prefix-caching --gpu-memory-utilization 0.90 --tool-call-parser minimax_m3 --reasoning-parser minimax_m3 --enable-auto-tool-choice" env: "VLLM_USE_V1=1 VLLM_ROCM_USE_AITER=1 VLLM_ROCM_USE_AITER_MOE=1 VLLM_USE_BREAKABLE_CUDAGRAPH=0 VLLM_ENGINE_READY_TIMEOUT_S=3600" - prefill_env: "VLLM_ROCM_QUICK_REDUCE_QUANTIZATION=INT4 VLLM_ROCM_QUICK_REDUCE_MAX_SIZE_BYTES_MB=2048" hf_dir: "models--amd--MiniMax-M3-MXFP4" gpt-oss-120b: diff --git a/benchmarks/multi_node/amd_utils/server_vllm.sh b/benchmarks/multi_node/amd_utils/server_vllm.sh index 55154cd015..f19ce8560b 100755 --- a/benchmarks/multi_node/amd_utils/server_vllm.sh +++ b/benchmarks/multi_node/amd_utils/server_vllm.sh @@ -145,12 +145,10 @@ pf = bash_escape(m.get('prefill_flags', '--tensor-parallel-size 8')) df = bash_escape(m.get('decode_flags', '--tensor-parallel-size 8')) ev = bash_escape(m.get('env', '')) dev = bash_escape(m.get('decode_env', '')) -pev = bash_escape(m.get('prefill_env', '')) print(f'PREFILL_SERVER_CONFIG=\"{pf}\"') print(f'DECODE_SERVER_CONFIG=\"{df}\"') print(f'MODEL_ENVS=\"{ev}\"') print(f'DECODE_MODEL_ENVS=\"{dev}\"') -print(f'PREFILL_MODEL_ENVS=\"{pev}\"') ")" echo "Loaded model configuration for: $MODEL_NAME" @@ -253,11 +251,6 @@ if [ "$NODE_RANK" -eq 0 ]; then setup_vllm_env - for env_pair in ${PREFILL_MODEL_ENVS}; do - export "$env_pair" - echo "[PREFILL_ENV] $env_pair" - done - # Router is started as an external container by job.slurm (VLLM_ROUTER_IMAGE) echo "Using external vllm-router container (started by job.slurm on this node)" @@ -427,11 +420,6 @@ elif [ "$NODE_RANK" -gt 0 ] && [ "$NODE_RANK" -lt "$xP" ]; then setup_vllm_env - for env_pair in ${PREFILL_MODEL_ENVS}; do - export "$env_pair" - echo "[PREFILL_ENV] $env_pair" - done - SERVED_MODEL="${MODEL_NAME}" PREFILL_CMD="vllm serve ${MODEL_PATH} \ --served-model-name ${SERVED_MODEL} \ From f1e314d52050e0f3c9154473b8db53f5f78d09ed Mon Sep 17 00:00:00 2001 From: Duyi-Wang Date: Thu, 25 Jun 2026 05:46:15 +0000 Subject: [PATCH 09/10] [AMD] minimaxm3-fp4 disagg: mori-0625 image, 1P1D conc 1..512, re-add 2P1D - image -> rocm/vllm-dev:vllm-0.23.1-rocm723-mi35x-mori-0625 - 1P1D TP4 conc sweep back to 1..512 - re-add 2P1D TP4 layout at conc 128/256/512 --- .github/configs/amd-master.yaml | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/.github/configs/amd-master.yaml b/.github/configs/amd-master.yaml index 698f2d02d3..6e06029ff1 100644 --- a/.github/configs/amd-master.yaml +++ b/.github/configs/amd-master.yaml @@ -2589,7 +2589,7 @@ minimaxm3-fp8-mi355x-vllm-mtp: # MiniMax-M3 MXFP4 MI355X vLLM disaggregated (prefill/decode) config. minimaxm3-fp4-mi355x-vllm-disagg: - image: rocm/sgl-dev:vllm-0.23.1-rocm723-mi35x-mori-0624-2 + image: rocm/vllm-dev:vllm-0.23.1-rocm723-mi35x-mori-0625 model: amd/MiniMax-M3-MXFP4 model-prefix: minimaxm3 runner: mi355x-disagg @@ -2602,9 +2602,9 @@ minimaxm3-fp4-mi355x-vllm-disagg: - isl: 8192 osl: 1024 search-space: - # 1P TP4 + 1D TP4 (2 nodes total), conc sweep 1..128 (single job, looped) + # 1P TP4 + 1D TP4 (2 nodes total), conc sweep 1..512 (single job, looped) - spec-decoding: "none" - conc-list: [ 1, 2, 4, 8, 16, 32, 64, 128 ] + conc-list: [ 1, 2, 4, 8, 16, 32, 64, 128, 256, 512 ] prefill: num-worker: 1 tp: 4 @@ -2619,6 +2619,23 @@ minimaxm3-fp4-mi355x-vllm-disagg: dp-attn: false additional-settings: - "DECODE_NODES=1" + # 2P TP4 + 1D TP4 (3 nodes total), conc 128/256/512 (single job, looped) + - spec-decoding: "none" + conc-list: [ 128, 256, 512 ] + prefill: + num-worker: 2 + tp: 4 + ep: 1 + dp-attn: false + additional-settings: + - "PREFILL_NODES=2" + decode: + num-worker: 1 + tp: 4 + ep: 1 + dp-attn: false + additional-settings: + - "DECODE_NODES=1" # MiniMax-M3 MXFP4 MI355X atom recipe: # https://github.com/ROCm/ATOM/blob/5d42d49f9e4292e5b61475917e92e7ec1b1dacb7/recipes/MiniMax-M3.md From eff31ec4e3deb96afbab282075cdc8302555f76a Mon Sep 17 00:00:00 2001 From: functionstackx <47992694+functionstackx@users.noreply.github.com> Date: Thu, 25 Jun 2026 15:13:31 -0400 Subject: [PATCH 10/10] fix: keep perf-changelog.yaml append-only for reuse merge PR 1914 had stripped trailing whitespace on 3 existing entries (1676, 1865, 1927), breaking the byte-for-byte append-only rule enforced by validate_perf_changelog. Restore main's historical bytes verbatim and append only the new minimaxm3-fp4-mi355x-vllm-disagg entry. Co-Authored-By: Claude Opus 4.8 --- perf-changelog.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/perf-changelog.yaml b/perf-changelog.yaml index 887abf5e53..f504fc4d92 100644 --- a/perf-changelog.yaml +++ b/perf-changelog.yaml @@ -4146,7 +4146,7 @@ - "Image: lmsysorg/sglang:nightly-dev-cu13-20260528-0abe6a85" - "8 topologies: low-latency 1p1d-tp8-tp8 + 1p6d-dep8-tp8; mid-curve 1p1d through 6p1d-dep8-dep16." pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/1676 - + - config-keys: - minimaxm3-fp8-b300-dynamo-vllm description: @@ -4162,7 +4162,7 @@ - "server_atom.sh: fix _MAX_CONC assignment before cudagraph size check; gate ATOM_MOE_GU_ITLV/AITER_BF16_FP8_MOE_BOUND on DeepSeek-V4-Pro only" - "Search space: ISL=8192 and ISL=1024, 1P1D TP4, conc 1-512" pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/1865 - + - config-keys: - minimaxm3-fp8-mi355x-vllm-disagg description: @@ -4183,7 +4183,7 @@ - "server_atom.sh: fix _MAX_CONC assignment before cudagraph size check; gate ATOM_MOE_GU_ITLV/AITER_BF16_FP8_MOE_BOUND on DeepSeek-V4-Pro only" - "Search space: ISL=8192 and ISL=1024, 1P1D TP4, conc 1-512" pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/1927 - + - config-keys: - dsv4-fp4-b200-dynamo-vllm description: